summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xc/include/extensions/randr.h58
-rw-r--r--xc/include/extensions/randrproto.h193
-rw-r--r--xc/lib/X11/Xintatom.h33
-rw-r--r--xc/lib/X11/Xintconn.h27
-rw-r--r--xc/lib/Xrandr/Imakefile33
-rw-r--r--xc/lib/Xrandr/Xrandr-def.cpp18
-rw-r--r--xc/lib/Xrandr/Xrandr.c472
-rw-r--r--xc/lib/Xrandr/Xrandr.h107
-rw-r--r--xc/lib/Xrandr/Xrandrint.h67
-rw-r--r--xc/lib/Xrandr/test.c21
-rw-r--r--xc/lib/Xt/ShellI.h12
-rw-r--r--xc/lib/font/fontfile/fontencc.c74
-rw-r--r--xc/lib/font/include/fontencc.h36
-rw-r--r--xc/lib/fontenc/Imakefile28
-rw-r--r--xc/programs/Xserver/Xext/sleepuntil.h47
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/XView.h44
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/XView.m195
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/XWindow.h37
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/XWindow.m111
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/fakeBoxRec.h15
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/rootless.h127
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/rootlessAqua.h15
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/rootlessAquaGlue.c193
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/rootlessAquaImp.h38
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/rootlessAquaImp.m135
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/rootlessCommon.c191
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/rootlessCommon.h209
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/rootlessGC.c1170
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/rootlessScreen.c430
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/rootlessValTree.c744
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/rootlessWindow.c753
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/rootlessWindow.h32
-rw-r--r--xc/programs/Xserver/hw/kdrive/ipaq/Imakefile13
-rw-r--r--xc/programs/Xserver/hw/kdrive/ipaq/ipaq.c89
-rw-r--r--xc/programs/Xserver/hw/kdrive/kaa.c636
-rw-r--r--xc/programs/Xserver/hw/kdrive/linux/ms.c158
-rw-r--r--xc/programs/Xserver/hw/kdrive/mach64/Imakefile20
-rw-r--r--xc/programs/Xserver/hw/kdrive/mach64/mach64.c450
-rw-r--r--xc/programs/Xserver/hw/kdrive/mach64/mach64.h655
-rw-r--r--xc/programs/Xserver/hw/kdrive/mach64/mach64curs.c389
-rw-r--r--xc/programs/Xserver/hw/kdrive/mach64/mach64draw.c420
-rw-r--r--xc/programs/Xserver/hw/kdrive/mach64/mach64draw.h72
-rw-r--r--xc/programs/Xserver/hw/kdrive/mach64/mach64stub.c58
-rw-r--r--xc/programs/Xserver/hw/kdrive/mach64/mach64video.c1045
-rw-r--r--xc/programs/Xserver/hw/kdrive/pcmcia/Imakefile13
-rw-r--r--xc/programs/Xserver/hw/kdrive/pcmcia/modes.h66
-rw-r--r--xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.c1251
-rw-r--r--xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.h264
-rw-r--r--xc/programs/Xserver/hw/kdrive/pcmcia/pcmciacurs.c449
-rw-r--r--xc/programs/Xserver/hw/kdrive/pcmcia/pcmciashadow.c197
-rw-r--r--xc/programs/Xserver/hw/kdrive/pcmcia/pcmciastub.c54
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/OS2Notes.sgml214
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/QuickStart.sgml679
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/VideoModes.sgml1428
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3/Imakefile60
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3/newmmio.h263
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3/s3.h231
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3/s3_IBMRGB.c551
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3/s3_Ti.c754
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3/s3_Trio64DAC.c354
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3/s3_accel.c605
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3/s3_bios.c83
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3/s3_cursor.c226
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3/s3_dga.c318
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3/s3_driver.c1759
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3/s3_reg.h262
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3/s3_video.c669
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/bin-excl6
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/bin-list36
-rwxr-xr-xxc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/build-bindist148
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/dir1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/etc-dir1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/etc-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/fsrv-list2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/host.def3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/lib-excl14
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/lib-list2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/man-excl2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/man-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/nest-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/prog-excl5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/prog-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/prt-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/update-upd32
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/vfb-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/xserv-list2
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/acecad/acecad.c916
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/acecad/acecad.h111
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/acecad/acecad.man40
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/calcomp/Imakefile26
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/calcomp/calcomp.man82
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/calcomp/xf86Calcomp.c834
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/calcomp/xf86Calcomp.h144
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/dmc/Imakefile30
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/dmc/dmc.man39
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/dmc/xf86DMC.c692
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/dmc/xf86DMC.h93
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/magictouch/Imakefile30
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/magictouch/magictouch.man25
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/magictouch/xf86MagicTouch.c1107
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sunos/Imakefile85
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_bios.c104
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_init.c330
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_inout.s124
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_io.c56
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_kbd.c112
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_kbdEv.c497
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_mouse.c316
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_vid.c239
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf86cfg/TODO33
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf86cfg/loadmod.c595
-rw-r--r--xc/programs/Xserver/hw/xwin/XWin.man86
-rw-r--r--xc/programs/Xserver/hw/xwin/wincutpaste.c53
-rw-r--r--xc/programs/Xserver/hw/xwin/winlayer.c236
-rw-r--r--xc/programs/Xserver/hw/xwin/winnativegdi.c387
-rw-r--r--xc/programs/Xserver/miext/layer/Imakefile44
-rw-r--r--xc/programs/Xserver/miext/layer/layer.h145
-rw-r--r--xc/programs/Xserver/miext/layer/layergc.c192
-rw-r--r--xc/programs/Xserver/miext/layer/layerinit.c351
-rw-r--r--xc/programs/Xserver/miext/layer/layerpict.c145
-rw-r--r--xc/programs/Xserver/miext/layer/layerstr.h411
-rw-r--r--xc/programs/Xserver/miext/layer/layerwin.c443
-rw-r--r--xc/programs/Xserver/miext/shadow/shrot16pack_180.c29
-rw-r--r--xc/programs/Xserver/miext/shadow/shrot16pack_270.c29
-rw-r--r--xc/programs/Xserver/miext/shadow/shrot16pack_90.c29
-rw-r--r--xc/programs/Xserver/miext/shadow/shrot32pack_180.c29
-rw-r--r--xc/programs/Xserver/miext/shadow/shrot32pack_270.c29
-rw-r--r--xc/programs/Xserver/miext/shadow/shrot32pack_90.c29
-rw-r--r--xc/programs/Xserver/miext/shadow/shrot8pack_180.c29
-rw-r--r--xc/programs/Xserver/miext/shadow/shrot8pack_270.c29
-rw-r--r--xc/programs/Xserver/miext/shadow/shrot8pack_90.c29
-rw-r--r--xc/programs/Xserver/miext/shadow/shrotate.c243
-rw-r--r--xc/programs/Xserver/render/miindex.c252
133 files changed, 30591 insertions, 0 deletions
diff --git a/xc/include/extensions/randr.h b/xc/include/extensions/randr.h
new file mode 100644
index 000000000..da579a1c0
--- /dev/null
+++ b/xc/include/extensions/randr.h
@@ -0,0 +1,58 @@
+/*
+ * $XFree86: xc/include/extensions/randr.h,v 1.3 2001/06/07 17:54:01 keithp Exp $
+ *
+ * Copyright © 2000 Compaq Computer Corporation, 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 Compaq not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Compaq makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * COMPAQ DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL COMPAQ
+ * 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: Jim Gettys, Compaq Computer Corporation, Inc.
+ */
+
+#ifndef _RANDR_H_
+#define _RANDR_H_
+
+typedef CARD16 Rotation;
+typedef CARD16 VisualGroupID;
+typedef CARD16 GroupOfVisualGroupID;
+typedef CARD16 SizeID;
+
+#define RANDR_NAME "RANDR"
+#define RANDR_MAJOR 0
+#define RANDR_MINOR 0
+
+#define RRNumberErrors 0
+#define RRNumberEvents 1
+
+#define X_RRQueryVersion 0
+#define X_RRGetScreenInfo 1
+#define X_RRSetScreenConfig 2
+#define X_RRScreenChangeSelectInput 3
+
+#define RRScreenChangeNotify 0
+
+#define RR_Rotate_0 1
+#define RR_Rotate_90 2
+#define RR_Rotate_180 4
+#define RR_Rotate_270 8
+
+#define RRSetConfigSuccess 0
+#define RRSetConfigInvalidConfigTime 1
+#define RRSetConfigInvalidTime 2
+#define RRSetConfigFailed 3
+
+#endif /* _RANDR_H_ */
diff --git a/xc/include/extensions/randrproto.h b/xc/include/extensions/randrproto.h
new file mode 100644
index 000000000..e9218d9ec
--- /dev/null
+++ b/xc/include/extensions/randrproto.h
@@ -0,0 +1,193 @@
+/*
+ * $XFree86: xc/include/extensions/randrproto.h,v 1.5 2001/08/01 00:44:35 tsi Exp $
+ *
+ * Copyright © 2000 Compaq Computer Corporation
+ *
+ * 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 Compaq not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Compaq makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * COMPAQ DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL COMPAQ
+ * 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: Jim Gettys, Compaq Computer Corporation, Inc.
+ */
+
+#ifndef _XRANDRP_H_
+#define _XRANDRP_H_
+
+#include <X11/extensions/randr.h>
+
+#define Window CARD32
+#define Drawable CARD32
+#define Font CARD32
+#define Pixmap CARD32
+#define Cursor CARD32
+#define Colormap CARD32
+#define GContext CARD32
+#define Atom CARD32
+#define VisualID CARD32
+#define Time CARD32
+#define KeyCode CARD8
+#define KeySym CARD32
+
+#define Rotation CARD16
+#define VisualGroupID CARD16
+#define GroupOfVisualGroupID CARD16
+#define SizeID CARD16
+
+/*
+ * data structures
+ */
+
+typedef struct {
+ CARD16 widthInPixels B16;
+ CARD16 heightInPixels B16;
+ CARD16 widthInMillimeters B16;
+ CARD16 heightInMillimeters B16;
+ GroupOfVisualGroupID visualGroup B16;
+ CARD16 pad1 B16;
+} xScreenSizes;
+#define sz_xScreenSizes 12
+
+
+
+/*
+ * requests and replies
+ */
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ CARD32 majorVersion B32;
+ CARD32 minorVersion B32;
+} xRRQueryVersionReq;
+#define sz_xRRQueryVersionReq 12
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE pad1;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 majorVersion B32;
+ CARD32 minorVersion B32;
+ CARD32 pad2 B32;
+ CARD32 pad3 B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+} xRRQueryVersionReply;
+#define sz_xRRQueryVersionReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ Window window B32;
+} xRRGetScreenInfoReq;
+#define sz_xRRGetScreenInfoReq 8
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE setOfRotations;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ Window root B32;
+ Time timestamp B32;
+ Time configTimestamp B32;
+ CARD16 nVisualGroups B16;
+ CARD16 nGroupsOfVisualGroups B16;
+ CARD16 nSizes B16;
+ SizeID sizeID B16;
+ VisualGroupID visualGroupID B16;
+ Rotation rotation B16;
+} xRRGetScreenInfoReply;
+#define sz_xRRGetScreenInfoReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ Drawable drawable B32;
+ Time timestamp B32;
+ Time configTimestamp B32;
+ SizeID sizeID B16;
+ Rotation rotation B16;
+ VisualGroupID visualGroupID B16;
+ CARD16 pad B16;
+} xRRSetScreenConfigReq;
+#define sz_xRRSetScreenConfigReq 24
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ CARD8 status;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ Time newTimestamp B32;
+ Time newConfigTimestamp B32;
+ Window root;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+ CARD32 pad6 B32;
+} xRRSetScreenConfigReply;
+#define sz_xRRSetScreenConfigReply 32
+
+typedef struct {
+ CARD8 reqType;
+ CARD8 randrReqType;
+ CARD16 length B16;
+ Window window B32;
+ BYTE enable; /* xTrue -> send events */
+ BYTE pad1;
+ CARD16 pad2 B16;
+} xRRScreenChangeSelectInputReq;
+#define sz_xRRScreenChangeSelectInputReq 12
+
+/*
+ * event
+ */
+typedef struct {
+ CARD8 type; /* always evBase + ScreenChangeNotify */
+ CARD8 rotation; /* new rotation */
+ CARD16 sequenceNumber B16;
+ Time timestamp B32; /* time screen was changed */
+ Time configTimestamp B32; /* time config data was changed */
+ Window root B32; /* root window */
+ Window window B32; /* window requesting notification */
+ SizeID sizeID B16; /* new size ID */
+ VisualGroupID visualGroupID B16; /* new visual group ID */
+ CARD16 widthInPixels B16; /* new size */
+ CARD16 heightInPixels B16;
+ CARD16 widthInMillimeters B16;
+ CARD16 heightInMillimeters B16;
+} xRRScreenChangeNotifyEvent;
+#define sz_xRRScreenChangeNotifyEvent 32
+
+#undef Window
+#undef Drawable
+#undef Font
+#undef Pixmap
+#undef Cursor
+#undef Colormap
+#undef GContext
+#undef Atom
+#undef VisualID
+#undef Time
+#undef KeyCode
+#undef KeySym
+#undef Rotation
+#undef VisualGroupID
+#undef GroupOfVisualGroupID
+#undef SizeID
+
+#endif /* _XRANDRP_H_ */
diff --git a/xc/lib/X11/Xintatom.h b/xc/lib/X11/Xintatom.h
new file mode 100644
index 000000000..910c0fa21
--- /dev/null
+++ b/xc/lib/X11/Xintatom.h
@@ -0,0 +1,33 @@
+/* $XFree86: xc/lib/X11/Xintatom.h,v 1.1 2001/08/18 02:41:28 dawes Exp $ */
+
+#ifndef _XINTATOM_H_
+#define _XINTATOM_H_ 1
+
+#include <X11/Xfuncproto.h>
+
+/* IntAtom.c */
+
+#define TABLESIZE 64
+
+typedef struct _Entry {
+ unsigned long sig;
+ Atom atom;
+} EntryRec, *Entry;
+
+#define RESERVED ((Entry) 1)
+
+#define EntryName(e) ((char *)(e+1))
+
+typedef struct _XDisplayAtoms {
+ Entry table[TABLESIZE];
+} AtomTable;
+
+_XFUNCPROTOBEGIN
+
+extern void _XUpdateAtomCache(Display *dpy, const char *name, Atom atom,
+ unsigned long sig, int idx, int n);
+extern void _XFreeAtomTable(Display *dpy);
+
+_XFUNCPROTOEND
+
+#endif /* _XINTATOM_H_ */
diff --git a/xc/lib/X11/Xintconn.h b/xc/lib/X11/Xintconn.h
new file mode 100644
index 000000000..3010da4f0
--- /dev/null
+++ b/xc/lib/X11/Xintconn.h
@@ -0,0 +1,27 @@
+/* $XFree86: xc/lib/X11/Xintconn.h,v 1.1 2001/08/18 02:41:28 dawes Exp $ */
+
+#ifndef _XINTCONN_H_
+#define _XINTCONN_H_ 1
+
+#include <X11/Xfuncproto.h>
+
+_XFUNCPROTOBEGIN
+
+/* ConnDis.c */
+
+extern int _XDisconnectDisplay(XtransConnInfo trans_conn);
+extern Bool _XSendClientPrefix(Display *dpy, xConnClientPrefix *client,
+ char *auth_proto, char *auth_string,
+ xConnSetupPrefix *prefix);
+extern XtransConnInfo _X11TransConnectDisplay(char *display_name,
+ char **fullnamep, int *dpynump,
+ int *screenp, char **auth_namep,
+ int *auth_namelenp, char **auth_datap,
+ int *auth_datalenp);
+
+/* OpenDis.c */
+extern void _XFreeDisplayStructure(Display *dpy);
+
+_XFUNCPROTOEND
+
+#endif /* _XINTCONN_H_ */
diff --git a/xc/lib/Xrandr/Imakefile b/xc/lib/Xrandr/Imakefile
new file mode 100644
index 000000000..b429281dd
--- /dev/null
+++ b/xc/lib/Xrandr/Imakefile
@@ -0,0 +1,33 @@
+XCOMM $XFree86: xc/lib/Xrandr/Imakefile,v 1.1 2001/05/23 03:29:44 keithp Exp $
+
+
+#define DoNormalLib NormalLibXrandr
+#define DoSharedLib SharedLibXrandr
+#define DoDebugLib DebugLibXrandr
+#define DoProfileLib ProfileLibXrandr
+#define LibName Xrandr
+#define SoRev SOXRANDRREV
+#define IncSubdir X11
+#define IncSubSubdir extensions
+
+#include <Threads.tmpl>
+
+#ifdef SharedXrandrReqs
+REQUIREDLIBS = SharedXrandrReqs
+#endif
+
+#if Malloc0ReturnsNull
+ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL
+#endif
+
+ DEFINES = $(ALLOC_DEFINES)
+ INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC)
+ SRCS = Xrandr.c
+ OBJS = Xrandr.o
+ LINTLIBS = $(LINTXLIB)
+
+HEADERS = Xrandr.h
+
+#include <Library.tmpl>
+
+DependTarget()
diff --git a/xc/lib/Xrandr/Xrandr-def.cpp b/xc/lib/Xrandr/Xrandr-def.cpp
new file mode 100644
index 000000000..1c94e08a1
--- /dev/null
+++ b/xc/lib/Xrandr/Xrandr-def.cpp
@@ -0,0 +1,18 @@
+LIBRARY Xrandr
+VERSION LIBRARY_VERSION
+EXPORTS
+ XRRCurrentConfig
+ XRRFindDisplay
+ XRRFreeScreenInfo
+ XRRGetScreenInfo
+ XRRQueryExtension
+ XRRQueryVersion
+ XRRRootToScreen
+ XRRRotations
+ XRRScreenChangeSelectInput
+ XRRSetScreenConfig
+ XRRSizes
+ XRRTimes
+ XRRVisualIDToVisual
+ XRRVisualToDepth
+/* $XFree86: xc/lib/Xrandr/Xrandr-def.cpp,v 1.1 2001/08/19 15:22:58 alanh Exp $ */
diff --git a/xc/lib/Xrandr/Xrandr.c b/xc/lib/Xrandr/Xrandr.c
new file mode 100644
index 000000000..84dba2183
--- /dev/null
+++ b/xc/lib/Xrandr/Xrandr.c
@@ -0,0 +1,472 @@
+/*
+ * $XFree86: xc/lib/Xrandr/Xrandr.c,v 1.6 2001/06/11 01:37:53 keithp Exp $
+ *
+ * Copyright © 2000 Compaq Computer Corporation, 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 Compaq not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Compaq makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * COMPAQ DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL COMPAQ
+ * 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: Jim Gettys, Compaq Computer Corporation, Inc.
+ */
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include "Xrandrint.h"
+
+XExtensionInfo XRRExtensionInfo;
+char XRRExtensionName[] = RANDR_NAME;
+
+static Bool XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire);
+static Status XRREventToWire(Display *dpy, XEvent *event, xEvent *wire);
+
+static int
+XRRCloseDisplay (Display *dpy, XExtCodes *codes);
+
+static /* const */ XExtensionHooks rr_extension_hooks = {
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ XRRCloseDisplay, /* close_display */
+ XRRWireToEvent, /* wire_to_event */
+ XRREventToWire, /* event_to_wire */
+ NULL, /* error */
+ NULL, /* error_string */
+};
+
+static Bool XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ XRRScreenChangeNotifyEvent *aevent;
+ xRRScreenChangeNotifyEvent *awire;
+
+ RRCheckExtension(dpy, info, False);
+
+ switch ((wire->u.u.type & 0x7F) - info->codes->first_event)
+ {
+ case RRScreenChangeNotify:
+ awire = (xRRScreenChangeNotifyEvent *) wire;
+ aevent = (XRRScreenChangeNotifyEvent *) event;
+ aevent->type = awire->type & 0x7F;
+ aevent->serial = _XSetLastRequestRead(dpy,
+ (xGenericReply *) wire);
+ aevent->send_event = (awire->type & 0x80) != 0;
+ aevent->display = dpy;
+ aevent->window = awire->window;
+ aevent->root = awire->root;
+ aevent->timestamp = awire->timestamp;
+ aevent->config_timestamp = awire->configTimestamp;
+ aevent->size_index = awire->sizeID;
+ aevent->visual_group_index = awire->visualGroupID;
+ aevent->rotation = awire->rotation;
+ aevent->width = awire->widthInPixels;
+ aevent->height = awire->heightInPixels;
+ aevent->mwidth = awire->widthInMillimeters;
+ aevent->mheight = awire->heightInMillimeters;
+ return True;
+ }
+
+ return False;
+}
+
+static Status XRREventToWire(Display *dpy, XEvent *event, xEvent *wire)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ XRRScreenChangeNotifyEvent *aevent;
+ xRRScreenChangeNotifyEvent *awire;
+
+ RRCheckExtension(dpy, info, False);
+
+ switch ((event->type & 0x7F) - info->codes->first_event)
+ {
+ case RRScreenChangeNotify:
+ awire = (xRRScreenChangeNotifyEvent *) wire;
+ aevent = (XRRScreenChangeNotifyEvent *) event;
+ awire->type = aevent->type | (aevent->send_event ? 0x80 : 0);
+ awire->rotation = (CARD8) aevent->rotation;
+ awire->sequenceNumber = aevent->serial & 0xFFFF;
+ awire->timestamp = aevent->timestamp;
+ awire->configTimestamp = aevent->config_timestamp;
+ awire->root = aevent->root;
+ awire->window = aevent->window;
+ awire->sizeID = aevent->size_index;
+ awire->visualGroupID = aevent->visual_group_index;
+ awire->widthInPixels = aevent->width;
+ awire->heightInPixels = aevent->height;
+ awire->widthInMillimeters = aevent->mwidth;
+ awire->heightInMillimeters = aevent->mheight;
+ return True;
+ }
+ return False;
+}
+
+XExtDisplayInfo *
+XRRFindDisplay (Display *dpy)
+{
+ XExtDisplayInfo *dpyinfo;
+
+ dpyinfo = XextFindDisplay (&XRRExtensionInfo, dpy);
+ if (!dpyinfo)
+ dpyinfo = XextAddDisplay (&XRRExtensionInfo, dpy,
+ XRRExtensionName,
+ &rr_extension_hooks,
+ RRNumberEvents, 0);
+ return dpyinfo;
+}
+
+static int
+XRRCloseDisplay (Display *dpy, XExtCodes *codes)
+{
+ XExtDisplayInfo *info = XRRFindDisplay (dpy);
+ if (info->data) XFree (info->data);
+
+ return XextRemoveDisplay (&XRRExtensionInfo, dpy);
+}
+
+/****************************************************************************
+ * *
+ * RandR public interfaces *
+ * *
+ ****************************************************************************/
+int XRRVisualToDepth(Display *dpy, Visual *visual)
+{
+ int s;
+ for (s = 0; s < ScreenCount(dpy); s++) {
+ Screen *sp = ScreenOfDisplay(dpy, s);
+ int d;
+ for (d = 0; d < sp->ndepths; d++) {
+ int v;
+ for (v = 0; v < sp->depths[s].nvisuals; v++) {
+ if ( &sp->depths[s].visuals[v] == visual ) return d;
+ }
+ }
+ }
+ return -1; /* should not ever happen */
+}
+
+Visual *XRRVisualIDToVisual(Display *dpy, int screen, VisualID id)
+{
+ int d, v;
+ Screen *sp = ScreenOfDisplay(dpy, screen);
+ for (d = 0; d < sp->ndepths; d++) {
+ for (v = 0; v < sp->depths[d].nvisuals; v++) {
+ if ( sp->depths[d].visuals[v].visualid == id )
+ return (&sp->depths[d].visuals[v]);
+ }
+ }
+ return NULL;
+}
+
+Rotation XRRRotations(XRRScreenConfiguration *config, Rotation *current_rotation)
+{
+ *current_rotation = config->current_rotation;
+ return config->rotations;
+}
+
+XRRScreenSize *XRRSizes(XRRScreenConfiguration *config, int *nsizes)
+{
+ *nsizes = config->nsizes;
+ return config->sizes;
+}
+
+Time XRRTimes (XRRScreenConfiguration *config, Time *config_timestamp)
+{
+ *config_timestamp = config->config_timestamp;
+ return config->timestamp;
+}
+
+SizeID XRRCurrentConfig (XRRScreenConfiguration *config, VisualGroupID *visual_group, Rotation *rotation)
+{
+ *visual_group = (VisualGroupID) config->current_visual_group;
+ *rotation = (Rotation) config->current_rotation;
+ return (SizeID) config->current_size;
+}
+
+int XRRRootToScreen(Display *dpy, Window root)
+{
+ int snum;
+ for (snum = 0; snum < ScreenCount(dpy); snum++) {
+ if (RootWindow(dpy, snum) == root) return snum;
+ }
+ return -1;
+}
+
+
+Bool XRRQueryExtension (Display *dpy, int *event_basep, int *error_basep)
+{
+ XExtDisplayInfo *info = XRRFindDisplay (dpy);
+
+ if (XextHasExtension(info)) {
+ *event_basep = info->codes->first_event;
+ *error_basep = info->codes->first_error;
+ return True;
+ } else {
+ return False;
+ }
+}
+
+
+Status XRRQueryVersion (Display *dpy,
+ int *major_versionp,
+ int *minor_versionp)
+{
+ XExtDisplayInfo *info = XRRFindDisplay (dpy);
+ xRRQueryVersionReply rep;
+ xRRQueryVersionReq *req;
+
+ RRCheckExtension (dpy, info, 0);
+
+ LockDisplay (dpy);
+ GetReq (RRQueryVersion, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRQueryVersion;
+ req->majorVersion = RANDR_MAJOR;
+ req->minorVersion = RANDR_MINOR;
+ if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return 0;
+ }
+ *major_versionp = rep.majorVersion;
+ *minor_versionp = rep.minorVersion;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return 1;
+}
+
+XRRScreenConfiguration *XRRGetScreenInfo (Display *dpy, Window window)
+{
+ XExtDisplayInfo *info = XRRFindDisplay(dpy);
+ xRRGetScreenInfoReply rep;
+ xRRGetScreenInfoReq *req;
+ int nbytes, rbytes;
+ int i, j;
+ int nvisuals, ngroups;
+ int snum;
+ xScreenSizes *psize;
+ char *data;
+ struct _XRRScreenConfiguration *scp;
+ XRRVisualGroup *vgp;
+ XRRGroupOfVisualGroup *gvgp;
+ XRRVisualGroup **gp;
+ XRRScreenSize *ssp;
+ Visual **vgpp;
+ CARD32 *data32;
+ CARD16 *data16;
+
+ RRCheckExtension (dpy, info, 0);
+
+ LockDisplay (dpy);
+ GetReq (RRGetScreenInfo, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRGetScreenInfo;
+ req->window = window;
+ if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
+ {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return NULL;
+ }
+ nbytes = (long) rep.length << 2;
+ data = (char *) Xmalloc ((unsigned) nbytes);
+ if (!data)
+ {
+ _XEatData (dpy, (unsigned long) nbytes);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return NULL;
+ }
+ _XReadPad (dpy, data, nbytes);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+
+ /*
+ * first we must compute how much space to allocate for
+ * randr library's use; we'll allocate the structures in a single
+ * allocation, on cleanlyness grounds.
+ */
+
+ /* pick up in the protocol buffer after the protocol size information */
+ psize = (xScreenSizes *) data;
+ data32 = (CARD32 *) &psize[rep.nSizes];
+ vgp = (XRRVisualGroup *) ssp; /* visual groups after size structures */
+ /* and groups of visual groups structures after the array of visual groups */
+ gvgp = (XRRGroupOfVisualGroup *) &vgp[rep.nVisualGroups];
+
+ /*
+ * first we count up the number of groups
+ */
+ nvisuals = 0;
+ for (i = 0; i < rep.nVisualGroups; i++) {
+ j = *data32;
+ data32 += j + 1;
+ nvisuals += j;
+ }
+
+ /*
+ * Next comes the groups of visual groups
+ */
+
+ data16 = (CARD16 *) data32;
+ /*
+ * We count up the number of groups
+ */
+ ngroups = 0;
+ for (i = 0; i < rep.nGroupsOfVisualGroups; i++) {
+ j = *data16;
+ data16 += j + 1;
+ ngroups += j;
+ }
+
+ rbytes = sizeof (XRRScreenConfiguration) +
+ (rep.nVisualGroups * sizeof (XRRVisualGroup)) +
+ (rep.nGroupsOfVisualGroups * sizeof (XRRGroupOfVisualGroup)) +
+ (rep.nSizes * sizeof (XRRScreenSize)) +
+ (nvisuals * sizeof (Visual *)) +
+ (ngroups * sizeof (XRRGroupOfVisualGroup *));
+
+ scp = (struct _XRRScreenConfiguration *) Xmalloc(rbytes);
+ if (scp == NULL) return NULL;
+
+
+ ssp = (XRRScreenSize *)(scp + 1);
+ vgp = (XRRVisualGroup *) (&ssp[rep.nSizes]);
+ gvgp = (XRRGroupOfVisualGroup *) (&vgp[rep.nVisualGroups]);
+ vgpp = (Visual **) (&gvgp[rep.nGroupsOfVisualGroups]);
+ gp = (XRRVisualGroup **) (&vgpp[ngroups]);
+ /* set up the screen configuration structure */
+ scp->screen = ScreenOfDisplay (dpy, (snum = XRRRootToScreen(dpy, rep.root)));
+
+ scp->visual_group = vgp;
+ scp->groups_of_visual_groups = gvgp;
+ scp->sizes = ssp;
+ scp->rotations = rep.setOfRotations;
+ scp->current_size = rep.sizeID;
+ scp->current_visual_group = rep.visualGroupID;
+ scp->current_rotation = rep.rotation;
+ scp->timestamp = rep.timestamp;
+ scp->config_timestamp = rep.configTimestamp;
+ scp->nsizes = rep.nSizes;
+
+ /*
+ * Time to unpack the data from the server.
+ */
+
+ /*
+ * First comes the size information
+ */
+ psize = (xScreenSizes *) data;
+ for (i = 0; i < rep.nSizes; i++) {
+ ssp[i].width = psize[i].widthInPixels;
+ ssp[i].height = psize[i].heightInPixels;
+ ssp[i].mwidth = psize[i].widthInMillimeters;
+ ssp[i].mheight = psize[i].heightInMillimeters;
+ ssp[i].group = psize[i].visualGroup;
+ }
+ /*
+ * Next comes the visual groups
+ */
+
+ data32 = (CARD32 *) &psize[i];
+
+ for (i = 0; i < rep.nVisualGroups; i++) {
+ vgp[i].visuals = vgpp;
+ vgp[i].nvisuals = (int) *data32++;
+ for (j = 0; j < vgp->nvisuals; j++) {
+ *vgpp = XRRVisualIDToVisual(dpy, snum, (VisualID) *data32++);
+ vgpp += 1;
+ }
+ }
+
+
+ data16 = (CARD16 *) data32;
+
+ for (i = 0; i < rep.nGroupsOfVisualGroups; i++) {
+ gvgp[i].groups = gp;
+ gvgp[i].ngroups = (int) *data16++;
+ for (j = 0; j < gvgp[i].ngroups; j++) {
+ gvgp[i].groups[j] = &vgp[*data16++];
+ gp += 1;
+ }
+ }
+
+ return (XRRScreenConfiguration *)(scp);
+}
+
+void XRRFreeScreenInfo (XRRScreenConfiguration *config)
+{
+ Xfree (config);
+}
+
+void XRRScreenChangeSelectInput (Display *dpy, Window window, Bool enable)
+{
+ XExtDisplayInfo *info = XRRFindDisplay (dpy);
+ xRRScreenChangeSelectInputReq *req;
+
+ RRSimpleCheckExtension (dpy, info);
+
+ LockDisplay (dpy);
+ GetReq (RRScreenChangeSelectInput, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRScreenChangeSelectInput;
+ req->window = window;
+ req->enable = xFalse;
+ if (enable) req->enable = xTrue;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return;
+}
+
+Status XRRSetScreenConfig (Display *dpy,
+ XRRScreenConfiguration *config,
+ Drawable draw,
+ int size_index,
+ int visual_group_index,
+ Rotation rotation, Time timestamp)
+{
+ XExtDisplayInfo *info = XRRFindDisplay (dpy);
+ xRRSetScreenConfigReply rep;
+ xRRSetScreenConfigReq *req;
+
+ RRCheckExtension (dpy, info, 0);
+
+ LockDisplay (dpy);
+ GetReq (RRSetScreenConfig, req);
+ req->reqType = info->codes->major_opcode;
+ req->randrReqType = X_RRSetScreenConfig;
+ req->drawable = draw;
+ req->sizeID = size_index;
+ req->visualGroupID = visual_group_index;
+ req->rotation = rotation;
+ req->timestamp = timestamp;
+ req->configTimestamp = config->config_timestamp;
+ (void) _XReply (dpy, (xReply *) &rep, 0, xTrue);
+
+ if (rep.status == RRSetConfigSuccess) {
+ /* if we succeed, set our view of reality to what we set it to */
+ config->config_timestamp = rep.newConfigTimestamp;
+ config->timestamp = rep.newTimestamp;
+ config->screen = ScreenOfDisplay (dpy, XRRRootToScreen(dpy, rep.root));
+ config->current_size = size_index;
+ config->current_rotation = rotation;
+ config->current_visual_group = visual_group_index;
+ }
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return(rep.status);
+}
diff --git a/xc/lib/Xrandr/Xrandr.h b/xc/lib/Xrandr/Xrandr.h
new file mode 100644
index 000000000..c7b5dc3ac
--- /dev/null
+++ b/xc/lib/Xrandr/Xrandr.h
@@ -0,0 +1,107 @@
+/*
+ * $XFree86: xc/lib/Xrandr/Xrandr.h,v 1.7 2001/08/01 00:44:40 tsi Exp $
+ *
+ * Copyright © 2000 Compaq Computer Corporation, 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 Compaq not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Compaq makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * COMPAQ DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL COMPAQ
+ * 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: Jim Gettys, Compaq Computer Corporation
+ */
+
+#ifndef _XRANDR_H_
+#define _XRANDR_H_
+
+#include <X11/extensions/randr.h>
+
+typedef struct {
+ int nvisuals;
+ Visual **visuals;
+} XRRVisualGroup;
+
+typedef struct {
+ int ngroups;
+ XRRVisualGroup **groups;
+} XRRGroupOfVisualGroup;
+
+typedef struct {
+ int width, height;
+ int mwidth, mheight;
+ int group;
+} XRRScreenSize;
+
+/*
+ * Events
+ */
+
+typedef struct {
+ int type; /* event base */
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came from a SendEvent request */
+ Display *display; /* Display the event was read from */
+ Window window; /* window which selected for this event */
+ Window root; /* Root window for changed screen */
+ Time timestamp;
+ Time config_timestamp;
+ SizeID size_index;
+ VisualGroupID visual_group_index;
+ Rotation rotation;
+ int width;
+ int height;
+ int mwidth;
+ int mheight;
+} XRRScreenChangeNotifyEvent;
+
+/* internal representation is private to the library */
+typedef struct _XRRScreenConfiguration XRRScreenConfiguration;
+
+Bool XRRQueryExtension (Display *dpy, int *event_basep, int *error_basep);
+
+Status XRRQueryVersion (Display *dpy,
+ int *major_versionp,
+ int *minor_versionp);
+
+XRRScreenConfiguration *XRRGetScreenInfo (Display *dpy,
+ Drawable draw);
+
+void XRRFreeScreenInfo (XRRScreenConfiguration *config);
+
+Status XRRSetScreenConfig (Display *dpy,
+ XRRScreenConfiguration *config,
+ Drawable draw,
+ int size_index,
+ int visual_group_index,
+ Rotation rotation,
+ Time timestamp);
+
+XRRScreenSize *XRRSizes(XRRScreenConfiguration *config, int *nsizes);
+
+void XRRScreenChangeSelectInput (Display *dpy, Window window, Bool enable);
+
+Visual *XRRVisualIDToVisual(Display *dpy, int screen, VisualID id);
+
+int XRRVisualToDepth(Display *dpy, Visual *visual);
+
+Rotation XRRRotations(XRRScreenConfiguration *config, Rotation *current_rotation);
+
+Time XRRTimes (XRRScreenConfiguration *config, Time *config_timestamp);
+
+SizeID XRRCurrentConfig (XRRScreenConfiguration *config, VisualGroupID *visual_group, Rotation *rotation);
+
+int XRRRootToScreen(Display *dpy, Window root);
+
+#endif /* _XRANDR_H_ */
diff --git a/xc/lib/Xrandr/Xrandrint.h b/xc/lib/Xrandr/Xrandrint.h
new file mode 100644
index 000000000..dd7f08b97
--- /dev/null
+++ b/xc/lib/Xrandr/Xrandrint.h
@@ -0,0 +1,67 @@
+/*
+ * $XFree86: xc/lib/Xrandr/Xrandrint.h,v 1.2 2001/06/07 15:33:43 keithp Exp $
+ *
+ * Copyright © 2000 Compaq Computer Corporation, 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 Compaq not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Compaq makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * COMPAQ DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL COMPAQ
+ * 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: Jim Gettys, Compaq Computer Corporation, Inc.
+ */
+
+#ifndef _XRANDRINT_H_
+#define _XRANDRINT_H_
+
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+#include "Xext.h" /* in ../include */
+#include "extutil.h" /* in ../include */
+#include "Xrandr.h"
+#include "randr.h"
+#include "randrproto.h"
+
+extern XExtensionInfo XrandrExtensionInfo;
+extern char XrandrExtensionName[];
+
+#define RRCheckExtension(dpy,i,val) \
+ XextCheckExtension (dpy, i, XRRExtensionName, val)
+
+#define RRSimpleCheckExtension(dpy,i) \
+ XextSimpleCheckExtension (dpy, i, XRRExtensionName)
+
+XExtDisplayInfo *
+XRRFindDisplay (Display *dpy);
+
+/* deliberately opaque internal data structure; can be extended,
+ but not reordered */
+struct _XRRScreenConfiguration {
+ Screen *screen; /* the root window in GetScreenInfo */
+ XRRVisualGroup *visual_group;
+ XRRGroupOfVisualGroup *groups_of_visual_groups;
+ XRRScreenSize *sizes;
+ Rotation rotations;
+ Rotation current_rotation;
+ int nsizes;
+ int current_size;
+ int current_visual_group;
+ Time timestamp;
+ Time config_timestamp;
+};
+
+#endif /* _XRANDRINT_H_ */
diff --git a/xc/lib/Xrandr/test.c b/xc/lib/Xrandr/test.c
new file mode 100644
index 000000000..333d2a6ab
--- /dev/null
+++ b/xc/lib/Xrandr/test.c
@@ -0,0 +1,21 @@
+/* $XFree86: xc/lib/Xrandr/test.c,v 1.2 2001/08/06 21:46:03 dawes Exp $ */
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include "Xrandr.h"
+
+main (int argc, char **argv)
+
+{
+ char *display_name = ":0";
+ Display *display;
+ int major, minor, status;
+
+ if ((display = XOpenDisplay (display_name)) == NULL) {
+ fprintf(stderr, "Can't open display!\n");
+ }
+ status = XRRQueryVersion (display, &major, &minor);
+ fprintf(stderr, "status = %d, major = %d, minor = %d\n,
+ status, major, minor");
+
+}
diff --git a/xc/lib/Xt/ShellI.h b/xc/lib/Xt/ShellI.h
new file mode 100644
index 000000000..33d45dab4
--- /dev/null
+++ b/xc/lib/Xt/ShellI.h
@@ -0,0 +1,12 @@
+/* $XFree86: xc/lib/Xt/ShellI.h,v 1.1 2001/08/18 02:41:29 dawes Exp $ */
+
+#ifndef _XtShellInternal_h
+#define _XtShellInternal_h
+
+#include <X11/Xfuncproto.h>
+
+_XFUNCPROTOBEGIN
+
+extern void _XtShellGetCoordinates(Widget widget, Position *x, Position *y);
+
+#endif /* _XtShellInternal_h */
diff --git a/xc/lib/font/fontfile/fontencc.c b/xc/lib/font/fontfile/fontencc.c
new file mode 100644
index 000000000..2c8bdbd14
--- /dev/null
+++ b/xc/lib/font/fontfile/fontencc.c
@@ -0,0 +1,74 @@
+/*
+Copyright (c) 1998-2001 by Juliusz Chroboczek
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+/* $XFree86: xc/lib/font/fontfile/fontencc.c,v 1.2 2001/08/16 14:33:46 dawes Exp $ */
+
+/* Binary compatibility code. */
+
+/* This file includes code to make modules compiled for earlier
+ versions of the fontenc interfaces link with this one. It does
+ *not* provide source compatibility, as many of the data structures
+ now have different names. */
+
+#include "fontenc.h"
+#include "fontencc.h"
+
+extern void ErrorF(const char *f, ...);
+
+char *
+font_encoding_from_xlfd(const char * name, int length)
+{
+ return FontEncFromXLFD(name, length);
+}
+
+FontEncPtr
+font_encoding_find(const char *encoding_name, const char *filename)
+{
+ return FontEncFind(encoding_name, filename);
+}
+
+unsigned
+font_encoding_recode(unsigned code,
+ FontEncPtr encoding, FontMapPtr mapping)
+{
+ if(encoding != mapping->encoding) {
+ ErrorF("Inconsistent mapping/encoding\n");
+ return 0;
+ }
+ return FontEncRecode(code, mapping);
+}
+
+char *
+font_encoding_name(unsigned code,
+ FontEncPtr encoding, FontMapPtr mapping)
+{
+ if(encoding != mapping->encoding) {
+ ErrorF("Inconsistent mapping/encoding\n");
+ return 0;
+ }
+ return FontEncName(code, mapping);
+}
+
+char **
+identifyEncodingFile(const char *filename)
+{
+ return FontEncIdentify(filename);
+}
diff --git a/xc/lib/font/include/fontencc.h b/xc/lib/font/include/fontencc.h
new file mode 100644
index 000000000..8ed1d33c8
--- /dev/null
+++ b/xc/lib/font/include/fontencc.h
@@ -0,0 +1,36 @@
+/*
+Copyright (c) 1998-2001 by Juliusz Chroboczek
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+/* $XFree86: xc/lib/font/include/fontencc.h,v 1.1 2001/08/16 14:33:47 dawes Exp $ */
+
+/* Binary compatibility entry points. */
+
+/* This file includes code to make modules compiled for earlier
+ versions of the fontenc interfaces link with this one. It does
+ *not* provide source compatibility, as many of the data structures
+ now have different names. */
+
+extern char *font_encoding_from_xlfd(const char*, int);
+extern unsigned font_encoding_recode(unsigned, FontEncPtr, FontMapPtr);
+extern FontEncPtr font_encoding_find(const char*, const char*);
+extern char *font_encoding_name(unsigned, FontEncPtr, FontMapPtr);
+extern char **identifyEncodingFile(const char *fileName);
+
diff --git a/xc/lib/fontenc/Imakefile b/xc/lib/fontenc/Imakefile
new file mode 100644
index 000000000..b29bb8e4d
--- /dev/null
+++ b/xc/lib/fontenc/Imakefile
@@ -0,0 +1,28 @@
+XCOMM $XFree86: xc/lib/fontenc/Imakefile,v 1.2 2001/08/16 14:33:47 dawes Exp $
+
+ INCLUDES = -I$(FONTINCSRC) -I$(FONTLIBSRC)/include -I$(FONTLIBSRC)/fontfile \
+ -I$(XTOP)/include
+
+FONTENCDEFS = -DFONTENC_NO_LIBFONT \
+ -DFONT_ENCODINGS_DIRECTORY=\"$(FONTDIR)/encodings/encodings.dir\"
+
+ DEFINES = StrcasecmpDefines $(FONTENCDEFS)
+
+ SRCS = fontenc.c encparse.c
+ OBJS = fontenc.o encparse.o
+
+#define DoNormalLib NormalLibFontEnc
+#define DoSharedLib SharedLibFontEnc
+#define DoDebugLib DebugLibFontEnc
+#define DoProfileLib ProfileLibFontEnc
+#define LibName fontenc
+#define LibHeaders NO
+#define SoRev SOFONTENCREV
+
+#include <Library.tmpl>
+
+LinkSourceFile(fontenc.c,$(FONTLIBSRC)/fontfile)
+LinkSourceFile(encparse.c,$(FONTLIBSRC)/fontfile)
+
+DependTarget()
+
diff --git a/xc/programs/Xserver/Xext/sleepuntil.h b/xc/programs/Xserver/Xext/sleepuntil.h
new file mode 100644
index 000000000..29d761a0e
--- /dev/null
+++ b/xc/programs/Xserver/Xext/sleepuntil.h
@@ -0,0 +1,47 @@
+/* $XFree86: xc/programs/Xserver/Xext/sleepuntil.h,v 1.1 2001/08/01 00:44:44 tsi Exp $ */
+/*
+ * Copyright (C) 2001 The XFree86 Project, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the XFree86 Project shall
+ * not be used in advertising or otherwise to promote the sale, use or other
+ * dealings in this Software without prior written authorization from the
+ * XFree86 Project.
+ */
+
+#ifndef _SLEEPUNTIL_H_
+#define _SLEEPUNTIL_H_ 1
+
+#include "dix.h"
+
+extern int ClientSleepUntil(
+#if NeedFunctionPrototypes
+ ClientPtr client,
+ TimeStamp *revive,
+ void (*notifyFunc)(
+#if NeedNestedPrototypes
+ ClientPtr /* client */,
+ pointer /* closure */
+#endif
+ ),
+ pointer Closure
+#endif
+);
+
+#endif
diff --git a/xc/programs/Xserver/hw/darwin/bundle/XView.h b/xc/programs/Xserver/hw/darwin/bundle/XView.h
new file mode 100644
index 000000000..c6f730298
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/bundle/XView.h
@@ -0,0 +1,44 @@
+/*
+ * NSView subclass for Mac OS X rootless X server
+ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/XView.h,v 1.1 2001/07/01 02:13:40 torrey Exp $ */
+
+#import <Cocoa/Cocoa.h>
+
+#include <drivers/event_status_driver.h>
+#include "fakeBoxRec.h"
+
+@interface XView : NSView
+{
+ char *mBits;
+ int mBytesPerRow;
+ int mBitsPerSample;
+ int mSamplesPerPixel;
+ int mBitsPerPixel;
+ int mDepth;
+}
+
+-(id) initWithFrame:(NSRect)aRect;
+-(void) dealloc;
+
+-(void) drawRect:(NSRect)aRect;
+-(BOOL) isFlipped;
+-(BOOL) acceptsFirstResponder;
+-(BOOL) acceptsFirstMouse:(NSEvent *)theEvent;
+-(BOOL) shouldDelayWindowOrderingForEvent:(NSEvent *)theEvent;
+
+-(void) mouseDown:(NSEvent *)anEvent;
+
+-(void) setFrameSize:(NSSize)newSize;
+
+-(void) allocBitsForSize:(NSSize)newSize;
+-(char *) bits;
+-(void) getBits:(char **)bits
+ rowBytes:(int *)rowBytes
+ depth:(int *)depth
+ bitsPerPixel:(int *)bpp;
+
+-(void) refreshRects:(fakeBoxRec *)rectList count:(int)count;
+-(void) copyRects:(fakeBoxRec *)rectList count:(int)count;
+
+@end
diff --git a/xc/programs/Xserver/hw/darwin/bundle/XView.m b/xc/programs/Xserver/hw/darwin/bundle/XView.m
new file mode 100644
index 000000000..2cf002811
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/bundle/XView.m
@@ -0,0 +1,195 @@
+/*
+ * NSView subclass for Mac OS X rootless X server
+ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/XView.m,v 1.1 2001/07/01 02:13:41 torrey Exp $ */
+
+#include <ApplicationServices/ApplicationServices.h>
+
+#import "XWindow.h"
+#import "XView.h"
+#include "fakeBoxRec.h"
+
+static const void *infobytes(void *info)
+{
+ return info;
+}
+
+
+@implementation XView
+
+-(id) initWithFrame:(NSRect)aRect
+{
+ self = [super initWithFrame:aRect];
+ if (!self) return nil;
+
+ mBitsPerSample = 8;
+ mSamplesPerPixel = 3;
+ mDepth = mBitsPerSample * mSamplesPerPixel;
+ mBitsPerPixel = 32;
+ mBits = nil;
+ [self allocBitsForSize:aRect.size];
+
+ return self;
+}
+
+-(void) dealloc
+{
+ if (mBits) free(mBits);
+ [super dealloc];
+}
+
+-(void) drawRect:(NSRect)aRect
+{
+ // Never draw here.
+}
+
+-(BOOL) isFlipped
+{
+ return NO; // YES inverts the BitmapImageRep too...
+}
+
+-(BOOL) isOpaque
+{
+ // fixme
+ return YES;
+}
+
+-(BOOL) acceptsFirstResponder
+{
+ return YES;
+}
+
+-(BOOL) acceptsFirstMouse:(NSEvent *)theEvent
+{
+ return YES;
+}
+
+-(BOOL) shouldDelayWindowOrderingForEvent:(NSEvent *)theEvent
+{
+ return YES;
+}
+
+
+-(void) mouseDown:(NSEvent *)anEvent
+{
+ // Only X is allowed to restack windows.
+ [NSApp preventWindowOrdering];
+ [[self nextResponder] mouseDown:anEvent];
+}
+
+-(void) mouseUp:(NSEvent *)anEvent
+{
+ // Bring app to front if necessary
+ // Don't bring app to front in mouseDown; mousedown-mouseup is too
+ // long and X gets what looks like a mouse drag.
+ if (! [NSApp isActive]) {
+ [NSApp activateIgnoringOtherApps:YES];
+ [NSApp arrangeInFront:nil]; // fixme only bring some windows forward?
+ }
+
+ [[self nextResponder] mouseDown:anEvent];
+}
+
+
+// Reallocate bits.
+// setFrame goes through here too.
+-(void) setFrameSize:(NSSize)newSize
+{
+ [self allocBitsForSize:newSize];
+ [super setFrameSize:newSize];
+}
+
+-(void) allocBitsForSize:(NSSize)newSize
+{
+ if (mBits) free(mBits);
+ mBytesPerRow = newSize.width * mBitsPerPixel / 8;
+ mBits = malloc(mBytesPerRow * newSize.height);
+}
+
+-(char *) bits
+{
+ return mBits;
+}
+
+-(void) getBits:(char **)bits
+ rowBytes:(int *)rowBytes
+ depth:(int *)depth
+ bitsPerPixel:(int *)bpp
+{
+ *bits = mBits;
+ *rowBytes = mBytesPerRow;
+ *depth = mDepth;
+ *bpp = mBitsPerPixel;
+}
+
+-(void) refreshRects:(fakeBoxRec *)rectList count:(int)count
+{
+ [self lockFocus];
+ [self copyRects:rectList count:count];
+ [[NSGraphicsContext currentContext] flushGraphics];
+ [self unlockFocus];
+}
+
+// rectList is X-flipped and LOCAL coords
+-(void) copyRects:(fakeBoxRec *)rectList count:(int)count
+{
+ unsigned char *offsetbits;
+
+ fakeBoxRec *r;
+ fakeBoxRec *end;
+ NSRect bounds;
+
+ CGContextRef destCtx = (CGContextRef)[[NSGraphicsContext currentContext]
+ graphicsPort];
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ const CGDataProviderDirectAccessCallbacks cb = {
+ infobytes, NULL, NULL, NULL
+ };
+
+ bounds = [self frame];
+ bounds.origin.x = bounds.origin.y = 0;
+
+ r = rectList;
+ end = rectList + count;
+ for ( ; r < end; r++) {
+ NSRect nsr = {{r->x1, r->y1}, {r->x2-r->x1, r->y2-r->y1}};
+ CGRect destRect;
+ CGDataProviderRef dataProviderRef;
+ CGImageRef imageRef;
+
+ // Clip to window
+ // (bounds origin is (0,0) so it can be used in either flip)
+ // fixme is this necessary with pixmap-per-window?
+ nsr = NSIntersectionRect(nsr, bounds);
+
+ // Disallow empty rects
+ if (nsr.size.width <= 0 || nsr.size.height <= 0) continue;
+
+ offsetbits = mBits + (int)(nsr.origin.y * mBytesPerRow +
+ nsr.origin.x * mBitsPerPixel/8);
+
+ // Flip r to Cocoa-flipped
+ nsr.origin.y = bounds.size.height - nsr.origin.y - nsr.size.height;
+ destRect = CGRectMake(nsr.origin.x, nsr.origin.y,
+ nsr.size.width, nsr.size.height);
+
+ // NSDrawBitmap but doesn't scale and can use more pixel layouts than
+ // Cocoa's RGBA. Maybe CGDrawBitmap is like this.
+
+ dataProviderRef = CGDataProviderCreateDirectAccess(offsetbits,
+ destRect.size.height * mBytesPerRow, &cb);
+
+ imageRef = CGImageCreate(destRect.size.width, destRect.size.height,
+ mBitsPerSample, mBitsPerPixel,
+ mBytesPerRow, colorSpace,
+ kCGImageAlphaNoneSkipFirst, // ARGB
+ dataProviderRef, NULL,
+ 1, kCGRenderingIntentDefault);
+
+ CGContextDrawImage(destCtx, destRect, imageRef);
+ CGImageRelease(imageRef);
+ CGDataProviderRelease(dataProviderRef);
+ }
+}
+
+@end
diff --git a/xc/programs/Xserver/hw/darwin/bundle/XWindow.h b/xc/programs/Xserver/hw/darwin/bundle/XWindow.h
new file mode 100644
index 000000000..1049fc471
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/bundle/XWindow.h
@@ -0,0 +1,37 @@
+/*
+ * NSWindow subclass for Mac OS X rootless X server
+ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/XWindow.h,v 1.1 2001/07/01 02:13:41 torrey Exp $ */
+
+#import <Cocoa/Cocoa.h>
+#import "XView.h"
+
+#include "fakeBoxRec.h"
+
+@interface XWindow : NSWindow
+{
+ XView *mView;
+}
+
+-(id) initWithContentRect:(NSRect)aRect
+ isRoot:(BOOL)isRoot;
+-(void) dealloc;
+
+-(char *) bits;
+-(void) getBits:(char **)bits
+ rowBytes:(int *)rowBytes
+ depth:(int *)depth
+ bitsPerPixel:(int *)bpp;
+
+-(void) refreshRects:(fakeBoxRec *)rectList
+ count:(int)count;
+
+-(void) orderWindow:(NSWindowOrderingMode)place
+ relativeTo:(int)otherWindowNumber;
+
+-(void) sendEvent:(NSEvent *)anEvent;
+-(BOOL) canBecomeMainWindow;
+-(BOOL) canBecomeKeyWindow;
+-(BOOL) useOptimizedDrawing;
+
+@end
diff --git a/xc/programs/Xserver/hw/darwin/bundle/XWindow.m b/xc/programs/Xserver/hw/darwin/bundle/XWindow.m
new file mode 100644
index 000000000..58ec17b58
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/bundle/XWindow.m
@@ -0,0 +1,111 @@
+/*
+ * NSWindow subclass for Mac OS X rootless X server
+ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/XWindow.m,v 1.2 2001/08/01 05:34:06 torrey Exp $ */
+
+#import "XWindow.h"
+#import "Xserver.h"
+
+
+@implementation XWindow
+
+// XWindow MUST NOT autodisplay! Autodisplay can cause a deadlock.
+// event thread - autodisplay: locks view hierarchy, then window
+// X Server thread - window resize: locks window, then view hierarchy
+// Deadlock occurs if each thread gets one lock and waits for the other.
+
+// XWindow MUST defer! Otherwise an assertion fails in
+// NSViewHierarchyLock sometimes.
+
+-(id) initWithContentRect:(NSRect)aRect
+ isRoot:(BOOL)isRoot
+{
+ int style;
+ NSRect viewRect = {{0, 0}, {aRect.size.width, aRect.size.height}};
+ style = NSBorderlessWindowMask;
+
+ self = [super initWithContentRect: aRect
+ styleMask: style
+ backing: NSBackingStoreBuffered
+ defer: YES];
+ if (! self) return NULL;
+
+ // fixme!
+ // [self setBackgroundColor:[NSColor clearColor]]; // erase transparent
+ [self setAlphaValue:1.0]; // draw opaque
+ // [self setOpaque:NO];
+
+ [self setAutodisplay:FALSE]; // MUST NOT autodisplay! see comment above
+ [self setHasShadow: !isRoot]; // All windows have shadows except the root.
+
+ // [self setAcceptsMouseMovedEvents:YES]; // MUST be AFTER orderFront?
+ [self setDelegate:self]; // fixme is this still needed?
+
+ mView = [[XView alloc] initWithFrame: viewRect];
+ [self setContentView:mView];
+ [self setInitialFirstResponder:mView];
+
+ return self;
+}
+
+-(void) dealloc
+{
+ [mView release];
+ [super dealloc];
+}
+
+-(char *) bits
+{
+ return [mView bits];
+}
+
+-(void) getBits:(char **)bits
+ rowBytes:(int *)rowBytes
+ depth:(int *)depth
+ bitsPerPixel:(int *)bpp
+{
+ [mView getBits:bits rowBytes:rowBytes depth:depth bitsPerPixel:bpp];
+}
+
+
+// rects are X-flip and LOCAL coords
+-(void) refreshRects:(fakeBoxRec *)rectList count:(int)count;
+{
+ [mView refreshRects:rectList count:count];
+}
+
+
+// Deferred windows don't handle mouse moved events very well.
+-(void) orderWindow:(NSWindowOrderingMode)place
+ relativeTo:(int)otherWindowNumber
+{
+ [super orderWindow:place relativeTo:otherWindowNumber];
+ [self setAcceptsMouseMovedEvents:YES];
+}
+
+-(void) sendEvent:(NSEvent *)anEvent
+{
+ [super sendEvent:anEvent];
+ [self setAcceptsMouseMovedEvents:YES];
+}
+
+// XWindow may be frameless, and frameless windows default to
+// NO key and NO main.
+// update: we *don't* want main or key status after all
+-(BOOL) canBecomeMainWindow
+{
+ return NO;
+}
+
+-(BOOL) canBecomeKeyWindow
+{
+ return NO;
+}
+
+// XWindow has no overlapping subviews
+-(BOOL) useOptimizedDrawing
+{
+ return YES;
+}
+
+@end
diff --git a/xc/programs/Xserver/hw/darwin/bundle/fakeBoxRec.h b/xc/programs/Xserver/hw/darwin/bundle/fakeBoxRec.h
new file mode 100644
index 000000000..1e5027cc8
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/bundle/fakeBoxRec.h
@@ -0,0 +1,15 @@
+/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/fakeBoxRec.h,v 1.1 2001/07/01 02:13:41 torrey Exp $ */
+
+#ifndef FAKEBOXREC_H
+#define FAKEBOXREC_H
+
+// This struct is byte-compatible with X11's BoxRec, for use in
+// code that can't include X headers.
+typedef struct _fakeBox {
+ short x1;
+ short y1;
+ short x2;
+ short y2;
+} fakeBoxRec;
+
+#endif
diff --git a/xc/programs/Xserver/hw/darwin/bundle/rootless.h b/xc/programs/Xserver/hw/darwin/bundle/rootless.h
new file mode 100644
index 000000000..705dbf9f2
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/bundle/rootless.h
@@ -0,0 +1,127 @@
+/*
+ * External interface to generic rootless mode
+ *
+ * Greg Parker gparker@cs.stanford.edu March 3, 2001
+ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/rootless.h,v 1.3 2001/08/01 05:34:06 torrey Exp $ */
+
+#ifndef _ROOTLESS_H
+#define _ROOTLESS_H
+
+#include "mi.h"
+#include "gcstruct.h"
+
+// RootlessFrameRec
+// Describes a single rootless window (aka frame).
+// The rootless mode keeps track of window position, and the
+// rootless implementation is responsible for the pixmap.
+// Multiple screens: all coordinates are SCREEN-LOCAL, not global.
+
+
+typedef struct RootlessFrameRec {
+ /* Data maintained by rootless mode */
+ /* position and size, including window border, in screen coordinates */
+ int x;
+ int y;
+ unsigned int w;
+ unsigned int h;
+ WindowPtr win; /* the top-level window drawn in this frame */
+ int isRoot; /* TRUE if this is the root window */
+
+ /* Data maintained by rootless implementation */
+ char *pixelData;
+ int depth; // color bits per pixel; depth <= bitsPerPixel
+ int bitsPerPixel;
+ int bytesPerRow;
+
+ void *devPrivate; /* for caller's use */
+} RootlessFrameRec, *RootlessFramePtr;
+
+
+// Create a new frame.
+// pUpper is the window above the new frame, or NULL if the new
+// frame will be on top.
+// pFrame is completely initialized. devPrivate is NULL
+// The pixmap must be valid when this is done.
+typedef void (*RootlessCreateFrameProc)
+ (ScreenPtr pScreen, RootlessFramePtr pFrame, RootlessFramePtr pUpper);
+
+// Destroy a frame. Caller must free any private data and the pixmap.
+// All drawing is stopped and all updates are flushed before this is called.
+typedef void (*RootlessDestroyFrameProc)
+ (ScreenPtr pScreen, RootlessFramePtr pFrame);
+
+// Move a frame on screen.
+// The frame changes position and nothing else.
+// pFrame and pFrame->win already contain the information about the
+// new position. oldX and oldY are the old position.
+// All updates are flushed before this is called.
+// The pixmap may change during this function.
+typedef void (*RootlessMoveFrameProc)
+ (ScreenPtr pScreen, RootlessFramePtr pFrame, int oldX, int oldY);
+
+// Change frame ordering (aka stacking, layering)
+// pFrame->win already has its new siblings.
+// pOldNext is the window that was below this one, or NULL if this was
+// at the bottom.
+// pNewNext is the window that is now below this one, or NULL if this is
+// now at the bottom.
+typedef void (*RootlessRestackFrameProc)
+ (ScreenPtr pScreen, RootlessFramePtr pFrame,
+ RootlessFramePtr pOldNext, RootlessFramePtr pNewNext);
+
+// Flush drawing updates to the screen.
+// pDamage contains all changed pixels.
+// pDamage is in frame-local coordinates.
+// pDamage is clipped to the frame bounds and the frame shape.
+typedef void (*RootlessUpdateRegionProc)
+ (ScreenPtr pScreen, RootlessFramePtr pFrame, RegionPtr pDamage);
+
+// Change the frame's shape.
+// pNewShape is in frame-local coordinates.
+// Everything outside pNewShape is no longer part of the frame.
+// pNewShape is {0, 0, width, height} for a plain-shaped frame.
+// fixme can the pixmap change here?
+// fixme reimplement shape
+typedef void (*RootlessReshapeFrameProc)
+ (ScreenPtr pScreen, RootlessFramePtr pFrame, RegionPtr pNewShape);
+
+// Frame is about to resize.
+// The frame has its new position and size already.
+// postconditions:
+// The pixmap MUST point to a pixmap with the new size.
+// The pixmap data is undefined.
+// The old pixmap may be destroyed here.
+typedef void (*RootlessStartResizeFrameProc)
+ (ScreenPtr pScreen, RootlessFramePtr pFrame,
+ int oldX, int oldY, unsigned int oldW, unsigned int oldH);
+
+// Frame is done resizing.
+// Destroy the old pixmap if you haven't already.
+typedef void (*RootlessFinishResizeFrameProc)
+ (ScreenPtr pScreen, RootlessFramePtr pFrame,
+ int oldX, int oldY, unsigned int oldW, unsigned int oldH);
+
+
+// The callback function list.
+// Any of these may be NULL.
+typedef struct RootlessFrameProcs {
+ RootlessCreateFrameProc CreateFrame;
+ RootlessDestroyFrameProc DestroyFrame;
+
+ RootlessMoveFrameProc MoveFrame;
+ RootlessStartResizeFrameProc StartResizeFrame;
+ RootlessFinishResizeFrameProc FinishResizeFrame;
+ RootlessRestackFrameProc RestackFrame;
+ RootlessReshapeFrameProc ReshapeFrame;
+
+ RootlessUpdateRegionProc UpdateRegion;
+
+ // RootlessStartDrawingProc StartDrawing;
+ // RootlessStopDrawingProc StopDrawing;
+} RootlessFrameProcs;
+
+// Initialize rootless mode on the given screen.
+Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcs *procs);
+
+#endif /* _ROOTLESS_H */
diff --git a/xc/programs/Xserver/hw/darwin/bundle/rootlessAqua.h b/xc/programs/Xserver/hw/darwin/bundle/rootlessAqua.h
new file mode 100644
index 000000000..721dc1695
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/bundle/rootlessAqua.h
@@ -0,0 +1,15 @@
+/*
+ * Rootless setup for Aqua
+ *
+ * Greg Parker gparker@cs.stanford.edu
+ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/rootlessAqua.h,v 1.2 2001/08/01 05:34:06 torrey Exp $ */
+
+#ifndef _ROOTLESSAQUA_H
+#define _ROOTLESSAQUA_H
+
+Bool AquaAddScreen(int index, ScreenPtr pScreen);
+Bool AquaSetupScreen(int index, ScreenPtr pScreen);
+void AquaDisplayInit(void);
+
+#endif /* _ROOTLESSAQUA_H */
diff --git a/xc/programs/Xserver/hw/darwin/bundle/rootlessAquaGlue.c b/xc/programs/Xserver/hw/darwin/bundle/rootlessAquaGlue.c
new file mode 100644
index 000000000..14815ec01
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/bundle/rootlessAquaGlue.c
@@ -0,0 +1,193 @@
+/*
+ * Generic rootless to Aqua specific glue code
+ *
+ * This code acts as a glue between the generic rootless X server code
+ * and the Aqua specific implementation, which includes definitions that
+ * conflict with stardard X types.
+ *
+ * Greg Parker gparker@cs.stanford.edu
+ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/rootlessAquaGlue.c,v 1.3 2001/08/01 05:34:06 torrey Exp $ */
+
+#include "regionstr.h"
+#include "scrnintstr.h"
+
+#include "darwin.h"
+#include "quartz.h"
+#include "rootlessAqua.h"
+#include "rootlessAquaImp.h"
+#include "rootless.h"
+#include "globals.h" // dixScreenOrigins[]
+
+
+/////////////////////////////////////////
+// Rootless mode callback glue
+
+static void
+AquaGlueCreateFrame(ScreenPtr pScreen, RootlessFramePtr pFrame,
+ RootlessFramePtr pUpper)
+{
+ int sx = dixScreenOrigins[pScreen->myNum].x;
+ int sy = dixScreenOrigins[pScreen->myNum].y;
+
+ pFrame->devPrivate = AquaNewWindow(pUpper ? pUpper->devPrivate : NULL,
+ pFrame->x+sx, pFrame->y+sy,
+ pFrame->w, pFrame->h,
+ pFrame->isRoot);
+ AquaGetPixmap(pFrame->devPrivate, &pFrame->pixelData,
+ &pFrame->bytesPerRow, &pFrame->depth,
+ &pFrame->bitsPerPixel);
+}
+
+
+static void
+AquaGlueDestroyFrame(ScreenPtr pScreen, RootlessFramePtr pFrame)
+{
+ AquaDestroyWindow(pFrame->devPrivate);
+}
+
+static void
+AquaGlueMoveFrame(ScreenPtr pScreen, RootlessFramePtr pFrame,
+ int oldX, int oldY)
+{
+ int sx = dixScreenOrigins[pScreen->myNum].x;
+ int sy = dixScreenOrigins[pScreen->myNum].y;
+
+ AquaMoveWindow(pFrame->devPrivate, pFrame->x+sx, pFrame->y+sy);
+}
+
+
+static void
+AquaGlueStartResizeFrame(ScreenPtr pScreen, RootlessFramePtr pFrame,
+ int oldX, int oldY,
+ unsigned int oldW, unsigned int oldH)
+{
+ int sx = dixScreenOrigins[pScreen->myNum].x;
+ int sy = dixScreenOrigins[pScreen->myNum].y;
+
+ AquaStartResizeWindow(pFrame->devPrivate,
+ pFrame->x+sx, pFrame->y+sy, pFrame->w, pFrame->h);
+ AquaGetPixmap(pFrame->devPrivate, &pFrame->pixelData,
+ &pFrame->bytesPerRow, &pFrame->depth,
+ &pFrame->bitsPerPixel);
+}
+
+static void
+AquaGlueFinishResizeFrame(ScreenPtr pScreen, RootlessFramePtr pFrame,
+ int oldX, int oldY,
+ unsigned int oldW, unsigned int oldH)
+{
+ int sx = dixScreenOrigins[pScreen->myNum].x;
+ int sy = dixScreenOrigins[pScreen->myNum].y;
+
+ AquaFinishResizeWindow(pFrame->devPrivate,
+ pFrame->x+sx, pFrame->y+sy, pFrame->w, pFrame->h);
+}
+
+
+static void
+AquaGlueRestackFrame(ScreenPtr pScreen, RootlessFramePtr pFrame,
+ RootlessFramePtr pOldPrev,
+ RootlessFramePtr pNewPrev)
+{
+ AquaRestackWindow(pFrame->devPrivate,
+ pNewPrev ? pNewPrev->devPrivate : NULL);
+}
+
+static void
+AquaGlueReshapeFrame(ScreenPtr pScreen, RootlessFramePtr pFrame,
+ RegionPtr pNewShape)
+{
+ int sx = dixScreenOrigins[pScreen->myNum].x;
+ int sy = dixScreenOrigins[pScreen->myNum].y;
+
+ if (pFrame->isRoot) return; // shouldn't happen; mi or dix covers this
+ REGION_TRANSLATE(pScreen, pNewShape, sx, sy);
+ AquaReshapeWindow(pFrame->devPrivate,
+ (fakeBoxRec *) REGION_RECTS(pNewShape),
+ REGION_NUM_RECTS(pNewShape));
+}
+
+static void
+AquaGlueUpdateRegion(ScreenPtr pScreen, RootlessFramePtr pFrame,
+ RegionPtr pDamage)
+{
+ AquaUpdateRects(pFrame->devPrivate,
+ (fakeBoxRec *) REGION_RECTS(pDamage),
+ REGION_NUM_RECTS(pDamage));
+}
+
+#if 0
+static void
+AquaGlueStartDrawing(ScreenPtr pScreen, RootlessFramePtr pFrame)
+{
+ AquaStartDrawing(pFrame->devPrivate, &pFrame->pixelData,
+ &pFrame->bytesPerRow, &pFrame->depth,
+ &pFrame->bitsPerPixel);
+}
+
+static void
+AquaGlueStopDrawing(ScreenPtr pScreen, RootlessFramePtr pFrame)
+{
+ AquaStopDrawing(pFrame->devPrivate);
+}
+#endif
+
+static RootlessFrameProcs aquaRootlessProcs = {
+ AquaGlueCreateFrame,
+ AquaGlueDestroyFrame,
+ AquaGlueMoveFrame,
+ AquaGlueStartResizeFrame,
+ AquaGlueFinishResizeFrame,
+ AquaGlueRestackFrame,
+ AquaGlueReshapeFrame,
+ AquaGlueUpdateRegion
+};
+
+
+///////////////////////////////////////
+// Rootless mode initialization.
+// Exported by rootlessAqua.h
+
+/*
+ * AquaDisplayInit
+ * Find all Aqua screens.
+ */
+void
+AquaDisplayInit(void)
+{
+ darwinScreensFound = AquaDisplayCount();
+}
+
+
+/*
+ * AquaAddScreen
+ * Init the framebuffer and record pixmap parameters for the screen.
+ */
+Bool
+AquaAddScreen(int index, ScreenPtr pScreen)
+{
+ DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
+
+ dfb->pixelInfo.pixelType = kIORGBDirectPixels;
+ AquaScreenInit(index, &dfb->x, &dfb->y, &dfb->width, &dfb->height,
+ &dfb->pitch, &dfb->pixelInfo.bitsPerComponent,
+ &dfb->pixelInfo.componentCount, &dfb->bitsPerPixel);
+ dfb->colorBitsPerPixel = dfb->pixelInfo.bitsPerComponent *
+ dfb->pixelInfo.componentCount;
+
+ // No frame buffer - it's all in window pixmaps.
+ dfb->framebuffer = NULL; // malloc(dfb.pitch * dfb.height);
+
+ return TRUE;
+}
+
+/*
+ * AquaSetupScreen
+ * Setup the screen for rootless access.
+ */
+Bool
+AquaSetupScreen(int index, ScreenPtr pScreen)
+{
+ return RootlessInit(pScreen, &aquaRootlessProcs);
+}
diff --git a/xc/programs/Xserver/hw/darwin/bundle/rootlessAquaImp.h b/xc/programs/Xserver/hw/darwin/bundle/rootlessAquaImp.h
new file mode 100644
index 000000000..fe2d4e3a4
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/bundle/rootlessAquaImp.h
@@ -0,0 +1,38 @@
+/*
+ * Rootless implementation for Mac OS X Aqua environment
+ *
+ * Greg Parker gparker@cs.stanford.edu
+ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/rootlessAquaImp.h,v 1.3 2001/08/01 05:34:06 torrey Exp $ */
+
+#ifndef _ROOTLESSAQUAIMP_H
+#define _ROOTLESSAQUAIMP_H
+
+#include "fakeBoxRec.h"
+
+int AquaDisplayCount();
+
+void AquaScreenInit(int index, int *x, int *y, int *width, int *height,
+ int *rowBytes, unsigned long *bps, unsigned long *spp,
+ int *bpp);
+
+void *AquaNewWindow(void *upperw, int x, int y, int w, int h, int isRoot);
+
+void AquaDestroyWindow(void *rw);
+
+void AquaMoveWindow(void *rw, int x, int y);
+
+void AquaStartResizeWindow(void *rw, int x, int y, int w, int h);
+
+void AquaFinishResizeWindow(void *rw, int x, int y, int w, int h);
+
+void AquaUpdateRects(void *rw, fakeBoxRec *rects, int count);
+
+void AquaRestackWindow(void *rw, void *lowerw);
+
+void AquaReshapeWindow(void *rw, fakeBoxRec *rects, int count);
+
+void AquaGetPixmap(void *rw, char **bits,
+ int *rowBytes, int *depth, int *bpp);
+
+#endif /* _ROOTLESSAQUAIMP_H */
diff --git a/xc/programs/Xserver/hw/darwin/bundle/rootlessAquaImp.m b/xc/programs/Xserver/hw/darwin/bundle/rootlessAquaImp.m
new file mode 100644
index 000000000..f9ed35f42
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/bundle/rootlessAquaImp.m
@@ -0,0 +1,135 @@
+/*
+ * Rootless implementation for Mac OS X Aqua environment
+ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/rootlessAquaImp.m,v 1.3 2001/08/01 05:34:06 torrey Exp $ */
+
+#include "rootlessAquaImp.h"
+#include "XWindow.h"
+#include "fakeBoxRec.h"
+
+
+typedef struct {
+ XWindow *window;
+} AquaWindowRec;
+
+
+#define WINREC(rw) ((AquaWindowRec *)rw)
+
+int AquaDisplayCount()
+{
+ return [[NSScreen screens] count];
+}
+
+void AquaScreenInit(int index, int *x, int *y, int *width, int *height,
+ int *rowBytes, unsigned long *bps, unsigned long *spp,
+ int *bpp)
+{
+ NSScreen *screen = [[NSScreen screens] objectAtIndex:index];
+ NSRect frame = [screen frame];
+
+ // fixme
+ *bps = 8;
+ *spp = 3;
+ *bpp = 32;
+
+ // set x,y so (0,0) is top left of main screen
+ *x = frame.origin.x;
+ *y = [[NSScreen mainScreen] frame].size.height -
+ frame.size.height - frame.origin.y;
+
+ *width = frame.size.width;
+ *height = frame.size.height;
+ *rowBytes = (*width) * (*bpp) / 8;
+}
+
+void *AquaNewWindow(void *upperw, int x, int y, int w, int h, int isRoot)
+{
+ AquaWindowRec *winRec = (AquaWindowRec *)malloc(sizeof(AquaWindowRec));
+ NSRect frame = {{x, y}, {w, h}};
+
+ frame.origin.y = [[NSScreen mainScreen] frame].size.height - y - h;
+ winRec->window = [[XWindow alloc] initWithContentRect:frame isRoot:isRoot];
+
+ if (upperw) {
+ AquaWindowRec *upperRec = WINREC(upperw);
+ int uppernum = [upperRec->window windowNumber];
+ [winRec->window orderWindow:NSWindowBelow relativeTo:uppernum];
+ } else {
+ [winRec->window orderFront:nil];
+ }
+
+ // fixme hide root for now
+ if (isRoot) [winRec->window orderOut:nil];
+
+ return winRec;
+}
+
+void AquaDestroyWindow(void *rw)
+{
+ AquaWindowRec *winRec = WINREC(rw);
+
+ [winRec->window release];
+}
+
+void AquaMoveWindow(void *rw, int x, int y)
+{
+ AquaWindowRec *winRec = WINREC(rw);
+ NSPoint topLeft = {x, y};
+
+ topLeft.y = [[NSScreen mainScreen] frame].size.height - topLeft.y;
+ [winRec->window setFrameTopLeftPoint:topLeft];
+}
+
+void AquaStartResizeWindow(void *rw, int x, int y, int w, int h)
+{
+ AquaWindowRec *winRec = WINREC(rw);
+ NSRect frame = {{x, y}, {w, h}};
+
+ frame.origin.y = [[NSScreen mainScreen] frame].size.height - y - h;
+ [winRec->window setFrame:frame display:NO];
+}
+
+void AquaFinishResizeWindow(void *rw, int x, int y, int w, int h)
+{
+ // refresh everything? fixme yes for testing
+ fakeBoxRec box = {0, 0, w, h};
+ AquaWindowRec *winRec = WINREC(rw);
+
+ [winRec->window refreshRects:&box count:1];
+}
+
+void AquaUpdateRects(void *rw, fakeBoxRec *rects, int count)
+{
+ AquaWindowRec *winRec = WINREC(rw);
+
+ [winRec->window refreshRects:rects count:count];
+}
+
+// fixme is this upperw or lowerw?
+void AquaRestackWindow(void *rw, void *upperw)
+{
+ AquaWindowRec *winRec = WINREC(rw);
+
+ if (upperw) {
+ AquaWindowRec *upperRec = WINREC(upperw);
+ int uppernum = [upperRec->window windowNumber];
+ [winRec->window orderWindow:NSWindowBelow relativeTo:uppernum];
+ } else {
+ [winRec->window orderFront:nil];
+ }
+ // [winRec->window setAcceptsMouseMovedEvents:YES];
+ // fixme prefer to orderFront whenever possible - pass upperw, not lowerw
+}
+
+void AquaReshapeWindow(void *rw, fakeBoxRec *rects, int count)
+{
+ // fixme reimplement shape
+}
+
+void AquaGetPixmap(void *rw, char **bits,
+ int *rowBytes, int *depth, int *bpp)
+{
+ AquaWindowRec *winRec = WINREC(rw);
+ [winRec->window getBits:bits rowBytes:rowBytes depth:depth
+ bitsPerPixel:bpp];
+}
diff --git a/xc/programs/Xserver/hw/darwin/bundle/rootlessCommon.c b/xc/programs/Xserver/hw/darwin/bundle/rootlessCommon.c
new file mode 100644
index 000000000..69d8c97a3
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/bundle/rootlessCommon.c
@@ -0,0 +1,191 @@
+/*
+ * Common rootless definitions and code
+ *
+ * Greg Parker gparker@cs.stanford.edu
+ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/rootlessCommon.c,v 1.2 2001/07/01 03:24:57 torrey Exp $ */
+
+#include "rootlessCommon.h"
+
+
+RegionRec rootlessHugeRoot = {{-32767, -32767, 32767, 32767}, NULL};
+
+
+// Returns the top-level parent of pWindow.
+// The root is the top-level parent of itself, even though the root is
+// not otherwise considered to be a top-level window.
+WindowPtr TopLevelParent(WindowPtr pWindow)
+{
+ WindowPtr top = pWindow;
+
+ if (IsRoot(pWindow)) return pWindow; // root is top-level parent of itself
+ while (top && ! IsTopLevel(top)) top = top->parent;
+ return top;
+}
+
+
+// Returns TRUE if this window is visible inside a frame
+// (e.g. it is visible and has a top-level or root parent)
+Bool IsFramedWindow(WindowPtr pWin)
+{
+ WindowPtr top;
+
+ if (! pWin->realized) return FALSE;
+ top = TopLevelParent(pWin);
+ return (top && WINREC(top));
+}
+
+
+// Move the given pixmap's base address to where pixel (0, 0)
+// would be if the pixmap's actual data started at (x, y)
+void SetPixmapBaseToScreen(PixmapPtr pix, int x, int y)
+{
+ pix->devPrivate.ptr = (char *)(pix->devPrivate.ptr) -
+ (pix->drawable.bitsPerPixel/8 * x + y*pix->devKind);
+}
+
+
+// Update pWindow's pixmap.
+// This needs to be called every time a window moves relative to
+// its top-level parent, or the parent's pixmap data is reallocated.
+// Three cases:
+// * window is top-level with no existing pixmap: make one
+// * window is top-level with existing pixmap: update it in place
+// * window is descendant of top-level: point to top-level's pixmap
+void UpdatePixmap(WindowPtr pWindow)
+{
+ WindowPtr top = TopLevelParent(pWindow);
+ RootlessWindowRec *winRec;
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ PixmapPtr pix;
+
+ RL_DEBUG_MSG("update pixmap (win 0x%x)", pWindow);
+
+ // Don't use IsFramedWindow(); window is unrealized during RealizeWindow().
+
+ if (! top) {
+ RL_DEBUG_MSG("no parent\n");
+ return;
+ }
+ winRec = WINREC(top);
+ if (!winRec) {
+ RL_DEBUG_MSG("not framed\n");
+ return;
+ }
+
+ if (pWindow == top) {
+ // This is the top window. Update its pixmap.
+ if (winRec->pixmap == NULL) {
+ // Allocate a new pixmap.
+ pix = GetScratchPixmapHeader(pScreen,
+ winRec->frame.w, winRec->frame.h,
+ winRec->frame.depth,
+ winRec->frame.bitsPerPixel,
+ winRec->frame.bytesPerRow,
+ winRec->frame.pixelData);
+ SetPixmapBaseToScreen(pix, winRec->frame.x, winRec->frame.y);
+ pScreen->SetWindowPixmap(pWindow, pix);
+ winRec->pixmap = pix;
+ } else {
+ // Update existing pixmap.
+ // Update in place so we don't have to change the children's pixmaps.
+ pix = winRec->pixmap;
+ pScreen->ModifyPixmapHeader(pix,
+ winRec->frame.w, winRec->frame.h,
+ winRec->frame.depth,
+ winRec->frame.bitsPerPixel,
+ winRec->frame.bytesPerRow,
+ winRec->frame.pixelData);
+ SetPixmapBaseToScreen(pix, winRec->frame.x, winRec->frame.y);
+ }
+ } else {
+ // This is not the top window. Point to the parent's pixmap.
+ pix = winRec->pixmap;
+ pScreen->SetWindowPixmap(pWindow, pix);
+ }
+
+ RL_DEBUG_MSG("done\n");
+}
+
+
+// pRegion is GLOBAL
+void
+RootlessDamageRegion(WindowPtr pWindow, RegionPtr pRegion)
+{
+ pWindow = TopLevelParent(pWindow);
+ if (!pWindow) {
+ RL_DEBUG_MSG("RootlessDamageRegion: window is not framed\n");
+ } else if (!WINREC(pWindow)) {
+ RL_DEBUG_MSG("RootlessDamageRegion: top-level window not a frame\n");
+ } else {
+ REGION_UNION((pWindow)->drawable.pScreen, &WINREC(pWindow)->damage,
+ &WINREC(pWindow)->damage, (pRegion));
+ }
+}
+
+
+// pBox is GLOBAL
+void
+RootlessDamageBox(WindowPtr pWindow, BoxPtr pBox)
+{
+ RegionRec region;
+
+ REGION_INIT(pWindow->drawable.pScreen, &region, pBox, 1);
+ RootlessDamageRegion(pWindow, &region);
+}
+
+
+// (x, y, w, h) is WINDOW-LOCAL
+void
+RootlessDamageRect(WindowPtr pWindow, int x, int y, int w, int h)
+{
+ BoxRec box;
+ RegionRec region;
+
+ x += pWindow->drawable.x;
+ y += pWindow->drawable.y;
+ box.x1 = x;
+ box.x2 = x + w;
+ box.y1 = y;
+ box.y2 = y + h;
+ REGION_INIT(pWindow->drawable.pScreen, &region, &box, 1);
+ RootlessDamageRegion(pWindow, &region);
+}
+
+
+void
+RootlessRedisplay(WindowPtr pWindow)
+{
+ RootlessWindowRec *winRec = WINREC(pWindow);
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+
+ if (REGION_NOTEMPTY(pScreen, &winRec->damage)) {
+ REGION_INTERSECT(pScreen, &winRec->damage, &winRec->damage,
+ &pWindow->borderSize);
+
+ // move region to window local coords
+ REGION_TRANSLATE(pScreen, &winRec->damage,
+ -winRec->frame.x, -winRec->frame.y);
+ CallFrameProc(pScreen, UpdateRegion,
+ (pScreen, &winRec->frame, &winRec->damage));
+ REGION_EMPTY(pScreen, &winRec->damage);
+ }
+}
+
+
+void
+RootlessRedisplayScreen(ScreenPtr pScreen)
+{
+ WindowPtr root = WindowTable[pScreen->myNum];
+
+ if (root) {
+ WindowPtr win;
+
+ RootlessRedisplay(root);
+ for (win = root->firstChild; win; win = win->nextSib) {
+ if (WINREC(win)) {
+ RootlessRedisplay(win);
+ }
+ }
+ }
+}
diff --git a/xc/programs/Xserver/hw/darwin/bundle/rootlessCommon.h b/xc/programs/Xserver/hw/darwin/bundle/rootlessCommon.h
new file mode 100644
index 000000000..de5c65b57
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/bundle/rootlessCommon.h
@@ -0,0 +1,209 @@
+/*
+ * Common internal rootless definitions and code
+ *
+ * Greg Parker gparker@cs.stanford.edu
+ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/rootlessCommon.h,v 1.2 2001/07/01 03:24:57 torrey Exp $ */
+
+#ifndef _ROOTLESSCOMMON_H
+#define _ROOTLESSCOMMON_H
+
+#include "rootless.h"
+
+#include "pixmapstr.h"
+#include "windowstr.h"
+
+#ifdef RENDER
+#include "picturestr.h"
+#endif
+
+
+// Debug output, or not.
+
+#ifdef ROOTLESSDEBUG
+#define RL_DEBUG_MSG ErrorF
+#else
+#define RL_DEBUG_MSG(a, ...)
+#endif
+
+
+// Global variables
+extern int rootlessGCPrivateIndex;
+extern int rootlessScreenPrivateIndex;
+extern int rootlessWindowPrivateIndex;
+
+
+// RootlessGCRec: private per-gc data
+typedef struct {
+ GCFuncs *originalFuncs;
+ GCOps *originalOps;
+} RootlessGCRec;
+
+
+// RootlessWindowRec: private per-window data
+typedef struct RootlessWindowRec {
+ RootlessFrameRec frame;
+ RegionRec damage;
+ unsigned int borderWidth; // needed for MoveWindow(VTOther) (%$#@!!!)
+ PixmapPtr pixmap;
+} RootlessWindowRec;
+
+
+// RootlessScreenRec: per-screen private data
+typedef struct {
+ ScreenPtr pScreen;
+ RootlessFrameProcs frameProcs;
+
+ CloseScreenProcPtr CloseScreen;
+
+ CreateWindowProcPtr CreateWindow;
+ DestroyWindowProcPtr DestroyWindow;
+ RealizeWindowProcPtr RealizeWindow;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ MoveWindowProcPtr MoveWindow;
+ ResizeWindowProcPtr ResizeWindow;
+ RestackWindowProcPtr RestackWindow;
+ ChangeBorderWidthProcPtr ChangeBorderWidth;
+ PositionWindowProcPtr PositionWindow;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+
+ CreateGCProcPtr CreateGC;
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ CopyWindowProcPtr CopyWindow;
+ GetImageProcPtr GetImage;
+
+ MarkOverlappedWindowsProcPtr MarkOverlappedWindows;
+ ValidateTreeProcPtr ValidateTree;
+
+#ifdef SHAPE
+ SetShapeProcPtr SetShape;
+#endif
+
+#ifdef RENDER
+ CompositeProcPtr Composite;
+ GlyphsProcPtr Glyphs;
+#endif
+
+} RootlessScreenRec;
+
+
+// "Definition of the Porting Layer for the X11 Sample Server" says
+// unwrap and rewrap of screen functions is unnecessary, but
+// screen->CreateGC changes after a call to cfbCreateGC.
+
+#define SCREEN_UNWRAP(screen, fn) \
+ screen->fn = SCREENREC(screen)->fn;
+
+#define SCREEN_WRAP(screen, fn) \
+ SCREENREC(screen)->fn = screen->fn; \
+ screen->fn = Rootless##fn
+
+
+// Accessors for screen and window privates
+
+#define SCREENREC(pScreen) \
+ ((RootlessScreenRec*)(pScreen)->devPrivates[rootlessScreenPrivateIndex].ptr)
+
+#define WINREC(pWin) \
+ ((RootlessWindowRec *)(pWin)->devPrivates[rootlessWindowPrivateIndex].ptr)
+
+
+// Call a rootless implementation function.
+// Many rootless implementation functions are allowed to be NULL.
+#define CallFrameProc(pScreen, proc, params) \
+ if (SCREENREC(pScreen)->frameProcs.proc) { \
+ RL_DEBUG_MSG("calling frame proc " #proc " "); \
+ SCREENREC(pScreen)->frameProcs.proc params; \
+ }
+
+
+// BoxRec manipulators
+// Copied from shadowfb
+
+#define TRIM_BOX(box, pGC) { \
+ BoxPtr extents = &pGC->pCompositeClip->extents;\
+ if(box.x1 < extents->x1) box.x1 = extents->x1; \
+ if(box.x2 > extents->x2) box.x2 = extents->x2; \
+ if(box.y1 < extents->y1) box.y1 = extents->y1; \
+ if(box.y2 > extents->y2) box.y2 = extents->y2; \
+}
+
+#define TRANSLATE_BOX(box, pDraw) { \
+ box.x1 += pDraw->x; \
+ box.x2 += pDraw->x; \
+ box.y1 += pDraw->y; \
+ box.y2 += pDraw->y; \
+}
+
+#define TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC) { \
+ TRANSLATE_BOX(box, pDraw); \
+ TRIM_BOX(box, pGC); \
+}
+
+#define BOX_NOT_EMPTY(box) \
+ (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))
+
+
+// HUGE_ROOT and NORMAL_ROOT
+// We don't want to clip windows to the edge of the screen.
+// HUGE_ROOT temporarily makes the root window really big.
+// This is needed as a wrapper around any function that calls
+// SetWinSize or SetBorderSize which clip a window against its
+// parents, including the root.
+
+extern RegionRec rootlessHugeRoot;
+
+#define HUGE_ROOT(pWin) \
+ { \
+ WindowPtr w = pWin; \
+ while (w->parent) w = w->parent; \
+ saveRoot = w->winSize; \
+ w->winSize = rootlessHugeRoot; \
+ }
+
+#define NORMAL_ROOT(pWin) \
+ { \
+ WindowPtr w = pWin; \
+ while (w->parent) w = w->parent; \
+ w->winSize = saveRoot; \
+ }
+
+
+// Returns TRUE if this window is a top-level window (i.e. child of the root)
+// The root is not a top-level window.
+#define IsTopLevel(pWin) \
+ ((pWin) && (pWin)->parent && !(pWin)->parent->parent)
+
+// Returns TRUE if this window is a root window
+#define IsRoot(pWin) \
+ ((pWin) == WindowTable[(pWin)->drawable.pScreen->myNum])
+
+// Returns the top-level parent of pWindow.
+// The root is the top-level parent of itself, even though the root is
+// not otherwise considered to be a top-level window.
+WindowPtr TopLevelParent(WindowPtr pWindow);
+
+// Returns TRUE if this window is visible inside a frame
+// (e.g. it is visible and has a top-level or root parent)
+Bool IsFramedWindow(WindowPtr pWin);
+
+// Move the given pixmap's base address to where pixel (0, 0)
+// would be if the pixmap's actual data started at (x, y)
+void SetPixmapBaseToScreen(PixmapPtr pix, int x, int y);
+
+// Update pWindow's pixmap.
+// This needs to be called every time a window moves relative to
+// its top-level parent, or the parent's pixmap data is reallocated.
+void UpdatePixmap(WindowPtr pWindow);
+
+// Routines that cause regions to get redrawn.
+// DamageRegion and DamageRect are GLOBAL coords
+// DamageBox is WINDOW-LOCAL coords
+void RootlessDamageRegion(WindowPtr pWindow, RegionPtr pRegion);
+void RootlessDamageRect(WindowPtr pWindow, int x, int y, int w, int h);
+void RootlessDamageBox(WindowPtr pWindow, BoxPtr pBox);
+void RootlessRedisplay(WindowPtr pWindow);
+void RootlessRedisplayScreen(ScreenPtr pScreen);
+
+#endif // _ROOTLESSCOMMON_H
diff --git a/xc/programs/Xserver/hw/darwin/bundle/rootlessGC.c b/xc/programs/Xserver/hw/darwin/bundle/rootlessGC.c
new file mode 100644
index 000000000..a82118b23
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/bundle/rootlessGC.c
@@ -0,0 +1,1170 @@
+/*
+ * Graphics Context support for Mac OS X rootless X server
+ *
+ * Greg Parker gparker@cs.stanford.edu
+ *
+ * February 2001 Created
+ * March 3, 2001 Restructured as generic rootless mode
+ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/rootlessGC.c,v 1.3 2001/07/01 03:24:57 torrey Exp $ */
+
+#include "mi.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "dixfontstr.h"
+#include "mivalidate.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "rootlessCommon.h"
+
+
+// GC functions
+static void RootlessValidateGC(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDrawable);
+static void RootlessChangeGC(GCPtr pGC, unsigned long mask);
+static void RootlessCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
+static void RootlessDestroyGC(GCPtr pGC);
+static void RootlessChangeClip(GCPtr pGC, int type, pointer pvalue,
+ int nrects);
+static void RootlessDestroyClip(GCPtr pGC);
+static void RootlessCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
+
+GCFuncs rootlessGCFuncs = {
+ RootlessValidateGC,
+ RootlessChangeGC,
+ RootlessCopyGC,
+ RootlessDestroyGC,
+ RootlessChangeClip,
+ RootlessDestroyClip,
+ RootlessCopyClip,
+};
+
+// GC operations
+static void RootlessFillSpans();
+static void RootlessSetSpans();
+static void RootlessPutImage();
+static RegionPtr RootlessCopyArea();
+static RegionPtr RootlessCopyPlane();
+static void RootlessPolyPoint();
+static void RootlessPolylines();
+static void RootlessPolySegment();
+static void RootlessPolyRectangle();
+static void RootlessPolyArc();
+static void RootlessFillPolygon();
+static void RootlessPolyFillRect();
+static void RootlessPolyFillArc();
+static int RootlessPolyText8();
+static int RootlessPolyText16();
+static void RootlessImageText8();
+static void RootlessImageText16();
+static void RootlessImageGlyphBlt();
+static void RootlessPolyGlyphBlt();
+static void RootlessPushPixels();
+
+static GCOps rootlessGCOps = {
+ RootlessFillSpans,
+ RootlessSetSpans,
+ RootlessPutImage,
+ RootlessCopyArea,
+ RootlessCopyPlane,
+ RootlessPolyPoint,
+ RootlessPolylines,
+ RootlessPolySegment,
+ RootlessPolyRectangle,
+ RootlessPolyArc,
+ RootlessFillPolygon,
+ RootlessPolyFillRect,
+ RootlessPolyFillArc,
+ RootlessPolyText8,
+ RootlessPolyText16,
+ RootlessImageText8,
+ RootlessImageText16,
+ RootlessImageGlyphBlt,
+ RootlessPolyGlyphBlt,
+ RootlessPushPixels
+#ifdef NEED_LINEHELPER
+ , NULL
+#endif
+};
+
+
+Bool
+RootlessCreateGC(GCPtr pGC)
+{
+ RootlessGCRec *gcrec;
+ RootlessScreenRec *s;
+ Bool result;
+
+ SCREEN_UNWRAP(pGC->pScreen, CreateGC);
+ s = (RootlessScreenRec *) pGC->pScreen->
+ devPrivates[rootlessScreenPrivateIndex].ptr;
+ result = s->CreateGC(pGC);
+ gcrec = (RootlessGCRec *) pGC->devPrivates[rootlessGCPrivateIndex].ptr;
+ gcrec->originalOps = NULL; // don't wrap ops yet
+ gcrec->originalFuncs = pGC->funcs;
+ pGC->funcs = &rootlessGCFuncs;
+
+ SCREEN_WRAP(pGC->pScreen, CreateGC);
+ return result;
+}
+
+
+// GC func wrapping
+// ValidateGC wraps gcOps iff dest is viewable. All others just unwrap&call.
+
+// GCFUN_UNRAP assumes funcs have been wrapped and
+// does not assume ops have been wrapped
+#define GCFUNC_UNWRAP(pGC) \
+ RootlessGCRec *gcrec = (RootlessGCRec *) \
+ (pGC)->devPrivates[rootlessGCPrivateIndex].ptr; \
+ (pGC)->funcs = gcrec->originalFuncs; \
+ if (gcrec->originalOps) { \
+ (pGC)->ops = gcrec->originalOps; \
+}
+
+#define GCFUNC_WRAP(pGC) \
+ gcrec->originalFuncs = (pGC)->funcs; \
+ (pGC)->funcs = &rootlessGCFuncs; \
+ if (gcrec->originalOps) { \
+ gcrec->originalOps = (pGC)->ops; \
+ (pGC)->ops = &rootlessGCOps; \
+}
+
+
+static void
+RootlessValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
+{
+ GCFUNC_UNWRAP(pGC);
+
+ pGC->funcs->ValidateGC(pGC, changes, pDrawable);
+
+ gcrec->originalOps = NULL;
+
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ WindowPtr pWin = (WindowPtr) pDrawable;
+
+ if (pWin->viewable) {
+ gcrec->originalOps = pGC->ops;
+ }
+ }
+
+ GCFUNC_WRAP(pGC);
+}
+
+static void RootlessChangeGC(GCPtr pGC, unsigned long mask)
+{
+ GCFUNC_UNWRAP(pGC);
+ pGC->funcs->ChangeGC(pGC, mask);
+ GCFUNC_WRAP(pGC);
+}
+
+static void RootlessCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
+{
+ GCFUNC_UNWRAP(pGCDst);
+ pGCDst->funcs->CopyGC(pGCSrc, mask, pGCDst);
+ GCFUNC_WRAP(pGCDst);
+}
+
+static void RootlessDestroyGC(GCPtr pGC)
+{
+ GCFUNC_UNWRAP(pGC);
+ pGC->funcs->DestroyGC(pGC);
+ GCFUNC_WRAP(pGC);
+}
+
+static void RootlessChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
+{
+ GCFUNC_UNWRAP(pGC);
+ pGC->funcs->ChangeClip(pGC, type, pvalue, nrects);
+ GCFUNC_WRAP(pGC);
+}
+
+static void RootlessDestroyClip(GCPtr pGC)
+{
+ GCFUNC_UNWRAP(pGC);
+ pGC->funcs->DestroyClip(pGC);
+ GCFUNC_WRAP(pGC);
+}
+
+static void RootlessCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ GCFUNC_UNWRAP(pgcDst);
+ pgcDst->funcs->CopyClip(pgcDst, pgcSrc);
+ GCFUNC_WRAP(pgcDst);
+}
+
+
+// GC ops
+// We can't use shadowfb because shadowfb assumes one pixmap
+// and our root window is a special case.
+// So much of this code is copied from shadowfb.
+
+// assumes both funcs and ops are wrapped
+#define GCOP_UNWRAP(pGC) \
+ RootlessGCRec *gcrec = (RootlessGCRec *) \
+ (pGC)->devPrivates[rootlessGCPrivateIndex].ptr; \
+ GCFuncs *saveFuncs = pGC->funcs; \
+ (pGC)->funcs = gcrec->originalFuncs; \
+ (pGC)->ops = gcrec->originalOps;
+
+#define GCOP_WRAP(pGC) \
+ gcrec->originalOps = (pGC)->ops; \
+ (pGC)->funcs = saveFuncs; \
+ (pGC)->ops = &rootlessGCOps;
+
+
+static void
+RootlessFillSpans(DrawablePtr dst, GCPtr pGC, int nInit,
+ DDXPointPtr pptInit, int *pwidthInit, int sorted)
+{
+ GCOP_UNWRAP(pGC);
+ RL_DEBUG_MSG("fill spans start ");
+
+ if (nInit <= 0) {
+ pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted);
+ } else {
+ DDXPointPtr ppt = pptInit;
+ int *pwidth = pwidthInit;
+ int i = nInit;
+ BoxRec box;
+
+ box.x1 = ppt->x;
+ box.x2 = box.x1 + *pwidth;
+ box.y2 = box.y1 = ppt->y;
+
+ while(--i) {
+ ppt++;
+ pwidthInit++;
+ if(box.x1 > ppt->x)
+ box.x1 = ppt->x;
+ if(box.x2 < (ppt->x + *pwidth))
+ box.x2 = ppt->x + *pwidth;
+ if(box.y1 > ppt->y)
+ box.y1 = ppt->y;
+ else if(box.y2 < ppt->y)
+ box.y2 = ppt->y;
+ }
+
+ box.y2++;
+
+ pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted);
+
+ TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+ }
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("fill spans end\n");
+}
+
+static void
+RootlessSetSpans(DrawablePtr dst, GCPtr pGC, char *pSrc,
+ DDXPointPtr pptInit, int *pwidthInit,
+ int nspans, int sorted)
+{
+ GCOP_UNWRAP(pGC);
+ RL_DEBUG_MSG("set spans start ");
+
+ if (nspans <= 0) {
+ pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit,
+ nspans, sorted);
+ } else {
+ DDXPointPtr ppt = pptInit;
+ int *pwidth = pwidthInit;
+ int i = nspans;
+ BoxRec box;
+
+ box.x1 = ppt->x;
+ box.x2 = box.x1 + *pwidth;
+ box.y2 = box.y1 = ppt->y;
+
+ while(--i) {
+ ppt++;
+ pwidth++;
+ if(box.x1 > ppt->x)
+ box.x1 = ppt->x;
+ if(box.x2 < (ppt->x + *pwidth))
+ box.x2 = ppt->x + *pwidth;
+ if(box.y1 > ppt->y)
+ box.y1 = ppt->y;
+ else if(box.y2 < ppt->y)
+ box.y2 = ppt->y;
+ }
+
+ box.y2++;
+
+ pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit,
+ nspans, sorted);
+
+ TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+ }
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("set spans end\n");
+}
+
+static void
+RootlessPutImage(DrawablePtr dst, GCPtr pGC,
+ int depth, int x, int y, int w, int h,
+ int leftPad, int format, char *pBits)
+{
+ BoxRec box;
+
+ GCOP_UNWRAP(pGC);
+ RL_DEBUG_MSG("put image start ");
+
+ pGC->ops->PutImage(dst, pGC, depth, x,y,w,h, leftPad, format, pBits);
+
+ box.x1 = x + dst->x;
+ box.x2 = box.x1 + w;
+ box.y1 = y + dst->y;
+ box.y2 = box.y1 + h;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("put image end\n");
+}
+
+/* changed area is *dest* rect */
+/* If this code ever goes back go StartDrawing/StopDrawing:
+ * start and stop dst always
+ * start and stop src if src->type is DRAWABLE_WINDOW and src is framed
+ */
+static RegionPtr
+RootlessCopyArea(DrawablePtr pSrc, DrawablePtr dst, GCPtr pGC,
+ int srcx, int srcy, int w, int h,
+ int dstx, int dsty)
+{
+ RegionPtr result;
+ BoxRec box;
+
+ GCOP_UNWRAP(pGC);
+ RL_DEBUG_MSG("copy area start (src 0x%x, dst 0x%x)", pSrc, dst);
+
+ result = pGC->ops->CopyArea(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty);
+
+ box.x1 = dstx + dst->x;
+ box.x2 = box.x1 + w;
+ box.y1 = dsty + dst->y;
+ box.y2 = box.y1 + h;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("copy area end\n");
+ return result;
+}
+
+/* changed area is *dest* rect */
+/* If this code ever goes back go StartDrawing/StopDrawing:
+ * start and stop dst always
+ * start and stop src if src->type is DRAWABLE_WINDOW and src is framed
+ */
+static RegionPtr RootlessCopyPlane(DrawablePtr pSrc, DrawablePtr dst,
+ GCPtr pGC, int srcx, int srcy,
+ int w, int h, int dstx, int dsty,
+ unsigned long plane)
+{
+ RegionPtr result;
+ BoxRec box;
+
+ GCOP_UNWRAP(pGC);
+ RL_DEBUG_MSG("copy plane start ");
+
+ result = pGC->ops->CopyPlane(pSrc, dst, pGC, srcx, srcy, w, h,
+ dstx, dsty, plane);
+
+ box.x1 = dstx + dst->x;
+ box.x2 = box.x1 + w;
+ box.y1 = dsty + dst->y;
+ box.y2 = box.y1 + h;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("copy plane end\n");
+ return result;
+}
+
+// Options for size of changed area:
+// 0 = box per point
+// 1 = big box around all points
+// 2 = accumulate point in 20 pixel radius
+#define ROOTLESS_CHANGED_AREA 1
+#define abs(a) ((a) > 0 ? (a) : -(a))
+
+/* changed area is box around all points */
+static void RootlessPolyPoint(DrawablePtr dst, GCPtr pGC,
+ int mode, int npt, DDXPointPtr pptInit)
+{
+ GCOP_UNWRAP(pGC);
+
+ RL_DEBUG_MSG("polypoint start ");
+
+ pGC->ops->PolyPoint(dst, pGC, mode, npt, pptInit);
+
+ if (npt > 0) {
+#if ROOTLESS_CHANGED_AREA==0
+ // box per point
+ BoxRec box;
+
+ while (npt) {
+ box.x1 = pptInit->x;
+ box.y1 = pptInit->y;
+ box.x2 = box.x1 + 1;
+ box.y2 = box.y1 + 1;
+
+ TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+
+ npt--;
+ pptInit++;
+ }
+
+#elif ROOTLESS_CHANGED_AREA==1
+ // one big box
+ BoxRec box;
+
+ box.x2 = box.x1 = pptInit->x;
+ box.y2 = box.y1 = pptInit->y;
+ while(--npt) {
+ pptInit++;
+ if(box.x1 > pptInit->x)
+ box.x1 = pptInit->x;
+ else if(box.x2 < pptInit->x)
+ box.x2 = pptInit->x;
+ if(box.y1 > pptInit->y)
+ box.y1 = pptInit->y;
+ else if(box.y2 < pptInit->y)
+ box.y2 = pptInit->y;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+
+#elif ROOTLESS_CHANGED_AREA==2
+ // clever(?) method: accumulate point in 20-pixel radius
+ BoxRec box;
+ int firstx, firsty;
+
+ box.x2 = box.x1 = firstx = pptInit->x;
+ box.y2 = box.y1 = firsty = pptInit->y;
+ while(--npt) {
+ pptInit++;
+ if (abs(pptInit->x - firstx) > 20 ||
+ abs(pptInit->y - firsty) > 20) {
+ box.x2++;
+ box.y2++;
+ TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+ box.x2 = box.x1 = firstx = pptInit->x;
+ box.y2 = box.y1 = firsty = pptInit->y;
+ } else {
+ if (box.x1 > pptInit->x) box.x1 = pptInit->x;
+ else if (box.x2 < pptInit->x) box.x2 = pptInit->x;
+ if (box.y1 > pptInit->y) box.y1 = pptInit->y;
+ else if (box.y2 < pptInit->y) box.y2 = pptInit->y;
+ }
+ }
+ box.x2++;
+ box.y2++;
+ TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+#endif /* ROOTLESS_CHANGED_AREA */
+ }
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("polypoint end\n");
+}
+
+#undef ROOTLESS_CHANGED_AREA
+
+/* changed area is box around each line */
+static void RootlessPolylines(DrawablePtr dst, GCPtr pGC,
+ int mode, int npt, DDXPointPtr pptInit)
+{
+ GCOP_UNWRAP(pGC);
+
+ RL_DEBUG_MSG("poly lines start ");
+
+ pGC->ops->Polylines(dst, pGC, mode, npt, pptInit);
+
+ if (npt > 0) {
+ BoxRec box;
+ int extra = pGC->lineWidth >> 1;
+
+ box.x2 = box.x1 = pptInit->x;
+ box.y2 = box.y1 = pptInit->y;
+
+ if(npt > 1) {
+ if(pGC->joinStyle == JoinMiter)
+ extra = 6 * pGC->lineWidth;
+ else if(pGC->capStyle == CapProjecting)
+ extra = pGC->lineWidth;
+ }
+
+ if(mode == CoordModePrevious) {
+ int x = box.x1;
+ int y = box.y1;
+
+ while(--npt) {
+ pptInit++;
+ x += pptInit->x;
+ y += pptInit->y;
+ if(box.x1 > x)
+ box.x1 = x;
+ else if(box.x2 < x)
+ box.x2 = x;
+ if(box.y1 > y)
+ box.y1 = y;
+ else if(box.y2 < y)
+ box.y2 = y;
+ }
+ } else {
+ while(--npt) {
+ pptInit++;
+ if(box.x1 > pptInit->x)
+ box.x1 = pptInit->x;
+ else if(box.x2 < pptInit->x)
+ box.x2 = pptInit->x;
+ if(box.y1 > pptInit->y)
+ box.y1 = pptInit->y;
+ else if(box.y2 < pptInit->y)
+ box.y2 = pptInit->y;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ if(extra) {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+ }
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("poly lines end\n");
+}
+
+/* changed area is box around each line segment */
+static void RootlessPolySegment(DrawablePtr dst, GCPtr pGC,
+ int nseg, xSegment *pSeg)
+{
+ GCOP_UNWRAP(pGC);
+
+ RL_DEBUG_MSG("poly segment start (win 0x%x)", dst);
+
+ pGC->ops->PolySegment(dst, pGC, nseg, pSeg);
+
+ if (nseg > 0) {
+ BoxRec box;
+ int extra = pGC->lineWidth;
+
+ if(pGC->capStyle != CapProjecting)
+ extra >>= 1;
+
+ if(pSeg->x2 > pSeg->x1) {
+ box.x1 = pSeg->x1;
+ box.x2 = pSeg->x2;
+ } else {
+ box.x2 = pSeg->x1;
+ box.x1 = pSeg->x2;
+ }
+
+ if(pSeg->y2 > pSeg->y1) {
+ box.y1 = pSeg->y1;
+ box.y2 = pSeg->y2;
+ } else {
+ box.y2 = pSeg->y1;
+ box.y1 = pSeg->y2;
+ }
+
+ while(--nseg) {
+ pSeg++;
+ if(pSeg->x2 > pSeg->x1) {
+ if(pSeg->x1 < box.x1) box.x1 = pSeg->x1;
+ if(pSeg->x2 > box.x2) box.x2 = pSeg->x2;
+ } else {
+ if(pSeg->x2 < box.x1) box.x1 = pSeg->x2;
+ if(pSeg->x1 > box.x2) box.x2 = pSeg->x1;
+ }
+ if(pSeg->y2 > pSeg->y1) {
+ if(pSeg->y1 < box.y1) box.y1 = pSeg->y1;
+ if(pSeg->y2 > box.y2) box.y2 = pSeg->y2;
+ } else {
+ if(pSeg->y2 < box.y1) box.y1 = pSeg->y2;
+ if(pSeg->y1 > box.y2) box.y2 = pSeg->y1;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ if(extra) {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+ }
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("poly segment end\n");
+}
+
+/* changed area is box around each line (not entire rects) */
+static void RootlessPolyRectangle(DrawablePtr dst, GCPtr pGC,
+ int nRects, xRectangle *pRects)
+{
+ GCOP_UNWRAP(pGC);
+
+ RL_DEBUG_MSG("poly rectangle start ");
+
+ pGC->ops->PolyRectangle(dst, pGC, nRects, pRects);
+
+ if (nRects > 0) {
+ BoxRec box;
+ int offset1, offset2, offset3;
+
+ offset2 = pGC->lineWidth;
+ if(!offset2) offset2 = 1;
+ offset1 = offset2 >> 1;
+ offset3 = offset2 - offset1;
+
+ while(nRects--) {
+ box.x1 = pRects->x - offset1;
+ box.y1 = pRects->y - offset1;
+ box.x2 = box.x1 + pRects->width + offset2;
+ box.y2 = box.y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+
+ box.x1 = pRects->x - offset1;
+ box.y1 = pRects->y + offset3;
+ box.x2 = box.x1 + offset2;
+ box.y2 = box.y1 + pRects->height - offset2;
+ TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+
+ box.x1 = pRects->x + pRects->width - offset1;
+ box.y1 = pRects->y + offset3;
+ box.x2 = box.x1 + offset2;
+ box.y2 = box.y1 + pRects->height - offset2;
+ TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+
+ box.x1 = pRects->x - offset1;
+ box.y1 = pRects->y + pRects->height - offset1;
+ box.x2 = box.x1 + pRects->width + offset2;
+ box.y2 = box.y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+
+ pRects++;
+ }
+ }
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("poly rectangle end\n");
+}
+
+
+/* changed area is box around each arc (assumes all arcs are 360 degrees) */
+static void RootlessPolyArc(DrawablePtr dst, GCPtr pGC, int narcs, xArc *parcs)
+{
+ GCOP_UNWRAP(pGC);
+
+ RL_DEBUG_MSG("poly arc start ");
+
+ pGC->ops->PolyArc(dst, pGC, narcs, parcs);
+
+ if (narcs > 0) {
+ int extra = pGC->lineWidth >> 1;
+ BoxRec box;
+
+ box.x1 = parcs->x;
+ box.x2 = box.x1 + parcs->width;
+ box.y1 = parcs->y;
+ box.y2 = box.y1 + parcs->height;
+
+ /* should I break these up instead ? */
+
+ while(--narcs) {
+ parcs++;
+ if(box.x1 > parcs->x)
+ box.x1 = parcs->x;
+ if(box.x2 < (parcs->x + parcs->width))
+ box.x2 = parcs->x + parcs->width;
+ if(box.y1 > parcs->y)
+ box.y1 = parcs->y;
+ if(box.y2 < (parcs->y + parcs->height))
+ box.y2 = parcs->y + parcs->height;
+ }
+
+ if(extra) {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+ }
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("poly arc end\n");
+}
+
+
+/* changed area is box around each poly */
+static void RootlessFillPolygon(DrawablePtr dst, GCPtr pGC,
+ int shape, int mode, int count,
+ DDXPointPtr pptInit)
+{
+ GCOP_UNWRAP(pGC);
+
+ RL_DEBUG_MSG("fill poly start ");
+
+ if (count <= 2) {
+ pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit);
+ } else {
+ DDXPointPtr ppt = pptInit;
+ int i = count;
+ BoxRec box;
+
+ box.x2 = box.x1 = ppt->x;
+ box.y2 = box.y1 = ppt->y;
+
+ if(mode != CoordModeOrigin) {
+ int x = box.x1;
+ int y = box.y1;
+
+ while(--i) {
+ ppt++;
+ x += ppt->x;
+ y += ppt->y;
+ if(box.x1 > x)
+ box.x1 = x;
+ else if(box.x2 < x)
+ box.x2 = x;
+ if(box.y1 > y)
+ box.y1 = y;
+ else if(box.y2 < y)
+ box.y2 = y;
+ }
+ } else {
+ while(--i) {
+ ppt++;
+ if(box.x1 > ppt->x)
+ box.x1 = ppt->x;
+ else if(box.x2 < ppt->x)
+ box.x2 = ppt->x;
+ if(box.y1 > ppt->y)
+ box.y1 = ppt->y;
+ else if(box.y2 < ppt->y)
+ box.y2 = ppt->y;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit);
+
+ TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+ }
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("fill poly end\n");
+}
+
+/* changed area is the rects */
+static void RootlessPolyFillRect(DrawablePtr dst, GCPtr pGC,
+ int nRectsInit, xRectangle *pRectsInit)
+{
+ GCOP_UNWRAP(pGC);
+
+ RL_DEBUG_MSG("fill rect start (win 0x%x)", dst);
+
+ if (nRectsInit <= 0) {
+ pGC->ops->PolyFillRect(dst, pGC, nRectsInit, pRectsInit);
+ } else {
+ BoxRec box;
+ xRectangle *pRects = pRectsInit;
+ int nRects = nRectsInit;
+
+ box.x1 = pRects->x;
+ box.x2 = box.x1 + pRects->width;
+ box.y1 = pRects->y;
+ box.y2 = box.y1 + pRects->height;
+
+ while(--nRects) {
+ pRects++;
+ if(box.x1 > pRects->x)
+ box.x1 = pRects->x;
+ if(box.x2 < (pRects->x + pRects->width))
+ box.x2 = pRects->x + pRects->width;
+ if(box.y1 > pRects->y)
+ box.y1 = pRects->y;
+ if(box.y2 < (pRects->y + pRects->height))
+ box.y2 = pRects->y + pRects->height;
+ }
+
+ /* cfb messes with the pRectsInit so we have to do our
+ calculations first */
+
+ pGC->ops->PolyFillRect(dst, pGC, nRectsInit, pRectsInit);
+
+ TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+ }
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("fill rect end\n");
+}
+
+
+/* changed area is box around each arc (assuming arcs are all 360 degrees) */
+static void RootlessPolyFillArc(DrawablePtr dst, GCPtr pGC,
+ int narcs, xArc *parcs)
+{
+ GCOP_UNWRAP(pGC);
+
+ RL_DEBUG_MSG("fill arc start ");
+
+ pGC->ops->PolyFillArc(dst, pGC, narcs, parcs);
+
+ if (narcs > 0) {
+ BoxRec box;
+
+ box.x1 = parcs->x;
+ box.x2 = box.x1 + parcs->width;
+ box.y1 = parcs->y;
+ box.y2 = box.y1 + parcs->height;
+
+ /* should I break these up instead ? */
+
+ while(--narcs) {
+ parcs++;
+ if(box.x1 > parcs->x)
+ box.x1 = parcs->x;
+ if(box.x2 < (parcs->x + parcs->width))
+ box.x2 = parcs->x + parcs->width;
+ if(box.y1 > parcs->y)
+ box.y1 = parcs->y;
+ if(box.y2 < (parcs->y + parcs->height))
+ box.y2 = parcs->y + parcs->height;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, dst, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+ }
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("fill arc end");
+}
+
+
+static void RootlessImageText8(DrawablePtr dst, GCPtr pGC,
+ int x, int y, int count, char *chars)
+{
+ GCOP_UNWRAP(pGC);
+ RL_DEBUG_MSG("imagetext8 start ");
+
+ pGC->ops->ImageText8(dst, pGC, x, y, count, chars);
+
+ if (count > 0) {
+ int top, bot, Min, Max;
+ BoxRec box;
+
+ top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
+ bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
+
+ Min = count * FONTMINBOUNDS(pGC->font, characterWidth);
+ if(Min > 0) Min = 0;
+ Max = count * FONTMAXBOUNDS(pGC->font, characterWidth);
+ if(Max < 0) Max = 0;
+
+ /* ugh */
+ box.x1 = dst->x + x + Min +
+ FONTMINBOUNDS(pGC->font, leftSideBearing);
+ box.x2 = dst->x + x + Max +
+ FONTMAXBOUNDS(pGC->font, rightSideBearing);
+
+ box.y1 = dst->y + y - top;
+ box.y2 = dst->y + y + bot;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+ }
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("imagetext8 end\n");
+}
+
+static int RootlessPolyText8(DrawablePtr dst, GCPtr pGC,
+ int x, int y, int count, char *chars)
+{
+ int width; // the result, sorta
+
+ GCOP_UNWRAP(pGC);
+ RL_DEBUG_MSG("polytext8 start ");
+
+ width = pGC->ops->PolyText8(dst, pGC, x, y, count, chars);
+ width -= x;
+
+ if(width > 0) {
+ BoxRec box;
+
+ /* ugh */
+ box.x1 = dst->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing);
+ box.x2 = dst->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing);
+
+ if(count > 1) {
+ if(width > 0) box.x2 += width;
+ else box.x1 += width;
+ }
+
+ box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent);
+ box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent);
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+ }
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("polytext8 end\n");
+ return (width + x);
+}
+
+static void RootlessImageText16(DrawablePtr dst, GCPtr pGC,
+ int x, int y, int count, unsigned short *chars)
+{
+ GCOP_UNWRAP(pGC);
+ RL_DEBUG_MSG("imagetext16 start ");
+
+ pGC->ops->ImageText16(dst, pGC, x, y, count, chars);
+
+ if (count > 0) {
+ int top, bot, Min, Max;
+ BoxRec box;
+
+ top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
+ bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
+
+ Min = count * FONTMINBOUNDS(pGC->font, characterWidth);
+ if(Min > 0) Min = 0;
+ Max = count * FONTMAXBOUNDS(pGC->font, characterWidth);
+ if(Max < 0) Max = 0;
+
+ /* ugh */
+ box.x1 = dst->x + x + Min +
+ FONTMINBOUNDS(pGC->font, leftSideBearing);
+ box.x2 = dst->x + x + Max +
+ FONTMAXBOUNDS(pGC->font, rightSideBearing);
+
+ box.y1 = dst->y + y - top;
+ box.y2 = dst->y + y + bot;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+ }
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("imagetext16 end\n");
+}
+
+static int RootlessPolyText16(DrawablePtr dst, GCPtr pGC,
+ int x, int y, int count, unsigned short *chars)
+{
+ int width; // the result, sorta
+
+ GCOP_UNWRAP(pGC);
+ RL_DEBUG_MSG("polytext16 start ");
+
+ width = pGC->ops->PolyText16(dst, pGC, x, y, count, chars);
+ width -= x;
+
+ if (width > 0) {
+ BoxRec box;
+
+ /* ugh */
+ box.x1 = dst->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing);
+ box.x2 = dst->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing);
+
+ if(count > 1) {
+ if(width > 0) box.x2 += width;
+ else box.x1 += width;
+ }
+
+ box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent);
+ box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent);
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+ }
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("polytext16 end\n");
+ return width + x;
+}
+
+static void RootlessImageGlyphBlt(DrawablePtr dst, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer unused)
+{
+ GCOP_UNWRAP(pGC);
+ RL_DEBUG_MSG("imageglyph start ");
+
+ pGC->ops->ImageGlyphBlt(dst, pGC, x, y, nglyph, ppci, unused);
+
+ if (nglyph > 0) {
+ int top, bot, width = 0;
+ BoxRec box;
+
+ top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
+ bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
+
+ box.x1 = ppci[0]->metrics.leftSideBearing;
+ if(box.x1 > 0) box.x1 = 0;
+ box.x2 = ppci[nglyph - 1]->metrics.rightSideBearing -
+ ppci[nglyph - 1]->metrics.characterWidth;
+ if(box.x2 < 0) box.x2 = 0;
+
+ box.x2 += dst->x + x;
+ box.x1 += dst->x + x;
+
+ while(nglyph--) {
+ width += (*ppci)->metrics.characterWidth;
+ ppci++;
+ }
+
+ if(width > 0)
+ box.x2 += width;
+ else
+ box.x1 += width;
+
+ box.y1 = dst->y + y - top;
+ box.y2 = dst->y + y + bot;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+ }
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("imageglyph end\n");
+}
+
+static void RootlessPolyGlyphBlt(DrawablePtr dst, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ GCOP_UNWRAP(pGC);
+ RL_DEBUG_MSG("polyglyph start ");
+
+ pGC->ops->PolyGlyphBlt(dst, pGC, x, y, nglyph, ppci, pglyphBase);
+
+ if (nglyph > 0) {
+ BoxRec box;
+
+ /* ugh */
+ box.x1 = dst->x + x + ppci[0]->metrics.leftSideBearing;
+ box.x2 = dst->x + x + ppci[nglyph - 1]->metrics.rightSideBearing;
+
+ if(nglyph > 1) {
+ int width = 0;
+
+ while(--nglyph) {
+ width += (*ppci)->metrics.characterWidth;
+ ppci++;
+ }
+
+ if(width > 0) box.x2 += width;
+ else box.x1 += width;
+ }
+
+ box.y1 = dst->y + y - FONTMAXBOUNDS(pGC->font, ascent);
+ box.y2 = dst->y + y + FONTMAXBOUNDS(pGC->font, descent);
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+ }
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("polyglyph end\n");
+}
+
+
+/* changed area is in dest */
+static void
+RootlessPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr dst,
+ int dx, int dy, int xOrg, int yOrg)
+{
+ BoxRec box;
+ GCOP_UNWRAP(pGC);
+
+ pGC->ops->PushPixels(pGC, pBitMap, dst, dx, dy, xOrg, yOrg);
+
+ box.x1 = xOrg + dst->x;
+ box.x2 = box.x1 + dx;
+ box.y1 = yOrg + dst->y;
+ box.y2 = box.y1 + dy;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ RootlessDamageBox ((WindowPtr) dst, &box);
+
+ GCOP_WRAP(pGC);
+ RL_DEBUG_MSG("push pixels end\n");
+}
diff --git a/xc/programs/Xserver/hw/darwin/bundle/rootlessScreen.c b/xc/programs/Xserver/hw/darwin/bundle/rootlessScreen.c
new file mode 100644
index 000000000..cbbccb9ce
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/bundle/rootlessScreen.c
@@ -0,0 +1,430 @@
+/*
+ * Screen routines for Mac OS X rootless X server
+ *
+ * Greg Parker gparker@cs.stanford.edu
+ *
+ * February 2001 Created
+ * March 3, 2001 Restructured as generic rootless mode
+ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/rootlessScreen.c,v 1.2 2001/07/01 02:13:41 torrey Exp $ */
+
+
+#include "mi.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "propertyst.h"
+#include "mivalidate.h"
+#include "picturestr.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "rootlessCommon.h"
+#include "rootlessWindow.h"
+
+extern int
+rootlessMiValidateTree(WindowPtr pRoot, WindowPtr pChild, VTKind kind);
+extern Bool
+RootlessCreateGC(GCPtr pGC);
+
+// Initialize globals
+int rootlessGCPrivateIndex = -1;
+int rootlessScreenPrivateIndex = -1;
+int rootlessWindowPrivateIndex = -1;
+
+
+static Bool
+RootlessCloseScreen(int i, ScreenPtr pScreen)
+{
+ RootlessScreenRec *s;
+
+ s = SCREENREC(pScreen);
+
+ // fixme unwrap everything that was wrapped?
+ pScreen->CloseScreen = s->CloseScreen;
+
+ xfree(s);
+ return pScreen->CloseScreen(i, pScreen);
+}
+
+
+static void
+RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
+ unsigned int format, unsigned long planeMask, char *pdstLine)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ SCREEN_UNWRAP(pScreen, GetImage);
+
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ /* Many apps use GetImage to sync with the visible frame buffer */
+ // fixme entire screen or just window or all screens?
+ RootlessRedisplayScreen(pScreen);
+ }
+ pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
+ SCREEN_WRAP(pScreen, GetImage);
+}
+
+
+#ifdef RENDER
+
+static void
+RootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
+ INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask,
+ INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ WindowPtr srcWin, maskWin, dstWin;
+
+ srcWin = (pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
+ (WindowPtr)pSrc->pDrawable : NULL;
+ maskWin = (pMask->pDrawable->type == DRAWABLE_WINDOW) ?
+ (WindowPtr)pMask->pDrawable : NULL;
+ dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
+ (WindowPtr)pDst->pDrawable : NULL;
+
+ // SCREEN_UNWRAP(ps, Composite);
+ ps->Composite = SCREENREC(pScreen)->Composite;
+
+ ps->Composite(op, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask,
+ xDst, yDst, width, height);
+
+ if (dstWin && IsFramedWindow(dstWin)) {
+ RootlessDamageRect(dstWin, xDst, yDst, width, height);
+ }
+
+ ps->Composite = RootlessComposite;
+ // SCREEN_WRAP(ps, Composite);
+}
+
+
+static void
+RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int nlist, GlyphListPtr list, GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ int x, y;
+ int n;
+ GlyphPtr glyph;
+ WindowPtr srcWin, dstWin;
+
+ srcWin = (pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
+ (WindowPtr)pSrc->pDrawable : NULL;
+ dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
+ (WindowPtr)pDst->pDrawable : NULL;
+
+ //SCREEN_UNWRAP(ps, Glyphs);
+ ps->Glyphs = SCREENREC(pScreen)->Glyphs;
+ ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+ ps->Glyphs = RootlessGlyphs;
+ //SCREEN_WRAP(ps, Glyphs);
+
+ if (dstWin && IsFramedWindow(dstWin)) {
+ x = xSrc;
+ y = ySrc;
+ while (nlist--) {
+ x += list->xOff;
+ y += list->yOff;
+ n = list->len;
+ while (n--) {
+ glyph = *glyphs++;
+ RootlessDamageRect(dstWin,
+ x - glyph->info.x, y - glyph->info.y,
+ glyph->info.width, glyph->info.height);
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+ list++;
+ }
+ }
+}
+
+#endif // RENDER
+
+
+// RootlessValidateTree
+// ValidateTree is modified in two ways:
+// * top-level windows don't clip each other
+// * windows aren't clipped against root.
+// These only matter when validating from the root.
+static int
+RootlessValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
+{
+ int result;
+ RegionRec saveRoot;
+ ScreenPtr pScreen = pParent->drawable.pScreen;
+
+ SCREEN_UNWRAP(pScreen, ValidateTree);
+ RL_DEBUG_MSG("VALIDATETREE start ");
+
+ // Use our custom version to validate from root
+ if (IsRoot(pParent)) {
+ RL_DEBUG_MSG("custom ");
+ result = rootlessMiValidateTree(pParent, pChild, kind);
+ } else {
+ HUGE_ROOT(pParent);
+ result = pScreen->ValidateTree(pParent, pChild, kind);
+ NORMAL_ROOT(pParent);
+ }
+
+ SCREEN_WRAP(pScreen, ValidateTree);
+ RL_DEBUG_MSG("VALIDATETREE end\n");
+
+ return result;
+}
+
+
+// RootlessMarkOverlappedWindows
+// MarkOverlappedWindows is modified to ignore overlapping
+// top-level windows.
+static Bool
+RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst,
+ WindowPtr *ppLayerWin)
+{
+ RegionRec saveRoot;
+ Bool result;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ SCREEN_UNWRAP(pScreen, MarkOverlappedWindows);
+ RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS start ");
+
+ HUGE_ROOT(pWin);
+ if (IsRoot(pWin)) {
+ // root - mark nothing
+ RL_DEBUG_MSG("is root not marking ");
+ result = FALSE;
+ }
+ else if (! IsTopLevel(pWin)) {
+ // not top-level window - mark normally
+ result = pScreen->MarkOverlappedWindows(pWin, pFirst, ppLayerWin);
+ }
+ else {
+ //top-level window - mark children ONLY - NO overlaps with sibs (?)
+ // This code copied from miMarkOverlappedWindows()
+
+ register WindowPtr pChild;
+ Bool anyMarked = FALSE;
+ void (* MarkWindow)() = pScreen->MarkWindow;
+
+ RL_DEBUG_MSG("is top level! ");
+ /* single layered systems are easy */
+ if (ppLayerWin) *ppLayerWin = pWin;
+
+ if (pWin == pFirst) {
+ /* Blindly mark pWin and all of its inferiors. This is a slight
+ * overkill if there are mapped windows that outside pWin's border,
+ * but it's better than wasting time on RectIn checks.
+ */
+ pChild = pWin;
+ while (1) {
+ if (pChild->viewable) {
+ if (REGION_BROKEN (pScreen, &pChild->winSize))
+ SetWinSize (pChild);
+ if (REGION_BROKEN (pScreen, &pChild->borderSize))
+ SetBorderSize (pChild);
+ (* MarkWindow)(pChild);
+ if (pChild->firstChild) {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+ anyMarked = TRUE;
+ pFirst = pFirst->nextSib;
+ }
+ if (anyMarked)
+ (* MarkWindow)(pWin->parent);
+ result = anyMarked;
+ }
+ NORMAL_ROOT(pWin);
+ SCREEN_WRAP(pScreen, MarkOverlappedWindows);
+ RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS end\n");
+ return result;
+}
+
+
+static void
+RootlessPaintWindowBackground(WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ int oldBackgroundState = 0;
+ PixUnion oldBackground;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ SCREEN_UNWRAP(pScreen, PaintWindowBackground);
+ RL_DEBUG_MSG("paintwindowbackground start (win 0x%x) ", pWin);
+ if (IsFramedWindow(pWin)) {
+ if (IsRoot(pWin)) {
+ // set root background to magic transparent color
+ oldBackgroundState = pWin->backgroundState;
+ oldBackground = pWin->background;
+ pWin->backgroundState = BackgroundPixel;
+ pWin->background.pixel = 0x00fffffe;
+ }
+ }
+
+ pScreen->PaintWindowBackground(pWin, pRegion, what);
+
+ if (IsFramedWindow(pWin)) {
+ RootlessDamageRegion(pWin, pRegion);
+ if (IsRoot(pWin)) {
+ pWin->backgroundState = oldBackgroundState;
+ pWin->background = oldBackground;
+ }
+ }
+ SCREEN_WRAP(pScreen, PaintWindowBackground);
+ RL_DEBUG_MSG("paintwindowbackground end\n");
+}
+
+
+static void
+RootlessPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ SCREEN_UNWRAP(pWin->drawable.pScreen, PaintWindowBorder);
+ RL_DEBUG_MSG("paintwindowborder start (win 0x%x) ", pWin);
+ pWin->drawable.pScreen->PaintWindowBorder(pWin, pRegion, what);
+ if (IsFramedWindow(pWin)) {
+ RootlessDamageRegion(pWin, pRegion);
+ }
+ SCREEN_WRAP(pWin->drawable.pScreen, PaintWindowBorder);
+ RL_DEBUG_MSG("paintwindowborder end\n");
+}
+
+
+// Flush drawing before blocking on select().
+static void
+RootlessBlockHandler(pointer pbdata, OSTimePtr pTimeout, pointer pReadmask)
+{
+ RootlessRedisplayScreen((ScreenPtr) pbdata);
+}
+
+
+static void
+RootlessWakeupHandler(pointer data, int i, pointer LastSelectMask)
+{
+ // nothing here
+}
+
+
+static Bool
+RootlessAllocatePrivates(ScreenPtr pScreen)
+{
+ RootlessScreenRec *s;
+ static int rootlessGeneration = -1;
+
+ if (rootlessGeneration != serverGeneration) {
+ rootlessScreenPrivateIndex = AllocateScreenPrivateIndex();
+ if (rootlessScreenPrivateIndex == -1) return FALSE;
+ rootlessGCPrivateIndex = AllocateGCPrivateIndex();
+ if (rootlessGCPrivateIndex == -1) return FALSE;
+ rootlessWindowPrivateIndex = AllocateWindowPrivateIndex();
+ if (rootlessWindowPrivateIndex == -1) return FALSE;
+ rootlessGeneration = serverGeneration;
+ }
+
+ // no allocation needed for screen privates
+ if (!AllocateGCPrivate(pScreen, rootlessGCPrivateIndex,
+ sizeof(RootlessGCRec)))
+ return FALSE;
+ if (!AllocateWindowPrivate(pScreen, rootlessWindowPrivateIndex, 0))
+ return FALSE;
+
+ s = xalloc(sizeof(RootlessScreenRec));
+ if (! s) return FALSE;
+ SCREENREC(pScreen) = s;
+
+ return TRUE;
+}
+
+
+static void
+RootlessWrap(ScreenPtr pScreen)
+{
+ RootlessScreenRec *s = (RootlessScreenRec*)
+ pScreen->devPrivates[rootlessScreenPrivateIndex].ptr;
+
+#define WRAP(a) \
+ if (pScreen->a) { \
+ s->a = pScreen->a; \
+ } else { \
+ RL_DEBUG_MSG("null screen fn " #a "\n"); \
+ s->a = NULL; \
+ } \
+ pScreen->a = Rootless##a
+
+ WRAP(CloseScreen);
+ WRAP(CreateGC);
+ WRAP(PaintWindowBackground);
+ WRAP(PaintWindowBorder);
+ WRAP(CopyWindow);
+ WRAP(GetImage);
+ WRAP(CreateWindow);
+ WRAP(DestroyWindow);
+ WRAP(RealizeWindow);
+ WRAP(UnrealizeWindow);
+ WRAP(MoveWindow);
+ WRAP(PositionWindow);
+ WRAP(ResizeWindow);
+ WRAP(RestackWindow);
+ WRAP(ChangeBorderWidth);
+ WRAP(MarkOverlappedWindows);
+ WRAP(ValidateTree);
+ WRAP(ChangeWindowAttributes);
+
+#ifdef SHAPE
+ WRAP(SetShape);
+#endif
+
+#ifdef RENDER
+ {
+ // Composite and Glyphs don't use normal screen wrapping
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ s->Composite = ps->Composite;
+ ps->Composite = RootlessComposite;
+ s->Glyphs = ps->Glyphs;
+ ps->Glyphs = RootlessGlyphs;
+ }
+#endif
+
+ // WRAP(ClearToBackground); fixme put this back? useful for shaped wins?
+ // WRAP(RestoreAreas); fixme put this back?
+
+#undef WRAP
+}
+
+
+/*
+ * RootlessInit
+ * Rootless wraps lots of stuff and needs a bunch of devPrivates.
+ */
+Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcs *procs)
+{
+ RootlessScreenRec *s;
+
+ if (! RootlessAllocatePrivates(pScreen)) return FALSE;
+ s = (RootlessScreenRec*)
+ pScreen->devPrivates[rootlessScreenPrivateIndex].ptr;
+
+ s->pScreen = pScreen;
+ s->frameProcs = *procs;
+
+ RootlessWrap(pScreen);
+
+ if (!RegisterBlockAndWakeupHandlers (RootlessBlockHandler,
+ RootlessWakeupHandler,
+ (pointer) pScreen))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/darwin/bundle/rootlessValTree.c b/xc/programs/Xserver/hw/darwin/bundle/rootlessValTree.c
new file mode 100644
index 000000000..a6d33b6f1
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/bundle/rootlessValTree.c
@@ -0,0 +1,744 @@
+/*
+ * Calculate window clip lists for rootless mode
+ *
+ * This file is very closely based on mivaltree.c.
+ */
+ /* $XFree86: xc/programs/Xserver/hw/darwin/bundle/rootlessValTree.c,v 1.1 2001/06/26 23:29:13 torrey Exp $ */
+
+/*
+ * mivaltree.c --
+ * Functions for recalculating window clip lists. Main function
+ * is miValidateTree.
+ *
+
+Copyright 1987, 1988, 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ *
+ * Copyright 1987, 1988, 1989 by
+ * Digital Equipment Corporation, Maynard, Massachusetts,
+ *
+ * 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 notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Digital not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * DIGITAL 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.
+ *
+ ******************************************************************/
+
+/* The panoramix components contained the following notice */
+/****************************************************************
+* *
+* Copyright (c) Digital Equipment Corporation, 1991, 1997 *
+* *
+* All Rights Reserved. Unpublished rights reserved under *
+* the copyright laws of the United States. *
+* *
+* The software contained on this media is proprietary to *
+* and embodies the confidential technology of Digital *
+* Equipment Corporation. Possession, use, duplication or *
+* dissemination of the software and media is authorized only *
+* pursuant to a valid written license from Digital Equipment *
+* Corporation. *
+* *
+* RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure *
+* by the U.S. Government is subject to restrictions as set *
+* forth in Subparagraph (c)(1)(ii) of DFARS 252.227-7013, *
+* or in FAR 52.227-19, as applicable. *
+* *
+*****************************************************************/
+
+ /*
+ * Aug '86: Susan Angebranndt -- original code
+ * July '87: Adam de Boor -- substantially modified and commented
+ * Summer '89: Joel McCormack -- so fast you wouldn't believe it possible.
+ * In particular, much improved code for window mapping and
+ * circulating.
+ * Bob Scheifler -- avoid miComputeClips for unmapped windows,
+ * valdata changes
+ */
+#include "X.h"
+#include "scrnintstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "mivalidate.h"
+
+#include "globals.h"
+
+#ifdef SHAPE
+/*
+ * Compute the visibility of a shaped window
+ */
+int
+rootlessShapedWindowIn (pScreen, universe, bounding, rect, x, y)
+ ScreenPtr pScreen;
+ RegionPtr universe, bounding;
+ BoxPtr rect;
+ register int x, y;
+{
+ BoxRec box;
+ register BoxPtr boundBox;
+ int nbox;
+ Bool someIn, someOut;
+ register int t, x1, y1, x2, y2;
+
+ nbox = REGION_NUM_RECTS (bounding);
+ boundBox = REGION_RECTS (bounding);
+ someIn = someOut = FALSE;
+ x1 = rect->x1;
+ y1 = rect->y1;
+ x2 = rect->x2;
+ y2 = rect->y2;
+ while (nbox--)
+ {
+ if ((t = boundBox->x1 + x) < x1)
+ t = x1;
+ box.x1 = t;
+ if ((t = boundBox->y1 + y) < y1)
+ t = y1;
+ box.y1 = t;
+ if ((t = boundBox->x2 + x) > x2)
+ t = x2;
+ box.x2 = t;
+ if ((t = boundBox->y2 + y) > y2)
+ t = y2;
+ box.y2 = t;
+ if (box.x1 > box.x2)
+ box.x2 = box.x1;
+ if (box.y1 > box.y2)
+ box.y2 = box.y1;
+ switch (RECT_IN_REGION(pScreen, universe, &box))
+ {
+ case rgnIN:
+ if (someOut)
+ return rgnPART;
+ someIn = TRUE;
+ break;
+ case rgnOUT:
+ if (someIn)
+ return rgnPART;
+ someOut = TRUE;
+ break;
+ default:
+ return rgnPART;
+ }
+ boundBox++;
+ }
+ if (someIn)
+ return rgnIN;
+ return rgnOUT;
+}
+#endif
+
+#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
+ HasBorder(w) && \
+ (w)->backgroundState == ParentRelative)
+
+
+/*
+ *-----------------------------------------------------------------------
+ * miComputeClips --
+ * Recompute the clipList, borderClip, exposed and borderExposed
+ * regions for pParent and its children. Only viewable windows are
+ * taken into account.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * clipList, borderClip, exposed and borderExposed are altered.
+ * A VisibilityNotify event may be generated on the parent window.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+rootlessComputeClips (pParent, pScreen, universe, kind, exposed)
+ register WindowPtr pParent;
+ register ScreenPtr pScreen;
+ register RegionPtr universe;
+ VTKind kind;
+ RegionPtr exposed; /* for intermediate calculations */
+{
+ int dx,
+ dy;
+ RegionRec childUniverse;
+ register WindowPtr pChild;
+ int oldVis, newVis;
+ BoxRec borderSize;
+ RegionRec childUnion;
+ Bool overlap;
+ RegionPtr borderVisible;
+ Bool resized;
+ /*
+ * Figure out the new visibility of this window.
+ * The extent of the universe should be the same as the extent of
+ * the borderSize region. If the window is unobscured, this rectangle
+ * will be completely inside the universe (the universe will cover it
+ * completely). If the window is completely obscured, none of the
+ * universe will cover the rectangle.
+ */
+ borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
+ borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
+ dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent);
+ if (dx > 32767)
+ dx = 32767;
+ borderSize.x2 = dx;
+ dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent);
+ if (dy > 32767)
+ dy = 32767;
+ borderSize.y2 = dy;
+
+ oldVis = pParent->visibility;
+ switch (RECT_IN_REGION( pScreen, universe, &borderSize))
+ {
+ case rgnIN:
+ newVis = VisibilityUnobscured;
+ break;
+ case rgnPART:
+ newVis = VisibilityPartiallyObscured;
+#ifdef SHAPE
+ {
+ RegionPtr pBounding;
+
+ if ((pBounding = wBoundingShape (pParent)))
+ {
+ switch (rootlessShapedWindowIn (pScreen, universe,
+ pBounding, &borderSize,
+ pParent->drawable.x,
+ pParent->drawable.y))
+ {
+ case rgnIN:
+ newVis = VisibilityUnobscured;
+ break;
+ case rgnOUT:
+ newVis = VisibilityFullyObscured;
+ break;
+ }
+ }
+ }
+#endif
+ break;
+ default:
+ newVis = VisibilityFullyObscured;
+ break;
+ }
+
+ pParent->visibility = newVis;
+ if (oldVis != newVis &&
+ ((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
+ SendVisibilityNotify(pParent);
+
+ dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
+ dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
+
+ /*
+ * avoid computations when dealing with simple operations
+ */
+
+ switch (kind) {
+ case VTMap:
+ case VTStack:
+ case VTUnmap:
+ break;
+ case VTMove:
+ if ((oldVis == newVis) &&
+ ((oldVis == VisibilityFullyObscured) ||
+ (oldVis == VisibilityUnobscured)))
+ {
+ pChild = pParent;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ if (pChild->visibility != VisibilityFullyObscured)
+ {
+ REGION_TRANSLATE( pScreen, &pChild->borderClip,
+ dx, dy);
+ REGION_TRANSLATE( pScreen, &pChild->clipList,
+ dx, dy);
+ pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ if (pScreen->ClipNotify)
+ (* pScreen->ClipNotify) (pChild, dx, dy);
+
+ }
+ if (pChild->valdata)
+ {
+ REGION_INIT(pScreen,
+ &pChild->valdata->after.borderExposed,
+ NullBox, 0);
+ if (HasParentRelativeBorder(pChild))
+ {
+ REGION_SUBTRACT(pScreen,
+ &pChild->valdata->after.borderExposed,
+ &pChild->borderClip,
+ &pChild->winSize);
+ }
+ REGION_INIT( pScreen, &pChild->valdata->after.exposed,
+ NullBox, 0);
+ }
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pParent))
+ pChild = pChild->parent;
+ if (pChild == pParent)
+ break;
+ pChild = pChild->nextSib;
+ }
+ return;
+ }
+ /* fall through */
+ default:
+ /*
+ * To calculate exposures correctly, we have to translate the old
+ * borderClip and clipList regions to the window's new location so there
+ * is a correspondence between pieces of the new and old clipping regions.
+ */
+ if (dx || dy)
+ {
+ /*
+ * We translate the old clipList because that will be exposed or copied
+ * if gravity is right.
+ */
+ REGION_TRANSLATE( pScreen, &pParent->borderClip, dx, dy);
+ REGION_TRANSLATE( pScreen, &pParent->clipList, dx, dy);
+ }
+ break;
+ case VTBroken:
+ REGION_EMPTY (pScreen, &pParent->borderClip);
+ REGION_EMPTY (pScreen, &pParent->clipList);
+ break;
+ }
+
+ borderVisible = pParent->valdata->before.borderVisible;
+ resized = pParent->valdata->before.resized;
+ REGION_INIT( pScreen, &pParent->valdata->after.borderExposed, NullBox, 0);
+ REGION_INIT( pScreen, &pParent->valdata->after.exposed, NullBox, 0);
+
+ /*
+ * Since the borderClip must not be clipped by the children, we do
+ * the border exposure first...
+ *
+ * 'universe' is the window's borderClip. To figure the exposures, remove
+ * the area that used to be exposed from the new.
+ * This leaves a region of pieces that weren't exposed before.
+ */
+
+ if (HasBorder (pParent))
+ {
+ if (borderVisible)
+ {
+ /*
+ * when the border changes shape, the old visible portions
+ * of the border will be saved by DIX in borderVisible --
+ * use that region and destroy it
+ */
+ REGION_SUBTRACT( pScreen, exposed, universe, borderVisible);
+ REGION_DESTROY( pScreen, borderVisible);
+ }
+ else
+ {
+ REGION_SUBTRACT( pScreen, exposed, universe, &pParent->borderClip);
+ }
+ if (HasParentRelativeBorder(pParent) && (dx || dy)) {
+ REGION_SUBTRACT( pScreen, &pParent->valdata->after.borderExposed,
+ universe,
+ &pParent->winSize);
+ } else {
+ REGION_SUBTRACT( pScreen, &pParent->valdata->after.borderExposed,
+ exposed, &pParent->winSize);
+ }
+
+ REGION_COPY( pScreen, &pParent->borderClip, universe);
+
+ /*
+ * To get the right clipList for the parent, and to make doubly sure
+ * that no child overlaps the parent's border, we remove the parent's
+ * border from the universe before proceeding.
+ */
+
+ REGION_INTERSECT( pScreen, universe, universe, &pParent->winSize);
+ }
+ else
+ REGION_COPY( pScreen, &pParent->borderClip, universe);
+
+ if ((pChild = pParent->firstChild) && pParent->mapped)
+ {
+ REGION_INIT(pScreen, &childUniverse, NullBox, 0);
+ REGION_INIT(pScreen, &childUnion, NullBox, 0);
+ if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
+ ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
+ (pChild->drawable.x < pParent->lastChild->drawable.x)))
+ {
+ for (; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->viewable)
+ REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
+ }
+ }
+ else
+ {
+ for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib)
+ {
+ if (pChild->viewable)
+ REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
+ }
+ }
+ REGION_VALIDATE( pScreen, &childUnion, &overlap);
+
+ for (pChild = pParent->firstChild;
+ pChild;
+ pChild = pChild->nextSib)
+ {
+ if (pChild->viewable) {
+ /*
+ * If the child is viewable, we want to remove its extents
+ * from the current universe, but we only re-clip it if
+ * it's been marked.
+ */
+ if (pChild->valdata) {
+ /*
+ * Figure out the new universe from the child's
+ * perspective and recurse.
+ */
+ REGION_INTERSECT( pScreen, &childUniverse,
+ universe,
+ &pChild->borderSize);
+ rootlessComputeClips (pChild, pScreen, &childUniverse,
+ kind, exposed);
+ }
+ /*
+ * Once the child has been processed, we remove its extents
+ * from the current universe, thus denying its space to any
+ * other sibling.
+ */
+ if (overlap)
+ REGION_SUBTRACT( pScreen, universe, universe,
+ &pChild->borderSize);
+ }
+ }
+ if (!overlap)
+ REGION_SUBTRACT( pScreen, universe, universe, &childUnion);
+ REGION_UNINIT( pScreen, &childUnion);
+ REGION_UNINIT( pScreen, &childUniverse);
+ } /* if any children */
+
+ /*
+ * 'universe' now contains the new clipList for the parent window.
+ *
+ * To figure the exposure of the window we subtract the old clip from the
+ * new, just as for the border.
+ */
+
+ if (oldVis == VisibilityFullyObscured ||
+ oldVis == VisibilityNotViewable)
+ {
+ REGION_COPY( pScreen, &pParent->valdata->after.exposed, universe);
+ }
+ else if (newVis != VisibilityFullyObscured &&
+ newVis != VisibilityNotViewable)
+ {
+ REGION_SUBTRACT( pScreen, &pParent->valdata->after.exposed,
+ universe, &pParent->clipList);
+ }
+
+ /*
+ * One last thing: backing storage. We have to try to save what parts of
+ * the window are about to be obscured. We can just subtract the universe
+ * from the old clipList and get the areas that were in the old but aren't
+ * in the new and, hence, are about to be obscured.
+ */
+ if (pParent->backStorage && !resized)
+ {
+ REGION_SUBTRACT( pScreen, exposed, &pParent->clipList, universe);
+ (* pScreen->SaveDoomedAreas)(pParent, exposed, dx, dy);
+ }
+
+ /* HACK ALERT - copying contents of regions, instead of regions */
+ {
+ RegionRec tmp;
+
+ tmp = pParent->clipList;
+ pParent->clipList = *universe;
+ *universe = tmp;
+ }
+
+#ifdef NOTDEF
+ REGION_COPY( pScreen, &pParent->clipList, universe);
+#endif
+
+ pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ if (pScreen->ClipNotify)
+ (* pScreen->ClipNotify) (pParent, dx, dy);
+}
+
+static void
+rootlessTreeObscured(pParent)
+ register WindowPtr pParent;
+{
+ register WindowPtr pChild;
+ register int oldVis;
+
+ pChild = pParent;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ oldVis = pChild->visibility;
+ if (oldVis != (pChild->visibility = VisibilityFullyObscured) &&
+ ((pChild->eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask))
+ SendVisibilityNotify(pChild);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pParent))
+ pChild = pChild->parent;
+ if (pChild == pParent)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * miValidateTree --
+ * Recomputes the clip list for pParent and all its inferiors.
+ *
+ * Results:
+ * Always returns 1.
+ *
+ * Side Effects:
+ * The clipList, borderClip, exposed, and borderExposed regions for
+ * each marked window are altered.
+ *
+ * Notes:
+ * This routine assumes that all affected windows have been marked
+ * (valdata created) and their winSize and borderSize regions
+ * adjusted to correspond to their new positions. The borderClip and
+ * clipList regions should not have been touched.
+ *
+ * The top-most level is treated differently from all lower levels
+ * because pParent is unchanged. For the top level, we merge the
+ * regions taken up by the marked children back into the clipList
+ * for pParent, thus forming a region from which the marked children
+ * can claim their areas. For lower levels, where the old clipList
+ * and borderClip are invalid, we can't do this and have to do the
+ * extra operations done in miComputeClips, but this is much faster
+ * e.g. when only one child has moved...
+ *
+ *-----------------------------------------------------------------------
+ */
+/*
+ Quartz version: used for validate from root in rootless mode.
+ We need to make sure top-level windows don't clip each other,
+ and that top-level windows aren't clipped to the root window.
+*/
+/*ARGSUSED*/
+// fixme this is ugly
+// Xprint/ValTree.c doesn't work, but maybe that method can?
+int
+rootlessMiValidateTree (pRoot, pChild, kind)
+ WindowPtr pRoot; /* Parent to validate */
+ WindowPtr pChild; /* First child of pRoot that was
+ * affected */
+ VTKind kind; /* What kind of configuration caused call */
+{
+ RegionRec totalClip; /* Total clipping region available to
+ * the marked children. pRoot's clipList
+ * merged with the borderClips of all
+ * the marked children. */
+ RegionRec childClip; /* The new borderClip for the current
+ * child */
+ RegionRec childUnion; /* the space covered by borderSize for
+ * all marked children */
+ RegionRec exposed; /* For intermediate calculations */
+ register ScreenPtr pScreen;
+ register WindowPtr pWin;
+ Bool overlap;
+ int viewvals;
+ Bool forward;
+
+ pScreen = pRoot->drawable.pScreen;
+ if (pChild == NullWindow)
+ pChild = pRoot->firstChild;
+
+ REGION_INIT(pScreen, &childClip, NullBox, 0);
+ REGION_INIT(pScreen, &exposed, NullBox, 0);
+
+ /*
+ * compute the area of the parent window occupied
+ * by the marked children + the parent itself. This
+ * is the area which can be divied up among the marked
+ * children in their new configuration.
+ */
+ REGION_INIT(pScreen, &totalClip, NullBox, 0);
+ viewvals = 0;
+ if (REGION_BROKEN (pScreen, &pRoot->clipList) &&
+ !REGION_BROKEN (pScreen, &pRoot->borderClip))
+ {
+ kind = VTBroken;
+ /*
+ * When rebuilding clip lists after out of memory,
+ * assume everything is busted.
+ */
+ forward = TRUE;
+ REGION_COPY (pScreen, &totalClip, &pRoot->borderClip);
+ REGION_INTERSECT (pScreen, &totalClip, &totalClip, &pRoot->winSize);
+
+ for (pWin = pRoot->firstChild; pWin != pChild; pWin = pWin->nextSib)
+ {
+ if (pWin->viewable)
+ REGION_SUBTRACT (pScreen, &totalClip, &totalClip, &pWin->borderSize);
+ }
+ for (pWin = pChild; pWin; pWin = pWin->nextSib)
+ if (pWin->valdata && pWin->viewable)
+ viewvals++;
+
+ REGION_EMPTY (pScreen, &pRoot->clipList);
+ ErrorF("ValidateTree: BUSTED!\n");
+ }
+ else
+ {
+ if ((pChild->drawable.y < pRoot->lastChild->drawable.y) ||
+ ((pChild->drawable.y == pRoot->lastChild->drawable.y) &&
+ (pChild->drawable.x < pRoot->lastChild->drawable.x)))
+ {
+ forward = TRUE;
+ for (pWin = pChild; pWin; pWin = pWin->nextSib)
+ {
+ if (pWin->valdata)
+ {
+ REGION_APPEND( pScreen, &totalClip, &pWin->borderClip);
+ if (pWin->viewable)
+ viewvals++;
+ }
+ }
+ }
+ else
+ {
+ forward = FALSE;
+ pWin = pRoot->lastChild;
+ while (1)
+ {
+ if (pWin->valdata)
+ {
+ REGION_APPEND( pScreen, &totalClip, &pWin->borderClip);
+ if (pWin->viewable)
+ viewvals++;
+ }
+ if (pWin == pChild)
+ break;
+ pWin = pWin->prevSib;
+ }
+ }
+ REGION_VALIDATE( pScreen, &totalClip, &overlap);
+ }
+
+
+ // calculate childUnion so we can subtract it from totalClip later
+ REGION_INIT(pScreen, &childUnion, NullBox, 0);
+ if (kind != VTStack) {
+ if (forward)
+ {
+ for (pWin = pChild; pWin; pWin = pWin->nextSib)
+ if (pWin->valdata && pWin->viewable)
+ REGION_APPEND( pScreen, &childUnion,
+ &pWin->borderSize);
+ }
+ else
+ {
+ pWin = pRoot->lastChild;
+ while (1)
+ {
+ if (pWin->valdata && pWin->viewable)
+ REGION_APPEND( pScreen, &childUnion,
+ &pWin->borderSize);
+ if (pWin == pChild)
+ break;
+ pWin = pWin->prevSib;
+ }
+ }
+ REGION_VALIDATE(pScreen, &childUnion, &overlap);
+ }
+
+
+ /*
+ * Now go through the children of the root and figure their new
+ * borderClips from the totalClip, passing that off to miComputeClips
+ * to handle recursively. Once that's done, we remove the child
+ * from the totalClip to clip any siblings below it.
+ */
+
+ for (pWin = pChild;
+ pWin != NullWindow;
+ pWin = pWin->nextSib)
+ {
+ if (pWin->viewable) {
+ if (pWin->valdata) {
+ REGION_COPY( pScreen, &childClip, &pWin->borderSize);
+ rootlessComputeClips (pWin, pScreen, &childClip, kind, &exposed);
+ } else if (pWin->visibility == VisibilityNotViewable) {
+ rootlessTreeObscured(pWin);
+ }
+ } else {
+ if (pWin->valdata) {
+ REGION_EMPTY( pScreen, &pWin->clipList);
+ if (pScreen->ClipNotify)
+ (* pScreen->ClipNotify) (pWin, 0, 0);
+ REGION_EMPTY( pScreen, &pWin->borderClip);
+ pWin->valdata = (ValidatePtr)NULL;
+ }
+ }
+ }
+
+ REGION_UNINIT( pScreen, &childClip);
+
+ // REGION_SUBTRACT(pScreen, &totalClip, &totalClip, &childUnion);
+ REGION_UNINIT(pScreen, &childUnion);
+
+ REGION_INIT( pScreen, &pRoot->valdata->after.exposed, NullBox, 0);
+ REGION_INIT( pScreen, &pRoot->valdata->after.borderExposed, NullBox, 0);
+
+
+ REGION_UNINIT( pScreen, &totalClip);
+ REGION_UNINIT( pScreen, &exposed);
+ //if (pScreen->ClipNotify)
+ //(*pScreen->ClipNotify) (pRoot, 0, 0);
+ return (1);
+}
diff --git a/xc/programs/Xserver/hw/darwin/bundle/rootlessWindow.c b/xc/programs/Xserver/hw/darwin/bundle/rootlessWindow.c
new file mode 100644
index 000000000..56418c351
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/bundle/rootlessWindow.c
@@ -0,0 +1,753 @@
+/*
+ * Rootless window management
+ *
+ * Greg Parker gparker@cs.stanford.edu
+ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/rootlessWindow.c,v 1.4 2001/08/01 05:34:06 torrey Exp $ */
+
+#include "rootlessCommon.h"
+#include "rootlessWindow.h"
+
+#include "fb.h"
+
+// PanoramiX/Xinerama creates a copy of every window, one per screen.
+// Windows in rootless mode really can cross screens, so we only want to
+// work with one copy of each.
+#ifdef PANORAMIX
+#include "../Xext/panoramiX.h"
+#include "../Xext/panoramiXsrv.h"
+// LookupIDByType doesn't find root window, but root windows are "real" here.
+// LookupIDByType doesn't find anything when panoramix is off
+#define IS_FAKE_WINDOW(w) \
+ (!noPanoramiXExtension && \
+ pWin->parent && \
+ !LookupIDByType(w->drawable.id, XRT_WINDOW))
+#else
+#define IS_FAKE_WINDOW(w) (0)
+#endif
+
+
+// RootlessCreateWindow
+// For now, don't create a frame until the window is realized.
+// Do reset the window size so it's not clipped by the root window.
+Bool
+RootlessCreateWindow(WindowPtr pWin)
+{
+ Bool result;
+ RegionRec saveRoot;
+
+ WINREC(pWin) = NULL;
+ SCREEN_UNWRAP(pWin->drawable.pScreen, CreateWindow);
+ if (!IsRoot(pWin)) {
+ // win/border size set by DIX, not by wrapped CreateWindow, so
+ // correct it here.
+ // Don't HUGE_ROOT when pWin is the root!
+ HUGE_ROOT(pWin);
+ SetWinSize(pWin);
+ SetBorderSize(pWin);
+ }
+ result = pWin->drawable.pScreen->CreateWindow(pWin);
+ if (pWin->parent) {
+ NORMAL_ROOT(pWin);
+ }
+ SCREEN_WRAP(pWin->drawable.pScreen, CreateWindow);
+ return result;
+}
+
+
+// RootlessDestroyWindow
+// For now, all window destruction takes place in UnrealizeWindow
+Bool
+RootlessDestroyWindow(WindowPtr pWin)
+{
+ Bool result;
+
+ SCREEN_UNWRAP(pWin->drawable.pScreen, DestroyWindow);
+ result = pWin->drawable.pScreen->DestroyWindow(pWin);
+ SCREEN_WRAP(pWin->drawable.pScreen, DestroyWindow);
+ return result;
+}
+
+
+#ifdef SHAPE
+
+// fixme reimplement shape
+
+// boundingShape = outside border (like borderClip)
+// clipShape = inside border (like clipList)
+// Both are in window-local coordinates
+// We only care about boundingShape (fixme true?)
+
+// RootlessReallySetShape is used in several places other than SetShape.
+// Most importantly, SetShape is often called on unmapped windows, so we
+// have to wait until the window is mapped to reshape the frame.
+static void RootlessReallySetShape(WindowPtr pWin)
+{
+ RootlessWindowRec *winRec = WINREC(pWin);
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RegionRec newShape;
+
+ // fixme reimplement shape
+ return;
+
+ if (IsRoot(pWin)) return;
+ if (!IsTopLevel(pWin)) return;
+ if (!winRec) return;
+
+ if (wBoundingShape(pWin)) {
+ // wBoundingShape is relative to *inner* origin of window.
+ // Translate by borderWidth to get the outside-relative position.
+ REGION_INIT(pScreen, &newShape, NullBox, 0);
+ REGION_COPY(pScreen, &newShape, wBoundingShape(pWin));
+ REGION_TRANSLATE(pScreen, &newShape, pWin->borderWidth,
+ pWin->borderWidth);
+ } else {
+ newShape.data = NULL;
+ newShape.extents.x1 = 0;
+ newShape.extents.y1 = 0;
+ newShape.extents.x2 = winRec->frame.w;
+ newShape.extents.y2 = winRec->frame.h;
+ }
+ RL_DEBUG_MSG("reshaping...");
+ RL_DEBUG_MSG("numrects %d, extents %d %d %d %d ",
+ REGION_NUM_RECTS(&newShape),
+ newShape.extents.x1, newShape.extents.y1,
+ newShape.extents.x2, newShape.extents.y2);
+ CallFrameProc(pScreen, ReshapeFrame,(pScreen, &winRec->frame, &newShape));
+ REGION_UNINIT(pScreen, &newShape);
+}
+
+
+void
+RootlessSetShape(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ RootlessReallySetShape(pWin);
+ SCREEN_UNWRAP(pScreen, SetShape);
+ pScreen->SetShape(pWin);
+ SCREEN_WRAP(pScreen, SetShape);
+}
+
+#endif // SHAPE
+
+
+// Disallow ParentRelative background on top-level windows
+// because the root window doesn't really have the right background
+// and cfb will try to draw on the root instead of on the window.
+// fixme what about fb?
+// fixme implement ParentRelative with real transparency?
+// ParentRelative prevention is also in RealizeWindow()
+Bool
+RootlessChangeWindowAttributes(WindowPtr pWin, unsigned long vmask)
+{
+ Bool result;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ RL_DEBUG_MSG("change window attributes start ");
+
+ SCREEN_UNWRAP(pScreen, ChangeWindowAttributes);
+ result = pScreen->ChangeWindowAttributes(pWin, vmask);
+ SCREEN_WRAP(pScreen, ChangeWindowAttributes);
+
+ if (WINREC(pWin)) {
+ // disallow ParentRelative background state
+ if (pWin->backgroundState == ParentRelative) {
+ XID pixel = 0;
+ ChangeWindowAttributes(pWin, CWBackPixel, &pixel, serverClient);
+ }
+ }
+
+ RL_DEBUG_MSG("change window attributes end\n");
+ return result;
+}
+
+
+// Update the frame position now.
+// (x, y) are *inside* position!
+// After this, mi and fb are expecting the pixmap to be at the new location.
+Bool
+RootlessPositionWindow(WindowPtr pWin, int x, int y)
+{
+ RootlessWindowRec *winRec = WINREC(pWin);
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ Bool result;
+
+ RL_DEBUG_MSG("positionwindow start\n");
+ if (winRec) {
+ winRec->frame.x = x - pWin->borderWidth;
+ winRec->frame.y = y - pWin->borderWidth;
+ }
+
+ UpdatePixmap(pWin);
+
+ SCREEN_UNWRAP(pScreen, PositionWindow);
+ result = pScreen->PositionWindow(pWin, x, y);
+ SCREEN_WRAP(pScreen, PositionWindow);
+
+ RL_DEBUG_MSG("positionwindow end\n");
+ return result;
+}
+
+
+// RootlessRealizeWindow
+// The frame is created here and not in CreateWindow.
+// fixme change this? probably not - would be faster, but eat more memory
+Bool
+RootlessRealizeWindow(WindowPtr pWin)
+{
+ Bool result = FALSE;
+ RegionRec saveRoot;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ if (IS_FAKE_WINDOW(pWin)) {
+ // Don't map fake windows
+ // They won't get a frame or take time to draw (fixme true?)
+ RL_DEBUG_MSG("realize window: skipping fake window\n");
+ pWin->mapped = FALSE;
+ pWin->realized = FALSE;
+ pWin->viewable = FALSE;
+ return Success;
+ }
+
+ RL_DEBUG_MSG("realizewindow start ");
+
+ if (IsTopLevel(pWin) || IsRoot(pWin)) {
+ DrawablePtr d = &pWin->drawable;
+ RootlessWindowRec *winRec = xalloc(sizeof(RootlessWindowRec));
+
+ if (! winRec) goto windowcreatebad;
+
+ winRec->frame.isRoot = (pWin == WindowTable[pScreen->myNum]);
+ winRec->frame.x = d->x - pWin->borderWidth;
+ winRec->frame.y = d->y - pWin->borderWidth;
+ winRec->frame.w = d->width + 2*pWin->borderWidth;
+ winRec->frame.h = d->height + 2*pWin->borderWidth;
+ winRec->frame.win = pWin;
+ winRec->frame.devPrivate = NULL;
+
+ REGION_INIT(pScreen, &winRec->damage, NullBox, 0);
+ winRec->borderWidth = pWin->borderWidth;
+
+ winRec->pixmap = NULL;
+ // UpdatePixmap() called below
+
+ WINREC(pWin) = winRec;
+
+ RL_DEBUG_MSG("creating frame ");
+ CallFrameProc(pScreen, CreateFrame,
+ (pScreen, &WINREC(pWin)->frame,
+ pWin->prevSib ? &WINREC(pWin->prevSib)->frame : NULL));
+
+ // fixme implement ParentRelative with transparency?
+ // need non-interfering fb first
+ // Disallow ParentRelative background state
+ // This might have been set before the window was mapped
+ if (pWin->backgroundState == ParentRelative) {
+ XID pixel = 0;
+ ChangeWindowAttributes(pWin, CWBackPixel, &pixel, serverClient);
+ }
+
+#ifdef SHAPE
+ // Shape is usually set before the window is mapped, but
+ // (for now) we don't keep track of frames before they're mapped.
+ // RootlessReallySetShape(pWin);
+ // fixme reimplement shape
+#endif
+ }
+
+ UpdatePixmap(pWin);
+
+ if (!IsRoot(pWin)) HUGE_ROOT(pWin);
+ SCREEN_UNWRAP(pScreen, RealizeWindow);
+ result = pScreen->RealizeWindow(pWin);
+ SCREEN_WRAP(pScreen, RealizeWindow);
+ if (!IsRoot(pWin)) NORMAL_ROOT(pWin);
+
+ RL_DEBUG_MSG("realizewindow end\n");
+ return result;
+
+windowcreatebad:
+ RL_DEBUG_MSG("window create bad! ");
+ RL_DEBUG_MSG("realizewindow end\n");
+ return NULL;
+}
+
+
+Bool
+RootlessUnrealizeWindow(WindowPtr pWin)
+{
+ Bool result;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ RL_DEBUG_MSG("unrealizewindow start ");
+
+ if (IsTopLevel(pWin) || IsRoot(pWin)) {
+ RootlessWindowRec *winRec = WINREC(pWin);
+
+ RootlessRedisplay(pWin);
+ CallFrameProc(pScreen, DestroyFrame, (pScreen, &winRec->frame));
+
+ REGION_UNINIT(pScreen, &winRec->damage);
+
+ xfree(winRec);
+ WINREC(pWin) = NULL;
+ }
+
+ SCREEN_UNWRAP(pScreen, UnrealizeWindow);
+ result = pScreen->UnrealizeWindow(pWin);
+ SCREEN_WRAP(pScreen, UnrealizeWindow);
+ RL_DEBUG_MSG("unrealizewindow end\n");
+ return result;
+}
+
+
+void
+RootlessRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib)
+{
+ RegionRec saveRoot;
+ RootlessWindowRec *winRec = WINREC(pWin);
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ RL_DEBUG_MSG("restackwindow start ");
+ if (winRec) RL_DEBUG_MSG("restack top level \n");
+
+ HUGE_ROOT(pWin);
+ SCREEN_UNWRAP(pScreen, RestackWindow);
+ if (pScreen->RestackWindow) pScreen->RestackWindow(pWin, pOldNextSib);
+ SCREEN_WRAP(pScreen, RestackWindow);
+ NORMAL_ROOT(pWin);
+
+ if (winRec) {
+ // fixme simplify the following
+
+ WindowPtr oldNextW, newNextW, oldPrevW, newPrevW;
+ RootlessFramePtr oldNext, newNext, oldPrev, newPrev;
+
+ oldNextW = pOldNextSib;
+ while (oldNextW && ! WINREC(oldNextW)) oldNextW = oldNextW->nextSib;
+ oldNext = oldNextW ? &WINREC(oldNextW)->frame : NULL;
+
+ newNextW = pWin->nextSib;
+ while (newNextW && ! WINREC(newNextW)) newNextW = newNextW->nextSib;
+ newNext = newNextW ? &WINREC(newNextW)->frame : NULL;
+
+ oldPrevW= pOldNextSib ? pOldNextSib->prevSib : pWin->parent->lastChild;
+ while (oldPrevW && ! WINREC(oldPrevW)) oldPrevW = oldPrevW->prevSib;
+ oldPrev = oldPrevW ? &WINREC(oldPrevW)->frame : NULL;
+
+ newPrevW = pWin->prevSib;
+ while (newPrevW && ! WINREC(newPrevW)) newPrevW = newPrevW->prevSib;
+ newPrev = newPrevW ? &WINREC(newPrevW)->frame : NULL;
+
+ if (pWin->prevSib) {
+ WindowPtr w = pWin->prevSib;
+ while (w) {
+ RL_DEBUG_MSG("w 0x%x\n", w);
+ w = w->parent;
+ }
+ }
+
+ CallFrameProc(pScreen, RestackFrame,
+ (pScreen, &winRec->frame, oldPrev, newPrev));
+ }
+
+ RL_DEBUG_MSG("restackwindow end\n");
+}
+
+
+/*
+ * Specialized window copy procedures
+ */
+
+// Globals needed during window resize and move.
+static PixmapPtr gResizeDeathPix = NULL;
+static pointer gResizeDeathBits = NULL;
+static PixmapPtr gResizeCopyWindowSource = NULL;
+static CopyWindowProcPtr gResizeOldCopyWindowProc = NULL;
+
+// CopyWindow() that doesn't do anything.
+// For MoveWindow() of top-level windows.
+static void
+RootlessNoCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+ // some code expects the region to be translated
+ int dx = ptOldOrg.x - pWin->drawable.x;
+ int dy = ptOldOrg.y - pWin->drawable.y;
+ RL_DEBUG_MSG("ROOTLESSNOCOPYWINDOW ");
+
+ REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
+}
+
+
+// CopyWindow used during ResizeWindow for gravity moves.
+// Cloned from fbCopyWindow
+// The original always draws on the root pixmap (which we don't have).
+// Instead, draw on the parent window's pixmap.
+// Resize version: the old location's pixels are in gResizeCopyWindowSource
+static void
+RootlessResizeCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ SCREEN_UNWRAP(pScreen, CopyWindow);
+ RL_DEBUG_MSG("resizecopywindowFB start (win 0x%x) ", pWin);
+
+ {
+ RegionRec rgnDst;
+ int dx, dy;
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
+ REGION_INIT (pScreen, &rgnDst, NullBox, 0);
+ REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
+
+ fbCopyRegion (&gResizeCopyWindowSource->drawable,
+ &pScreen->GetWindowPixmap(pWin)->drawable,
+ 0,
+ &rgnDst, dx, dy, fbCopyWindowProc, 0, 0);
+
+ // don't update - resize will update everything
+ // fixme DO update?
+ REGION_UNINIT(pScreen, &rgnDst);
+ fbValidateDrawable (&pWin->drawable);
+ }
+
+ SCREEN_WRAP(pScreen, CopyWindow);
+ RL_DEBUG_MSG("resizecopywindowFB end\n");
+}
+
+
+/* Update *new* location of window. Old location is redrawn with
+ * PaintWindowBackground/Border.
+ * Cloned from fbCopyWindow
+ * The original always draws on the root pixmap (which we don't have).
+ * Instead, draw on the parent window's pixmap.
+ */
+void
+RootlessCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ SCREEN_UNWRAP(pScreen, CopyWindow);
+ RL_DEBUG_MSG("copywindowFB start (win 0x%x) ", pWin);
+
+ {
+ RegionRec rgnDst;
+ int dx, dy;
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
+
+ REGION_INIT(pScreen, &rgnDst, NullBox, 0);
+ REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
+
+ fbCopyRegion ((DrawablePtr)pWin, (DrawablePtr)pWin,
+ 0,
+ &rgnDst, dx, dy, fbCopyWindowProc, 0, 0);
+
+ // prgnSrc has been translated to dst position
+ RootlessDamageRegion(pWin, prgnSrc);
+ REGION_UNINIT(pScreen, &rgnDst);
+ fbValidateDrawable (&pWin->drawable);
+ }
+
+ SCREEN_WRAP(pScreen, CopyWindow);
+ RL_DEBUG_MSG("copywindowFB end\n");
+}
+
+
+/*
+ * Window resize procedures
+ */
+
+// Prepare to resize a window.
+// The old window's pixels are saved and the implementation is told
+// to change the window size.
+// (x,y,w,h) is outer frame of window (outside border)
+static void
+StartFrameResize(WindowPtr pWin, Bool gravity,
+ int oldX, int oldY,
+ unsigned int oldW, unsigned int oldH, unsigned int oldBW,
+ int newX, int newY,
+ unsigned int newW, unsigned int newH, unsigned int newBW)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RootlessWindowRec *winRec = WINREC(pWin);
+
+ RL_DEBUG_MSG("RESIZE TOPLEVEL WINDOW ");
+ RL_DEBUG_MSG("%d %d %d %d %d %d %d %d %d %d ",
+ oldX, oldY, oldW, oldH, oldBW,
+ newX, newY, newW, newH, newBW);
+
+ RootlessRedisplay(pWin);
+
+/*
+#ifdef SHAPE
+ // make the frame shape a rect
+ // fixme reimplement shape
+ if (wBoundingShape(pWin)) {
+ RegionPtr saveShape = wBoundingShape(pWin);
+
+ pWin->optional->boundingShape = NULL;
+ RL_DEBUG_MSG("RootlessReallySetShape from resize ");
+ RootlessReallySetShape(pWin);
+ pWin->optional->boundingShape = saveShape;
+ }
+#endif // SHAPE
+*/
+
+ // Make a copy of the current pixmap and all its data.
+ // The original will go away when we ask the frame manager to
+ // allocate the new pixmap.
+
+ gResizeDeathBits = xalloc(winRec->frame.bytesPerRow * winRec->frame.h);
+ memcpy(gResizeDeathBits, winRec->frame.pixelData,
+ winRec->frame.bytesPerRow * winRec->frame.h);
+ gResizeDeathPix =
+ GetScratchPixmapHeader(pScreen, winRec->frame.w, winRec->frame.h,
+ winRec->frame.depth, winRec->frame.bitsPerPixel,
+ winRec->frame.bytesPerRow, gResizeDeathBits);
+ SetPixmapBaseToScreen(gResizeDeathPix, winRec->frame.x, winRec->frame.y);
+
+ winRec->frame.x = newX;
+ winRec->frame.y = newY;
+ winRec->frame.w = newW;
+ winRec->frame.h = newH;
+ winRec->borderWidth = newBW;
+
+ CallFrameProc(pScreen, StartResizeFrame,
+ (pScreen, &winRec->frame, oldX, oldY, oldW, oldH));
+ UpdatePixmap(pWin);
+
+ // Use custom CopyWindow when moving gravity bits around
+ // ResizeWindow assumes the old window contents are in the same
+ // pixmap, but here they're in deathPix instead.
+ if (gravity) {
+ gResizeCopyWindowSource = gResizeDeathPix;
+ gResizeOldCopyWindowProc = pScreen->CopyWindow;
+ pScreen->CopyWindow = RootlessResizeCopyWindow;
+ }
+
+ // Copy pixels in intersection from src to dst.
+ // ResizeWindow assumes these pixels are already present when
+ // making gravity adjustments.
+ // pWin currently has new-sized pixmap but is in old position
+ // fixme border width change!
+ {
+ RegionRec r;
+ DrawablePtr src = &gResizeDeathPix->drawable;
+ DrawablePtr dst = &pScreen->GetWindowPixmap(pWin)->drawable;
+
+ r.data = NULL;
+ r.extents.x1 = max(oldX, newX);
+ r.extents.y1 = max(oldY, newY);
+ r.extents.x2 = min(oldX + oldW, newX + newW);
+ r.extents.y2 = min(oldY + oldH, newY + newH);
+
+ // r is now intersection of of old location and new location
+ if (r.extents.x2 > r.extents.x1 && r.extents.y2 > r.extents.y1) {
+#if 0
+ DDXPointRec srcPt = {r.extents.x1, r.extents.y1};
+ // Correct for border width change
+ // fixme need to correct for border width change
+ int dx = newX - oldX;
+ int dy = newY - oldY;
+ REGION_TRANSLATE(pScreen, &r, dx, dy);
+#endif
+ fbCopyRegion(src, dst, NULL, &r, 0, 0, fbCopyWindowProc, 0, 0);
+ }
+ REGION_UNINIT(pScreen, &r);
+ }
+}
+
+
+static void
+FinishFrameResize(WindowPtr pWin, Bool gravity,
+ int oldX, int oldY,
+ unsigned int oldW, unsigned int oldH, unsigned int oldBW,
+ int newX, int newY,
+ unsigned int newW, unsigned int newH, unsigned int newBW)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RootlessWindowRec *winRec = WINREC(pWin);
+
+ CallFrameProc(pScreen, FinishResizeFrame,
+ (pScreen, &winRec->frame, oldX, oldY, oldW, oldH));
+
+ // Destroy temp pixmap
+ FreeScratchPixmapHeader(gResizeDeathPix);
+ xfree(gResizeDeathBits);
+ gResizeDeathPix = gResizeDeathBits = NULL;
+
+ if (gravity) {
+ pScreen->CopyWindow = gResizeOldCopyWindowProc;
+ gResizeCopyWindowSource = NULL;
+ }
+}
+
+
+// If kind==VTOther, window border is resizing (and borderWidth is
+// already changed!!@#$) This case works like window resize, not move.
+void
+RootlessMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind)
+{
+ CopyWindowProcPtr oldCopyWindowProc = NULL;
+ RegionRec saveRoot;
+ RootlessWindowRec *winRec = WINREC(pWin);
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ int oldX = 0, oldY = 0, newX = 0, newY = 0;
+ unsigned int oldW = 0, oldH = 0, oldBW = 0, newW = 0, newH = 0, newBW = 0;
+
+ RL_DEBUG_MSG("movewindow start \n");
+
+ if (winRec) {
+ if (kind == VTMove) {
+ oldX = winRec->frame.x;
+ oldY = winRec->frame.y;
+ RootlessRedisplay(pWin);
+ } else {
+ RL_DEBUG_MSG("movewindow border resizing ");
+ oldBW = winRec->borderWidth;
+ oldX = winRec->frame.x;
+ oldY = winRec->frame.y;
+ oldW = winRec->frame.w;
+ oldH = winRec->frame.h;
+ newBW = pWin->borderWidth;
+ newX = x;
+ newY = y;
+ newW = pWin->drawable.width + 2*newBW;
+ newH = pWin->drawable.height + 2*newBW;
+ StartFrameResize(pWin, FALSE, oldX, oldY, oldW, oldH, oldBW,
+ newX, newY, newW, newH, newBW);
+ }
+ }
+
+ HUGE_ROOT(pWin);
+ SCREEN_UNWRAP(pScreen, MoveWindow);
+ if (winRec) {
+ oldCopyWindowProc = pScreen->CopyWindow;
+ pScreen->CopyWindow = RootlessNoCopyWindow;
+ }
+ pScreen->MoveWindow(pWin, x, y, pSib, kind);
+ if (winRec) {
+ pScreen->CopyWindow = oldCopyWindowProc;
+ }
+ NORMAL_ROOT(pWin);
+ SCREEN_WRAP(pScreen, MoveWindow);
+
+ if (winRec) {
+ if (kind == VTMove) {
+ // PositionWindow has already set the new frame position.
+ CallFrameProc(pScreen, MoveFrame,
+ (pScreen, &winRec->frame, oldX, oldY));
+ } else {
+ FinishFrameResize(pWin, FALSE, oldX, oldY, oldW, oldH, oldBW,
+ newX, newY, newW, newH, newBW);
+ }
+ }
+
+ RL_DEBUG_MSG("movewindow end\n");
+}
+
+
+// Note: (x, y, w, h) as passed to this procedure don't match
+// the frame definition.
+// (x,y) is corner of very outer edge, *outside* border
+// w,h is width and height *inside8 border, *ignoring* border width
+// The rect (x, y, w, h) doesn't mean anything.
+// (x, y, w+2*bw, h+2*bw) is total rect
+// (x+bw, y+bw, w, h) is inner rect
+
+void
+RootlessResizeWindow(WindowPtr pWin, int x, int y,
+ unsigned int w, unsigned int h, WindowPtr pSib)
+{
+ RegionRec saveRoot;
+ RootlessWindowRec *winRec = WINREC(pWin);
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ int oldX = 0, oldY = 0, newX = 0, newY = 0;
+ unsigned int oldW = 0, oldH = 0, oldBW = 0, newW = 0, newH = 0, newBW = 0;
+
+ RL_DEBUG_MSG("resizewindow start (win 0x%x) ", pWin);
+
+ if (winRec) {
+ oldBW = winRec->borderWidth;
+ oldX = winRec->frame.x;
+ oldY = winRec->frame.y;
+ oldW = winRec->frame.w;
+ oldH = winRec->frame.h;
+
+ newBW = oldBW;
+ newX = x;
+ newY = y;
+ newW = w + 2*newBW;
+ newH = h + 2*newBW;
+
+ StartFrameResize(pWin, TRUE, oldX, oldY, oldW, oldH, oldBW,
+ newX, newY, newW, newH, newBW);
+ }
+
+ HUGE_ROOT(pWin);
+ SCREEN_UNWRAP(pScreen, ResizeWindow);
+ pScreen->ResizeWindow(pWin, x, y, w, h, pSib);
+ SCREEN_WRAP(pScreen, ResizeWindow);
+ NORMAL_ROOT(pWin);
+
+ if (winRec) {
+ FinishFrameResize(pWin, TRUE, oldX, oldY, oldW, oldH, oldBW,
+ newX, newY, newW, newH, newBW);
+ }
+
+ RL_DEBUG_MSG("resizewindow end\n");
+}
+
+
+// fixme untested!
+// pWin inside corner stays the same
+// pWin->drawable.[xy] stays the same
+// frame moves and resizes
+void
+RootlessChangeBorderWidth(WindowPtr pWin, unsigned int width)
+{
+ RegionRec saveRoot;
+
+ RL_DEBUG_MSG("change border width ");
+ if (width != pWin->borderWidth) {
+ RootlessWindowRec *winRec = WINREC(pWin);
+ int oldX = 0, oldY = 0, newX = 0, newY = 0;
+ unsigned int oldW = 0, oldH = 0, oldBW = 0;
+ unsigned int newW = 0, newH = 0, newBW = 0;
+
+ if (winRec) {
+ oldBW = winRec->borderWidth;
+ oldX = winRec->frame.x;
+ oldY = winRec->frame.y;
+ oldW = winRec->frame.w;
+ oldH = winRec->frame.h;
+
+ newBW = width;
+ newX = pWin->drawable.x - newBW;
+ newY = pWin->drawable.y - newBW;
+ newW = pWin->drawable.width + 2*newBW;
+ newH = pWin->drawable.height + 2*newBW;
+
+ StartFrameResize(pWin, FALSE, oldX, oldY, oldW, oldH, oldBW,
+ newX, newY, newW, newH, newBW);
+ }
+
+ HUGE_ROOT(pWin);
+ SCREEN_UNWRAP(pWin->drawable.pScreen, ChangeBorderWidth);
+ pWin->drawable.pScreen->ChangeBorderWidth(pWin, width);
+ SCREEN_WRAP(pWin->drawable.pScreen, ChangeBorderWidth);
+ NORMAL_ROOT(pWin);
+
+ if (winRec) {
+ FinishFrameResize(pWin, FALSE, oldX, oldY, oldW, oldH, oldBW,
+ newX, newY, newW, newH, newBW);
+ }
+ }
+ RL_DEBUG_MSG("change border width end\n");
+}
diff --git a/xc/programs/Xserver/hw/darwin/bundle/rootlessWindow.h b/xc/programs/Xserver/hw/darwin/bundle/rootlessWindow.h
new file mode 100644
index 000000000..ba14c787a
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/bundle/rootlessWindow.h
@@ -0,0 +1,32 @@
+/*
+ * Rootless window management
+ *
+ * Greg Parker gparker@cs.stanford.edu
+ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/rootlessWindow.h,v 1.1 2001/07/01 02:13:41 torrey Exp $ */
+
+#ifndef _ROOTLESSWINDOW_H
+#define _ROOTLESSWINDOW_H
+
+#include "rootlessCommon.h"
+
+
+Bool RootlessCreateWindow(WindowPtr pWin);
+Bool RootlessDestroyWindow(WindowPtr pWin);
+
+#ifdef SHAPE
+void RootlessSetShape(WindowPtr pWin);
+#endif // SHAPE
+
+Bool RootlessChangeWindowAttributes(WindowPtr pWin, unsigned long vmask);
+Bool RootlessPositionWindow(WindowPtr pWin, int x, int y);
+Bool RootlessRealizeWindow(WindowPtr pWin);
+Bool RootlessUnrealizeWindow(WindowPtr pWin);
+void RootlessRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib);
+void RootlessCopyWindow(WindowPtr pWin,DDXPointRec ptOldOrg,RegionPtr prgnSrc);
+void RootlessMoveWindow(WindowPtr pWin,int x,int y,WindowPtr pSib,VTKind kind);
+void RootlessResizeWindow(WindowPtr pWin, int x, int y,
+ unsigned int w, unsigned int h, WindowPtr pSib);
+void RootlessChangeBorderWidth(WindowPtr pWin, unsigned int width);
+
+#endif
diff --git a/xc/programs/Xserver/hw/kdrive/ipaq/Imakefile b/xc/programs/Xserver/hw/kdrive/ipaq/Imakefile
new file mode 100644
index 000000000..8fb723ca2
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/ipaq/Imakefile
@@ -0,0 +1,13 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/ipaq/Imakefile,v 1.1 2001/05/23 17:28:39 alanh Exp $
+KDRIVE=..
+#include "../Kdrive.tmpl"
+
+SRCS = ipaq.c
+
+OBJS = ipaq.o
+
+INCLUDES = -I. $(KDINCS) -I$(KDRIVE)/fbdev -I$(KDRIVE)/pcmcia
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(ipaq,$(OBJS))
+DependTarget()
diff --git a/xc/programs/Xserver/hw/kdrive/ipaq/ipaq.c b/xc/programs/Xserver/hw/kdrive/ipaq/ipaq.c
new file mode 100644
index 000000000..b281c213b
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/ipaq/ipaq.c
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ *
+ * Adapted from ts300.c by Alan Hourihane <alanh@fairlite.demon.co.uk>
+ * For the Compaq IPAQ handheld, with the HP VGA Out Card (F1252A).
+ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/ipaq/ipaq.c,v 1.2 2001/05/29 17:47:55 keithp Exp $ */
+
+#include "pcmcia.h"
+
+extern KdCardFuncs pcmciaFuncs;
+
+void
+InitCard (char *name)
+{
+ KdCardAttr attr;
+ if (name && !strcmp(name, "pcmcia"))
+ KdCardInfoAdd (&pcmciaFuncs, &attr, 0);
+ else
+ KdCardInfoAdd (&fbdevFuncs, &attr, 0);
+}
+
+void
+InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ KdInitOutput (pScreenInfo, argc, argv);
+}
+
+void
+InitInput (int argc, char **argv)
+{
+#ifdef __powerpc__
+ KdInitInput (&BusMouseFuncs, &LinuxKeyboardFuncs);
+#else
+ KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+#endif
+#ifdef TOUCHSCREEN
+ KdInitTouchScreen (&TsFuncs);
+#endif
+}
+
+extern pcmciaDisplayModeRec pcmciaDefaultModes[];
+
+int
+ddxProcessArgument (int argc, char **argv, int i)
+{
+ int ret;
+
+ if (!strcmp (argv[i], "-listmodes"))
+ {
+ int j = 0, bpp = 0;
+ ErrorF("Valid modes are....\n\n");
+
+ for (bpp = 8; bpp < 24; bpp += 8) {
+ while (pcmciaDefaultModes[j].Width != 0) {
+ if ((pcmciaDefaultModes[j].Width *
+ pcmciaDefaultModes[j].Height * bpp/8) <= 512 * 1024) {
+ ErrorF("%dx%dx%dx%d\n",
+ pcmciaDefaultModes[j].Width,
+ pcmciaDefaultModes[j].Height,
+ bpp,
+ pcmciaDefaultModes[j].Refresh);
+ }
+ j++;
+ }
+ j = 0;
+ }
+ exit(1);
+ }
+ return KdProcessArgument (argc, argv, i);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/kaa.c b/xc/programs/Xserver/hw/kdrive/kaa.c
new file mode 100644
index 000000000..3e362cfb8
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/kaa.c
@@ -0,0 +1,636 @@
+/*
+ * $XFree86: xc/programs/Xserver/hw/kdrive/kaa.c,v 1.5 2001/06/29 13:55:53 keithp Exp $
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, 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 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 "fontstruct.h"
+#include "dixfontstr.h"
+
+int kaaGeneration;
+int kaaScreenPrivateIndex;
+
+#define KaaScreenPriv(s) KaaScreenPrivPtr pKaaScr = (KaaScreenPrivPtr) (s)->devPrivates[kaaScreenPrivateIndex].ptr
+
+void
+kaaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ KdScreenPriv (pScreen);
+ KaaScreenPriv (pScreen);
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ BoxPtr pextent, pbox;
+ int nbox;
+ int extentX1, extentX2, extentY1, extentY2;
+ int fullX1, fullX2, fullY1;
+ int partX1, partX2;
+
+ if (!pScreenPriv->enabled ||
+ pGC->fillStyle != FillSolid ||
+ !(*pKaaScr->PrepareSolid) (pDrawable,
+ pGC->alu,
+ pGC->planemask,
+ pGC->fgPixel))
+ {
+ KdCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
+ return;
+ }
+
+ 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)
+ {
+ (*pKaaScr->Solid) (fullX1, fullY1, fullX2, fullY1 + 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)
+ (*pKaaScr->Solid) (partX1, fullY1, partX2, fullY1 + 1);
+ }
+ pbox++;
+ }
+ }
+ }
+ (*pKaaScr->DoneSolid) ();
+ KdMarkSync(pDrawable->pScreen);
+}
+
+void
+kaaCopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ KdScreenPriv (pDstDrawable->pScreen);
+ KaaScreenPriv (pDstDrawable->pScreen);
+ int srcX, srcY, dstX, dstY;
+ int w, h;
+ CARD32 flags;
+ CARD32 cmd;
+ CARD8 alu;
+
+ if (pScreenPriv->enabled &&
+ pSrcDrawable->type == DRAWABLE_WINDOW &&
+ (*pKaaScr->PrepareCopy) (pSrcDrawable,
+ pDstDrawable,
+ dx,
+ dy,
+ pGC ? pGC->alu : GXcopy,
+ pGC ? pGC->planemask : FB_ALLONES))
+ {
+ while (nbox--)
+ {
+ (*pKaaScr->Copy) (pbox->x1 + dx, pbox->y1 + dy,
+ pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ pbox++;
+ }
+ (*pKaaScr->DoneCopy) ();
+ KdMarkSync(pDstDrawable->pScreen);
+ }
+ else
+ {
+ KdCheckSync (pDstDrawable->pScreen);
+ fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
+ pbox, nbox, dx, dy, reverse, upsidedown,
+ bitplane, closure);
+ }
+}
+
+RegionPtr
+kaaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height, int dstx, int dsty)
+{
+ return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height,
+ dstx, dsty, kaaCopyNtoN, 0, 0);
+}
+
+void
+kaaPolyFillRect(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nrect,
+ xRectangle *prect)
+{
+ KdScreenPriv (pDrawable->pScreen);
+ KaaScreenPriv (pDrawable->pScreen);
+ 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;
+
+ if (!pScreenPriv->enabled ||
+ pGC->fillStyle != FillSolid ||
+ !(*pKaaScr->PrepareSolid) (pDrawable,
+ pGC->alu,
+ pGC->planemask,
+ pGC->fgPixel))
+ {
+ KdCheckPolyFillRect (pDrawable, pGC, nrect, prect);
+ return;
+ }
+
+ 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)
+ {
+ (*pKaaScr->Solid) (fullX1, fullY1, fullX2, fullY2);
+ }
+ 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)
+ (*pKaaScr->Solid) (partX1, partY1,
+ partX2, partY2);
+ }
+ }
+ }
+ (*pKaaScr->DoneSolid) ();
+ KdMarkSync(pDrawable->pScreen);
+}
+
+void
+kaaSolidBoxClipped (DrawablePtr pDrawable,
+ RegionPtr pClip,
+ FbBits pm,
+ FbBits fg,
+ int x1,
+ int y1,
+ int x2,
+ int y2)
+{
+ KdScreenPriv (pDrawable->pScreen);
+ KaaScreenPriv (pDrawable->pScreen);
+ BoxPtr pbox;
+ int nbox;
+ int partX1, partX2, partY1, partY2;
+ CARD32 cmd;
+
+ if (!pScreenPriv->enabled ||
+ !(*pKaaScr->PrepareSolid) (pDrawable, GXcopy, pm, fg))
+ {
+ KdCheckSync (pDrawable->pScreen);
+ fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
+ fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2,
+ fbAnd (GXcopy, fg, pm),
+ fbXor (GXcopy, fg, pm));
+ return;
+ }
+ 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;
+
+ (*pKaaScr->Solid) (partX1, partY1, partX2, partY2);
+ }
+ (*pKaaScr->DoneSolid) ();
+ KdMarkSync(pDrawable->pScreen);
+}
+
+void
+kaaImageGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppciInit,
+ pointer pglyphBase)
+{
+ KaaScreenPriv (pDrawable->pScreen);
+ 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;
+ int dstXoff, dstYoff;
+ 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, dstXoff, dstYoff);
+ 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);
+ kaaSolidBoxClipped (pDrawable,
+ fbGetCompositeClip(pGC),
+ pGC->planemask,
+ pGC->bgPixel,
+ xBack,
+ yBack,
+ xBack + widthBack,
+ yBack + heightBack);
+ 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 - dstYoff) * dstStride,
+ dstStride,
+ dstBpp,
+ (FbStip *) pglyph,
+ pPriv->fg,
+ gx - dstXoff,
+ 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 kaaOps = {
+ kaaFillSpans,
+ KdCheckSetSpans,
+ KdCheckPutImage,
+ kaaCopyArea,
+ KdCheckCopyPlane,
+ KdCheckPolyPoint,
+ KdCheckPolylines,
+ KdCheckPolySegment,
+ miPolyRectangle,
+ KdCheckPolyArc,
+ miFillPolygon,
+ kaaPolyFillRect,
+ miPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ kaaImageGlyphBlt,
+ KdCheckPolyGlyphBlt,
+ KdCheckPushPixels,
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+void
+kaaValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable)
+{
+ FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC);
+
+ fbValidateGC (pGC, changes, pDrawable);
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ pGC->ops = (GCOps *) &kaaOps;
+ else
+ pGC->ops = (GCOps *) &kdAsyncPixmapGCOps;
+}
+
+GCFuncs kaaGCFuncs = {
+ kaaValidateGC,
+ miChangeGC,
+ miCopyGC,
+ miDestroyGC,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip
+};
+
+int
+kaaCreateGC (GCPtr pGC)
+{
+ if (!fbCreateGC (pGC))
+ return FALSE;
+
+ pGC->funcs = &kaaGCFuncs;
+
+ return TRUE;
+}
+
+void
+kaaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ KaaScreenPriv (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, kaaCopyNtoN, 0, 0);
+
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+}
+
+void
+kaaFillRegionSolid (DrawablePtr pDrawable,
+ RegionPtr pRegion,
+ Pixel pixel)
+{
+ KdScreenPriv(pDrawable->pScreen);
+ KaaScreenPriv(pDrawable->pScreen);
+
+ if (pScreenPriv->enabled &&
+ (*pKaaScr->PrepareSolid) (pDrawable, GXcopy, FB_ALLONES, pixel))
+ {
+ int nbox = REGION_NUM_RECTS (pRegion);
+ BoxPtr pBox = REGION_RECTS (pRegion);
+
+ while (nbox--)
+ {
+ (*pKaaScr->Solid) (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
+ pBox++;
+ }
+ (*pKaaScr->DoneSolid) ();
+ KdMarkSync(pDrawable->pScreen);
+ }
+ else
+ {
+ KdCheckSync (pDrawable->pScreen);
+ fbFillRegionSolid (pDrawable, pRegion, 0,
+ fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
+ }
+}
+
+void
+kaaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ 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 BackgroundPixel:
+ kaaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->background.pixel);
+ return;
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel)
+ {
+ kaaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->border.pixel);
+ return;
+ }
+ break;
+ }
+ KdCheckPaintWindow (pWin, pRegion, what);
+}
+
+Bool
+kaaDrawInit (ScreenPtr pScreen,
+ KaaScreenPrivPtr pScreenPriv)
+{
+ if (kaaGeneration != serverGeneration)
+ {
+ kaaScreenPrivateIndex = AllocateScreenPrivateIndex();
+ kaaGeneration = serverGeneration;
+ }
+ pScreen->devPrivates[kaaScreenPrivateIndex].ptr = (pointer) pScreenPriv;
+
+ /*
+ * Hook up asynchronous drawing
+ */
+ KdScreenInitAsync (pScreen);
+ /*
+ * Replace various fb screen functions
+ */
+ pScreen->CreateGC = kaaCreateGC;
+ pScreen->CopyWindow = kaaCopyWindow;
+ pScreen->PaintWindowBackground = kaaPaintWindow;
+ pScreen->PaintWindowBorder = kaaPaintWindow;
+
+ return TRUE;
+}
+
diff --git a/xc/programs/Xserver/hw/kdrive/linux/ms.c b/xc/programs/Xserver/hw/kdrive/linux/ms.c
new file mode 100644
index 000000000..9c30d2c38
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/linux/ms.c
@@ -0,0 +1,158 @@
+/*
+Copyright (c) 2001 by Juliusz Chroboczek
+Copyright (c) 1999 by Keith Packard
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+/* $XFree86: xc/programs/Xserver/hw/kdrive/linux/ms.c,v 1.1 2001/08/09 20:45:15 dawes Exp $ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "kdrive.h"
+#include "Xpoll.h"
+#include <errno.h>
+#include <termios.h>
+
+int
+MsReadBytes (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
+MsRead (int port)
+{
+ unsigned char buf[3 * 200];
+ unsigned char *b;
+ int n;
+ int dx, dy;
+ unsigned long flags;
+
+ while ((n = MsReadBytes (port, buf, sizeof (buf), 3)) > 0)
+ {
+ b = buf;
+ while (n >= 3)
+ {
+ flags = KD_MOUSE_DELTA;
+
+ if (b[0] & 0x20)
+ flags |= KD_BUTTON_1;
+ if (b[0] & 0x10)
+ flags |= KD_BUTTON_3;
+
+ dx = (char)(((b[0] & 0x03) << 6) | (b[1] & 0x3F));
+ dy = (char)(((b[0] & 0x0C) << 4) | (b[2] & 0x3F));
+ n -= 3;
+ b += 3;
+ KdEnqueueMouseEvent (flags, dx, dy);
+ }
+ }
+}
+
+int
+MsInit (void)
+{
+ int port;
+ char *device = "/dev/mouse";
+ struct termios t;
+ int ret;
+
+ port = open (device, O_RDWR | O_NONBLOCK);
+ if(port < 0) {
+ ErrorF("Couldn't open %s (%d)\n", device, (int)errno);
+ return 0;
+ } else if (port == 0) {
+ ErrorF("Opening %s returned 0! Please complain to Keith.\n",
+ device);
+ close(port);
+ return 0;
+ }
+
+ if(!isatty(port)) {
+ ErrorF("%s is not a tty\n", device);
+ goto bail;
+ }
+
+ ret = tcgetattr(port, &t);
+ if(ret < 0) {
+ ErrorF("Couldn't tcgetattr(%s): %d\n", device, errno);
+ goto bail;
+ }
+ t.c_iflag &= ~ (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR |
+ IGNCR | ICRNL | IXON | IXOFF);
+ t.c_oflag &= ~ OPOST;
+ t.c_lflag &= ~ (ECHO | ECHONL | ICANON | ISIG | IEXTEN);
+ t.c_cflag &= ~ (CSIZE | PARENB);
+ t.c_cflag |= CS8 | CLOCAL | CSTOPB;
+
+ cfsetispeed (&t, B1200);
+ cfsetospeed (&t, B1200);
+ t.c_cc[VMIN] = 1;
+ t.c_cc[VTIME] = 0;
+ ret = tcsetattr(port, TCSANOW, &t);
+ if(ret < 0) {
+ ErrorF("Couldn't tcsetattr(%s): %d\n", device, errno);
+ goto bail;
+ }
+ return port;
+
+ bail:
+ close(port);
+ return 0;
+}
+
+void
+MsFini (int port)
+{
+ if (port >= 0)
+ close(port);
+}
+
+KdMouseFuncs MsMouseFuncs = {
+ MsInit,
+ MsRead,
+ MsFini
+};
diff --git a/xc/programs/Xserver/hw/kdrive/mach64/Imakefile b/xc/programs/Xserver/hw/kdrive/mach64/Imakefile
new file mode 100644
index 000000000..bd024c68b
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/mach64/Imakefile
@@ -0,0 +1,20 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/mach64/Imakefile,v 1.2 2001/06/16 05:48:48 keithp Exp $
+KDRIVE=..
+#include "../Kdrive.tmpl"
+
+#if BuildXvExt
+XVSRCS=mach64video.c
+XVOBJS=mach64video.o
+#endif
+
+SRCS = mach64.c mach64draw.c mach64stub.c $(XVSRCS)
+
+OBJS = mach64.o mach64draw.o mach64stub.o $(XVOBJS)
+
+DEFINES = XvExtensionDefines -DVESA /* -DUSE_PCI*/
+
+INCLUDES = -I. $(KDINCS) -I$(KDRIVE)/vesa
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(mach64,$(OBJS))
+DependTarget()
diff --git a/xc/programs/Xserver/hw/kdrive/mach64/mach64.c b/xc/programs/Xserver/hw/kdrive/mach64/mach64.c
new file mode 100644
index 000000000..7df5c9d61
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/mach64/mach64.c
@@ -0,0 +1,450 @@
+/*
+ * Copyright © 2001 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64.c,v 1.8 2001/07/24 21:26:17 keithp Exp $ */
+
+#include "mach64.h"
+#include <sys/io.h>
+
+Bool
+mach64CardInit (KdCardInfo *card)
+{
+ Mach64CardInfo *mach64c;
+
+ mach64c = (Mach64CardInfo *) xalloc (sizeof (Mach64CardInfo));
+ if (!mach64c)
+ return FALSE;
+
+ (void) mach64MapReg (card, mach64c);
+ mach64c->lcdEnabled = FALSE;
+
+ if (!vesaInitialize (card, &mach64c->vesa))
+ {
+ xfree (mach64c);
+ return FALSE;
+ }
+
+ card->driver = mach64c;
+
+ return TRUE;
+}
+
+Bool
+mach64ScreenInit (KdScreenInfo *screen)
+{
+ Mach64CardInfo *mach64c = screen->card->driver;
+ Mach64ScreenInfo *mach64s;
+ int screen_size, memory;
+
+ mach64s = (Mach64ScreenInfo *) xalloc (sizeof (Mach64ScreenInfo));
+ if (!mach64s)
+ return FALSE;
+ memset (mach64s, '\0', sizeof (Mach64ScreenInfo));
+ if (!vesaScreenInitialize (screen, &mach64s->vesa))
+ {
+ xfree (mach64s);
+ return FALSE;
+ }
+ if (!mach64c->reg)
+ screen->dumb = TRUE;
+ if (mach64s->vesa.mapping != VESA_LINEAR)
+ screen->dumb = TRUE;
+ mach64s->screen = mach64s->vesa.fb;
+ switch (screen->fb[0].depth) {
+ case 8:
+ mach64s->colorKey = 0xff;
+ break;
+ case 15:
+ case 16:
+ mach64s->colorKey = 0x001e;
+ break;
+ case 24:
+ mach64s->colorKey = 0x0000fe;
+ break;
+ default:
+ mach64s->colorKey = 1;
+ break;
+ }
+ memory = mach64s->vesa.fb_size;
+ screen_size = screen->fb[0].byteStride * screen->height;
+ if (mach64s->screen && memory >= screen_size + 2048)
+ {
+ memory -= 2048;
+ mach64s->cursor_base = mach64s->screen + memory - 2048;
+ }
+ else
+ mach64s->cursor_base = 0;
+ screen->softCursor = TRUE; /* XXX for now */
+ memory -= screen_size;
+ if (memory > screen->fb[0].byteStride)
+ {
+ mach64s->off_screen = mach64s->screen + screen_size;
+ mach64s->off_screen_size = memory;
+ }
+ else
+ {
+ mach64s->off_screen = 0;
+ mach64s->off_screen_size = 0;
+ }
+ screen->driver = mach64s;
+ return TRUE;
+}
+
+Bool
+mach64InitScreen (ScreenPtr pScreen)
+{
+#ifdef XV
+ KdScreenPriv(pScreen);
+ Mach64CardInfo *mach64c = pScreenPriv->screen->card->driver;
+ if (mach64c->media_reg && mach64c->reg)
+ mach64InitVideo(pScreen);
+#endif
+ return vesaInitScreen (pScreen);
+}
+
+#ifdef RANDR
+mach64RandRSetConfig (ScreenPtr pScreen,
+ Rotation rotation,
+ RRScreenSizePtr pSize,
+ RRVisualGroupPtr pVisualGroup)
+{
+ KdScreenPriv(pScreen);
+
+ KdCheckSync (pScreen);
+
+ if (!vesaRandRSetConfig (pScreen, rotation, pSize, pVisualGroup))
+ return FALSE;
+
+ return TRUE;
+}
+
+void
+mach64RandRInit (ScreenPtr pScreen)
+{
+ rrScrPriv(pScreen);
+
+ pScrPriv->rrSetConfig = mach64RandRSetConfig;
+}
+#endif
+
+Bool
+mach64FinishInitScreen (ScreenPtr pScreen)
+{
+ Bool ret;
+ ret = vesaFinishInitScreen (pScreen);
+#ifdef RANDR
+ mach64RandRInit (pScreen);
+#endif
+ return ret;
+}
+
+CARD32
+mach64ReadLCD (Reg *reg, int id)
+{
+ CARD32 LCD_INDEX;
+
+ LCD_INDEX = reg->LCD_INDEX & ~(0x3f);
+ reg->LCD_INDEX = (LCD_INDEX | id);
+ return reg->LCD_DATA;
+}
+
+void
+mach64WriteLCD (Reg *reg, int id, CARD32 data)
+{
+ CARD32 LCD_INDEX;
+
+ LCD_INDEX = reg->LCD_INDEX & ~(0x3f);
+ reg->LCD_INDEX = (LCD_INDEX | id);
+ reg->LCD_DATA = data;
+}
+
+void
+mach64Preserve (KdCardInfo *card)
+{
+ Mach64CardInfo *mach64c = card->driver;
+ Reg *reg = mach64c->reg;
+
+ vesaPreserve(card);
+ if (reg)
+ {
+ mach64c->save.LCD_GEN_CTRL = mach64ReadLCD (reg, 1);
+ }
+}
+
+Bool
+mach64MapReg (KdCardInfo *card, Mach64CardInfo *mach64c)
+{
+ mach64c->reg_base = (CARD8 *) KdMapDevice (MACH64_REG_BASE(card),
+ MACH64_REG_SIZE(card));
+
+ if (!mach64c->reg_base)
+ {
+ mach64c->reg = 0;
+ mach64c->media_reg = 0;
+ return FALSE;
+ }
+
+ KdSetMappedMode (MACH64_REG_BASE(card),
+ MACH64_REG_SIZE(card),
+ KD_MAPPED_MODE_REGISTERS);
+ mach64c->reg = (Reg *) (mach64c->reg_base + MACH64_REG_OFF(card));
+ mach64c->media_reg = (MediaReg *) (mach64c->reg_base + MACH64_MEDIA_REG_OFF(card));
+ return TRUE;
+}
+
+void
+mach64UnmapReg (KdCardInfo *card, Mach64CardInfo *mach64c)
+{
+ if (mach64c->reg_base)
+ {
+ KdResetMappedMode (MACH64_REG_BASE(card),
+ MACH64_REG_SIZE(card),
+ KD_MAPPED_MODE_REGISTERS);
+ KdUnmapDevice ((void *) mach64c->reg_base, MACH64_REG_SIZE(card));
+ mach64c->reg_base = 0;
+ mach64c->reg = 0;
+ mach64c->media_reg = 0;
+ }
+}
+
+void
+mach64SetMMIO (KdCardInfo *card, Mach64CardInfo *mach64c)
+{
+ if (!mach64c->reg_base)
+ mach64MapReg (card, mach64c);
+ if (mach64c->reg)
+ {
+ if (mach64c->reg->GUI_STAT == 0xffffffff)
+ FatalError ("Mach64 REG not visible\n");
+ }
+}
+
+void
+mach64ResetMMIO (KdCardInfo *card, Mach64CardInfo *mach64c)
+{
+ mach64UnmapReg (card, mach64c);
+}
+
+Bool
+mach64Enable (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ Mach64CardInfo *mach64c = pScreenPriv->card->driver;
+
+ if (!vesaEnable (pScreen))
+ return FALSE;
+
+ mach64SetMMIO (pScreenPriv->card, mach64c);
+ mach64DPMS (pScreen, KD_DPMS_NORMAL);
+#ifdef XV
+ KdXVEnable (pScreen);
+#endif
+ return TRUE;
+}
+
+void
+mach64Disable (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ Mach64CardInfo *mach64c = pScreenPriv->card->driver;
+
+#ifdef XV
+ KdXVDisable (pScreen);
+#endif
+ mach64ResetMMIO (pScreenPriv->card, mach64c);
+ vesaDisable (pScreen);
+}
+
+const CARD8 mach64DPMSModes[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 */
+};
+
+#define PWR_MGT_ON (1 << 0)
+#define PWR_MGT_MODE (3 << 1)
+#define PWR_MGT_MODE_PIN (0 << 1)
+#define PWR_MGT_MODE_REG (1 << 1)
+#define PWR_MGT_MODE_TIMER (2 << 1)
+#define PWR_MGR_MODE_PCI (3 << 1)
+#define AUTO_PWRUP_EN (1 << 3)
+#define ACTIVITY_PIN_ON (1 << 4)
+#define STANDBY_POL (1 << 5)
+#define SUSPEND_POL (1 << 6)
+#define SELF_REFRESH (1 << 7)
+#define ACTIVITY_PIN_EN (1 << 8)
+#define KEYBD_SNOOP (1 << 9)
+#define DONT_USE_F32KHZ (1 << 10)
+#define TRISTATE_MEM_EN (1 << 11)
+#define LCDENG_TEST_MODE (0xf << 12)
+#define STANDBY_COUNT (0xf << 16)
+#define SUSPEND_COUNT (0xf << 20)
+#define BIASON (1 << 24)
+#define BLON (1 << 25)
+#define DIGON (1 << 26)
+#define PM_D3_RST_ENB (1 << 27)
+#define STANDBY_NOW (1 << 28)
+#define SUSPEND_NOW (1 << 29)
+#define PWR_MGT_STATUS (3 << 30)
+#define PWR_MGT_STATUS_ON (0 << 30)
+#define PWR_MGT_STATUS_STANDBY (1 << 30)
+#define PWR_MGT_STATUS_SUSPEND (2 << 30)
+#define PWR_MGT_STATUS_TRANSITION (3 << 30)
+
+Bool
+mach64DPMS (ScreenPtr pScreen, int mode)
+{
+ KdScreenPriv(pScreen);
+ Mach64CardInfo *mach64c = pScreenPriv->card->driver;
+ int hsync_off, vsync_off, blank;
+ CARD32 CRTC_GEN_CNTL;
+ CARD32 LCD_GEN_CTRL;
+ Reg *reg = mach64c->reg;
+
+ if (!reg)
+ return FALSE;
+
+ CRTC_GEN_CNTL = reg->CRTC_GEN_CNTL;
+ LCD_GEN_CTRL = mach64ReadLCD (reg, 1);
+
+ switch (mode) {
+ case KD_DPMS_NORMAL:
+ hsync_off = 0;
+ vsync_off = 0;
+ blank = 0;
+ break;
+ case KD_DPMS_STANDBY:
+ hsync_off = 1;
+ vsync_off = 0;
+ blank = 1;
+ break;
+ case KD_DPMS_SUSPEND:
+ hsync_off = 0;
+ vsync_off = 1;
+ blank = 1;
+ break;
+ case KD_DPMS_POWERDOWN:
+ hsync_off = 1;
+ vsync_off = 1;
+ blank = 1;
+ }
+
+ if (hsync_off)
+ CRTC_GEN_CNTL |= (1 << 2);
+ else
+ CRTC_GEN_CNTL &= ~(1 << 2);
+ if (vsync_off)
+ CRTC_GEN_CNTL |= (1 << 3);
+ else
+ CRTC_GEN_CNTL &= ~(1 << 3);
+ if (blank)
+ {
+ mach64c->lcdEnabled = (LCD_GEN_CTRL & (1 << 1)) != 0;
+ LCD_GEN_CTRL &= ~(1 << 1);
+ CRTC_GEN_CNTL |= (1 << 6);
+
+ }
+ else
+ {
+ if (!(LCD_GEN_CTRL & 3) || mach64c->lcdEnabled)
+ LCD_GEN_CTRL |= (1 << 1);
+ CRTC_GEN_CNTL &= ~(1 << 6);
+ }
+
+ KdCheckSync (pScreen);
+
+ mach64WriteLCD (reg, 1, LCD_GEN_CTRL);
+
+ reg->CRTC_GEN_CNTL = CRTC_GEN_CNTL;
+ return TRUE;
+}
+
+void
+mach64Restore (KdCardInfo *card)
+{
+ Mach64CardInfo *mach64c = card->driver;
+ Reg *reg = mach64c->reg;
+
+ if (reg)
+ {
+ mach64WriteLCD (reg, 1, mach64c->save.LCD_GEN_CTRL);
+ }
+ mach64ResetMMIO (card, mach64c);
+ vesaRestore (card);
+}
+
+void
+mach64ScreenFini (KdScreenInfo *screen)
+{
+ Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
+
+ vesaScreenFini (screen);
+ xfree (mach64s);
+ screen->driver = 0;
+}
+
+void
+mach64CardFini (KdCardInfo *card)
+{
+ Mach64CardInfo *mach64c = card->driver;
+
+ mach64UnmapReg (card, mach64c);
+ vesaCardFini (card);
+}
+
+#define mach64CursorInit 0 /* initCursor */
+#define mach64CursorEnable 0 /* enableCursor */
+#define mach64CursorDisable 0 /* disableCursor */
+#define mach64CursorFini 0 /* finiCursor */
+#define mach64RecolorCursor 0 /* recolorCursor */
+
+KdCardFuncs mach64Funcs = {
+ mach64CardInit, /* cardinit */
+ mach64ScreenInit, /* scrinit */
+ mach64InitScreen, /* initScreen */
+ mach64Preserve, /* preserve */
+ mach64Enable, /* enable */
+ mach64DPMS, /* dpms */
+ mach64Disable, /* disable */
+ mach64Restore, /* restore */
+ mach64ScreenFini, /* scrfini */
+ mach64CardFini, /* cardfini */
+
+ mach64CursorInit, /* initCursor */
+ mach64CursorEnable, /* enableCursor */
+ mach64CursorDisable, /* disableCursor */
+ mach64CursorFini, /* finiCursor */
+ mach64RecolorCursor, /* recolorCursor */
+
+ mach64DrawInit, /* initAccel */
+ mach64DrawEnable, /* enableAccel */
+ mach64DrawSync, /* syncAccel */
+ mach64DrawDisable, /* disableAccel */
+ mach64DrawFini, /* finiAccel */
+
+ vesaGetColors, /* getColors */
+ vesaPutColors, /* putColors */
+
+ mach64FinishInitScreen, /* finishInitScreen */
+};
diff --git a/xc/programs/Xserver/hw/kdrive/mach64/mach64.h b/xc/programs/Xserver/hw/kdrive/mach64/mach64.h
new file mode 100644
index 000000000..c54238604
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/mach64/mach64.h
@@ -0,0 +1,655 @@
+/*
+ * Id: mach64.h,v 1.2 1999/11/02 08:17:24 keithp Exp $
+ *
+ * Copyright © 2001 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64.h,v 1.6 2001/07/24 19:06:03 keithp Exp $ */
+
+#ifndef _MACH64_H_
+#define _MACH64_H_
+#include <vesa.h>
+#include "kxv.h"
+
+/*
+ * offset from ioport beginning
+ */
+
+#define MACH64_REG_BASE(c) ((c)->attr.address[1])
+#define MACH64_REG_SIZE(c) (4096)
+
+#define MACH64_REG_OFF(c) (1024)
+#define MACH64_MEDIA_REG_OFF(c) (0)
+
+typedef volatile CARD8 VOL8;
+typedef volatile CARD16 VOL16;
+typedef volatile CARD32 VOL32;
+
+typedef struct _Reg {
+ VOL32 CRTC_H_TOTAL_DISP; /* 0x00 */
+ VOL32 CRTC_H_SYNC_STRT_WID; /* 0x01 */
+ VOL32 CRTC_V_TOTAL_DISP; /* 0x02 */
+ VOL32 CRTC_V_SYNC_STRT_WID; /* 0x03 */
+ VOL32 CRTC_VLINE_CRNT_VLINE; /* 0x04 */
+ VOL32 CRTC_OFF_PITCH; /* 0x05 */
+ VOL32 CRTC_INT_CNTL; /* 0x06 */
+ VOL32 CRTC_GEN_CNTL; /* 0x07 */
+ VOL32 DSP_CONFIG; /* 0x08 */
+ VOL32 DSP_ON_OFF; /* 0x09 */
+ VOL32 TIMER_CONFIG; /* 0x0a */
+ VOL32 MEM_BUF_CNTL; /* 0x0b */
+ VOL32 unused0; /* 0x0c */
+ VOL32 MEM_ADDR_CONFIG; /* 0x0d */
+ VOL32 CRT_TRAP; /* 0x0e */
+ VOL32 I2C_CNTL_0; /* 0x0f */
+ VOL32 OVR_CLR; /* 0x10 */
+ VOL32 OVR_WID_LEFT_RIGHT; /* 0x11 */
+ VOL32 OVR_WID_TOP_BOTTOM; /* 0x12 */
+ VOL32 VGA_DSP_CONFIG; /* 0x13 */
+ VOL32 VGA_DSP_ON_OFF; /* 0x14 */
+ VOL32 DSP2_CONFIG; /* 0x15 */
+ VOL32 DSP2_ON_OFF; /* 0x16 */
+ VOL32 CRTC2_OFF_PITCH; /* 0x17 */
+ VOL32 CUR_CLR0; /* 0x18 */
+ VOL32 CUR_CLR1; /* 0x19 */
+ VOL32 CUR_OFFSET; /* 0x1a */
+ VOL32 CUR_HORZ_VERT_POSN; /* 0x1b */
+ VOL32 CUR_HORZ_VERT_OFF; /* 0x1c */
+ VOL32 TV_OUT_INDEX; /* 0x1d */
+ VOL32 GP_IO; /* 0x1e */
+ VOL32 HW_DEBUG; /* 0x1f */
+ VOL32 SCRATCH_REG0; /* 0x20 */
+ VOL32 SCRATCH_REG1;
+ VOL32 SCRATCH_REG2;
+ VOL32 SCRATCH_REG3;
+ VOL32 CLOCK_CNTL;
+ VOL32 CONFIG_STAT1;
+ VOL32 CONFIG_STAT2;
+ VOL32 TV_OUT_DATA;
+ VOL32 BUS_CNTL; /* 0x28 */
+ VOL32 LCD_INDEX; /* 0x29 */
+ VOL32 LCD_DATA; /* 0x2a */
+ VOL32 EXT_MEM_CNTL;
+ VOL32 MEM_CNTL;
+ VOL32 MEM_VGA_WP_SEL;
+ VOL32 MEM_VGA_RP_SEL;
+ VOL32 I2C_CNTL_1;
+ VOL32 DAC_REGS; /* 0x30 */
+ VOL32 DAC_CNTL; /* 0x31 */
+ VOL32 unused_32;
+ VOL32 unused_33;
+ VOL32 GEN_TEST_CNTL; /* 0x34 */
+ VOL32 CUSTOM_MACRO_CNTL;
+ VOL32 unused36;
+ VOL32 CONFIG_CNTL;
+ VOL32 CONFIG_CHIP_ID;
+ VOL32 CONFIG_STAT0;
+ VOL32 CRC_SIG;
+ VOL32 unused_3b;
+ VOL32 unused_3c;
+ VOL32 unused_3d;
+ VOL32 unused_3e;
+ VOL32 unused_3f;
+ VOL32 DST_OFF_PITCH; /* 0x40 */
+ VOL32 DST_X;
+ VOL32 DST_Y;
+ VOL32 DST_Y_X;
+ VOL32 DST_WIDTH;
+ VOL32 DST_HEIGHT;
+ VOL32 DST_HEIGHT_WIDTH;
+ VOL32 DST_X_WIDTH;
+ VOL32 DST_BRES_LNTH;
+ VOL32 DST_BRES_ERR;
+ VOL32 DST_BRES_INC;
+ VOL32 DST_BRES_DEC;
+ VOL32 DST_CNTL;
+ VOL32 DST_Y_X_ALIAS;
+ VOL32 TRAIL_BRES_ERR;
+ VOL32 TRAIL_BRES_INC;
+ VOL32 TRAIL_BRES_DEC;
+ VOL32 LEAD_BRES_LNTH;
+ VOL32 Z_OFF_PITCH;
+ VOL32 Z_CNTL;
+ VOL32 ALPHA_TST_CNTL;
+ VOL32 unused55;
+ VOL32 SECONDARY_STW_EXP;
+ VOL32 SECONDARY_S_X_INC;
+ VOL32 SECONDARY_S_Y_INC;
+ VOL32 SECONDARY_S_START;
+ VOL32 SECONDARY_W_X_INC;
+ VOL32 SECONDARY_W_Y_INC;
+ VOL32 SECONDARY_W_START;
+ VOL32 SECONDARY_T_X_INC;
+ VOL32 SECONDARY_T_Y_INC;
+ VOL32 SECONDARY_T_START;
+ VOL32 SRC_OFF_PITCH;
+ VOL32 SRC_X;
+ VOL32 SRC_Y;
+ VOL32 SRC_Y_X;
+ VOL32 SRC_WIDTH1;
+ VOL32 SRC_HEIGHT1;
+ VOL32 SRC_HEIGHT1_WIDTH1;
+ VOL32 SRC_X_START;
+ VOL32 SRC_Y_START;
+ VOL32 SRC_Y_X_START;
+ VOL32 SRC_WIDTH2;
+ VOL32 SRC_HEIGHT2;
+ VOL32 SRC_HEIGHT2_WIDTH2;
+ VOL32 SRC_CNTL;
+ VOL32 unused6e;
+ VOL32 unused6f;
+ union {
+ struct {
+ VOL32 SCALE_OFF; /* 0x70 */
+ VOL32 unused71;
+ VOL32 unused72;
+ VOL32 unused73;
+ VOL32 unused74;
+ VOL32 unused75;
+ VOL32 unused76;
+ VOL32 SCALE_WIDTH;
+ VOL32 SCALE_HEIGHT;
+ VOL32 unused79;
+ VOL32 unused7a;
+ VOL32 SCALE_PITCH;
+ VOL32 SCALE_X_INC;
+ VOL32 SCALE_Y_INC;
+ VOL32 SCALE_VACC;
+ VOL32 SCALE_3D_CNTL; /* 0x7f */
+ } scaler;
+ struct {
+ VOL32 TEX_0_OFF; /* 0x70 */
+ VOL32 TEX_1_OFF;
+ VOL32 TEX_2_OFF;
+ VOL32 TEX_3_OFF;
+ VOL32 TEX_4_OFF;
+ VOL32 TEX_5_OFF;
+ VOL32 TEX_6_OFF;
+ VOL32 TEX_7_OFF;
+ VOL32 TEX_8_OFF;
+ VOL32 TEX_9_OFF;
+ VOL32 TEX_10_OFF;
+ VOL32 S_Y_INC;
+ VOL32 RED_X_INC;
+ VOL32 GREEN_X_INC; /* 0x7d */
+ VOL32 unused7e;
+ VOL32 unused7f;
+ } texture;
+ } u;
+ VOL32 HOST_DATA[16]; /* 0x80 */
+ VOL32 HOST_CNTL; /* 0x90 */
+ VOL32 BM_HOSTDATA; /* 0x91 */
+ VOL32 BM_ADDR; /* 0x92 */
+ VOL32 BM_GUI_TABLE_CMD; /* 0x93 */
+ VOL32 unused94; /* 0x94 */
+ VOL32 unused95; /* 0x95 */
+ VOL32 unused96; /* 0x96 */
+ VOL32 FOG_TABLE_INDEX; /* 0x97 */
+ VOL32 FOG_TABLE_DATA[8]; /* 0x98 */
+ VOL32 PAT_REG0; /* 0xa0 */
+ VOL32 PAT_REG1;
+ VOL32 PAT_CNTL;
+ VOL32 unused_0a3;
+ VOL32 unused_0a4;
+ VOL32 unused_0a5;
+ VOL32 unused_0a6;
+ VOL32 unused_0a7;
+ VOL32 SC_LEFT;
+ VOL32 SC_RIGHT;
+ VOL32 SC_LEFT_RIGHT;
+ VOL32 SC_TOP;
+ VOL32 SC_BOTTOM;
+ VOL32 SC_TOP_BOTTOM;
+ VOL32 USR1_DST_OFF_PITCH;
+ VOL32 USR2_DST_OFF_PITCH;
+ VOL32 DP_BKGD_CLR; /* 0xb0 */
+ VOL32 DP_FRGD_CLR;
+ VOL32 DP_WRITE_MSK;
+ VOL32 unused_0b3;
+ VOL32 DP_PIX_WIDTH;
+ VOL32 DP_MIX;
+ VOL32 DP_SRC;
+ VOL32 DP_FRGD_CLR_MIX;
+ VOL32 DP_FRGD_BKGD_CLR;
+ VOL32 unused_0b9;
+ VOL32 DST_X_Y;
+ VOL32 DST_WIDTH_HEIGHT;
+ VOL32 USR_DST_PITCH;
+ VOL32 unused_0bd;
+ VOL32 DP_SET_GUI_ENGINE2;
+ VOL32 DP_SET_GUI_ENGINE;
+ VOL32 CLR_CMP_CLR; /* 0xc0 */
+ VOL32 CLR_CMP_MSK;
+ VOL32 CLR_CMP_CNTL;
+ VOL32 unused_0c3;
+ VOL32 FIFO_STAT;
+ VOL32 unused_0c5;
+ VOL32 unused_0c6;
+ VOL32 unused_0c7;
+ VOL32 unused_0c8;
+ VOL32 unused_0c9;
+ VOL32 unused_0ca;
+ VOL32 unused_0cb;
+ VOL32 GUI_TRAJ_CNTL;
+ VOL32 unused_0cd;
+ VOL32 GUI_STAT;
+ VOL32 unused_0cf;
+ VOL32 TEX_PALETTE_INDEX;
+ VOL32 STW_EXP;
+ VOL32 LOG_MAX_INC;
+ VOL32 S_X_INC;
+ VOL32 S_Y_INC_2_SCALE_PITCH;
+ VOL32 S_START;
+ VOL32 W_X_INC;
+ VOL32 W_Y_INC;
+ VOL32 W_START;
+ VOL32 T_X_INC;
+ VOL32 T_Y_INC_SECONDARY_SCALE_PITCH;
+ VOL32 T_START;
+ VOL32 TEX_SIZE_PITCH;
+ VOL32 TEX_CNTL;
+ VOL32 SECONDARY_TEX_OFFSET_SECONDARY_SCALE_OFF;
+ VOL32 TEX_PALETTE;
+ VOL32 SCALE_PITCH_BOTH; /* 0xe0 */
+ VOL32 SECONDARY_SCALE_OFF_ACC;
+ VOL32 SCALE_OFF_ACC;
+ VOL32 SCALE_DST_Y_X;
+ VOL32 unused_0e4;
+ VOL32 unused_0e5;
+ VOL32 COMPOSITE_SHADOW_ID;
+ VOL32 SECONDARY_SCALE_X_INC_SPECULAR_RED_X_INC;
+ VOL32 SPECULAR_RED_Y_INC;
+ VOL32 SPECULAR_RED_START_SECONDARY_SCALE_HACC;;
+ VOL32 SPECULAR_GREEN_X_INC;
+ VOL32 SPECULAR_GREEN_Y_INC;
+ VOL32 SPECULAR_GREEN_START;
+ VOL32 SPECULAR_BLUE_X_INC;
+ VOL32 SPECULAR_BLUE_Y_INC;
+ VOL32 SPECULAR_BLUE_START;
+ VOL32 RED_X_INC_SCALE_X_INC;
+ VOL32 RED_Y_INC;
+ VOL32 RED_START_SCALE_HACC;
+ VOL32 GREEN_X_INC_SCALE_Y_INC;
+ VOL32 GREEN_Y_INC_SECONDARY_SCALE_Y_INC;
+ VOL32 GREEN_START_SECONDARY_SCALE_VACC;
+ VOL32 BLUE_X_INC;
+ VOL32 BLUE_Y_INC;
+ VOL32 BLUE_START;
+ VOL32 Z_X_INC;
+ VOL32 Z_Y_INC;
+ VOL32 Z_START;
+ VOL32 ALPHA_X_INC;
+ VOL32 FOG_X_INC;
+ VOL32 ALPHA_Y_INC;
+ VOL32 FOG_Y_INC;
+ VOL32 ALPHA_START;
+ VOL32 FOG_START;
+ VOL32 unused_0ff;
+} Reg; /* 0x100 */
+
+#define DST_X_DIR (1 << 0)
+#define DST_Y_DIR (1 << 1)
+#define DST_Y_MAJOR (1 << 2)
+#define DST_X_TILE (1 << 3)
+#define DST_Y_TILE (1 << 4)
+#define DST_LAST_PEL (1 << 5)
+#define DST_POLYGON_EN (1 << 6)
+#define DST_24_ROT_EN (1 << 7)
+#define DST_24_ROT(n) ((n) << 8)
+#define DST_BRES_ZERO (1 << 11)
+#define DST_POLYGON_RTEDGE_DIS (1 << 12)
+#define TRAIL_X_DIR (1 << 13)
+#define TRAP_FILL_DIR (1 << 14)
+#define TRAIL_BRES_SIGN (1 << 15)
+#define SRC_PATT_EN (1 << 16)
+#define SRC_PATT_ROT_EN (1 << 17)
+#define SRC_LINEAR_EN (1 << 18)
+#define SRC_BYTE_ALIGN (1 << 19)
+#define SRC_LINE_X_DIR (1 << 20)
+#define SRC_8x8x8_BRUSH (1 << 21)
+#define FAST_FILL_EN (1 << 22)
+#define SRC_TRACK_DST (1 << 23)
+#define PAT_MONO_EN (1 << 24)
+#define PAT_CLR_4x2_EN (1 << 25)
+#define PAT_CLR_8x1_EN (1 << 26)
+#define HOST_BYTE_ALIGN (1 << 28)
+#define HOST_BIG_ENDIAN_EN (1 << 29)
+
+/* BUS_CNTL bits */
+#define BUS_DBL_RESYNC (1 << 0)
+#define BUS_MSTR_RESET (1 << 1)
+#define BUS_FLUSH_BUF (1 << 2)
+#define BUS_STOP_REQ_DIS (1 << 3)
+#define BUS_APER_REG_DIS (1 << 4)
+#define BUS_EXTRA_PIPE_DIS (1 << 5)
+#define BUS_MASTER_DIS (1 << 6)
+#define ROM_WRT_EN (1 << 7)
+#define CHIP_HIDDEN_REV (3 << 8)
+#define BUS_PCI_READ_RETRY_EN (1 << 13)
+#define BUS_PCI_WRT_RETRY_EN (1 << 15)
+#define BUS_RETRY_WS (0xf << 16)
+#define BUS_MSTR_RD_MULT (1 << 20)
+#define BUS_MSTR_RD_LINE (1 << 21)
+#define BUS_SUSPEND (1 << 22)
+#define LAT16X (1 << 23)
+#define BUS_RD_DISCARD_EN (1 << 24)
+#define BUS_RD_ABORT_EN (1 << 25)
+#define BUS_MSTR_WS (1 << 26)
+#define BUS_EXT_REG_EN (1 << 27)
+#define BUS_MSTR_DISCONNECT_EN (1 << 28)
+#define BUS_WRT_BURST (1 << 29)
+#define BUS_READ_BURST (1 << 30)
+#define BUS_RDY_READ_DLY (1 << 31)
+
+#define SCALE_PIX_EXPAND (1 << 0)
+#define SCALE_Y2R_TEMP (1 << 1)
+#define SCALE_HORZ_MODE (1 << 2)
+#define SCALE_VERT_MODE (1 << 3)
+#define SCALE_SIGNED_UV (1 << 4)
+#define SCALE_GAMMA_SEL (3 << 5)
+#define SCALE_GAMMA_BRIGHT (0 << 5)
+#define SCALE_GAMMA_22 (1 << 5)
+#define SCALE_GAMMA_18 (2 << 5)
+#define SCALE_GAMMA_14 (3 << 5)
+#define SCALE_DISP_SEL (1 << 7)
+#define SCALE_BANDWIDTH (1 << 26)
+#define SCALE_DIS_LIMIT (1 << 27)
+#define SCALE_CLK_FORCE_ON (1 << 29)
+#define SCALE_OVERLAY_EN (1 << 30)
+#define SCALE_EN (1 << 31)
+
+#define VIDEO_IN_VYUY422 (0xb)
+#define VIDEO_IN_YVYU422 (0xc)
+#define SCALER_IN_15bpp (0x3 << 16)
+#define SCALER_IN_16bpp (0x4 << 16)
+#define SCALER_IN_32bpp (0x6 << 16)
+#define SCALER_IN_YUV_9 (0x9 << 16)
+#define SCALER_IN_YUV_12 (0xa << 16)
+#define SCALER_IN_VYUY422 (0xb << 16)
+#define SCALER_IN_YVYU422 (0xc << 16)
+
+#define CAP_INPUT_MODE (1 << 0)
+#define CAP_BUF_MODE (1 << 2)
+#define CAP_START_BUF (1 << 3)
+#define CAP_BUF_TYPE_FIELD (0 << 4)
+#define CAP_BUF_TYPE_ALTERNATING (1 << 4)
+#define CAP_BUF_TYPE_FRAME (2 << 4)
+
+#define OVL_BUF_MODE (1 << 28)
+#define OVL_BUF_NEXT (1 << 29)
+
+#define CAP_TRIGGER (3 << 0)
+#define OVL_CUR_BUF (1 << 5)
+#define OVL_BUF_STATUS (1 << 6)
+#define CAP_BUF_STATUS (1 << 7)
+#define CAPTURE_EN (1 << 31)
+
+typedef struct _MediaReg {
+ VOL32 OVERLAY_Y_X_START; /* 0x100 */
+ VOL32 OVERLAY_Y_X_END;
+ VOL32 OVERLAY_VIDEO_KEY_CLR;
+ VOL32 OVERLAY_VIDEO_KEY_MSK;
+ VOL32 OVERLAY_GRAPHICS_KEY_CLR;
+ VOL32 OVERLAY_GRAPHICS_KEY_MSK;
+ VOL32 OVERLAY_KEY_CNTL;
+ VOL32 unused_107;
+ VOL32 OVERLAY_SCALE_INC;
+ VOL32 OVERLAY_SCALE_CNTL;
+ VOL32 SCALER_HEIGHT_WIDTH;
+ VOL32 SCALER_TEST;
+ VOL32 unused_10c;
+ VOL32 SCALER_BUF0_OFFSET;
+ VOL32 SCALER_BUF1_OFFSET;
+ VOL32 SCALER_BUF_PITCH;
+ VOL32 CAPTURE_START_END; /* 0x110 */
+ VOL32 CAPTURE_X_WIDTH;
+ VOL32 VIDEO_FORMAT;
+ VOL32 VBI_START_END;
+ VOL32 CAPTURE_CONFIG;
+ VOL32 TRIG_CNTL;
+ VOL32 OVERLAY_EXCLUSIVE_HORZ;
+ VOL32 OVERLAY_EXCLUSIVE_VERT;
+ VOL32 VBI_WIDTH;
+ VOL32 CAPTURE_DEBUG;
+ VOL32 VIDEO_SYNC_TEST;
+ VOL32 unused_11b;
+ VOL32 SNAPSHOT_VH_COUNTS;
+ VOL32 SNAPSHOT_F_COUNT;
+ VOL32 N_VIF_COUNT;
+ VOL32 SNAPSHOT_VIF_COUNT;
+ VOL32 CAPTURE_BUF0_OFFSET; /* 0x120 */
+ VOL32 CAPTURE_BUF1_OFFSET;
+ VOL32 ONESHOT_BUF_OFFSET;
+ VOL32 unused_123;
+ VOL32 unused_124;
+ VOL32 unused_125;
+ VOL32 unused_126;
+ VOL32 unused_127;
+ VOL32 unused_128;
+ VOL32 unused_129;
+ VOL32 unused_12a;
+ VOL32 unused_12b;
+ VOL32 SNAPSHOT2_VH_COUNTS;
+ VOL32 SNAPSHOT2_F_COUNT;
+ VOL32 N_VIF2_COUNT;
+ VOL32 SNAPSHOT2_VIF_COUNT;
+ VOL32 MPP_CONFIG; /* 0x130 */
+ VOL32 MPP_STROBE_SEQ;
+ VOL32 MPP_ADDR;
+ VOL32 MPP_DATA;
+ VOL32 unused_134;
+ VOL32 unused_135;
+ VOL32 unused_136;
+ VOL32 unused_137;
+ VOL32 unused_138;
+ VOL32 unused_139;
+ VOL32 unused_13a;
+ VOL32 unused_13b;
+ VOL32 unused_13c;
+ VOL32 unused_13d;
+ VOL32 unused_13e;
+ VOL32 unused_13f;
+ VOL32 TVO_CNTL; /* 0x140 */
+ VOL32 unused_141[15];
+ VOL32 unused_150; /* 0x150 */
+ VOL32 CRT_HORZ_VERT_LOAD; /* 0x151 */
+ VOL32 AGP_BASE; /* 0x152 */
+ VOL32 AGP_CNTL; /* 0x153 */
+ VOL32 SCALER_COLOUR_CNTL; /* 0x154 */
+ VOL32 SCALER_H_COEFF0; /* 0x155 */
+ VOL32 SCALER_H_COEFF1; /* 0x156 */
+ VOL32 SCALER_H_COEFF2; /* 0x157 */
+ VOL32 SCALER_H_COEFF3; /* 0x158 */
+ VOL32 SCALER_H_COEFF4; /* 0x159 */
+ VOL32 unused_15a;
+ VOL32 unused_15b;
+ VOL32 GUI_CMDFIFO_DEBUG;
+ VOL32 GUI_CMDFIFO_DATA;
+ VOL32 GUI_CNTL;
+ VOL32 unused_15f;
+ VOL32 BM_FRAME_BUF_OFFSET; /* 0x160 */
+ VOL32 BM_SYSTEM_MEM_ADDR;
+ VOL32 BM_COMMAND;
+ VOL32 BM_STATUS;
+ VOL32 unused_164[10];
+ VOL32 BM_GUI_TABLE;
+ VOL32 BM_SYSTEM_TABLE;
+ VOL32 unused_170[5]; /* 0x170 */
+ VOL32 SCALER_BUF0_OFFSET_U;
+ VOL32 SCALER_BUF0_OFFSET_V;
+ VOL32 SCALER_BUF1_OFFSET_U;
+ VOL32 SCALER_BUF1_OFFSET_V;
+ VOL32 unused_179[7];
+ VOL32 unused_180[16]; /* 0x180 */
+ VOL32 setup_engine[0x40]; /* 0x190 */
+ VOL32 dvd_subpicture[0x30]; /* 0x1d0 */
+} MediaReg;
+
+#define MACH64_XY(x,y) (((x) & 0x7fff) | (((y) & 0x7fff) << 16))
+#define MACH64_YX(x,y) (((y) & 0x7fff) | (((x) & 0x7fff) << 16))
+
+typedef struct _mach64Save {
+ CARD32 LCD_GEN_CTRL;
+} Mach64Save;
+
+typedef struct _mach64CardInfo {
+ VesaCardPrivRec vesa;
+ CARD8 *reg_base;
+ Reg *reg;
+ MediaReg *media_reg;
+ Mach64Save save;
+ Bool lcdEnabled;
+} Mach64CardInfo;
+
+#define getMach64CardInfo(kd) ((Mach64CardInfo *) ((kd)->card->driver))
+#define mach64CardInfo(kd) Mach64CardInfo *mach64c = getMach64CardInfo(kd)
+
+typedef struct _mach64Cursor {
+ int width, height;
+ int xhot, yhot;
+ Bool has_cursor;
+ CursorPtr pCursor;
+ Pixel source, mask;
+} Mach64Cursor;
+
+#define MACH64_CURSOR_WIDTH 64
+#define MACH64_CURSOR_HEIGHT 64
+
+/*
+ * Xv information, optional
+ */
+typedef struct _mach64PortPriv {
+ CARD32 YBuf0Offset;
+
+ CARD32 YBuf1Offset;
+
+ CARD8 currentBuf;
+
+ int brightness;
+ int saturation;
+
+ RegionRec clip;
+ CARD32 colorKey;
+
+ Bool videoOn;
+ Time offTime;
+ Time freeTime;
+ CARD32 size;
+ CARD32 offset;
+} Mach64PortPrivRec, *Mach64PortPrivPtr;
+
+Bool mach64InitVideo(ScreenPtr pScreen);
+
+typedef struct _mach64ScreenInfo {
+ VesaScreenPrivRec vesa;
+ CARD8 *cursor_base;
+ CARD8 *screen;
+ CARD8 *off_screen;
+ int off_screen_size;
+ CARD32 DP_PIX_WIDTH;
+ CARD32 DP_SET_GUI_ENGINE;
+ CARD32 USR1_DST_OFF_PITCH;
+ Bool bpp24;
+ Mach64Cursor cursor;
+ CARD32 colorKey;
+ KdVideoAdaptorPtr pAdaptor;
+} Mach64ScreenInfo;
+
+#define getMach64ScreenInfo(kd) ((Mach64ScreenInfo *) ((kd)->screen->driver))
+#define mach64ScreenInfo(kd) Mach64ScreenInfo *mach64s = getMach64ScreenInfo(kd)
+
+CARD32
+mach64ReadLCD (Reg *reg, int id);
+
+void
+mach64WriteLCD (Reg *reg, int id, CARD32 data);
+
+void
+mach64Preserve (KdCardInfo *card);
+
+Bool
+mach64MapReg (KdCardInfo *card, Mach64CardInfo *mach64c);
+
+void
+mach64UnmapReg (KdCardInfo *card, Mach64CardInfo *mach64c);
+
+void
+mach64SetMMIO (KdCardInfo *card, Mach64CardInfo *mach64c);
+
+void
+mach64ResetMMIO (KdCardInfo *card, Mach64CardInfo *mach64c);
+
+Bool
+mach64Enable (ScreenPtr pScreen);
+
+void
+mach64Disable (ScreenPtr pScreen);
+
+void
+mach64WaitAvail(Reg *reg, int n);
+
+void
+mach64WaitIdle (Reg *reg);
+
+Bool
+mach64DrawSetup (ScreenPtr pScreen);
+
+Bool
+mach64DrawInit (ScreenPtr pScreen);
+
+void
+mach64DrawReinit (ScreenPtr pScreen);
+
+void
+mach64DrawEnable (ScreenPtr pScreen);
+
+void
+mach64DrawSync (ScreenPtr pScreen);
+
+void
+mach64DrawDisable (ScreenPtr pScreen);
+
+void
+mach64DrawFini (ScreenPtr pScreen);
+
+CARD8
+mach64ReadIndex (Mach64CardInfo *mach64c, CARD16 port, CARD8 index);
+
+void
+mach64WriteIndex (Mach64CardInfo *mach64c, CARD16 port, CARD8 index, CARD8 value);
+
+Bool
+mach64CursorInit (ScreenPtr pScreen);
+
+void
+mach64CursorEnable (ScreenPtr pScreen);
+
+void
+mach64CursorDisable (ScreenPtr pScreen);
+
+void
+mach64CursorFini (ScreenPtr pScreen);
+
+void
+mach64RecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdef);
+
+extern KdCardFuncs mach64Funcs;
+
+#endif /* _MACH64_H_ */
diff --git a/xc/programs/Xserver/hw/kdrive/mach64/mach64curs.c b/xc/programs/Xserver/hw/kdrive/mach64/mach64curs.c
new file mode 100644
index 000000000..fd0bdf76d
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/mach64/mach64curs.c
@@ -0,0 +1,389 @@
+/*
+ * Id: tridentcurs.c,v 1.1 1999/11/02 03:54:47 keithp Exp $
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64curs.c,v 1.1 2001/06/03 18:48:19 keithp 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, 0, pCursor,
+ &pCurPriv->source, &pCurPriv->mask);
+ switch (pScreenPriv->screen->fb[0].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 *) tridents->screen;
+ 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/mach64/mach64draw.c b/xc/programs/Xserver/hw/kdrive/mach64/mach64draw.c
new file mode 100644
index 000000000..6bd9d0d53
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/mach64/mach64draw.c
@@ -0,0 +1,420 @@
+/*
+ * Id: mach64draw.c,v 1.1 1999/11/02 03:54:47 keithp Exp $
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64draw.c,v 1.7 2001/07/24 19:06:03 keithp Exp $ */
+
+#include "mach64.h"
+#include "mach64draw.h"
+
+#include "Xmd.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "mistruct.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "fb.h"
+#include "migc.h"
+#include "miline.h"
+#include "picturestr.h"
+
+CARD8 mach64Rop[16] = {
+ /* GXclear */ 0x01, /* 0 */
+ /* GXand */ 0x0c, /* src AND dst */
+ /* GXandReverse */ 0x0d, /* src AND NOT dst */
+ /* GXcopy */ 0x07, /* src */
+ /* GXandInverted*/ 0x0e, /* NOT src AND dst */
+ /* GXnoop */ 0x03, /* dst */
+ /* GXxor */ 0x05, /* src XOR dst */
+ /* GXor */ 0x0b, /* src OR dst */
+ /* GXnor */ 0x0f, /* NOT src AND NOT dst */
+ /* GXequiv */ 0x06, /* NOT src XOR dst */
+ /* GXinvert */ 0x00, /* NOT dst */
+ /* GXorReverse */ 0x0a, /* src OR NOT dst */
+ /* GXcopyInverted*/ 0x04, /* NOT src */
+ /* GXorInverted */ 0x09, /* NOT src OR dst */
+ /* GXnand */ 0x08, /* NOT src OR NOT dst */
+ /* GXset */ 0x02, /* 1 */
+};
+
+#define MACH64_DRAW_COMBO_SOLID 0x1
+#define MACH64_DRAW_COMBO_COPY 0x8
+
+static Reg *reg;
+static CARD32 cmd;
+static CARD32 avail;
+static CARD32 triple;
+static CARD32 combo;
+
+#define IDX(reg,n) (&(reg)->n - &(reg)->CRTC_H_TOTAL_DISP)
+
+void
+mach64WaitAvail(Reg *reg, int n)
+{
+ if (avail < n)
+ {
+ while ((avail = ((reg->GUI_STAT) >> 16) & 0x3ff) < n)
+ ;
+ }
+ avail -= n;
+}
+
+void
+mach64WaitIdle (Reg *reg)
+{
+ while (reg->GUI_STAT & 1)
+ ;
+}
+
+static Bool
+mach64Setup (ScreenPtr pScreen, CARD32 combo, int wait)
+{
+ KdScreenPriv(pScreen);
+ mach64ScreenInfo(pScreenPriv);
+ mach64CardInfo(pScreenPriv);
+
+ avail = 0;
+ reg = mach64c->reg;
+ triple = mach64s->bpp24;
+ if (!reg)
+ return FALSE;
+
+ mach64WaitAvail(reg, wait + 3);
+ reg->DP_PIX_WIDTH = mach64s->DP_PIX_WIDTH;
+ reg->USR1_DST_OFF_PITCH = mach64s->USR1_DST_OFF_PITCH;
+ reg->DP_SET_GUI_ENGINE = mach64s->DP_SET_GUI_ENGINE | (combo << 20);
+ return TRUE;
+}
+
+Bool
+mach64PrepareSolid (DrawablePtr pDrawable,
+ int alu,
+ Pixel pm,
+ Pixel fg)
+{
+ if (!mach64Setup (pDrawable->pScreen, 1, 3))
+ return FALSE;
+ reg->DP_MIX = (mach64Rop[alu] << 16) | 0;
+ reg->DP_WRITE_MSK = pm;
+ reg->DP_FRGD_CLR = fg;
+ return TRUE;
+}
+
+void
+mach64Solid (int x1, int y1, int x2, int y2)
+{
+ if (triple)
+ {
+ CARD32 traj;
+
+ x1 *= 3;
+ x2 *= 3;
+
+ traj = (DST_X_DIR |
+ DST_Y_DIR |
+ DST_24_ROT_EN |
+ DST_24_ROT((x1 / 4) % 6));
+ mach64WaitAvail (reg, 1);
+ reg->GUI_TRAJ_CNTL = traj;
+ }
+ mach64WaitAvail(reg,2);
+ reg->DST_X_Y = MACH64_XY(x1,y1);
+ reg->DST_WIDTH_HEIGHT = MACH64_XY(x2-x1,y2-y1);
+}
+
+void
+mach64DoneSolid (void)
+{
+}
+
+static int copyDx;
+static int copyDy;
+
+Bool
+mach64PrepareCopy (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ int dx,
+ int dy,
+ int alu,
+ Pixel pm)
+{
+ CARD32 combo = 8;
+
+ if ((copyDx = dx) > 0)
+ combo |= 1;
+ if ((copyDy = dy) > 0)
+ combo |= 2;
+ if (!mach64Setup (pDstDrawable->pScreen, combo, 2))
+ return FALSE;
+
+ reg->DP_MIX = (mach64Rop[alu] << 16) | 0;
+ reg->DP_WRITE_MSK = pm;
+ return TRUE;
+}
+
+void
+mach64Copy (int srcX,
+ int srcY,
+ int dstX,
+ int dstY,
+ int w,
+ int h)
+{
+ if (triple)
+ {
+ CARD32 traj;
+
+ srcX *= 3;
+ dstX *= 3;
+ w *= 3;
+
+ traj = DST_24_ROT_EN | DST_24_ROT((dstX / 4) % 6);
+
+ if (copyDx > 0)
+ traj |= 1;
+ if (copyDy > 0)
+ traj |= 2;
+
+ mach64WaitAvail (reg, 1);
+ reg->GUI_TRAJ_CNTL = traj;
+ }
+ if (copyDx <= 0)
+ {
+ srcX += w - 1;
+ dstX += w - 1;
+ }
+ if (copyDy <= 0)
+ {
+ srcY += h - 1;
+ dstY += h - 1;
+ }
+ mach64WaitAvail (reg, 4);
+ reg->SRC_Y_X = MACH64_YX(srcX, srcY);
+ reg->SRC_WIDTH1 = w;
+ reg->DST_Y_X = MACH64_YX(dstX, dstY);
+ reg->DST_HEIGHT_WIDTH = MACH64_YX(w,h);
+}
+
+void
+mach64DoneCopy (void)
+{
+}
+
+KaaScreenPrivRec mach64Kaa = {
+ mach64PrepareSolid,
+ mach64Solid,
+ mach64DoneSolid,
+
+ mach64PrepareCopy,
+ mach64Copy,
+ mach64DoneCopy,
+};
+
+Bool
+mach64DrawInit (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+
+ if (pScreenPriv->screen->fb[0].depth == 4)
+ return FALSE;
+
+ if (!kaaDrawInit (pScreen, &mach64Kaa))
+ return FALSE;
+
+ return TRUE;
+}
+
+#define PIX_FORMAT_MONO 0
+#define PIX_FORMAT_PSEUDO_8 2
+#define PIX_FORMAT_TRUE_1555 3
+#define PIX_FORMAT_TRUE_565 4
+#define PIX_FORMAT_TRUE_8888 6
+#define PIX_FORMAT_TRUE_332 7
+#define PIX_FORMAT_GRAY_8 8
+#define PIX_FORMAT_YUV_422 0xb
+#define PIX_FORMAT_YUV_444 0xe
+#define PIX_FORMAT_TRUE_4444 0xf
+
+void
+mach64DrawEnable (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ mach64ScreenInfo(pScreenPriv);
+ CARD32 DP_PIX_WIDTH;
+ CARD32 DP_SET_GUI_ENGINE;
+ CARD32 SET_DP_DST_PIX_WIDTH;
+ CARD32 DST1_PITCH;
+
+ mach64s->bpp24 = FALSE;
+ switch (pScreenPriv->screen->fb[0].depth) {
+ case 1:
+ DP_PIX_WIDTH = ((PIX_FORMAT_MONO << 0) | /* DP_DST_PIX_WIDTH */
+ (PIX_FORMAT_TRUE_8888 << 4) | /* COMPOSITE_PIX_WIDTH */
+ (PIX_FORMAT_MONO << 8) | /* DP_SRC_PIX_WIDTH */
+ (0 << 13) | /* DP_HOST_TRIPLE_EN */
+ (0 << 14) | /* DP_PALETTE_TYPE */
+ (PIX_FORMAT_MONO << 16) | /* DP_HOST_PIX_WIDTH */
+ (0 << 20) | /* DP_C14_RGB_INDEX */
+ (0 << 24) | /* DP_BYTE_PIX_ORDER */
+ (0 << 25) | /* DP_CONVERSION_TEMP */
+ (0 << 26) | /* DP_C14_RGB_LOW_NIBBLE */
+ (0 << 27) | /* DP_C14_RGB_HIGH_NIBBLE */
+ (PIX_FORMAT_TRUE_8888 << 28) | /* DP_SCALE_PIX_WIDTH */
+ 0);
+ SET_DP_DST_PIX_WIDTH = PIX_FORMAT_MONO;
+ break;
+ case 4:
+ FatalError ("mach64 can't accelerate 4bpp");
+ break;
+ case 8:
+ DP_PIX_WIDTH = ((PIX_FORMAT_PSEUDO_8 << 0) | /* DP_DST_PIX_WIDTH */
+ (PIX_FORMAT_TRUE_8888 << 4) | /* COMPOSITE_PIX_WIDTH */
+ (PIX_FORMAT_PSEUDO_8 << 8) | /* DP_SRC_PIX_WIDTH */
+ (0 << 13) | /* DP_HOST_TRIPLE_EN */
+ (0 << 14) | /* DP_PALETTE_TYPE */
+ (PIX_FORMAT_PSEUDO_8 << 16) | /* DP_HOST_PIX_WIDTH */
+ (0 << 20) | /* DP_C14_RGB_INDEX */
+ (0 << 24) | /* DP_BYTE_PIX_ORDER */
+ (0 << 25) | /* DP_CONVERSION_TEMP */
+ (0 << 26) | /* DP_C14_RGB_LOW_NIBBLE */
+ (0 << 27) | /* DP_C14_RGB_HIGH_NIBBLE */
+ (PIX_FORMAT_TRUE_8888 << 28) | /* DP_SCALE_PIX_WIDTH */
+ 0);
+ SET_DP_DST_PIX_WIDTH = PIX_FORMAT_PSEUDO_8;
+ break;
+ case 15:
+ DP_PIX_WIDTH = ((PIX_FORMAT_TRUE_1555 << 0) | /* DP_DST_PIX_WIDTH */
+ (PIX_FORMAT_TRUE_8888 << 4) | /* COMPOSITE_PIX_WIDTH */
+ (PIX_FORMAT_TRUE_1555 << 8) | /* DP_SRC_PIX_WIDTH */
+ (0 << 13) | /* DP_HOST_TRIPLE_EN */
+ (0 << 14) | /* DP_PALETTE_TYPE */
+ (PIX_FORMAT_TRUE_1555 << 16) | /* DP_HOST_PIX_WIDTH */
+ (0 << 20) | /* DP_C14_RGB_INDEX */
+ (0 << 24) | /* DP_BYTE_PIX_ORDER */
+ (0 << 25) | /* DP_CONVERSION_TEMP */
+ (0 << 26) | /* DP_C14_RGB_LOW_NIBBLE */
+ (0 << 27) | /* DP_C14_RGB_HIGH_NIBBLE */
+ (PIX_FORMAT_TRUE_8888 << 28) | /* DP_SCALE_PIX_WIDTH */
+ 0);
+ SET_DP_DST_PIX_WIDTH = PIX_FORMAT_TRUE_1555;
+ break;
+ case 16:
+ DP_PIX_WIDTH = ((PIX_FORMAT_TRUE_565 << 0) | /* DP_DST_PIX_WIDTH */
+ (PIX_FORMAT_TRUE_8888 << 4) | /* COMPOSITE_PIX_WIDTH */
+ (PIX_FORMAT_TRUE_565 << 8) | /* DP_SRC_PIX_WIDTH */
+ (0 << 13) | /* DP_HOST_TRIPLE_EN */
+ (0 << 14) | /* DP_PALETTE_TYPE */
+ (PIX_FORMAT_TRUE_565 << 16) | /* DP_HOST_PIX_WIDTH */
+ (0 << 20) | /* DP_C14_RGB_INDEX */
+ (0 << 24) | /* DP_BYTE_PIX_ORDER */
+ (0 << 25) | /* DP_CONVERSION_TEMP */
+ (0 << 26) | /* DP_C14_RGB_LOW_NIBBLE */
+ (0 << 27) | /* DP_C14_RGB_HIGH_NIBBLE */
+ (PIX_FORMAT_TRUE_8888 << 28) | /* DP_SCALE_PIX_WIDTH */
+ 0);
+ SET_DP_DST_PIX_WIDTH = PIX_FORMAT_TRUE_565;
+ break;
+ case 24:
+ if (pScreenPriv->screen->fb[0].bitsPerPixel == 24)
+ {
+ mach64s->bpp24 = TRUE;
+ DP_PIX_WIDTH = ((PIX_FORMAT_PSEUDO_8 << 0) | /* DP_DST_PIX_WIDTH */
+ (PIX_FORMAT_PSEUDO_8 << 4) | /* COMPOSITE_PIX_WIDTH */
+ (PIX_FORMAT_PSEUDO_8 << 8) | /* DP_SRC_PIX_WIDTH */
+ (0 << 13) | /* DP_HOST_TRIPLE_EN */
+ (0 << 14) | /* DP_PALETTE_TYPE */
+ (PIX_FORMAT_PSEUDO_8 << 16) | /* DP_HOST_PIX_WIDTH */
+ (0 << 20) | /* DP_C14_RGB_INDEX */
+ (0 << 24) | /* DP_BYTE_PIX_ORDER */
+ (0 << 25) | /* DP_CONVERSION_TEMP */
+ (0 << 26) | /* DP_C14_RGB_LOW_NIBBLE */
+ (0 << 27) | /* DP_C14_RGB_HIGH_NIBBLE */
+ (PIX_FORMAT_TRUE_8888 << 28) | /* DP_SCALE_PIX_WIDTH */
+ 0);
+ SET_DP_DST_PIX_WIDTH = PIX_FORMAT_PSEUDO_8;
+ }
+ else
+ {
+ DP_PIX_WIDTH = ((PIX_FORMAT_TRUE_8888 << 0) | /* DP_DST_PIX_WIDTH */
+ (PIX_FORMAT_TRUE_8888 << 4) | /* COMPOSITE_PIX_WIDTH */
+ (PIX_FORMAT_TRUE_8888 << 8) | /* DP_SRC_PIX_WIDTH */
+ (0 << 13) | /* DP_HOST_TRIPLE_EN */
+ (0 << 14) | /* DP_PALETTE_TYPE */
+ (PIX_FORMAT_TRUE_8888 << 16) | /* DP_HOST_PIX_WIDTH */
+ (0 << 20) | /* DP_C14_RGB_INDEX */
+ (0 << 24) | /* DP_BYTE_PIX_ORDER */
+ (0 << 25) | /* DP_CONVERSION_TEMP */
+ (0 << 26) | /* DP_C14_RGB_LOW_NIBBLE */
+ (0 << 27) | /* DP_C14_RGB_HIGH_NIBBLE */
+ (PIX_FORMAT_TRUE_8888 << 28) | /* DP_SCALE_PIX_WIDTH */
+ 0);
+ SET_DP_DST_PIX_WIDTH = PIX_FORMAT_TRUE_8888;
+ }
+ break;
+ }
+
+ mach64s->DP_PIX_WIDTH = DP_PIX_WIDTH;
+ DST1_PITCH = (pScreenPriv->screen->fb[0].pixelStride) >> 3;
+ if (mach64s->bpp24)
+ DST1_PITCH *= 3;
+ mach64s->USR1_DST_OFF_PITCH = ((0 << 0) | /* USR1_DST_OFFSET */
+ (DST1_PITCH << 22) | /* USR1_DST_PITCH */
+ 0);
+ mach64s->DP_SET_GUI_ENGINE = ((SET_DP_DST_PIX_WIDTH << 3) |
+ (1 << 6) | /* SET_DP_SRC_PIX_WIDTH */
+ (0 << 7) | /* SET_DST_OFFSET */
+ (0 << 10) | /* SET_DST_PITCH */
+ (0 << 14) | /* SET_DST_PITCH_BY_2 */
+ (1 << 15) | /* SET_SRC_OFFPITCH_COPY */
+ (0 << 16) | /* SET_SRC_HGTWID1_2 */
+ (0 << 20) | /* SET_DRAWING_COMBO */
+ (1 << 24) | /* SET_BUS_MASTER_OP */
+ (0 << 26) | /* SET_BUS_MASTER_EN */
+ (0 << 27) | /* SET_BUS_MASTER_SYNC */
+ (0 << 28) | /* DP_HOST_TRIPLE_EN */
+ (0 << 29) | /* FAST_FILL_EN */
+ (0 << 30) | /* BLOCK_WRITE_EN */
+ 0);
+ KdMarkSync (pScreen);
+}
+
+void
+mach64DrawDisable (ScreenPtr pScreen)
+{
+}
+
+void
+mach64DrawFini (ScreenPtr pScreen)
+{
+}
+
+void
+mach64DrawSync (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ mach64CardInfo(pScreenPriv);
+ reg = mach64c->reg;
+
+ mach64WaitIdle (reg);
+}
diff --git a/xc/programs/Xserver/hw/kdrive/mach64/mach64draw.h b/xc/programs/Xserver/hw/kdrive/mach64/mach64draw.h
new file mode 100644
index 000000000..1a7e4cf73
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/mach64/mach64draw.h
@@ -0,0 +1,72 @@
+/*
+ * Id: tridentdraw.h,v 1.1 1999/11/02 03:54:47 keithp Exp $
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64draw.h,v 1.1 2001/06/03 18:48:19 keithp Exp $ */
+
+#ifndef _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); \
+ _tridentWaitDone(cop); \
+ (cop)->command = (cmd); \
+}
+
+#define COP_STATUS_BUSY (COP_STATUS_BE_BUSY | \
+ COP_STATUS_DPE_BUSY | \
+ COP_STATUS_MI_BUSY)
+
+#define _tridentWaitDone(cop) { \
+ int __q__ = 500000; \
+ while (__q__-- && (cop)->status & COP_STATUS_BUSY) \
+ ; \
+ if (!__q__) \
+ (cop)->status = 0; \
+}
+
+#define _tridentWaitIdleEmpty(cop) _tridentWaitDone(cop)
+
+#define sourceInvarient(alu) (((alu) & 3) == (((alu) >> 2) & 3))
+
+#endif
diff --git a/xc/programs/Xserver/hw/kdrive/mach64/mach64stub.c b/xc/programs/Xserver/hw/kdrive/mach64/mach64stub.c
new file mode 100644
index 000000000..730275b92
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/mach64/mach64stub.c
@@ -0,0 +1,58 @@
+/*
+ * Id: mach64stub.c,v 1.1 1999/11/02 08:19:15 keithp Exp $
+ *
+ * Copyright 1999 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64stub.c,v 1.1 2001/06/03 18:48:19 keithp Exp $ */
+
+#include "mach64.h"
+
+void
+InitCard (char *name)
+{
+ KdCardAttr attr;
+
+ if (LinuxFindPci (0x1002, 0x4c4d, 0, &attr))
+ KdCardInfoAdd (&mach64Funcs, &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)
+{
+ int ret;
+
+ if (!(ret = vesaProcessArgument (argc, argv, i)))
+ ret = KdProcessArgument(argc, argv, i);
+ return ret;
+}
diff --git a/xc/programs/Xserver/hw/kdrive/mach64/mach64video.c b/xc/programs/Xserver/hw/kdrive/mach64/mach64video.c
new file mode 100644
index 000000000..13b83a7f5
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/mach64/mach64video.c
@@ -0,0 +1,1045 @@
+/*
+ * Copyright © 2001 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64video.c,v 1.7 2001/08/09 09:08:55 keithp Exp $ */
+#include "mach64.h"
+
+#include "Xv.h"
+#include "../../xfree86/common/fourcc.h"
+
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+static Atom xvBrightness, xvSaturation, xvColorKey;
+
+#define IMAGE_MAX_WIDTH 720
+#define IMAGE_MAX_HEIGHT 576
+
+static void
+mach64StopVideo(KdScreenInfo *screen, pointer data, Bool exit)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ KdScreenPriv(pScreen);
+ KdCardInfo *card = pScreenPriv->card;
+ Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
+ Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver;
+ Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr;
+ Reg *reg = mach64c->reg;
+ MediaReg *media = mach64c->media_reg;
+
+ REGION_EMPTY(screen->pScreen, &pPortPriv->clip);
+
+ if (!media)
+ return;
+
+ if(pPortPriv->videoOn)
+ {
+ mach64WaitIdle (reg);
+ /* wait for buffer to be displayed */
+ while (((media->TRIG_CNTL >> 5) & 1) != pPortPriv->currentBuf)
+ ;
+ /* wait for buffer to be finished */
+ while (((media->TRIG_CNTL >> 6) & 1) != 0)
+ ;
+ mach64WaitAvail (reg, 1);
+ media->OVERLAY_SCALE_CNTL = 0;
+ pPortPriv->videoOn = FALSE;
+ mach64WaitIdle (reg);
+ }
+}
+
+static int
+mach64SetPortAttribute(KdScreenInfo *screen,
+ Atom attribute,
+ int value,
+ pointer data)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ KdScreenPriv(pScreen);
+ KdCardInfo *card = pScreenPriv->card;
+ Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
+ Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver;
+ Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr;
+ MediaReg *media = mach64c->media_reg;
+
+ if(attribute == xvBrightness)
+ {
+ if(value < -1000)
+ value = -1000;
+ if (value > 1000)
+ value = 1000;
+ pPortPriv->brightness = value;
+ }
+ else if(attribute == xvSaturation)
+ {
+ if (value < -1000)
+ value = -1000;
+ if (value > 1000)
+ value = 1000;
+ pPortPriv->saturation = value;
+ }
+ else if(attribute == xvColorKey)
+ {
+ if (pPortPriv->colorKey != value)
+ {
+ pPortPriv->colorKey = value;
+ REGION_EMPTY(screen->pScreen, &pPortPriv->clip);
+ }
+ }
+ else
+ return BadMatch;
+
+ return Success;
+}
+
+static int
+mach64GetPortAttribute(KdScreenInfo *screen,
+ Atom attribute,
+ int *value,
+ pointer data)
+{
+ Mach64PortPrivPtr pPortPriv = (Mach64PortPrivPtr)data;
+
+ if(attribute == xvBrightness)
+ *value = pPortPriv->brightness;
+ else if(attribute == xvSaturation)
+ *value = pPortPriv->saturation;
+ else if(attribute == xvColorKey)
+ *value = pPortPriv->colorKey;
+ else
+ return BadMatch;
+
+ return Success;
+}
+
+static void
+mach64QueryBestSize(KdScreenInfo *screen,
+ Bool motion,
+ short vid_w,
+ short vid_h,
+ short drw_w,
+ short drw_h,
+ unsigned int *p_w,
+ unsigned int *p_h,
+ pointer data)
+{
+ *p_w = drw_w;
+ *p_h = drw_h;
+}
+
+
+static void
+mach64CopyPackedData(KdScreenInfo *screen,
+ unsigned char *buf,
+ int rotate,
+ int srcPitch,
+ int dstPitch,
+ int srcW,
+ int srcH,
+ int top,
+ int left,
+ int h,
+ int w)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ KdScreenPriv(pScreen);
+ KdCardInfo *card = pScreenPriv->card;
+ Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
+ Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver;
+ Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr;
+ CARD8 *src, *dst;
+ int srcDown, srcRight, srcNext;
+ int p;
+
+ switch (rotate) {
+ case 0:
+ src = buf;
+ srcDown = srcPitch;
+ srcRight = 2;
+ break;
+ case 90:
+ src = src + (srcH - 1) * 2;
+ srcDown = -2;
+ srcRight = srcPitch;
+ break;
+ case 180:
+ src = src + srcPitch * (srcH - 1) + (srcW - 1) * 2;
+ srcDown = -srcPitch;
+ srcRight = -2;
+ break;
+ case 270:
+ src = src + srcPitch * (srcW - 1);
+ srcDown = 2;
+ srcRight = -srcPitch;
+ break;
+ }
+
+ src = src + top*srcDown + left*srcRight;
+
+ if (pPortPriv->currentBuf == 0)
+ dst = (CARD8 *) mach64s->vesa.fb + pPortPriv->YBuf0Offset;
+ else
+ dst = (CARD8 *) mach64s->vesa.fb + pPortPriv->YBuf1Offset;
+
+ w >>= 1;
+ srcRight >>= 1;
+ srcNext = srcRight >> 1;
+ while(h--)
+ {
+ CARD16 *s = (CARD16 *) src;
+ CARD32 *d = (CARD32 *) dst;
+ p = w;
+ while (p--)
+ {
+ *d++ = s[0] | (s[srcNext] << 16);
+ s += srcRight;
+ }
+ src += srcPitch;
+ dst += dstPitch;
+ }
+}
+
+static void
+mach64CopyPlanarData(KdScreenInfo *screen,
+ unsigned char *buf,
+ int rotate,
+ int srcPitch,
+ int srcPitch2,
+ int dstPitch, /* of chroma */
+ int srcW,
+ int srcH,
+ int height,
+ int top,
+ int left,
+ int h,
+ int w,
+ int id)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ KdScreenPriv(pScreen);
+ KdCardInfo *card = pScreenPriv->card;
+ Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
+ Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver;
+ Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr;
+ int i, j;
+ CARD8 *src1, *src2, *src3, *dst1;
+ int srcDown, srcDown2, srcRight, srcRight2, srcNext;
+
+ /* compute source data pointers */
+ src1 = buf;
+ src2 = src1 + height * srcPitch;
+ src3 = src2 + (height >> 1) * srcPitch2;
+ switch (rotate) {
+ case 0:
+ srcDown = srcPitch;
+ srcDown2 = srcPitch2;
+ srcRight = 2;
+ srcRight2 = 1;
+ srcNext = 1;
+ break;
+ case 90:
+ src1 = src1 + srcH - 1;
+ src2 = src2 + (srcH >> 1) - 1;
+ src3 = src3 + (srcH >> 1) - 1;
+ srcDown = -1;
+ srcDown2 = -1;
+ srcRight = srcPitch * 2;
+ srcRight2 = srcPitch2;
+ srcNext = srcPitch;
+ break;
+ case 180:
+ src1 = src1 + srcPitch * (srcH - 1) + (srcW - 1);
+ src2 = src2 + srcPitch2 * ((srcH >> 1) - 1) + ((srcW >> 1) - 1);
+ src3 = src3 + srcPitch2 * ((srcH >> 1) - 1) + ((srcW >> 1) - 1);
+ srcDown = -srcPitch;
+ srcDown2 = -srcPitch2;
+ srcRight = -2;
+ srcRight2 = -1;
+ srcNext = -1;
+ break;
+ case 270:
+ src1 = src1 + srcPitch * (srcW - 1);
+ src2 = src2 + srcPitch2 * ((srcW >> 1) - 1);
+ src3 = src3 + srcPitch2 * ((srcW >> 1) - 1);
+ srcDown = 1;
+ srcDown2 = 1;
+ srcRight = -srcPitch * 2;
+ srcRight2 = -srcPitch2;
+ srcNext = -srcPitch;
+ break;
+ }
+
+ /* adjust for origin */
+ src1 += top * srcDown + left * srcNext;
+ src2 += (top >> 1) * srcDown2 + (left >> 1) * srcRight2;
+ src3 += (top >> 1) * srcDown2 + (left >> 1) * srcRight2;
+
+ if (id == FOURCC_I420)
+ {
+ CARD8 *srct = src2;
+ src2 = src3;
+ src3 = srct;
+ }
+
+ if (pPortPriv->currentBuf == 0)
+ dst1 = (CARD8 *) mach64s->vesa.fb + pPortPriv->YBuf0Offset;
+ else
+ dst1 = (CARD8 *) mach64s->vesa.fb + pPortPriv->YBuf1Offset;
+
+ w >>= 1;
+ for (j = 0; j < h; j++)
+ {
+ CARD32 *dst = (CARD32 *) dst1;
+ CARD8 *s1l = src1;
+ CARD8 *s1r = src1 + srcNext;
+ CARD8 *s2 = src2;
+ CARD8 *s3 = src3;
+
+ for (i = 0; i < w; i++)
+ {
+ *dst++ = *s1l | (*s1r << 16) | (*s3 << 8) | (*s2 << 24);
+ s1l += srcRight;
+ s1r += srcRight;
+ s2 += srcRight2;
+ s3 += srcRight2;
+ }
+ src1 += srcDown;
+ dst1 += dstPitch;
+ if (j & 1)
+ {
+ src2 += srcDown2;
+ src3 += srcDown2;
+ }
+ }
+}
+
+/* I really should stick this in miregion */
+static Bool
+RegionsEqual(RegionPtr A, RegionPtr B)
+{
+ int *dataA, *dataB;
+ int num;
+
+ num = REGION_NUM_RECTS(A);
+ if(num != REGION_NUM_RECTS(B))
+ return FALSE;
+
+ if((A->extents.x1 != B->extents.x1) ||
+ (A->extents.x2 != B->extents.x2) ||
+ (A->extents.y1 != B->extents.y1) ||
+ (A->extents.y2 != B->extents.y2))
+ return FALSE;
+
+ dataA = (int*)REGION_RECTS(A);
+ dataB = (int*)REGION_RECTS(B);
+
+ while(num--) {
+ if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))
+ return FALSE;
+ dataA += 2;
+ dataB += 2;
+ }
+
+ return TRUE;
+}
+
+static void
+mach64PaintRegion (ScreenPtr pScreen, RegionPtr pRgn, Pixel fg)
+{
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+ GCPtr pGC;
+ CARD32 val[2];
+ xRectangle *rects, *r;
+ BoxPtr pBox = REGION_RECTS (pRgn);
+ int nBox = REGION_NUM_RECTS (pRgn);
+
+ rects = ALLOCATE_LOCAL (nBox * sizeof (xRectangle));
+ if (!rects)
+ goto bail0;
+ r = rects;
+ while (nBox--)
+ {
+ r->x = pBox->x1;
+ r->y = pBox->y1;
+ r->width = pBox->x2 - pBox->x1;
+ r->height = pBox->y2 - pBox->y1;
+ r++;
+ pBox++;
+ }
+
+ pGC = GetScratchGC (pRoot->drawable.depth, pScreen);
+ if (!pGC)
+ goto bail1;
+
+ val[0] = fg;
+ val[1] = IncludeInferiors;
+ ChangeGC (pGC, GCForeground|GCSubwindowMode, val);
+
+ ValidateGC (&pRoot->drawable, pGC);
+
+ (*pGC->ops->PolyFillRect) (&pRoot->drawable, pGC,
+ REGION_NUM_RECTS (pRgn), rects);
+
+ FreeScratchGC (pGC);
+bail1:
+ DEALLOCATE_LOCAL (rects);
+bail0:
+ ;
+}
+
+/* Mach64ClipVideo -
+
+ Takes the dst box in standard X BoxRec form (top and left
+ edges inclusive, bottom and right exclusive). The new dst
+ box is returned. The source boundaries are given (x1, y1
+ inclusive, x2, y2 exclusive) and returned are the new source
+ boundaries in 16.16 fixed point.
+*/
+
+static void
+Mach64ClipVideo(BoxPtr dst,
+ INT32 *x1,
+ INT32 *x2,
+ INT32 *y1,
+ INT32 *y2,
+ BoxPtr extents, /* extents of the clip region */
+ INT32 width,
+ INT32 height)
+{
+ INT32 vscale, hscale, delta;
+ int diff;
+
+ hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1);
+ vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1);
+
+ *x1 <<= 16; *x2 <<= 16;
+ *y1 <<= 16; *y2 <<= 16;
+
+ diff = extents->x1 - dst->x1;
+ if(diff > 0) {
+ dst->x1 = extents->x1;
+ *x1 += diff * hscale;
+ }
+ diff = dst->x2 - extents->x2;
+ if(diff > 0) {
+ dst->x2 = extents->x2;
+ *x2 -= diff * hscale;
+ }
+ diff = extents->y1 - dst->y1;
+ if(diff > 0) {
+ dst->y1 = extents->y1;
+ *y1 += diff * vscale;
+ }
+ diff = dst->y2 - extents->y2;
+ if(diff > 0) {
+ dst->y2 = extents->y2;
+ *y2 -= diff * vscale;
+ }
+
+ if(*x1 < 0) {
+ diff = (- *x1 + hscale - 1)/ hscale;
+ dst->x1 += diff;
+ *x1 += diff * hscale;
+ }
+ delta = *x2 - (width << 16);
+ if(delta > 0) {
+ diff = (delta + hscale - 1)/ hscale;
+ dst->x2 -= diff;
+ *x2 -= diff * hscale;
+ }
+ if(*y1 < 0) {
+ diff = (- *y1 + vscale - 1)/ vscale;
+ dst->y1 += diff;
+ *y1 += diff * vscale;
+ }
+ delta = *y2 - (height << 16);
+ if(delta > 0) {
+ diff = (delta + vscale - 1)/ vscale;
+ dst->y2 -= diff;
+ *y2 -= diff * vscale;
+ }
+}
+
+static void
+mach64DisplayVideo(KdScreenInfo *screen,
+ int id,
+ int dstPitch, /* of chroma for 4:2:0 */
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ int dst_x1,
+ int dst_y1,
+ int dst_x2,
+ int dst_y2,
+ short src_w,
+ short src_h,
+ short drw_w,
+ short drw_h)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ KdScreenPriv(pScreen);
+ KdCardInfo *card = pScreenPriv->card;
+ Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
+ Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver;
+ Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr;
+ Reg *reg = mach64c->reg;
+ MediaReg *media = mach64c->media_reg;
+ int xscaleInt, xscaleFract, yscaleInt, yscaleFract;
+ int xscaleIntUV = 0, xscaleFractUV = 0;
+ int yscaleIntUV = 0, yscaleFractUV = 0;
+ int rotate = mach64s->vesa.rotate;
+ int HORZ_INC, VERT_INC;
+ CARD32 SCALER_IN;
+ CARD32 OVERLAY_SCALE_CNTL;
+ int tmp;
+ int left;
+ int bright;
+ int sat;
+
+ if (id == FOURCC_UYVY)
+ SCALER_IN = SCALER_IN_YVYU422;
+ else
+ SCALER_IN = SCALER_IN_VYUY422;
+
+ mach64WaitAvail (reg, 4);
+
+ media->VIDEO_FORMAT = SCALER_IN | VIDEO_IN_VYUY422;
+
+ /* color key */
+ media->OVERLAY_GRAPHICS_KEY_MSK = (1 << screen->fb[0].depth) - 1;
+ media->OVERLAY_GRAPHICS_KEY_CLR = pPortPriv->colorKey;
+ /* set key control to obey only graphics color key */
+ media->OVERLAY_KEY_CNTL = 0x50;
+
+ mach64WaitAvail (reg, 9);
+ media->CAPTURE_DEBUG = 0;
+ /* no exclusive video region */
+ media->OVERLAY_EXCLUSIVE_HORZ = 0;
+ media->OVERLAY_EXCLUSIVE_VERT = 0;
+ /* scaling coefficients */
+ media->SCALER_H_COEFF0 = 0x00002000;
+ media->SCALER_H_COEFF1 = 0x0D06200D;
+ media->SCALER_H_COEFF2 = 0x0D0A1C0D;
+ media->SCALER_H_COEFF3 = 0x0C0E1A0C;
+ media->SCALER_H_COEFF4 = 0x0C14140C;
+ media->SCALER_TEST = 0;
+
+ mach64WaitAvail (reg, 2);
+ media->OVERLAY_SCALE_CNTL = (SCALE_PIX_EXPAND |
+ SCALE_GAMMA_BRIGHT |
+ SCALE_BANDWIDTH |
+ SCALE_OVERLAY_EN |
+ SCALE_EN);
+
+ bright = (pPortPriv->brightness * 64 / 1000);
+ if (bright < -0x40)
+ bright = -0x40;
+ if (bright > 0x3f)
+ bright = 0x3f;
+ bright = bright & 0x7f;
+ sat = ((pPortPriv->saturation * 31 + 31000) / 2000);
+ if (sat > 0x1f)
+ sat = 0x1f;
+ if (sat < 0)
+ sat = 0;
+
+ media->SCALER_COLOUR_CNTL = ((bright << 0) | /* BRIGHTNESS */
+ (sat << 8) | /* SATURATION_U */
+ (sat << 16) | /* SATURATION_V */
+ (0 << 21) | /* SCALER_VERT_ADJ_UV */
+ (0 << 28)); /* SCALER_HORZ_ADJ_UV */
+
+ VERT_INC = (src_h << 12) / drw_h;
+ HORZ_INC = (src_w << 12) / drw_w;
+
+ mach64WaitAvail (reg, 13);
+
+ /* lock registers to prevent non-atomic update */
+ media->OVERLAY_Y_X_START = 0x80000000 | MACH64_YX (dst_x1, dst_y1);
+ /* ending screen coordinate */
+ media->OVERLAY_Y_X_END = 0x80000000 | MACH64_YX (dst_x2, dst_y2);
+
+ media->OVERLAY_SCALE_INC = MACH64_YX(HORZ_INC, VERT_INC);
+
+ media->SCALER_BUF0_OFFSET = pPortPriv->YBuf0Offset;
+ media->SCALER_BUF1_OFFSET = pPortPriv->YBuf1Offset;
+
+ media->SCALER_BUF0_OFFSET_U = pPortPriv->YBuf0Offset;
+ media->SCALER_BUF1_OFFSET_U = pPortPriv->YBuf1Offset;
+
+ media->SCALER_BUF0_OFFSET_V = pPortPriv->YBuf0Offset;
+ media->SCALER_BUF1_OFFSET_V = pPortPriv->YBuf1Offset;
+
+ media->SCALER_BUF_PITCH = dstPitch >> 1;
+ media->SCALER_HEIGHT_WIDTH = MACH64_YX(src_w - (x1 >> 16), src_h - (y1 >> 16));
+
+ media->CAPTURE_CONFIG = pPortPriv->currentBuf << 28;
+
+ /* set XY location and unlock */
+ media->OVERLAY_Y_X_START = MACH64_YX (dst_x1, dst_y1);
+}
+
+static int
+mach64PutImage(KdScreenInfo *screen,
+ short src_x,
+ short src_y,
+ short drw_x,
+ short drw_y,
+ short src_w,
+ short src_h,
+ short drw_w,
+ short drw_h,
+ int id,
+ unsigned char *buf,
+ short width,
+ short height,
+ Bool sync,
+ RegionPtr clipBoxes,
+ pointer data)
+{
+ KdCardInfo *card = screen->card;
+ Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
+ Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver;
+ Mach64PortPrivPtr pPortPriv = (Mach64PortPrivPtr)data;
+ Reg *reg = mach64c->reg;
+ MediaReg *media = mach64c->media_reg;
+ INT32 x1, x2, y1, y2;
+ int rotate = mach64s->vesa.rotate;
+ int srcPitch, srcPitch2, dstPitch;
+ int top, left, npixels, nlines, size;
+ BoxRec dstBox;
+ int dst_width = width, dst_height = height;
+ int rot_x1, rot_y1, rot_x2, rot_y2;
+ int dst_x1, dst_y1, dst_x2, dst_y2;
+ int rot_src_w, rot_src_h, rot_drw_w, rot_drw_h;
+
+ /* Clip */
+ x1 = src_x;
+ x2 = src_x + src_w;
+ y1 = src_y;
+ y2 = src_y + src_h;
+
+ dstBox.x1 = drw_x;
+ dstBox.x2 = drw_x + drw_w;
+ dstBox.y1 = drw_y;
+ dstBox.y2 = drw_y + drw_h;
+
+ Mach64ClipVideo(&dstBox, &x1, &x2, &y1, &y2,
+ REGION_EXTENTS(pScreen, clipBoxes), width, height);
+
+ if((x1 >= x2) || (y1 >= y2))
+ return Success;
+
+ if (!media)
+ return BadAlloc;
+
+ switch (rotate) {
+ case 0:
+ case 180:
+ dst_width = width;
+ dst_height = height;
+ rot_src_w = src_w;
+ rot_src_h = src_h;
+ rot_drw_w = drw_w;
+ rot_drw_h = drw_h;
+ break;
+ case 90:
+ case 270:
+ dst_width = height;
+ dst_height = width;
+ rot_src_w = src_h;
+ rot_src_h = src_w;
+ rot_drw_w = drw_h;
+ rot_drw_h = drw_w;
+ break;
+ }
+
+ switch (rotate) {
+ case 0:
+ dst_x1 = dstBox.x1;
+ dst_y1 = dstBox.y1;
+ dst_x2 = dstBox.x2;
+ dst_y2 = dstBox.y2;
+ rot_x1 = x1;
+ rot_y1 = y1;
+ rot_x2 = x2;
+ rot_y2 = y2;
+ break;
+ case 90:
+ dst_x1 = dstBox.y1;
+ dst_y1 = screen->height - dstBox.x2;
+ dst_x2 = dstBox.y2;
+ dst_y2 = screen->height - dstBox.x1;
+
+ rot_x1 = y1;
+ rot_y1 = (src_w << 16) - x2;
+ rot_x2 = y2;
+ rot_y2 = (src_w << 16) - x1;
+ break;
+ case 180:
+ dst_x1 = screen->width - dstBox.x2;
+ dst_y1 = screen->height - dstBox.y2;
+ dst_x2 = screen->width - dstBox.x1;
+ dst_y2 = screen->height - dstBox.y1;
+ rot_x1 = (src_w << 16) - x2;
+ rot_y1 = (src_h << 16) - y2;
+ rot_x2 = (src_w << 16) - x1;
+ rot_y2 = (src_h << 16) - y1;
+ break;
+ case 270:
+ dst_x1 = screen->width - dstBox.y2;
+ dst_y1 = dstBox.x1;
+ dst_x2 = screen->width - dstBox.y1;
+ dst_y2 = dstBox.x2;
+ rot_x1 = (src_h << 16) - y2;
+ rot_y1 = x1;
+ rot_x2 = (src_h << 16) - y1;
+ rot_y2 = x2;
+ break;
+ }
+
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ dstPitch = ((dst_width << 1) + 15) & ~15;
+ srcPitch = (width + 3) & ~3;
+ srcPitch2 = ((width >> 1) + 3) & ~3;
+ size = dstPitch * (int) dst_height;
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ dstPitch = ((dst_width << 1) + 15) & ~15;
+ srcPitch = (width << 1);
+ size = dstPitch * (int) dst_height;
+ break;
+ }
+
+ pPortPriv->offset = mach64s->off_screen - (CARD8 *) mach64s->vesa.fb;
+ /* fixup pointers */
+
+ pPortPriv->YBuf0Offset = pPortPriv->offset;
+ pPortPriv->YBuf1Offset = pPortPriv->offset + size;
+
+#if 0
+ mach64WaitIdle (reg);
+
+ if (pPortPriv->videoOn)
+ {
+ /* wait for buffer to be displayed */
+ while (((media->TRIG_CNTL >> 5) & 1) != pPortPriv->currentBuf)
+ ;
+ }
+#endif
+ /*
+ * Use the other buffer
+ */
+ pPortPriv->currentBuf = 1 - pPortPriv->currentBuf;
+
+ /* copy data */
+ top = rot_y1 >> 16;
+ left = (rot_x1 >> 16) & ~1;
+ npixels = ((((rot_x2 + 0xffff) >> 16) + 1) & ~1) - left;
+
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ top &= ~1;
+ nlines = ((((rot_y2 + 0xffff) >> 16) + 1) & ~1) - top;
+ mach64CopyPlanarData(screen, buf, rotate,
+ srcPitch, srcPitch2, dstPitch,
+ rot_src_w, rot_src_h, height,
+ top, left, nlines, npixels, id);
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ nlines = ((rot_y2 + 0xffff) >> 16) - top;
+ mach64CopyPackedData(screen, buf, rotate,
+ srcPitch, dstPitch,
+ rot_src_w, rot_src_h,
+ top, left, nlines,
+ npixels);
+ break;
+ }
+
+ mach64DisplayVideo(screen, id, dstPitch,
+ rot_x1, rot_y1, rot_x2, rot_y2,
+ dst_x1, dst_y1,
+ dst_x2, dst_y2,
+ rot_src_w, rot_src_h, rot_drw_w, rot_drw_h);
+
+ /* update cliplist */
+ if (!RegionsEqual (&pPortPriv->clip, clipBoxes))
+ {
+ REGION_COPY (screen->pScreen, &pPortPriv->clip, clipBoxes);
+ mach64PaintRegion (screen->pScreen, &pPortPriv->clip, pPortPriv->colorKey);
+ }
+
+ pPortPriv->videoOn = TRUE;
+
+ return Success;
+}
+
+static int
+mach64QueryImageAttributes(KdScreenInfo *screen,
+ int id,
+ unsigned short *w,
+ unsigned short *h,
+ int *pitches,
+ int *offsets)
+{
+ int size, tmp;
+
+ if(*w > IMAGE_MAX_WIDTH)
+ *w = IMAGE_MAX_WIDTH;
+ if(*h > IMAGE_MAX_HEIGHT)
+ *h = IMAGE_MAX_HEIGHT;
+
+ *w = (*w + 1) & ~1;
+ if(offsets) offsets[0] = 0;
+
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ *h = (*h + 1) & ~1;
+ size = (*w + 3) & ~3;
+ if(pitches)
+ pitches[0] = size;
+ size *= *h;
+ if(offsets)
+ offsets[1] = size;
+ tmp = ((*w >> 1) + 3) & ~3;
+ if(pitches)
+ pitches[1] = pitches[2] = tmp;
+ tmp *= (*h >> 1);
+ size += tmp;
+ if(offsets)
+ offsets[2] = size;
+ size += tmp;
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ size = *w << 1;
+ if(pitches)
+ pitches[0] = size;
+ size *= *h;
+ break;
+ }
+
+ return size;
+}
+
+
+/* client libraries expect an encoding */
+static KdVideoEncodingRec DummyEncoding[1] =
+{
+ {
+ 0,
+ "XV_IMAGE",
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ {1, 1}
+ }
+};
+
+#define NUM_FORMATS 3
+
+static KdVideoFormatRec Formats[NUM_FORMATS] =
+{
+ {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
+};
+
+#define NUM_ATTRIBUTES 3
+
+static KdAttributeRec Attributes[NUM_ATTRIBUTES] =
+{
+ {XvSettable | XvGettable, 0, ~0, "XV_COLORKEY"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
+ {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"}
+};
+
+#define NUM_IMAGES 4
+
+static KdImageRec Images[NUM_IMAGES] =
+{
+ XVIMAGE_YUY2,
+ XVIMAGE_YV12,
+ XVIMAGE_I420,
+ XVIMAGE_UYVY
+};
+
+static void mach64ResetVideo(KdScreenInfo *screen)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ KdScreenPriv(pScreen);
+ KdCardInfo *card = pScreenPriv->card;
+ Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
+ Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver;
+ Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr;
+ MediaReg *media = mach64c->media_reg;
+
+ /*
+ * Default to maximum image size in YV12
+ */
+
+}
+
+static int
+mach64ReputImage (KdScreenInfo *screen,
+ short drw_x,
+ short drw_y,
+ RegionPtr clipBoxes,
+ pointer data)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ Mach64PortPrivPtr pPortPriv = (Mach64PortPrivPtr)data;
+ BoxPtr pOldExtents = REGION_EXTENTS (pScreen, &pPortPriv->clip);
+ BoxPtr pNewExtents = REGION_EXTENTS (pScreen, clipBoxes);
+
+ if (pOldExtents->x1 == pNewExtents->x1 &&
+ pOldExtents->x2 == pNewExtents->x2 &&
+ pOldExtents->y1 == pNewExtents->y1 &&
+ pOldExtents->y2 == pNewExtents->y2)
+ {
+ /* update cliplist */
+ if (!RegionsEqual (&pPortPriv->clip, clipBoxes))
+ {
+ REGION_COPY (screen->pScreen, &pPortPriv->clip, clipBoxes);
+ mach64PaintRegion (screen->pScreen, &pPortPriv->clip, pPortPriv->colorKey);
+ }
+ return Success;
+ }
+ return BadMatch;
+}
+
+static KdVideoAdaptorPtr
+mach64SetupImageVideo(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ mach64CardInfo(pScreenPriv);
+ mach64ScreenInfo(pScreenPriv);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ KdCardInfo *card = pScreenPriv->card;
+ KdVideoAdaptorPtr adapt;
+ Mach64PortPrivPtr pPortPriv;
+
+ if(!(adapt = xcalloc(1, sizeof(KdVideoAdaptorRec) +
+ sizeof(Mach64PortPrivRec) +
+ sizeof(DevUnion))))
+ return NULL;
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ adapt->name = "Mach64 Video Overlay";
+ adapt->nEncodings = 1;
+ adapt->pEncodings = DummyEncoding;
+ adapt->nFormats = NUM_FORMATS;
+ adapt->pFormats = Formats;
+ adapt->nPorts = 1;
+ adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
+
+ pPortPriv = (Mach64PortPrivPtr)(&adapt->pPortPrivates[1]);
+
+ adapt->pPortPrivates[0].ptr = (pointer)(pPortPriv);
+ adapt->pAttributes = Attributes;
+ adapt->nImages = NUM_IMAGES;
+ adapt->nAttributes = NUM_ATTRIBUTES;
+ adapt->pImages = Images;
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+ adapt->StopVideo = mach64StopVideo;
+ adapt->SetPortAttribute = mach64SetPortAttribute;
+ adapt->GetPortAttribute = mach64GetPortAttribute;
+ adapt->QueryBestSize = mach64QueryBestSize;
+ adapt->PutImage = mach64PutImage;
+ adapt->ReputImage = mach64ReputImage;
+ adapt->QueryImageAttributes = mach64QueryImageAttributes;
+
+ pPortPriv->colorKey = mach64s->colorKey;
+ pPortPriv->videoOn = FALSE;
+ pPortPriv->brightness = 0;
+ pPortPriv->saturation = 0;
+ pPortPriv->currentBuf = 0;
+
+ /* gotta uninit this someplace */
+ REGION_INIT(pScreen, &pPortPriv->clip, NullBox, 0);
+
+ mach64s->pAdaptor = adapt;
+
+ xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+ xvSaturation = MAKE_ATOM("XV_SATURATION");
+ xvColorKey = MAKE_ATOM("XV_COLORKEY");
+
+ mach64ResetVideo(screen);
+
+ return adapt;
+}
+
+Bool mach64InitVideo(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ KdVideoAdaptorPtr *adaptors, *newAdaptors = NULL;
+ KdVideoAdaptorPtr newAdaptor = NULL;
+ int num_adaptors;
+ KdCardInfo *card = pScreenPriv->card;
+ Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver;
+ Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver;
+
+ if (!mach64c->media_reg)
+ return FALSE;
+
+ newAdaptor = mach64SetupImageVideo(pScreen);
+
+ num_adaptors = KdXVListGenericAdaptors(screen, &adaptors);
+
+ if(newAdaptor)
+ {
+ if(!num_adaptors)
+ {
+ num_adaptors = 1;
+ adaptors = &newAdaptor;
+ }
+ else
+ {
+ newAdaptors = xalloc((num_adaptors + 1) *
+ sizeof(KdVideoAdaptorPtr*));
+ if(newAdaptors)
+ {
+ memcpy(newAdaptors, adaptors,
+ num_adaptors * sizeof(KdVideoAdaptorPtr));
+ newAdaptors[num_adaptors] = newAdaptor;
+ adaptors = newAdaptors;
+ num_adaptors++;
+ }
+ }
+ }
+
+ if(num_adaptors)
+ KdXVScreenInit(pScreen, adaptors, num_adaptors);
+
+ if(newAdaptors)
+ xfree(newAdaptors);
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/kdrive/pcmcia/Imakefile b/xc/programs/Xserver/hw/kdrive/pcmcia/Imakefile
new file mode 100644
index 000000000..4a2c059ba
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/pcmcia/Imakefile
@@ -0,0 +1,13 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/Imakefile,v 1.1 2001/05/23 08:56:08 alanh Exp $
+KDRIVE=..
+#include "../Kdrive.tmpl"
+
+SRCS = pcmcia.c pcmciacurs.c pcmciastub.c pcmciashadow.c
+
+OBJS = pcmcia.o pcmciacurs.o pcmciastub.o pcmciashadow.o
+
+INCLUDES = -I. $(KDINCS) -I$(KDRIVE)/fbdev
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(pcmcia,$(OBJS))
+DependTarget()
diff --git a/xc/programs/Xserver/hw/kdrive/pcmcia/modes.h b/xc/programs/Xserver/hw/kdrive/pcmcia/modes.h
new file mode 100644
index 000000000..49c7d5f42
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/pcmcia/modes.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * 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 Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE 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.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/modes.h,v 1.1 2001/05/23 08:56:08 alanh Exp $ */
+
+#define V_NHSYNC 0x01
+#define V_NVSYNC 0x02
+#define V_PHSYNC 0x04
+#define V_PVSYNC 0x08
+#define V_INTERLACE 0x10
+
+pcmciaDisplayModeRec pcmciaDefaultModes [] = {
+/* 640x400 @ 70Hz (VGA) hsync: 37.9kHz */
+ {640, 400, 70 ,31500, 640,672,736,832,0, 400,401,404,445,0, V_NHSYNC | V_PVSYNC},
+/* 640x480 @ 60Hz (Industry standard) hsync: 31.5kHz */
+ {640, 480, 60 ,25200, 640,656,752,800,0, 480,490,492,525,0, V_NHSYNC | V_NVSYNC},
+/* 640x480 @ 72Hz (VESA) hsync: 37.9kHz */
+ {640, 480, 72 ,31500, 640,664,704,832,0, 480,489,491,520,0, V_NHSYNC | V_NVSYNC},
+/* 640x480 @ 75Hz (VESA) hsync: 37.5kHz */
+ {640, 480, 75 ,31500, 640,656,720,840,0, 480,481,484,500,0, V_NHSYNC | V_NVSYNC},
+/* 640x480 @ 85Hz (VESA) hsync: 43.3kHz */
+ {640, 480, 85 ,36000, 640,696,752,832,0, 480,481,484,509,0, V_NHSYNC | V_NVSYNC},
+/* 800x600 @ 56Hz (VESA) hsync: 35.2kHz */
+ {800, 600, 56 ,36000, 800,824,896,1024,0, 600,601,603,625,0, V_PHSYNC | V_PVSYNC},
+/* 800x600 @ 60Hz (VESA) hsync: 37.9kHz */
+ {800, 600, 60 ,40000, 800,840,968,1056,0, 600,601,605,628,0, V_PHSYNC | V_PVSYNC},
+/* 800x600 @ 72Hz (VESA) hsync: 48.1kHz */
+ {800, 600, 72 ,50000, 800,856,976,1040,0, 600,637,643,666,0, V_PHSYNC | V_PVSYNC},
+/* 800x600 @ 75Hz (VESA) hsync: 46.9kHz */
+ {800, 600, 75 ,49500, 800,816,896,1056,0, 600,601,604,625,0, V_PHSYNC | V_PVSYNC},
+/* 800x600 @ 85Hz (VESA) hsync: 53.7kHz */
+ {800, 600, 85 ,56300, 800,832,896,1048,0, 600,601,604,631,0, V_PHSYNC | V_PVSYNC},
+/* 1024x768i @ 43Hz (industry standard) hsync: 35.5kHz */
+ {1024, 768, 43 ,44900, 1024,1032,1208,1264,0, 768,768,776,817,0, V_PHSYNC | V_PVSYNC | V_INTERLACE},
+/* 1024x768 @ 60Hz (VESA) hsync: 48.4kHz */
+ {1024, 768, 60 ,65000, 1024,1048,1184,1344,0, 768,771,777,806,0, V_NHSYNC | V_NVSYNC},
+/* 1024x768 @ 70Hz (VESA) hsync: 56.5kHz */
+ {1024, 768, 70 ,75000, 1024,1048,1184,1328,0, 768,771,777,806,0, V_NHSYNC | V_NVSYNC},
+/* 1024x768 @ 75Hz (VESA) hsync: 60.0kHz */
+ {1024, 768, 75 ,78800, 1024,1040,1136,1312,0, 768,769,772,800,0, V_PHSYNC | V_PVSYNC},
+/* 1024x768 @ 85Hz (VESA) hsync: 68.7kHz */
+ {1024, 768, 85 ,94500, 1024,1072,1168,1376,0, 768,769,772,808,0, V_PHSYNC | V_PVSYNC},
+/* 1152x864 @ 75Hz (VESA) hsync: 67.5kHz */
+ {1152, 864, 75 ,108000, 1152,1216,1344,1600,0, 864,865,868,900,0, V_PHSYNC | V_PVSYNC},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
+};
diff --git a/xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.c b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.c
new file mode 100644
index 000000000..88bab0237
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.c
@@ -0,0 +1,1251 @@
+/*
+ * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * 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 Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE 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.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * A driver for the following PCMCIA cards...
+ * Hewlett Packards HP VGA Out (Model F1252A)
+ * Colorgraphics Voyager VGA
+ *
+ * Tested running under a Compaq IPAQ Pocket PC running Linux
+ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.c,v 1.5 2001/07/20 19:35:30 keithp Exp $ */
+
+#include "pcmcia.h"
+#define extern
+#include <asm/io.h>
+#undef extern
+
+#define CLOCK 14318 /* KHz */
+#define CLK_N(a,b) (a & 0xff)
+#define CLK_M(a,b) ((b) & 0x3f)
+#define CLK_K(a,b) (((b) >> 6) & 3)
+#define CLK_FREQ(a,b) (((CLK_N(a,b) + 8) * CLOCK) / ((CLK_M(a,b)+2) << CLK_K(a,b)))
+
+#include "modes.h"
+
+extern void
+tridentUpdatePacked (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+extern void
+cirrusUpdatePacked (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+
+Bool
+pcmciaCardInit (KdCardInfo *card)
+{
+ pcmciaCardInfo *pcmciac;
+ CARD8 r9;
+
+ pcmciac = (pcmciaCardInfo *) xalloc (sizeof (pcmciaCardInfo));
+ if (!pcmciac)
+ return FALSE;
+
+ pcmciac->cop_base = (CARD8 *) KdMapDevice (PCMCIA_COP_BASE(card),
+ PCMCIA_COP_SIZE(card));
+
+ r9 = pcmciaReadIndex (pcmciac, 0x3c4, 0x09);
+ /*
+ * Crude detection....
+ * The trident chip has a read only register at 0x09, which returns 0x4.
+ * If it's not that, we assume the cirrus chip.
+ * BREAKAGE.! If we have an anonymous PCMCIA card inserted, we could
+ * potentially smash something here. FIXME !
+ */
+ if (r9 == 0x04) {
+ ErrorF("PCMCIA: Found HP VGA card\n");
+ pcmciac->HP = TRUE; /* Select HP VGA Out Card */
+ } else {
+ ErrorF("PCMCIA: Found Voyager VGA card\n");
+ pcmciac->HP = FALSE; /* Select Voyager VGA Card */
+ }
+
+ if (pcmciac->HP) {
+ /* needed by the accelerator - later */
+ pcmciac->cop = (Cop *) (pcmciac->cop_base + TRIDENT_COP_OFF(card));
+ }
+
+ /*
+ * Map frame buffer
+ */
+ if (pcmciac->HP)
+ pcmciac->fb = KdMapDevice (0x2ce00000, 0x80000);
+ else
+ pcmciac->fb = KdMapDevice (0x2c0a0000, 0x10000); /*64K bank switched*/
+
+ if (!pcmciac->fb)
+ return FALSE;
+
+ pcmciac->window = 0;
+
+ card->driver = pcmciac;
+
+ return TRUE;
+}
+
+Bool
+pcmciaScreenInit (KdScreenInfo *screen)
+{
+ pcmciaCardInfo *pcmciac = screen->card->driver;
+ pcmciaScreenInfo *pcmcias;
+ int screen_size, memory;
+ int i;
+
+ pcmcias = (pcmciaScreenInfo *) xalloc (sizeof (pcmciaScreenInfo));
+ if (!pcmcias)
+ return FALSE;
+ memset (pcmcias, '\0', sizeof (pcmciaScreenInfo));
+
+ /* if (!pcmciac->cop) */
+ screen->dumb = TRUE;
+
+ /* default to 8bpp */
+ if (!screen->fb[0].depth)
+ screen->fb[0].depth = 8;
+
+ /* default to 60Hz refresh */
+ if (!screen->rate)
+ screen->rate = 60;
+
+ i = 0;
+ pcmcias->Mode = -1;
+ while (pcmciaDefaultModes[i].Width != 0) {
+ if ( (screen->width == pcmciaDefaultModes[i].Width) &&
+ (screen->height == pcmciaDefaultModes[i].Height) &&
+ (screen->rate == pcmciaDefaultModes[i].Refresh) ) {
+ pcmcias->Mode = i;
+ break;
+ }
+ i++;
+ }
+
+ if ( pcmcias->Mode == -1 ) {
+ ErrorF("PCMCIA: no matching vesa mode for screen selection, aborting.\n");
+ ErrorF("PCMCIA: use -listmodes to check for supported list of modes.\n");
+ return FALSE; /* end of list */
+ }
+
+ pcmcias->rotation = screen->rotation;
+
+ memory = 512 * 1024;
+ pcmcias->screen = pcmciac->fb;
+
+ if (pcmciac->HP && !screen->softCursor && screen->fb[0].depth == 8) {
+ /* Let's do hw cursor for the HP card, only in 8bit mode though */
+ pcmcias->cursor_base = pcmcias->screen + memory - 4096;
+ memory -= 4096;
+ }
+
+ if (screen->fb[0].depth == 4) {
+ ErrorF("PCMCIA: depth 4 isn't supported.\n");
+ return FALSE; /* screen->fb[0].bitsPerPixel = 4; need fb to support it*/
+ } else
+ if (screen->fb[0].depth == 8)
+ screen->fb[0].bitsPerPixel = 8;
+ else
+ if (screen->fb[0].depth == 15 ||
+ screen->fb[0].depth == 16)
+ screen->fb[0].bitsPerPixel = 16;
+
+ if ( (screen->width * screen->height *
+ (screen->fb[0].bitsPerPixel / 8)) > memory) {
+ ErrorF("PCMCIA: Not enough memory for resolution requested, aborting.\n");
+ return FALSE;
+ }
+
+ screen->fb[0].pixelStride = screen->width;
+ screen->fb[0].byteStride = screen->width * (screen->fb[0].bitsPerPixel >>3);
+
+ screen->fb[0].frameBuffer = pcmciac->fb;
+ switch (screen->fb[0].depth) {
+ case 4:
+ screen->fb[0].visuals = ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor));
+ screen->fb[0].blueMask = 0x00;
+ screen->fb[0].greenMask = 0x00;
+ screen->fb[0].redMask = 0x00;
+ break;
+ case 8:
+ screen->fb[0].visuals = ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor) |
+ (1 << PseudoColor) |
+ (1 << TrueColor) |
+ (1 << DirectColor));
+ screen->fb[0].blueMask = 0x00;
+ screen->fb[0].greenMask = 0x00;
+ screen->fb[0].redMask = 0x00;
+ break;
+ case 15:
+ screen->fb[0].visuals = (1 << TrueColor);
+ screen->fb[0].blueMask = 0x001f;
+ screen->fb[0].greenMask = 0x03e0;
+ screen->fb[0].redMask = 0x7c00;
+ break;
+ case 16:
+ screen->fb[0].visuals = (1 << TrueColor);
+ screen->fb[0].blueMask = 0x001f;
+ screen->fb[0].greenMask = 0x07e0;
+ screen->fb[0].redMask = 0xf800;
+ break;
+ }
+ screen_size = screen->fb[0].byteStride * screen->height;
+
+ screen->driver = pcmcias;
+
+ return TRUE;
+}
+
+void *
+tridentWindowLinear (ScreenPtr pScreen,
+ CARD32 row,
+ CARD32 offset,
+ int mode,
+ CARD32 *size,
+ void *closure)
+{
+ KdScreenPriv(pScreen);
+ pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
+
+ if (!pScreenPriv->enabled)
+ return 0;
+
+ *size = pScreenPriv->screen->fb[0].byteStride;
+ return (CARD8 *) pcmciac->fb + row * pScreenPriv->screen->fb[0].byteStride + offset;
+}
+
+void *
+cirrusWindowWindowed (ScreenPtr pScreen,
+ CARD32 row,
+ CARD32 offset,
+ int mode,
+ CARD32 *size,
+ void *closure)
+{
+ KdScreenPriv(pScreen);
+ pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
+ int bank, boffset;
+
+ if (!pScreenPriv->enabled)
+ return 0;
+
+ bank = (row * pScreenPriv->screen->fb[0].byteStride) / 0x1000;
+ pcmciaWriteIndex(pcmciac, 0x3ce, 0x0B, 0x0c);
+ pcmciaWriteIndex(pcmciac, 0x3ce, 0x09, bank);
+ pcmciaWriteIndex(pcmciac, 0x3ce, 0x0A, bank);
+ *size = pScreenPriv->screen->fb[0].byteStride;
+ return (CARD8 *) pcmciac->fb + (row * pScreenPriv->screen->fb[0].byteStride) - (bank * 0x1000) + offset;
+}
+
+LayerPtr
+pcmciaLayerCreate (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
+ pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) pScreenPriv->screen->driver;
+ ShadowUpdateProc update;
+ ShadowWindowProc window;
+ KdMouseMatrix m;
+ PixmapPtr pPixmap;
+ int kind;
+
+ switch (pcmcias->rotation) {
+ case 0:
+ pScreen->width = screen->width;
+ pScreen->height = screen->height;
+ pScreen->mmWidth = screen->width_mm;
+ pScreen->mmHeight = screen->height_mm;
+ m.matrix[0][0] = 1; m.matrix[0][1] = 0; m.matrix[0][2] = 0;
+ m.matrix[1][0] = 0; m.matrix[1][1] = 1; m.matrix[1][2] = 0;
+ break;
+ case 90:
+ pScreen->width = screen->height;
+ pScreen->height = screen->width;
+ pScreen->mmWidth = screen->height_mm;
+ pScreen->mmHeight = screen->width_mm;
+ m.matrix[0][0] = 0; m.matrix[0][1] = -1; m.matrix[0][2] = screen->height - 1;
+ m.matrix[1][0] = 1; m.matrix[1][1] = 0; m.matrix[1][2] = 0;
+ break;
+ case 180:
+ pScreen->width = screen->width;
+ pScreen->height = screen->height;
+ pScreen->mmWidth = screen->width_mm;
+ pScreen->mmHeight = screen->height_mm;
+ m.matrix[0][0] = -1; m.matrix[0][1] = 0; m.matrix[0][2] = screen->width - 1;
+ m.matrix[1][0] = 0; m.matrix[1][1] = -1; m.matrix[1][2] = screen->height - 1;
+ break;
+ case 270:
+ pScreen->width = screen->height;
+ pScreen->height = screen->width;
+ pScreen->mmWidth = screen->height_mm;
+ pScreen->mmHeight = screen->width_mm;
+ m.matrix[0][0] = 0; m.matrix[0][1] = 1; m.matrix[0][2] = 0;
+ m.matrix[1][0] = -1; m.matrix[1][1] = 0; m.matrix[1][2] = screen->width - 1;
+ break;
+ }
+ KdSetMouseMatrix (&m);
+
+ if (pcmciac->HP) {
+ window = tridentWindowLinear;
+ switch (pcmcias->rotation) {
+ case 0:
+ update = tridentUpdatePacked;
+ break;
+ case 90:
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
+ case 8:
+ update = shadowUpdateRotate8_90; break;
+ case 16:
+ update = shadowUpdateRotate16_90; break;
+ }
+ break;
+ case 180:
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
+ case 8:
+ update = shadowUpdateRotate8_180; break;
+ case 16:
+ update = shadowUpdateRotate16_180; break;
+ }
+ break;
+ case 270:
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
+ case 8:
+ update = shadowUpdateRotate8_270; break;
+ case 16:
+ update = shadowUpdateRotate16_270; break;
+ }
+ break;
+ }
+ } else {
+ window = cirrusWindowWindowed;
+ switch (pcmcias->rotation) {
+ case 0:
+ update = cirrusUpdatePacked;
+ break;
+ case 90:
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
+ case 8:
+ update = shadowUpdateRotate8_90; break;
+ case 16:
+ update = shadowUpdateRotate16_90; break;
+ }
+ break;
+ case 180:
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
+ case 8:
+ update = shadowUpdateRotate8_180; break;
+ case 16:
+ update = shadowUpdateRotate16_180; break;
+ }
+ break;
+ case 270:
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
+ case 8:
+ update = shadowUpdateRotate8_270; break;
+ case 16:
+ update = shadowUpdateRotate16_270; break;
+ }
+ break;
+ }
+ }
+
+ if (!update)
+ abort ();
+
+ kind = LAYER_SHADOW;
+ pPixmap = 0;
+
+ return LayerCreate (pScreen, kind, screen->fb[0].depth,
+ pPixmap, update, window, pcmcias->rotation, 0);
+}
+
+#ifdef RANDR
+Bool
+pcmciaRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+ KdScreenPriv(pScreen);
+ pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
+ KdScreenInfo *screen = pScreenPriv->screen;
+ pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) pScreenPriv->screen->driver;
+ RRVisualGroupPtr pVisualGroup;
+ RRGroupOfVisualGroupPtr pGroupOfVisualGroup;
+ RRScreenSizePtr pSize;
+ Rotation rotateKind;
+ int rotation;
+ int n;
+
+ *rotations = RR_Rotate_0|RR_Rotate_90|RR_Rotate_180|RR_Rotate_270;
+
+ for (n = 0; n < pScreen->numDepths; n++)
+ if (pScreen->allowedDepths[n].numVids)
+ break;
+ if (n == pScreen->numDepths)
+ return FALSE;
+
+ pVisualGroup = RRCreateVisualGroup (pScreen);
+ if (!pVisualGroup)
+ return FALSE;
+ if (!RRAddDepthToVisualGroup (pScreen,
+ pVisualGroup,
+ &pScreen->allowedDepths[n]))
+ {
+ RRDestroyVisualGroup (pScreen, pVisualGroup);
+ return FALSE;
+ }
+
+ pVisualGroup = RRRegisterVisualGroup (pScreen, pVisualGroup);
+ if (!pVisualGroup)
+ return FALSE;
+
+ pGroupOfVisualGroup = RRCreateGroupOfVisualGroup (pScreen);
+
+ if (!RRAddVisualGroupToGroupOfVisualGroup (pScreen,
+ pGroupOfVisualGroup,
+ pVisualGroup))
+ {
+ RRDestroyGroupOfVisualGroup (pScreen, pGroupOfVisualGroup);
+ /* pVisualGroup left until screen closed */
+ return FALSE;
+ }
+
+ pGroupOfVisualGroup = RRRegisterGroupOfVisualGroup (pScreen, pGroupOfVisualGroup);
+ if (!pGroupOfVisualGroup)
+ return FALSE;
+
+ pSize = RRRegisterSize (pScreen,
+ screen->width,
+ screen->height,
+ screen->width_mm,
+ screen->height_mm,
+ pGroupOfVisualGroup);
+
+ rotation = pcmcias->rotation - screen->rotation;
+ if (rotation < 0)
+ rotation += 360;
+
+ switch (rotation)
+ {
+ case 0:
+ rotateKind = RR_Rotate_0;
+ break;
+ case 90:
+ rotateKind = RR_Rotate_90;
+ break;
+ case 180:
+ rotateKind = RR_Rotate_180;
+ break;
+ case 270:
+ rotateKind = RR_Rotate_270;
+ break;
+ }
+
+ RRSetCurrentConfig (pScreen, rotateKind, pSize, pVisualGroup);
+
+ return TRUE;
+ }
+
+int
+pcmciaLayerAdd (WindowPtr pWin, pointer value)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ LayerPtr pLayer = (LayerPtr) value;
+
+ if (!LayerWindowAdd (pScreen, pLayer, pWin))
+ return WT_STOPWALKING;
+
+ return WT_WALKCHILDREN;
+}
+
+int
+pcmciaLayerRemove (WindowPtr pWin, pointer value)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ LayerPtr pLayer = (LayerPtr) value;
+
+ LayerWindowRemove (pScreen, pLayer, pWin);
+
+ return WT_WALKCHILDREN;
+}
+
+pcmciaRandRSetConfig (ScreenPtr pScreen,
+ Rotation rotateKind,
+ RRScreenSizePtr pSize,
+ RRVisualGroupPtr pVisualGroup)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ FbdevPriv *priv = pScreenPriv->card->driver;
+ pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) pScreenPriv->screen->driver;
+ int rotation;
+ Bool wasEnabled = pScreenPriv->enabled;
+
+ /*
+ * The only thing that can change is rotation
+ */
+ switch (rotateKind)
+ {
+ case RR_Rotate_0:
+ rotation = screen->rotation;
+ break;
+ case RR_Rotate_90:
+ rotation = screen->rotation + 90;
+ break;
+ case RR_Rotate_180:
+ rotation = screen->rotation + 180;
+ break;
+ case RR_Rotate_270:
+ rotation = screen->rotation + 270;
+ break;
+ }
+ if (rotation >= 360)
+ rotation -= 360;
+
+ if (pcmcias->rotation != rotation)
+ {
+ LayerPtr pNewLayer;
+ int kind;
+ int oldrotation = pcmcias->rotation;
+ int oldwidth = pScreen->width;
+ int oldheight = pScreen->height;
+ PixmapPtr pPixmap;
+
+ if (wasEnabled)
+ KdDisableScreen (pScreen);
+
+ pcmcias->rotation = rotation;
+ pNewLayer = pcmciaLayerCreate (pScreen);
+ if (!pNewLayer)
+ {
+ pcmcias->rotation = oldrotation;
+ }
+ if (WalkTree (pScreen, pcmciaLayerAdd, (pointer) pNewLayer) == WT_STOPWALKING)
+ {
+ WalkTree (pScreen, pcmciaLayerRemove, (pointer) pNewLayer);
+ LayerDestroy (pScreen, pNewLayer);
+ pcmcias->rotation = oldrotation;
+ pScreen->width = oldwidth;
+ pScreen->height = oldheight;
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
+ return FALSE;
+ }
+ WalkTree (pScreen, pcmciaLayerRemove, (pointer) pcmcias->pLayer);
+ LayerDestroy (pScreen, pcmcias->pLayer);
+ pcmcias->pLayer = pNewLayer;
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
+ }
+ return TRUE;
+}
+
+Bool
+pcmciaRandRInit (ScreenPtr pScreen)
+{
+ rrScrPrivPtr pScrPriv;
+
+ if (!RRScreenInit (pScreen))
+ return FALSE;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+ pScrPriv->rrGetInfo = pcmciaRandRGetInfo;
+ pScrPriv->rrSetConfig = pcmciaRandRSetConfig;
+ return TRUE;
+}
+#endif
+
+Bool
+pcmciaInitScreen (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ FbdevPriv *priv = pScreenPriv->card->driver;
+ pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) pScreenPriv->screen->driver;
+
+ if (!LayerStartInit (pScreen))
+ return FALSE;
+ if (!LayerFinishInit (pScreen))
+ return FALSE;
+ pcmcias->pLayer = pcmciaLayerCreate (pScreen);
+ if (!pcmcias->pLayer)
+ return FALSE;
+#ifdef RANDR
+ if (!pcmciaRandRInit (pScreen))
+ return FALSE;
+#endif
+ return TRUE;
+}
+
+CARD8
+pcmciaReadIndex (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 index)
+{
+ CARD8 value;
+
+ pcmciac->cop_base[port] = index;
+ value = pcmciac->cop_base[port+1];
+ return value;
+}
+
+void
+pcmciaWriteIndex (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 index, CARD8 value)
+{
+ pcmciac->cop_base[port] = index;
+ pcmciac->cop_base[port+1] = value;
+}
+
+CARD8
+pcmciaReadReg (pcmciaCardInfo *pcmciac, CARD16 port)
+{
+ CARD8 value;
+
+ value = pcmciac->cop_base[port];
+
+ return value;
+}
+
+void
+pcmciaWriteReg (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 value)
+{
+ pcmciac->cop_base[port] = value;
+}
+
+
+void
+pcmciaPause ()
+{
+ struct timeval tv;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 50 * 1000;
+ select (1, 0, 0, 0, &tv);
+}
+
+void
+pcmciaPreserve (KdCardInfo *card)
+{
+}
+
+/* CLOCK_FACTOR is double the osc freq in kHz (osc = 14.31818 MHz) */
+#define CLOCK_FACTOR 28636
+
+/* stability constraints for internal VCO -- MAX_VCO also determines the maximum Video pixel clock */
+#define MIN_VCO CLOCK_FACTOR
+#define MAX_VCO 111000
+
+/* clock in kHz is (numer * CLOCK_FACTOR / (denom & 0x3E)) >> (denom & 1) */
+#define VCOVAL(n, d) \
+ ((((n) & 0x7F) * CLOCK_FACTOR / ((d) & 0x3E)) )
+
+#define CLOCKVAL(n, d) \
+ (VCOVAL(n, d) >> ((d) & 1))
+
+int CirrusFindClock(freq, max_clock, num_out, den_out)
+ int freq;
+ int max_clock;
+ int *num_out;
+ int *den_out;
+{
+ int n;
+ int num = 0, den = 0;
+ int mindiff;
+
+ /*
+ * If max_clock is greater than the MAX_VCO default, ignore
+ * MAX_VCO. On the other hand, if MAX_VCO is higher than max_clock,
+ * make use of the higher MAX_VCO value.
+ */
+ if (MAX_VCO > max_clock)
+ max_clock = MAX_VCO;
+
+ mindiff = freq;
+ for (n = 0x10; n < 0x7f; n++) {
+ int d;
+ for (d = 0x14; d < 0x3f; d++) {
+ int c, diff;
+ /* Avoid combinations that can be unstable. */
+ if ((VCOVAL(n, d) < MIN_VCO) || (VCOVAL(n, d) > max_clock))
+ continue;
+ c = CLOCKVAL(n, d);
+ diff = abs(c - freq);
+ if (diff < mindiff) {
+ mindiff = diff;
+ num = n;
+ den = d;
+ }
+ }
+ }
+
+ *num_out = num;
+ *den_out = den;
+
+ return 0;
+}
+
+
+void
+tridentSetCLK(int clock, CARD8 *a, CARD8 *b)
+{
+ int powerup[4] = { 1,2,4,8 };
+ int clock_diff = 750;
+ int freq, ffreq;
+ int m, n, k;
+ int p, q, r, s;
+ int startn, endn;
+ int endm, endk;
+
+ p = q = r = s = 0;
+
+ startn = 0;
+ endn = 121;
+ endm = 31;
+ endk = 1;
+
+ freq = clock;
+
+ for (k=0;k<=endk;k++)
+ for (n=startn;n<=endn;n++)
+ for (m=1;m<=endm;m++)
+ {
+ ffreq = ( ( ((n + 8) * CLOCK) / ((m + 2) * powerup[k]) ));
+ if ((ffreq > freq - clock_diff) && (ffreq < freq + clock_diff))
+ {
+ clock_diff = (freq > ffreq) ? freq - ffreq : ffreq - freq;
+ p = n; q = m; r = k; s = ffreq;
+ }
+ }
+
+#if 0
+ ErrorF ("ffreq %d clock %d\n", s, clock);
+#endif
+ if (s == 0)
+ {
+ FatalError("Unable to set programmable clock.\n"
+ "Frequency %d is not a valid clock.\n"
+ "Please modify XF86Config for a new clock.\n",
+ freq);
+ }
+
+ /* N is first 7bits, first M bit is 8th bit */
+ *a = ((1 & q) << 7) | p;
+ /* first 4bits are rest of M, 1bit for K value */
+ *b = (((q & 0xFE) >> 1) | (r << 4));
+}
+
+Bool
+pcmciaEnable (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
+ pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) pScreenPriv->screen->driver;
+ int i,j;
+ unsigned char Sequencer[6];
+ unsigned char CRTC[31];
+ unsigned char Graphics[9];
+ unsigned char Attribute[21];
+ unsigned char MiscOutReg;
+ pcmciaDisplayModeRec mode = pcmciaDefaultModes[pcmcias->Mode];
+
+ /*
+ * compute correct Hsync & Vsync polarity
+ */
+ if ((mode.Flags & (V_PHSYNC | V_NHSYNC))
+ && (mode.Flags & (V_PVSYNC | V_NVSYNC)))
+ {
+ MiscOutReg = 0x23;
+ if (mode.Flags & V_NHSYNC) MiscOutReg |= 0x40;
+ if (mode.Flags & V_NVSYNC) MiscOutReg |= 0x80;
+ }
+ else
+ {
+ int VDisplay = mode.VDisplay;
+ if (VDisplay < 400)
+ MiscOutReg = 0xA3; /* +hsync -vsync */
+ else if (VDisplay < 480)
+ MiscOutReg = 0x63; /* -hsync +vsync */
+ else if (VDisplay < 768)
+ MiscOutReg = 0xE3; /* -hsync -vsync */
+ else
+ MiscOutReg = 0x23; /* +hsync +vsync */
+ }
+
+ /*
+ * Time Sequencer
+ */
+ if (pScreenPriv->screen->fb[0].depth == 4)
+ Sequencer[0] = 0x02;
+ else
+ Sequencer[0] = 0x00;
+ Sequencer[1] = 0x01;
+ Sequencer[2] = 0x0F;
+ Sequencer[3] = 0x00; /* Font select */
+ if (pScreenPriv->screen->fb[0].depth < 8)
+ Sequencer[4] = 0x06; /* Misc */
+ else
+ Sequencer[4] = 0x0E; /* Misc */
+ Sequencer[5] = 0x00;
+
+ /*
+ * CRTC Controller
+ */
+ CRTC[0] = (mode.HTotal >> 3) - 5;
+ CRTC[1] = (mode.HDisplay >> 3) - 1;
+ CRTC[2] = ((min(mode.HSyncStart,mode.HDisplay)) >> 3) - 1;
+ CRTC[3] = ((((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & 0x1F) | 0x80;
+ i = (((mode.HSkew << 2) + 0x10) & ~0x1F);
+ if (i < 0x80)
+ CRTC[3] |= i;
+ CRTC[4] = (mode.HSyncStart >> 3);
+ CRTC[5] = (((((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & 0x20) << 2)
+ | (((mode.HSyncEnd >> 3)) & 0x1F);
+ CRTC[6] = (mode.VTotal - 2) & 0xFF;
+ CRTC[7] = (((mode.VTotal - 2) & 0x100) >> 8)
+ | (((mode.VDisplay - 1) & 0x100) >> 7)
+ | ((mode.VSyncStart & 0x100) >> 6)
+ | ((((min(mode.VSyncStart,mode.VDisplay)) - 1) & 0x100) >> 5)
+ | 0x10
+ | (((mode.VTotal - 2) & 0x200) >> 4)
+ | (((mode.VDisplay - 1) & 0x200) >> 3)
+ | ((mode.VSyncStart & 0x200) >> 2);
+ CRTC[8] = 0x00;
+ CRTC[9] = ((((min(mode.VSyncStart,mode.VDisplay))-1) & 0x200) >> 4) | 0x40;
+ CRTC[10] = 0x00;
+ CRTC[11] = 0x00;
+ CRTC[12] = 0x00;
+ CRTC[13] = 0x00;
+ CRTC[14] = 0x00;
+ CRTC[15] = 0x00;
+ CRTC[16] = mode.VSyncStart & 0xFF;
+ CRTC[17] = (mode.VSyncEnd & 0x0F) | 0x20;
+ CRTC[18] = (mode.VDisplay - 1) & 0xFF;
+ if (pScreenPriv->screen->fb[0].depth == 4)
+ CRTC[19] = pScreenPriv->screen->fb[0].pixelStride >> 4;
+ else
+ if (pScreenPriv->screen->fb[0].depth == 8)
+ CRTC[19] = pScreenPriv->screen->fb[0].pixelStride >> 3;
+ else
+ if (pScreenPriv->screen->fb[0].depth == 16 ||
+ pScreenPriv->screen->fb[0].depth == 15)
+ CRTC[19] = pScreenPriv->screen->fb[0].pixelStride >> 2;
+ CRTC[20] = 0x00;
+ CRTC[21] = ((min(mode.VSyncStart,mode.VDisplay)) - 1) & 0xFF;
+ CRTC[22] = ((min(mode.VSyncEnd,mode.VDisplay)) - 1) & 0xFF;
+ if (pScreenPriv->screen->fb[0].depth < 8)
+ CRTC[23] = 0xE3;
+ else
+ CRTC[23] = 0xC3;
+ CRTC[24] = 0xFF;
+ CRTC[25] = 0x00;
+ CRTC[26] = 0x00;
+ if (!pcmciac->HP)
+ if (mode.Flags & V_INTERLACE) CRTC[26] |= 0x01;
+ if (pcmciac->HP)
+ CRTC[27] = 0x00;
+ else
+ CRTC[27] = 0x22;
+ CRTC[28] = 0x00;
+ CRTC[29] = 0x00;
+ CRTC[30] = 0x80;
+ if (pcmciac->HP)
+ if (mode.Flags & V_INTERLACE) CRTC[30] |= 0x04;
+
+{
+ int nExtBits = 0;
+ CARD32 ExtBits;
+ CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 6;
+
+ CRTC[3] = (CRTC[3] & ~0x1F)
+ | ((((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & 0x1F);
+ CRTC[5] = (CRTC[5] & ~0x80)
+ | (((((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & 0x20) << 2);
+ ExtBits = (((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & ExtBitMask;
+
+ /* First the horizontal case */
+ if ((((min(mode.HSyncEnd,mode.HTotal)) >> 3) == (mode.HTotal >> 3)))
+ {
+ int i = (CRTC[3] & 0x1F)
+ | ((CRTC[5] & 0x80) >> 2)
+ | ExtBits;
+ if ((i-- > ((((min(mode.HSyncStart,mode.HDisplay)) >> 3) - 1)
+ & (0x3F | ExtBitMask)))
+ && ((min(mode.HSyncEnd,mode.HTotal)) == mode.HTotal))
+ i = 0;
+ CRTC[3] = (CRTC[3] & ~0x1F) | (i & 0x1F);
+ CRTC[5] = (CRTC[5] & ~0x80) | ((i << 2) & 0x80);
+ ExtBits = i & ExtBitMask;
+ }
+}
+{
+ CARD32 ExtBits;
+ CARD32 ExtBitMask = 0;
+ /* If width is not known nBits should be 0. In this
+ * case BitMask is set to 0 so we can check for it. */
+ CARD32 BitMask = 0;
+ int VBlankStart = ((min(mode.VSyncStart,mode.VDisplay)) - 1) & 0xFF;
+ CRTC[22] = ((min(mode.VSyncEnd,mode.VTotal)) - 1) & 0xFF;
+ ExtBits = ((min(mode.VSyncEnd,mode.VTotal)) - 1) & ExtBitMask;
+
+ if ((min(mode.VSyncEnd,mode.VTotal)) == mode.VTotal)
+ /* Null top overscan */
+ {
+ int i = CRTC[22] | ExtBits;
+ if (((BitMask && ((i & BitMask) > (VBlankStart & BitMask)))
+ || ((i > VBlankStart) && /* 8-bit case */
+ ((i & 0x7F) > (VBlankStart & 0x7F)))) && /* 7-bit case */
+ !(CRTC[9] & 0x9F)) /* 1 scanline/row */
+ i = 0;
+ else
+ i = (i - 1);
+ CRTC[22] = i & 0xFF;
+ ExtBits = i & 0xFF00;
+ }
+}
+
+ /*
+ * Graphics Display Controller
+ */
+ Graphics[0] = 0x00;
+ Graphics[1] = 0x00;
+ Graphics[2] = 0x00;
+ Graphics[3] = 0x00;
+ Graphics[4] = 0x00;
+ if (pScreenPriv->screen->fb[0].depth == 4)
+ Graphics[5] = 0x02;
+ else
+ Graphics[5] = 0x40;
+ Graphics[6] = 0x05; /* only map 64k VGA memory !!!! */
+ Graphics[7] = 0x0F;
+ Graphics[8] = 0xFF;
+
+ Attribute[0] = 0x00; /* standard colormap translation */
+ Attribute[1] = 0x01;
+ Attribute[2] = 0x02;
+ Attribute[3] = 0x03;
+ Attribute[4] = 0x04;
+ Attribute[5] = 0x05;
+ Attribute[6] = 0x06;
+ Attribute[7] = 0x07;
+ Attribute[8] = 0x08;
+ Attribute[9] = 0x09;
+ Attribute[10] = 0x0A;
+ Attribute[11] = 0x0B;
+ Attribute[12] = 0x0C;
+ Attribute[13] = 0x0D;
+ Attribute[14] = 0x0E;
+ Attribute[15] = 0x0F;
+ if (pScreenPriv->screen->fb[0].depth == 4)
+ Attribute[16] = 0x81;
+ else
+ Attribute[16] = 0x41;
+ if (pScreenPriv->screen->fb[0].bitsPerPixel == 16)
+ Attribute[17] = 0x00;
+ else
+ Attribute[17] = 0xFF;
+ Attribute[18] = 0x0F;
+ Attribute[19] = 0x00;
+ Attribute[20] = 0x00;
+
+ /* Wake up the card */
+ if (pcmciac->HP) {
+ pcmciaWriteReg(pcmciac, 0x3c3, 0x1);
+ pcmciaWriteReg(pcmciac, 0x46e8, 0x10);
+ } else {
+ pcmciaWriteReg(pcmciac, 0x105, 0x1);
+ pcmciaWriteReg(pcmciac, 0x46e8, 0x1f);
+ pcmciaWriteReg(pcmciac, 0x102, 0x1);
+ pcmciaWriteReg(pcmciac, 0x46e8, 0xf);
+ pcmciaWriteReg(pcmciac, 0x3c3, 0x1);
+ }
+
+ if (pcmciac->HP) {
+ /* unlock */
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x11, 0x92);
+ j = pcmciaReadIndex(pcmciac, 0x3c4, 0xb);
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0xe, 0xc2);
+
+ /* switch on dac */
+ pcmciaWriteIndex(pcmciac, 0x3d4, 0x29, 0x24);
+ /* switch on the accelerator */
+ pcmciaWriteIndex(pcmciac, 0x3d4, 0x36, 0x80);
+
+ /* bump up memory clk */
+ pcmciaWriteReg(pcmciac, 0x43c6, 0x65);
+ pcmciaWriteReg(pcmciac, 0x43c7, 0x00);
+ } else {
+ /* unlock */
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x06, 0x12);
+ pcmciaWriteReg(pcmciac, 0x3c2, MiscOutReg);
+ }
+
+ /* synchronous reset */
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0, 0);
+
+ pcmciaWriteReg(pcmciac, 0x3da, 0x10);
+
+ for (i=0;i<6;i++)
+ pcmciaWriteIndex(pcmciac, 0x3c4, i, Sequencer[i]);
+
+ if (pcmciac->HP) {
+ /* Stick chip into color mode */
+ pcmciaWriteIndex(pcmciac, 0x3ce, 0x2f, 0x06);
+ /* Switch on Linear addressing */
+ pcmciaWriteIndex(pcmciac, 0x3d4, 0x21, 0x2e);
+ } else {
+ /* Stick chip into 8bit access mode - ugh! */
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x0F, 0x20); /* 0x26 ? */
+ /* reset mclk */
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x1F, 0);
+ }
+
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0, 0x3);
+
+ for (i=0;i<31;i++)
+ pcmciaWriteIndex(pcmciac, 0x3d4, i, CRTC[i]);
+
+ for (i=0;i<9;i++)
+ pcmciaWriteIndex(pcmciac, 0x3ce, i, Graphics[i]);
+
+ j = pcmciaReadReg(pcmciac, 0x3da);
+
+ for (i=0;i<21;i++) {
+ pcmciaWriteReg(pcmciac, 0x3c0, i);
+ pcmciaWriteReg(pcmciac, 0x3c0, Attribute[i]);
+ }
+
+ j = pcmciaReadReg(pcmciac, 0x3da);
+ pcmciaWriteReg(pcmciac, 0x3c0, 0x20);
+
+ j = pcmciaReadReg(pcmciac, 0x3c8);
+ j = pcmciaReadReg(pcmciac, 0x3c6);
+ j = pcmciaReadReg(pcmciac, 0x3c6);
+ j = pcmciaReadReg(pcmciac, 0x3c6);
+ j = pcmciaReadReg(pcmciac, 0x3c6);
+ switch (pScreenPriv->screen->fb[0].depth) {
+ /* This is here for completeness, when/if we ever do 4bpp */
+ case 4:
+ pcmciaWriteReg(pcmciac, 0x3c6, 0x0);
+ if (pcmciac->HP) {
+ pcmciaWriteIndex(pcmciac, 0x3ce, 0x0f, 0x90);
+ pcmciaWriteIndex(pcmciac, 0x3d4, 0x38, 0x00);
+ } else
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x07, 0x00);
+ break;
+ case 8:
+ pcmciaWriteReg(pcmciac, 0x3c6, 0x0);
+ if (pcmciac->HP) {
+ pcmciaWriteIndex(pcmciac, 0x3ce, 0x0f, 0x92);
+ pcmciaWriteIndex(pcmciac, 0x3d4, 0x38, 0x00);
+ } else
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x07, 0x01);
+ break;
+ case 15:
+ if (pcmciac->HP) {
+ pcmciaWriteReg(pcmciac, 0x3c6, 0x10);
+ pcmciaWriteIndex(pcmciac, 0x3ce, 0x0f, 0x9a);
+ pcmciaWriteIndex(pcmciac, 0x3d4, 0x38, 0x04);
+ } else {
+ pcmciaWriteReg(pcmciac, 0x3c6, 0xC0);
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x07, 0x03);
+ }
+ break;
+ case 16:
+ if (pcmciac->HP) {
+ pcmciaWriteReg(pcmciac, 0x3c6, 0x30);
+ pcmciaWriteIndex(pcmciac, 0x3ce, 0x0f, 0x9a);
+ pcmciaWriteIndex(pcmciac, 0x3d4, 0x38, 0x04);
+ } else {
+ pcmciaWriteReg(pcmciac, 0x3c6, 0xC1);
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x07, 0x03);
+ }
+ break;
+ }
+ j = pcmciaReadReg(pcmciac, 0x3c8);
+
+ pcmciaWriteReg(pcmciac, 0x3c6, 0xff);
+
+ for (i=0;i<256;i++) {
+ pcmciaWriteReg(pcmciac, 0x3c8, i);
+ pcmciaWriteReg(pcmciac, 0x3c9, i);
+ pcmciaWriteReg(pcmciac, 0x3c9, i);
+ pcmciaWriteReg(pcmciac, 0x3c9, i);
+ }
+
+ /* Set the Clock */
+ if (pcmciac->HP) {
+ CARD8 a,b;
+ int clock = mode.Clock;
+ if (pScreenPriv->screen->fb[0].bitsPerPixel == 16)
+ clock *= 2;
+ tridentSetCLK(clock, &a, &b);
+ pcmciaWriteReg(pcmciac, 0x43c8, a);
+ pcmciaWriteReg(pcmciac, 0x43c9, b);
+ } else {
+ int num, den;
+ unsigned char tmp;
+ int clock = mode.Clock;
+ if (pScreenPriv->screen->fb[0].bitsPerPixel == 16)
+ clock *= 2;
+
+ CirrusFindClock(clock, MAX_VCO, &num, &den);
+
+ tmp = pcmciaReadIndex(pcmciac, 0x3c4, 0x0d);
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x0d, (tmp & 0x80) | num);
+ tmp = pcmciaReadIndex(pcmciac, 0x3c4, 0x1d);
+ pcmciaWriteIndex(pcmciac, 0x3c4, 0x1d, (tmp & 0xc0) | den);
+ }
+ pcmciaWriteReg(pcmciac, 0x3c2, MiscOutReg | 0x08);
+
+#if 0 /* for debugging */
+ for (i=1;i<0x3f;i++)
+ ErrorF("0x%x, ",pcmciaReadIndex(pcmciac, 0x3c4, i));
+
+ ErrorF("\n");
+
+ for (i=0;i<0x3f;i++)
+ ErrorF("0x%x, ",pcmciaReadIndex(pcmciac, 0x3ce, i));
+
+ ErrorF("\n");
+
+ for (i=0;i<0x3f;i++)
+ ErrorF("0x%x, ",pcmciaReadIndex(pcmciac, 0x3d4, i));
+#endif
+
+ return TRUE;
+}
+
+void
+pcmciaDisable (ScreenPtr pScreen)
+{
+}
+
+const CARD8 tridentDPMSModes[4] = {
+ 0x00, /* KD_DPMS_NORMAL */
+ 0x01, /* KD_DPMS_STANDBY */
+ 0x02, /* KD_DPMS_SUSPEND */
+ 0x03, /* KD_DPMS_POWERDOWN */
+};
+
+Bool
+pcmciaDPMS (ScreenPtr pScreen, int mode)
+{
+ KdScreenPriv(pScreen);
+ pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
+
+ if (pcmciac->HP) {
+ pcmciaWriteIndex (pcmciac, 0x3ce, 0x23, tridentDPMSModes[mode]);
+ pcmciaPause ();
+ } else {
+ /* Voyager */
+ }
+
+ return TRUE;
+}
+
+void
+pcmciaRestore (KdCardInfo *card)
+{
+}
+
+void
+pcmciaScreenFini (KdScreenInfo *screen)
+{
+ pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) screen->driver;
+
+ xfree (pcmcias);
+ screen->driver = 0;
+}
+
+void
+pcmciaCardFini (KdCardInfo *card)
+{
+ pcmciaCardInfo *pcmciac = card->driver;
+
+ if (pcmciac->cop_base)
+ KdUnmapDevice ((void *) pcmciac->cop_base, PCMCIA_COP_SIZE(card));
+}
+
+void
+pcmciaGetColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs)
+{
+ KdScreenPriv(pScreen);
+ pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
+
+ while (ndef--)
+ {
+ pcmciaWriteReg (pcmciac, 0x3C7, pdefs->pixel);
+ pdefs->red = pcmciaReadReg (pcmciac, 0x3C9) << 10;
+ pdefs->green = pcmciaReadReg (pcmciac, 0x3C9) << 10;
+ pdefs->blue = pcmciaReadReg (pcmciac, 0x3C9) << 10;
+ pdefs++;
+ }
+}
+
+void
+pcmciaPutColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs)
+{
+ KdScreenPriv(pScreen);
+ pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
+
+ while (ndef--)
+ {
+ pcmciaWriteReg (pcmciac, 0x3C8, pdefs->pixel);
+ pcmciaWriteReg (pcmciac, 0x3C9, pdefs->red >> 10);
+ pcmciaWriteReg (pcmciac, 0x3C9, pdefs->green >> 10);
+ pcmciaWriteReg (pcmciac, 0x3C9, pdefs->blue >> 10);
+ pdefs++;
+ }
+}
+
+
+KdCardFuncs pcmciaFuncs = {
+ pcmciaCardInit, /* cardinit */
+ pcmciaScreenInit, /* scrinit */
+ pcmciaInitScreen, /* initScreen */
+ pcmciaPreserve, /* preserve */
+ pcmciaEnable, /* enable */
+ pcmciaDPMS, /* dpms */
+ pcmciaDisable, /* disable */
+ pcmciaRestore, /* restore */
+ pcmciaScreenFini, /* scrfini */
+ pcmciaCardFini, /* cardfini */
+
+ pcmciaCursorInit, /* initCursor */
+ pcmciaCursorEnable, /* enableCursor */
+ pcmciaCursorDisable, /* disableCursor */
+ pcmciaCursorFini, /* finiCursor */
+ pcmciaRecolorCursor, /* recolorCursor */
+
+#if 0 /* not yet */
+ pcmciaDrawInit, /* initAccel */
+ pcmciaDrawEnable, /* enableAccel */
+ pcmciaDrawSync, /* syncAccel */
+ pcmciaDrawDisable, /* disableAccel */
+ pcmciaDrawFini, /* finiAccel */
+#else
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#endif
+
+ pcmciaGetColors, /* getColors */
+ pcmciaPutColors, /* putColors */
+};
diff --git a/xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.h b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.h
new file mode 100644
index 000000000..58eb58bd9
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.h
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * 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 Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE 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.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.h,v 1.2 2001/06/20 21:53:31 alanh Exp $ */
+
+#ifndef _PCMCIA_H_
+#define _PCMCIA_H_
+
+#include <fbdev.h>
+
+/*
+ * offset from ioport beginning
+ */
+
+#define PCMCIA_COP_BASE(c) 0x20000000
+#define PCMCIA_COP_SIZE(c) 0x10000
+#define TRIDENT_COP_OFF(c) 0x2100
+
+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_SRC_BLEND_0 0x00000000
+#define COP_ALPHA_SRC_BLEND_1 0x00000001
+#define COP_ALPHA_SRC_BLEND_SRC_C 0x00000002
+#define COP_ALPHA_SRC_BLEND_1_SRC_C 0x00000003
+#define COP_ALPHA_SRC_BLEND_SRC_A 0x00000004
+#define COP_ALPHA_SRC_BLEND_1_SRC_A 0x00000005
+#define COP_ALPHA_SRC_BLEND_DST_A 0x00000006
+#define COP_ALPHA_SRC_BLEND_1_DST_A 0x00000007
+#define COP_ALPHA_SRC_BLEND_DST_C 0x00000008
+#define COP_ALPHA_SRC_BLEND_1_DST_C 0x00000009
+#define COP_ALPHA_SRC_BLEND_SAT 0x0000000A
+#define COP_ALPHA_SRC_BLEND_BG 0x0000000B
+
+#define COP_ALPHA_DST_BLEND_0 0x00000000
+#define COP_ALPHA_DST_BLEND_1 0x00000010
+#define COP_ALPHA_DST_BLEND_SRC_C 0x00000020
+#define COP_ALPHA_DST_BLEND_1_SRC_C 0x00000030
+#define COP_ALPHA_DST_BLEND_SRC_A 0x00000040
+#define COP_ALPHA_DST_BLEND_1_SRC_A 0x00000050
+#define COP_ALPHA_DST_BLEND_DST_A 0x00000060
+#define COP_ALPHA_DST_BLEND_1_DST_A 0x00000070
+#define COP_ALPHA_DST_BLEND_DST_C 0x00000080
+#define COP_ALPHA_DST_BLEND_1_DST_C 0x00000090
+#define COP_ALPHA_DST_BLEND_OTHER 0x000000A0
+
+#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 _pcmciaCardInfo {
+ CARD8 *fb;
+ Bool HP;
+ CARD8 *cop_base;
+ Cop *cop;
+ CARD32 *window;
+ CARD32 cop_depth;
+ CARD32 cop_stride;
+} pcmciaCardInfo;
+
+#define getpcmciaCardInfo(kd) ((pcmciaCardInfo *) ((kd)->card->driver))
+#define pcmciaCardInfo(kd) pcmciaCardInfo *pcmciac = getpcmciaCardInfo(kd)
+
+typedef struct _pcmciaCursor {
+ int width, height;
+ int xhot, yhot;
+ Bool has_cursor;
+ CursorPtr pCursor;
+ Pixel source, mask;
+} pcmciaCursor;
+
+#define PCMCIA_CURSOR_WIDTH 64
+#define PCMCIA_CURSOR_HEIGHT 64
+
+typedef struct _pcmciaScreenInfo {
+ int Mode;
+ CARD8 *cursor_base;
+ CARD8 *screen;
+ CARD8 *off_screen;
+ int off_screen_size;
+ int rotation;
+ LayerPtr pLayer;
+ pcmciaCursor cursor;
+} pcmciaScreenInfo;
+
+#define getpcmciaScreenInfo(kd) ((pcmciaScreenInfo *) ((kd)->screen->driver))
+#define pcmciaScreenInfo(kd) pcmciaScreenInfo *pcmcias = getpcmciaScreenInfo(kd)
+
+Bool
+pcmciaDrawInit (ScreenPtr pScreen);
+
+void
+pcmciaDrawEnable (ScreenPtr pScreen);
+
+void
+pcmciaDrawSync (ScreenPtr pScreen);
+
+void
+pcmciaDrawDisable (ScreenPtr pScreen);
+
+void
+pcmciaDrawFini (ScreenPtr pScreen);
+
+CARD8
+pcmciaReadIndex (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 index);
+
+void
+pcmciaWriteIndex (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 index, CARD8 value);
+
+void
+pcmciaWriteReg (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 value);
+
+Bool
+pcmciaCursorInit (ScreenPtr pScreen);
+
+void
+pcmciaCursorEnable (ScreenPtr pScreen);
+
+void
+pcmciaCursorDisable (ScreenPtr pScreen);
+
+void
+pcmciaCursorFini (ScreenPtr pScreen);
+
+void
+pcmciaRecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdef);
+
+typedef struct _pcmciaDisplayModeRec {
+ int Width;
+ int Height;
+ int Refresh;
+ int Clock; /* pixel clock freq */
+ int HDisplay; /* horizontal timing */
+ int HSyncStart;
+ int HSyncEnd;
+ int HTotal;
+ int HSkew;
+ int VDisplay; /* vertical timing */
+ int VSyncStart;
+ int VSyncEnd;
+ int VTotal;
+ int VScan;
+ int Flags;
+} pcmciaDisplayModeRec, *pcmciaDisplayModePtr;
+
+extern KdCardFuncs pcmciaFuncs;
+
+#endif /* _PCMCIA_H_ */
diff --git a/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciacurs.c b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciacurs.c
new file mode 100644
index 000000000..78d50fb75
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciacurs.c
@@ -0,0 +1,449 @@
+/*
+ * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * 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 Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE 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.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/pcmciacurs.c,v 1.1 2001/05/23 08:56:09 alanh Exp $ */
+
+#include "pcmcia.h"
+#include "cursorstr.h"
+
+#define SetupCursor(s) KdScreenPriv(s); \
+ pcmciaCardInfo(pScreenPriv); \
+ pcmciaScreenInfo(pScreenPriv); \
+ pcmciaCursor *pCurPriv = &pcmcias->cursor
+
+static void
+_pcmciaMoveCursor (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;
+ }
+
+ /* This is the recommended order to move the cursor */
+ if (pcmciac->HP) {
+ xlow = (CARD8) x;
+ xhigh = (CARD8) (x >> 8);
+ ylow = (CARD8) y;
+ yhigh = (CARD8) (y >> 8);
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x40, xlow);
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x41, xhigh);
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x42, ylow);
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x43, yhigh);
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x46, xoff);
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x47, yoff);
+ } else {
+ x >>= 3;
+ y >>= 3;
+ xlow = (CARD8) x;
+ xhigh = (CARD8) (x >> 8);
+ ylow = (CARD8) y;
+ yhigh = (CARD8) (y >> 8);
+ /* Don't be alarmed, yes the upper 3bits of the index are correct */
+ pcmciaWriteIndex (pcmciac, 0x3c4, 0x10 | xhigh << 5, xlow);
+ pcmciaWriteIndex (pcmciac, 0x3c4, 0x11 | yhigh << 5, ylow);
+ }
+}
+
+static void
+pcmciaMoveCursor (ScreenPtr pScreen, int x, int y)
+{
+ SetupCursor (pScreen);
+
+ if (!pCurPriv->has_cursor)
+ return;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ _pcmciaMoveCursor (pScreen, x, y);
+}
+
+static void
+pcmciaAllocCursorColors (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+ CursorPtr pCursor = pCurPriv->pCursor;
+
+ KdAllocateCursorPixels (pScreen, 0, pCursor,
+ &pCurPriv->source, &pCurPriv->mask);
+ switch (pScreenPriv->screen->fb[0].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
+pcmciaSetCursorColors (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+ CursorPtr pCursor = pCurPriv->pCursor;
+ CARD32 fg, bg;
+
+ fg = pCurPriv->source;
+ bg = pCurPriv->mask;
+
+ if (pcmciac->HP) {
+ /*
+ * This trident chip uses the palette for it's cursor colors - ouch!
+ * We enforce it to always stay the black/white colors as we don't
+ * want it to muck with the overscan color. Tough. Use softCursor
+ * if you want to change cursor colors.
+ */
+ pcmciaWriteReg (pcmciac, 0x3c8, 0xff); /* DAC 0 */
+ pcmciaWriteReg (pcmciac, 0x3c9, 0x00);
+ pcmciaWriteReg (pcmciac, 0x3c9, 0x00);
+ pcmciaWriteReg (pcmciac, 0x3c9, 0x00);
+ pcmciaWriteReg (pcmciac, 0x3c8, 0x00); /* DAC 255 */
+ pcmciaWriteReg (pcmciac, 0x3c9, 0x3f);
+ pcmciaWriteReg (pcmciac, 0x3c9, 0x3f);
+ pcmciaWriteReg (pcmciac, 0x3c9, 0x3f);
+ } else {
+ CARD8 temp;
+ temp = pcmciaReadIndex(pcmciac, 0x3c4, 0x12);
+ pcmciaWriteIndex (pcmciac, 0x3c4, 0x12, (temp & 0xFE) | 0x02);
+
+ pcmciaWriteReg (pcmciac, 0x3c8, 0x00); /* DAC 256 */
+ pcmciaWriteReg (pcmciac, 0x3c9, fg);
+ pcmciaWriteReg (pcmciac, 0x3c9, fg >> 8);
+ pcmciaWriteReg (pcmciac, 0x3c9, fg >> 16);
+ pcmciaWriteReg (pcmciac, 0x3c8, 0x00); /* DAC 257 */
+ pcmciaWriteReg (pcmciac, 0x3c9, bg);
+ pcmciaWriteReg (pcmciac, 0x3c9, bg >> 8);
+ pcmciaWriteReg (pcmciac, 0x3c9, bg >> 16);
+
+ pcmciaWriteIndex (pcmciac, 0x3c4, 0x12, temp);
+ }
+}
+
+void
+pcmciaRecolorCursor (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;
+ }
+ pcmciaAllocCursorColors (pScreen);
+ pcmciaSetCursorColors (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
+pcmciaLoadCursor (ScreenPtr pScreen, int x, int y)
+{
+ SetupCursor(pScreen);
+ CursorPtr pCursor = pCurPriv->pCursor;
+ CursorBitsPtr bits = pCursor->bits;
+ int w, h;
+ CARD8 *ram;
+ CARD32 *msk, *mskLine, *src, *srcLine;
+ int i, j;
+ int cursor_address;
+ int lwsrc;
+ unsigned char ramdac_control_;
+ CARD32 offset;
+
+ /*
+ * Allocate new colors
+ */
+ pcmciaAllocCursorColors (pScreen);
+
+ pCurPriv->pCursor = pCursor;
+ pCurPriv->xhot = pCursor->bits->xhot;
+ pCurPriv->yhot = pCursor->bits->yhot;
+
+ /*
+ * Stick new image into cursor memory
+ */
+ if (pcmciac->HP) {
+ ram = (CARD8 *) pcmcias->cursor_base;
+ } else {
+ /* The last bank */
+ ram = (CARD8 *) pcmciac->fb;
+ pcmciaWriteIndex (pcmciac, 0x3ce, 0x09, 0x7f);
+ pcmciaWriteIndex (pcmciac, 0x3ce, 0x0A, 0x7f);
+ }
+
+ mskLine = (CARD32 *) bits->mask;
+ srcLine = (CARD32 *) bits->source;
+
+ h = bits->height;
+ if (h > PCMCIA_CURSOR_HEIGHT)
+ h = PCMCIA_CURSOR_HEIGHT;
+
+ lwsrc = BitmapBytePad(bits->width) / 4;
+
+ for (i = 0; i < PCMCIA_CURSOR_HEIGHT; i++) {
+ msk = mskLine;
+ src = srcLine;
+ mskLine += lwsrc;
+ srcLine += lwsrc;
+ for (j = 0; j < PCMCIA_CURSOR_WIDTH / 32; j++) {
+
+ CARD32 m, s;
+
+ if (i < h && j < lwsrc)
+ {
+ m = *msk++;
+ s = *src++;
+ InvertBits32(m);
+ InvertBits32(s);
+ }
+ else
+ {
+ m = 0;
+ s = 0;
+ }
+
+ /* Do 8bit access */
+ *ram++ = (m & 0xff);
+ *ram++ = (m & 0xff00) >> 8;
+ *ram++ = (m & 0xff0000) >> 16;
+ *ram++ = (m & 0xff000000) >> 24;
+ *ram++ = (s & 0xff);
+ *ram++ = (s & 0xff00) >> 8;
+ *ram++ = (s & 0xff0000) >> 16;
+ *ram++ = (s & 0xff000000) >> 24;
+ }
+ }
+
+ /* Set address for cursor bits */
+ if (pcmciac->HP) {
+ offset = pcmcias->cursor_base - (CARD8 *) pcmcias->screen;
+ offset >>= 10;
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x44, (CARD8) (offset & 0xff));
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x45, (CARD8) (offset >> 8));
+ } else {
+ pcmciaWriteIndex (pcmciac, 0x3c4, 0x13, 15); /* ?? */
+ }
+
+ /* Set new color */
+ pcmciaSetCursorColors (pScreen);
+
+ /* Enable the cursor */
+ if (pcmciac->HP)
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x50, 0xc1);
+ else
+ pcmciaWriteIndex (pcmciac, 0x3c4, 0x12, 0x05);
+
+ /* Move to new position */
+ pcmciaMoveCursor (pScreen, x, y);
+}
+
+static void
+pcmciaUnloadCursor (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ /* Disable cursor */
+ if (pcmciac->HP)
+ pcmciaWriteIndex (pcmciac, 0x3d4, 0x50, 0);
+ else
+ pcmciaWriteIndex (pcmciac, 0x3c4, 0x12, 0);
+}
+
+static Bool
+pcmciaRealizeCursor (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);
+ pcmciaLoadCursor (pScreen, x, y);
+ }
+ }
+ return TRUE;
+}
+
+static Bool
+pcmciaUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
+{
+ return TRUE;
+}
+
+static void
+pcmciaSetCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
+{
+ SetupCursor(pScreen);
+
+ pCurPriv->pCursor = pCursor;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ if (pCursor)
+ pcmciaLoadCursor (pScreen, x, y);
+ else
+ pcmciaUnloadCursor (pScreen);
+}
+
+miPointerSpriteFuncRec pcmciaPointerSpriteFuncs = {
+ pcmciaRealizeCursor,
+ pcmciaUnrealizeCursor,
+ pcmciaSetCursor,
+ pcmciaMoveCursor,
+};
+
+static void
+pcmciaQueryBestSize (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
+pcmciaCursorInit (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ if (!pcmcias->cursor_base)
+ {
+ pCurPriv->has_cursor = FALSE;
+ return FALSE;
+ }
+
+ pCurPriv->width = PCMCIA_CURSOR_WIDTH;
+ pCurPriv->height= PCMCIA_CURSOR_HEIGHT;
+ pScreen->QueryBestSize = pcmciaQueryBestSize;
+ miPointerInitialize (pScreen,
+ &pcmciaPointerSpriteFuncs,
+ &kdPointerScreenFuncs,
+ FALSE);
+ pCurPriv->has_cursor = TRUE;
+ pCurPriv->pCursor = NULL;
+ return TRUE;
+}
+
+void
+pcmciaCursorEnable (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ if (pCurPriv->has_cursor)
+ {
+ if (pCurPriv->pCursor)
+ {
+ int x, y;
+
+ miPointerPosition (&x, &y);
+ pcmciaLoadCursor (pScreen, x, y);
+ }
+ else
+ pcmciaUnloadCursor (pScreen);
+ }
+}
+
+void
+pcmciaCursorDisable (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ if (pCurPriv->has_cursor)
+ {
+ if (pCurPriv->pCursor)
+ {
+ pcmciaUnloadCursor (pScreen);
+ }
+ }
+}
+
+void
+pcmciaCursorFini (ScreenPtr pScreen)
+{
+ SetupCursor (pScreen);
+
+ pCurPriv->pCursor = NULL;
+}
diff --git a/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciashadow.c b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciashadow.c
new file mode 100644
index 000000000..eb6e64873
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciashadow.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * 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 Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE 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.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/pcmciashadow.c,v 1.2 2001/05/29 17:47:55 keithp Exp $ */
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "font.h"
+#include "dixfontstr.h"
+#include "fontstruct.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "globals.h"
+#include "gcstruct.h"
+#include "shadow.h"
+#include "fb.h"
+
+void
+tridentUpdatePacked (ScreenPtr pScreen,
+ shadowBufPtr pBuf)
+{
+ RegionPtr damage = &pBuf->damage;
+ PixmapPtr pShadow = pBuf->pPixmap;
+ shadowScrPriv(pScreen);
+ int nbox = REGION_NUM_RECTS (damage);
+ BoxPtr pbox = REGION_RECTS (damage);
+ FbBits *shaBase, *shaLine, *sha;
+ FbStride shaStride;
+ int scrBase, scrLine, scr;
+ int shaBpp;
+ int shaXoff, shaYoff; /* XXX assumed to be zero */
+ int x, y, w, h, width;
+ int i;
+ FbBits *winBase, *win;
+ CARD32 winSize;
+
+ fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
+ while (nbox--)
+ {
+ x = pbox->x1 * shaBpp;
+ y = pbox->y1;
+ w = (pbox->x2 - pbox->x1) * shaBpp;
+ h = pbox->y2 - pbox->y1;
+
+ scrLine = (x >> FB_SHIFT);
+ shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
+
+ x &= FB_MASK;
+ w = (w + x + FB_MASK) >> FB_SHIFT;
+
+ while (h--)
+ {
+ winSize = 0;
+ scrBase = 0;
+ width = w;
+ scr = scrLine;
+ sha = shaLine;
+ while (width) {
+ /* how much remains in this window */
+ i = scrBase + winSize - scr;
+ if (i <= 0 || scr < scrBase)
+ {
+ winBase = (FbBits *) (*pBuf->window) (pScreen,
+ y,
+ scr * sizeof (FbBits),
+ SHADOW_WINDOW_WRITE,
+ &winSize,
+ pBuf->closure);
+ if(!winBase)
+ return;
+ scrBase = scr;
+ winSize /= sizeof (FbBits);
+ i = winSize;
+ }
+ win = winBase + (scr - scrBase);
+ if (i > width)
+ i = width;
+ width -= i;
+ scr += i;
+ {
+ CARD16 *sha16 = (CARD16*)sha;
+ CARD16 *win16 = (CARD16*)win;
+ while (i--)
+ {
+ *win16++ = *sha16++;
+ *win16++ = *sha16++;
+ }
+ }
+ }
+ shaLine += shaStride;
+ y++;
+ }
+ pbox++;
+ }
+}
+
+void
+cirrusUpdatePacked (ScreenPtr pScreen,
+ shadowBufPtr pBuf)
+{
+ RegionPtr damage = &pBuf->damage;
+ PixmapPtr pShadow = pBuf->pPixmap;
+ shadowScrPriv(pScreen);
+ int nbox = REGION_NUM_RECTS (damage);
+ BoxPtr pbox = REGION_RECTS (damage);
+ FbBits *shaBase, *shaLine, *sha;
+ FbStride shaStride;
+ int scrBase, scrLine, scr;
+ int shaBpp;
+ int shaXoff, shaYoff; /* XXX assumed to be zero */
+ int x, y, w, h, width;
+ int i;
+ FbBits *winBase, *win;
+ CARD32 winSize;
+
+ fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
+ while (nbox--)
+ {
+ x = pbox->x1 * shaBpp;
+ y = pbox->y1;
+ w = (pbox->x2 - pbox->x1) * shaBpp;
+ h = pbox->y2 - pbox->y1;
+
+ scrLine = (x >> FB_SHIFT);
+ shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
+
+ x &= FB_MASK;
+ w = (w + x + FB_MASK) >> FB_SHIFT;
+
+ while (h--)
+ {
+ winSize = 0;
+ scrBase = 0;
+ width = w;
+ scr = scrLine;
+ sha = shaLine;
+ while (width) {
+ /* how much remains in this window */
+ i = scrBase + winSize - scr;
+ if (i <= 0 || scr < scrBase)
+ {
+ winBase = (FbBits *) (*pBuf->window) (pScreen,
+ y,
+ scr * sizeof (FbBits),
+ SHADOW_WINDOW_WRITE,
+ &winSize,
+ pBuf->closure);
+ if(!winBase)
+ return;
+ scrBase = scr;
+ winSize /= sizeof (FbBits);
+ i = winSize;
+ }
+ win = winBase + (scr - scrBase);
+ if (i > width)
+ i = width;
+ width -= i;
+ scr += i;
+ {
+ CARD8 *sha8 = (CARD8*)sha;
+ CARD8 *win8 = (CARD8*)win;
+ while (i--)
+ {
+ *win8++ = *sha8++;
+ *win8++ = *sha8++;
+ *win8++ = *sha8++;
+ *win8++ = *sha8++;
+ }
+ }
+ }
+ shaLine += shaStride;
+ y++;
+ }
+ pbox++;
+ }
+}
diff --git a/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciastub.c b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciastub.c
new file mode 100644
index 000000000..be5498ec9
--- /dev/null
+++ b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciastub.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK.
+ *
+ * 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 Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE 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.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/pcmciastub.c,v 1.1 2001/05/23 08:56:09 alanh Exp $ */
+
+#include "pcmcia.h"
+
+void
+InitCard (char *name)
+{
+ KdCardAttr attr;
+
+ KdCardInfoAdd (&pcmciaFuncs, &attr, 0);
+}
+
+void
+InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ KdInitOutput (pScreenInfo, argc, argv);
+}
+
+void
+InitInput (int argc, char **argv)
+{
+ KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs);
+}
+
+extern pcmciaDisplayModeRec pcmciaDefaultModes[];
+
+int
+ddxProcessArgument (int argc, char **argv, int i)
+{
+ return KdProcessArgument (argc, argv, i);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/OS2Notes.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/OS2Notes.sgml
new file mode 100644
index 000000000..832e9f63a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/OS2Notes.sgml
@@ -0,0 +1,214 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+<article>
+
+<title>Notes on Rebuilding XFree86/OS2 from Scratch
+<author>Holger Veit
+<date>Last modified March 8th, 2000
+
+<toc>
+
+<sect>Preface
+<p>
+X11 and XFree86 were initially developed on Unix-based systems. Usually
+Unix systems provide a rich number of tools and utilities to get certain
+things done. Under OS/2, these tools are not installed, but ports are
+available which are sometimes functionally equivalent to Unix utilities
+with the same name, but also differ sometimes in a subtle way.
+This guide will give you hints if you intend to rebuild the system
+from scratch under OS/2.
+<p>
+Please also read <htmlurl name=README.OS2 url=OS2.html> for end-user
+information, and set at least the environment variables described there.
+<p>
+At the current time, the most recent version available is XFree86-4.0.
+This is a full and unrestricted version which comes with complete source
+code. 4.0 is a highly experimental release, so many features that might
+have worked in earlier versions, may now no longer work, or work differently.
+Be aware that for OS/2, XFree86-4.0 is considered to be alpha software.
+
+If you want to join the XFree86 developer team, e.g. to add support for
+certain hardware, please send a request to BOD@XFree86.org. Please
+think about such a step carefully before, though, since much work is
+involved. Please use the XFree86-4.0 source code as a test example how
+to compile the system. The ability to manage that is a basic requirement
+for becoming a developer.
+
+
+<sect>Tools required
+<p>
+
+I have tried to reduce the number of external tools, but when looking back
+it seems I were not very successful. At least I managed to get everything
+working with the native CMD.EXE shell only. However, there is still plenty
+of software required.
+Most of this software is available from <tt/hobbes.nmsu.edu/ or <tt/ftp.leo.org/
+via anonymous FTP. The following shopping list shows what you will need:
+
+<itemize>
+<item>gcc EMX/gcc emx 0.9C patch4 or later (0.9d preferred!)
+<item>gzip GNU zip/unzip
+<item>tar GNU tar
+<item>patch Larry Wall's patch utility (attention: incompatible tool with same name in OS/2)
+<item>install BSD/GNU install
+<item>rm,mv,cp GNU file utilities
+<item>tee,.. GNU shell utilities
+<item>groff GNU nroff/troff
+<item>sed GNU sed stream editor
+<item>grep GNU grep
+<item>gawk GNU awk
+<item>make GNU make 3.71/3.72 (use the one from Xprog.zip!)
+<item>flex GNU flex
+<item>bison GNU bison
+<item>m4 GNU m4
+<item>find GNU find (attention: incompatible tool with the same name in OS/2)
+</itemize>
+
+If there is no version number given, any new version will do. Particularly
+critical is only EMX/gcc and GNU make. Note that the second GCC implementation
+which might still be available from some archives is NOT compatible.
+
+Furthermore, you need the XFree86 sources. These are available from
+the common XFree86 repositories. Look into a directory which is
+often named /pub/XFree86/4.0/source.
+
+<sect>Compiling and Installing
+<p>
+
+You need about 300MB of free HPFS space for the whole system. This does not
+include space for the postscript and troff documentation files. I have never
+installed them. Nor did I install the test subtree.
+
+<enum>
+<item>Install all the above utilities. Refer to the corresponding documentation.
+ Verify that everything works well, particularly EMX.
+<item>It is a good idea to use the same or a similar structure I have.
+ I have made a directory <tt>&bsol;x11</tt> on the partition for compiling and have
+ put everything below this tree. I found that a clean tree occupies
+ less than the half space of the disk, this gives me the opportunity to
+ rename this tree to <tt>&bsol;x11old</tt> and copy a new version to the
+ same disk to produce diffs. Last time the complete tree was
+ arranged under the root directory <tt>xc</tt>, this would become
+ <tt>&bsol;x11&bsol;xc</tt> then.
+<item>To unpack the files you would usually execute the command
+ <verb>gzip -dc file.tar.gz | tar xvf -</verb>
+ in the <tt>&bsol;x11</tt> directory. At the end you will usually see the
+ irritating, but non-fatal message "gzip: stdout Broken pipe". Ignore it.
+<item>After that, is is likely necessary to apply some patches, either from
+ the XConsortium or from the XFree86 project. Before you do this, enter
+ <verb>
+ chmod -R a+rw &bsol;x11&bsol;xc
+ </verb>
+ to make certain files in the tree writable.
+<item>There should be a file <tt>added-XXX</tt> accompanying the patch file
+ which lists the files that are newly created. The patch program has
+ a problem with creating new directories, so we need to create them
+ on advance. For each <tt/added-XXX/ file you find, execute from
+ <tt>&bsol;x11</tt> <verb>xc&bsol;config&bsol;util&bsol;added added-XXX</verb>
+ If there is no <tt>added-XXX</tt> file available, you can make one with
+ the following instructions:
+ <verb>
+ grep "&bsol;*&bsol;*&bsol;* xc/" patchfile >added-file
+ </verb>
+ Edit <tt/added-file/ with a text editor and remove the <tt/*** / at
+ the beginning and the time stamp at the end (search for a TAB and
+ erase to the end of the line). You get a list of file paths, one in a
+ line, which is the input to the added utility.
+<item>After that you can apply the patches in the right order. Usually this
+ is done by a command
+ <verb>
+ patch -p -E <patchfile 2>&1 | tee patchlog
+ </verb>
+ from the <tt>&bsol;x11</tt> directory. Be aware to use the right
+ patch - OS/2 has a utility with the same name and different functionality.
+ Don't use the recommended <tt/-s/ option, this makes <tt/patch/ quiet,
+ and you won't see problems in the patchlog file. Use
+ <verb>
+ find &bsol;x11 -name *.rej -print
+ find &bsol;x11 -name *# -print
+ </verb>
+ to find any rejects and unapplied patches (attention: yet another OS/2
+ program with wrong functionality). Normally there shouldn't
+ be any problems of this kind, else you have made a mistake. Finally
+ remove the original files with
+ <verb>
+ find &bsol;x11 -name *.orig -print -exec rm {} ;
+ </verb>
+<item>Go to the <tt>xc/config/cf</tt> directory and edit the <tt>xf86site.def</tt>
+ file to match your requirements (you probably don't want to compile
+ all X servers). Certain changes must be set to the following values:
+ <itemize>
+ <item>Disable if not already done any PC98 server; PC98 (Japanese XFree86)
+ does not work yet. Porters from Japan are welcome!
+ <item><tt>&num;define WacomSupport NO
+ &num;define ElographicsSupport NO</tt>
+ Both options are not yet supported.
+ <item>Tcl* and Tk* don't need to be set explicitly. Reasonable defaults
+ are in the other config files, provided you have a complete
+ XFree86/OS2 binary tree with the tcl/tk runtime support installed.
+ <item><tt>&num;define BuildDynamicLoading NO</tt>
+ This does not work.
+ </itemize>
+<item>Go to the directory <tt>xc&bsol;util&bsol;compress</tt> and
+ <tt>make compress.exe</tt> there. Install the program produced
+ there in your path. I stumbled more than once on half-ported
+ compress programs on OS/2 ftp servers that are defective w.r.t.
+ reading and writing stdin/stdout. In some stage (font compression)
+ otherwise you will get a core dump of mkfontdir, because all
+ compressed fonts are corrupt.
+<item>Set the environment variable <tt/X11ROOT/ to something different than
+ it is; otherwise the installation process will overwrite your
+ original XFree86/OS2 installation. If you have not set this variable,
+ go back to the prefix section of this document: you have forgotten
+ something.
+<item>Copy the file <tt>xc/programs/Xserver/hw/xfree86/etc/bindist/OS2/host.def.os2</tt>
+ to the location <tt>xc/config/cf/host.def</tt>. Use this file to do
+ any specific modifications to imake variables, rather than editing
+ the file xfree86.cf, imake.tmpl, or os2.cf directly.
+<item>Copy the file <tt>xc/config/util/buildos2.cmd</tt> into the <tt/xc/
+ directory. If this is a second or later attempt, you might need to
+ copy the saved toplevel Makefile.os2 back to Makefile.
+<item>Execute this <tt/buildos2.cmd/ command in the <tt/xc/ directory;
+ it will produce a logfile <tt>buildxc.log</tt> in this directory.
+<item>Go have a bucket of coffee, or better, buy new coffee - in Colombia!
+ The compile will need between 2 and 20 hours, depending on your
+ selections, and the horse power of your hardware.
+<item>When finished, view the logfile for errors, and fix the problems if
+ there are some. I have managed to compile the whole system
+ flawlessly, so there is at least one configuration that works.
+<item>Finally, from the <tt/xc/ dir, execute
+ <verb>
+ xmake install
+ xmake install.man
+ </verb>
+<item>There are a few minor glitches in the installation:
+<enum>
+<item>The xdm and linkkit directories will fail in compile and installation.
+ This is no problem and has no effect on the rest of the system.
+<item>The imake.exe which is installed in <tt/&bsol;XFree86&bsol;bin/ is usually defective.
+ The one which was built initially and installed in the root directory
+ of the drive where you have the source tree is okay. So simply copy
+ this <tt/&bsol;imake.exe/ to the <tt/&bsol;XFree86&bsol;bin/ directory
+ manually. Some day this might be fixed.
+<item><tt/XF86Setup/ is not ported yet and won't work with the tcl/tk port
+ available for XFree86/OS2. My idea was to replace this by some native
+ installation tool, which I didn't find the time to do yet. Feel free
+ to spend a bit of time to play with XF86Setup if you like.
+</enum>
+</enum>
+
+Well, you see, this was quite easy :-)
+
+
+
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/OS2Notes.sgml,v 1.1 2001/06/04 13:50:15 dawes Exp $
+
+
+
+
+
+$XConsortium: OS2note.sgml /main/1 1996/02/24 10:08:59 kaleb $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/QuickStart.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/QuickStart.sgml
new file mode 100644
index 000000000..af510ecd4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/QuickStart.sgml
@@ -0,0 +1,679 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+
+<title>Quick-Start Guide to XFree86 Setup
+
+<author>Joe Moss
+<date>27 February 1998
+
+<abstract>
+ Current releases of XFree86 include several tools that can help
+to automate the process of server configuration. Much of the existing
+documentation, however, describes how to do the job manually, including
+many technical details.
+
+ For those users with esoteric hardware or with the desire to
+get their hands dirty under the hood, this is great, but many users are
+using common hardware and just want to get X up and running quickly.
+This guide is for them.
+
+</abstract>
+
+<toc>
+
+<sect> Before You Start
+<p>
+ There are a few bits of information that you will need to have
+ before you can setup the server:
+ <descrip>
+ <tag> The model name of your video card </tag>
+ Make sure you know the exact model name of the card. It
+ may help to also know the graphics chipset, RAMDAC, and
+ clock chip used on your card.
+ <tag> The amount of memory on your video card </tag>
+ Find out how many megabytes of RAM are on your video card.
+ <tag> Whether or not your card is VGA compatible </tag>
+ Most cards these days are VGA compatible, but for example,
+ if you have and older monochrome card, it might not be.
+ <tag> Your monitor's specifications </tag>
+ Specifically, you need to know the horizontal sync rate(s),
+ and vertical refresh rate(s). These are <bf>important</bf>!
+ Consult your monitor's manual.
+ <tag> The protocol used by your mouse </tag>
+ It will help speed up the process, if you know which protocol
+ is used by your mouse to communicate. Some mice are capable
+ of using two different protocols, although the method of
+ switching between them varies. In some cases, with new
+ Plug-n-Play mice, the protocol can be determined
+ automatically.
+ </descrip>
+
+<sect> What to Do - An Overview
+<p>
+ There are three tools that can be used to set up XFree86:
+ <itemize>
+ <item>XF86Setup
+ <item>xf86config
+ <item>xvidtune
+ </itemize>
+<p>
+ XF86Setup primarily uses a graphical user interface and
+ is the preferred tool for initial setup, but there
+ are a few cases where it can't be used. If you are using a
+ card that is not VGA compatible, have a fixed-frequency
+ monitor, or are running OS/2, you'll not be able to use
+ XF86Setup, read about xf86config instead.
+ If you have limited RAM or a slow system, you might be better
+ off using xf86config as well.
+<p>
+ The xf86config program is text based only, but works for almost
+ any hardware combination. If you have a fixed frequency
+ monitor that won't work with standard text modes, you
+ will have to read the necessary documentation and
+ do the configuration manually.
+<p>
+ To get things looking just right, you may need to use
+ <tt>xvidtune</tt>, a program that allows you to make adjustments
+ to the displayed image (e.g. make it wider, move it a little
+ to the left, etc.). XF86Setup will allow you to run xvidtune
+ at the appropriate time; if you use xf86config, you can use
+ xvidtune afterwards.
+<p>
+ All of these are explained in detail in the following
+ sections. If you're the type that doesn't like to read
+ the documentation, but would rather just try and figure
+ your way through things, you can just type <tt/XF86Setup/
+ now.
+ If you have problems, the documentation will still be here.
+<p>
+ Although it is possible to use XF86Setup from within X to
+ make changes to your existing configuration, such use is
+ not specifically documented here. These instructions are
+ primarily for those initially setting up XFree86 on their
+ system.
+
+<sect> Using <tt>XF86Setup</tt>
+<p>
+ XF86Setup will first check around to make sure certain files
+ are installed and that you are running as root. If a problem
+ is found, it will display a message and exit. Correct the
+ problem (e.g. install the missing files) and run it again.
+
+ XF86Setup is internationalized. If you are Japanese and set
+ the LANG environment variable to ja, japan, japanese, etc.,
+ XF86Setup's screen can be Japanized. But it is necessary that
+ XF86Setup is built with Japanized Tcl/Tk. Other language can
+ be added, if you prepare its own directory under the directory
+ XF86Setup/texts. Please see under the directory
+ XF86Setup/texts/generic.
+
+<sect1> Initial questions
+<p>
+ If you have an existing XF86Config file, you will be asked if
+ you would like to use it to set the default values of various
+ configuration settings. If you've already got an (at least
+ somewhat) working configuration you will want to do this.
+
+ If you are running on an OS which has a mouse driver in the
+ kernel (e.g. SCO or SVR4), you may be asked if you'd like to
+ use it.
+
+ Once the questions (if any) are completed, you will see a message
+ indicating that the program is ready to switch into graphics mode.
+ Just press Enter. If you don't get a graphics screen saying
+ <it/Welcome to XFree86 Setup/ within a minute, something has
+ probably hung, you can try pressing Ctrl-Alt-Backspace to
+ switch back to text mode and you'll probably have to use
+ xf86config instead of XF86Setup.
+
+<sect1> Configuration areas
+<p>
+ Once the VGA16 server is started, and once the program has
+ finished loading, you will see a screen with six
+ buttons along the top and three along the bottom.
+ The buttons along the top correspond to the general categories
+ of configuration settings. They can be done in any order.
+ Each of these areas is explained in detail below.
+ The bottom row consists of the <bf/Abort/,
+ <bf/Done/, and <bf/Help/ buttons.
+<p>
+ <bf/Abort/ does as it name implies. It exits the program
+ without saving any changes that have been made. The one
+ possible exception is the link to the mouse device. Any
+ change to that is made as soon as <bf/Apply/ is selected.
+<p>
+ <bf/Done/ should be selected when you've finished
+ configuration in each of the various categories.
+<p>
+ The <bf/Help/ can be pressed at any time to get on-line
+ help regarding the current configuration screen.
+<p>
+ You should start with configuring your mouse as it will make
+ things a lot easier to perform the configuration of other
+ categories.
+
+<sect2> Mouse
+<p>
+ The mouse configuration screen is used to get the mouse working
+ properly. There are key bindings for everything so that you
+ can easily configure the mouse, if it's not already working.
+<p>
+ The screen includes a representation of a white mouse with
+ three buttons. As you move your mouse it should show the
+ pointer coordinates on the mouse and the buttons should turn
+ black as you press the corresponding button on your mouse.
+ If that is not happening, then your mouse is not correctly
+ configured.
+<p>
+ Along the top are some rows of buttons corresponding to
+ the various possible protocols. There will also be
+ several buttons and a couple of sliders
+ for other settings, a visual representation of the mouse,
+ and a button to apply any changes.
+ There may also be an entry box in which the
+ device can be set along with a list of possible devices.
+<p>
+ First try moving your mouse around and see if the pointer moves
+ correctly. If so, try testing that the buttons are working
+ properly. If those are working as desired, go ahead and go on
+ to another configuration area.
+<p>
+ If the mouse pointer doesn't move at all, you need to fix
+ either the mouse device or the protocol (or both).
+ You can press 'n' followed by a Tab, to move to the list
+ of mouse devices and select a different one.
+ Pressing 'p' will pick the next available protocol on the list
+ (protocols that are not available on your OS will be
+ greyed-out). If you have a PnP mouse, it may be easiest to
+ just select "Auto" as the protocol.
+ After changing these, press 'a' to apply the changes and try
+ again. Repeat the process until you are getting some response
+ from your mouse.
+<p>
+ If the mouse pointer or button indicators do something when you
+ move the mouse, but the pointer is not moving properly, you
+ probably have the wrong protocol selected. Try with a different
+ one.
+<p>
+ Most mice these days use the <bf/Microsoft/ protocol, the second
+ most common is <bf/MouseSystems/. Some mice do both.
+ These <it/dual-protocol/ mice have various methods of switching
+ between the two protocols.
+ Some have a switch on the mouse itself.
+ Some are switched by sending a certain signal to the mouse
+ when opening a connection to the mouse.
+ These signals can be controlled by using different
+ combinations of the 'ClearDTR' and 'ClearRTS' settings.
+ Other mice require a button to be depressed when the mouse
+ is opened (when the mouse driver first tries to talk to it).
+ If your mouse uses this method, hold down the appropriate
+ button while selecting apply (pressing 'a').
+<p>
+ Once the mouse pointer is moving correctly, test that all
+ three buttons are working properly. If your mouse only has
+ two buttons, select 'Emulate3Buttons' and you should be able
+ to press both buttons simultaneously to emulate the missing
+ middle button. If not all of the buttons are working, try
+ changing the 'ChordMiddle' setting or you may be using a
+ protocol that is similar to that of your mouse,
+ but not quite right.
+
+<sect2> Keyboard
+<p>
+ You need to specify the model and layout of your keyboard (and
+ press apply) if they are not already correct.
+ The graphical representation of the keyboard will be
+ updated when you choose a different model.
+<p>
+ For non-U.S. keyboards you may wish to choose a variant from
+ the list (at this time there is only one available variant:
+ <tt/nodeadkeys/>).
+<p>
+ You can also pick from the options to the right, if you wish.
+
+<sect2> Card
+<p>
+ Pick your card from the list.
+<p>
+ If there are README files that may pertain to your card
+ the 'Read README file' button will then be usable (i.e. not
+ greyed out).
+ Please read them.
+<p>
+ If your card is not in the list, or if there are any
+ special settings listed in the README file as required
+ by your card, you can press the 'Detailed Setup'
+ button to make sure that the required settings are selected.
+ Otherwise, you're finished with configuring your card.
+<p>
+ To use 'Detailed Setup':
+ First select the appropriate server for your card.
+ Then read the README file corresponding to the selected
+ server by pressing the 'Read README file' button
+ (it won't do anything, if there is no README).
+<p>
+ Next, pick the chipset, and Ramdac of your card, if
+ directed by the README file.
+ In most cases, you don't need to select these,
+ as the server will detect (probe) them automatically.
+<p>
+ The clockchip should generally be picked, if your card
+ has one, as these are often impossible to probe
+ (the exception is when the clockchip is built
+ into one of the other chips).
+<p>
+ Choose whatever options are appropriate (again,
+ according to the README).
+<p>
+ You can also set the maximum speed of your Ramdac.
+ Some Ramdacs are available with various speed ratings.
+ The max speed cannot be detected by the server
+ so it will use the speed rating of the slowest version
+ of the specified Ramdac, if you don't specify one.
+<p>
+ Additionally, you can also specify the amount of RAM on your
+ card, though the server will usually be able to detect this.
+
+
+<sect2> Modeselect
+<p>
+ Use this one to pick which depth you prefer to use (this
+ determines how many colors can be displayed at a time)
+ and to select all of the modes you are interested in
+ possibly using.
+<p>
+ Your hardware may not be able to support all
+ of depth and mode combinations that can be selected.
+ Any unsupported combinations will automatically be
+ rejected by the server when it tries to startup.
+ Note also that if you select multiple modes, you will
+ get a virtual screen as large as the largest of the
+ usable modes.
+
+<sect2> Monitor
+<p>
+ Enter the horizontal and vertical frequency ranges that your
+ monitor supports in the corresponding entry boxes near the
+ top of the screen.
+ You can enter specific frequencies or ranges of frequencies
+ (separated by hyphens).
+ If the monitor supports several different frequencies or
+ ranges, list them all, separated by commas.
+<p>
+ If you can not find this information in you monitor's manual,
+ pick one of the choices from the list of common monitor
+ capabilities. The program will use conservative values
+ for each of these, so you'll get better performance if you
+ type in the correct values from your monitor manual.
+
+<sect2> Other
+<p>
+ You can probably just skip this one.
+
+<sect2> Completing the configuration
+<p>
+ Once you've finished with the above, press the 'Done' button
+ and then the 'Okay' button which will appear. You will then
+ be switched back to text mode.
+
+<sect1> Back to text mode
+<p>
+ The program will now attempt to start the appropriate server
+ for your card, with all of the
+ configuration settings you selected.
+ If for some reason it is unable to start the server, you have
+ likely selected an improper setting and will be asked if you
+ would like to return to the graphical configuration screen
+ and try again.
+
+<sect1> The second server
+<p>
+ This is unlikely to happen, but
+ if when the server starts, the display is unreadable, try
+ pressing Ctrl-Alt-+ (using the plus on the numeric keypad)
+ to switch to a different video mode.
+<p>
+ The display will show an entry box and three buttons.
+<p>
+ The first button allows you to run xvidtune to adjust your
+ video modes. One important point to keep in mind when using
+ xvidtune is that switching video modes with Ctrl-Alt-+ is
+ disabled while xvidtune is running.
+ You must use the 'Next' and 'Prev' buttons to switch modes.
+ Because of this, you should be careful not to move the mouse
+ when pressing either of these. If by some chance the mode
+ you switch to doesn't produce a readable display on your
+ monitor, you can then just press the mouse button again to
+ move to the next (hopefully readable) mode.
+<p>
+ The second button causes the settings you've made to be
+ written to the filename given in the entry box.
+ After saving the settings a message will appear indicating
+ that it has finished. Just press the 'Okay' button and
+ you're done.
+<p>
+ And the third button causes the program to exit without
+ saving any of the configuration settings.
+
+<sect1> Ending text
+<p>
+ You are returned to text mode and the program will print a
+ `Configuration complete.' message. You should now have a
+ usable configuration file and can start the X server by
+ whichever method you wish (usually either the 'startx'
+ command or via 'xdm').
+
+<sect> Running <tt>xf86config</tt>
+<p>
+ From a text screen, run the <tt/xf86config/ program. This
+ program should be run as <it/root/ (although not absolutely
+ necessary, it will allow xf86config to do more of the work
+ for you). You can press your interrupt character (usually
+ Control-C or perhaps Delete), at any time to stop the program,
+ if you need to. You can just start it over again.
+
+ The <tt/xf86config/ program provides instructions on screen
+ as to what you need to do. Following are some notes that
+ document the various stages in the process. They should help
+ you get through the process quickly and provide some
+ documentation for those people who like to know what they're
+ getting themselves into, before running a program.
+
+<sect1> The intro screen
+<p>
+ First, <tt/xf86config/ begins by telling you a few things like
+ the fact that it can help you setup an XF86Config file or that
+ you can do the job yourself with an editor. Just read what
+ it says and press <sf/Enter/ when done.
+
+<sect1> Getting your <tt>PATH</tt> right
+<p>
+ The program will next check that you have the directory
+ <tt>/usr/X11R6</tt> (the standard installation directory)
+ on your system and tell you that it needs to be in your
+ <tt/PATH/ environment variable.
+
+ It will also check if you have the
+ <tt>/usr/X386</tt> directory as used by older (pre 3.0)
+ versions of XFree86. If by chance you do, it will warn you
+ that <tt>/usr/X11R6</tt> must be before <tt>/usr/X386</tt>
+ in your <tt/PATH/.
+
+ If everything is okay, just press Enter and go on, otherwise
+ press Control-C to exit and make any necessary changes and
+ restart <tt/xf86config/.
+
+<sect1> Mouse setup
+<p>
+ Pick the mouse type from the menu and enter the name of the
+ device to which mouse is connected, as directed.
+
+ If you are using an OS (e.g. SVR4, SCO) that has a built in
+ mouse driver that the Xserver could use, you'll need to edit
+ the XF86Config file to setup your mouse, so just pick any
+ mouse from the list and press enter when asked for the device.
+
+ If you don't know which protocol your mouse uses, you'll just
+ have to guess (the xf86config program will give you some hints
+ as to which might be most likely) and then see the
+ troubleshooting section if it doesn't work when you run the
+ server.
+
+ The xf86config program has not been updated to allow you to
+ select the latest mouse protocols, so you may have to edit
+ the config file by hand after xf86config has finished.
+
+<sect1> Keyboard setup
+<p>
+ Simply answer yes to the question regarding keyboard setup.
+
+ If there is some reason you need to use the right-alt and
+ control keys for something else, you can enter no.
+
+<sect1> Monitor setup
+<p>
+ Setting up a monitor consists of entering the specifications
+ of your monitor and a description of the model and manufacturer.
+
+ You are first asked for the horizontal sync rate. It is
+ <bf/VERY/ important to enter the correct value(s) from the
+ manual. If one of the ranges given matches the rate of your
+ monitor, then pick it, otherwise pick <tt/custom/ and enter
+ the values from your manual.
+
+ Next is the vertical refresh rate. Again, it is <bf/VERY/
+ important that this parameter be specified correctly.
+ Enter it in a manner similar to the horizontal sync rate.
+
+ <it>If either rate is mis-specified, it can result in damage
+ to your monitor.</it>
+
+ Finally, you are asked for an "identifier", your monitor
+ manufacturer, and model. You can just press enter to
+ get through these quickly.
+
+<sect1> Selecting your card
+<p>
+ You are next asked if you would like to view the database of
+ cards. Picking your card from the list will cause the answers
+ to the questions in the next two sections to be filled in for
+ you and so can save a little time.
+
+ If your card does not appear in the list, just press <tt/q/
+ and enter to skip on to the next step - where you'll have to
+ answer the questions yourself.
+
+<sect1> Server selection
+<p>
+ If you selected your card in the previous step, then server
+ selection is easy - just use the recommendation from the
+ database.
+
+ If you have a card which uses one of the chipsets for which a
+ specific server exists (Mach8, Mach32, Mach64, AGX/XGA,
+ 8514/A, S3, I128, P9000) you'll want to pick the
+ <tt/accel/ option.
+
+ Otherwise you'll probably want to use the SVGA server.
+
+ Next, answer yes when the program asks if you want it to
+ set the symbolic link for you. If you picked the <tt/accel/
+ option, you'll also need to indicate which particular
+ accelerated server to link to.
+
+<sect1> Screen/Video configuration
+<p>
+ Pick the appropriate option from the list to indicate the
+ amount of memory on your video card.
+
+ Then you are asked to provide and identifier, the manufacturer,
+ and the model of your card. You can just press enter to skip
+ through these, if you wish.
+
+ Next, the program will ask for the type of RAMDAC and Clockchip
+ on your card. If your card was in the database, you should
+ just to tell it to use the values from the database.
+
+ If you don't have one of the listed RAMDACs or Clockchips
+ on your card, just press enter when asked what type you have.
+ If you do not have a programmable clock chip, the program will
+ next attempt to probe to find out what clock rates are
+ supported by your clock chip.
+
+<sect1> Mode Selection
+<p>
+ Now you get to tell the program which video modes you would
+ like to be able to run.
+
+ The program will show you the common modes that should work
+ with your card (some might not work with your monitor, but
+ if you've correctly specified the monitor's sync rates, the
+ X server will just ignore them when it runs).
+
+ You could just accept the settings as they are given, but
+ you'll probably wish to reverse the order. For example, if
+ you have a card with 1 Meg RAM, it will list the modes
+ <tscreen><verb>
+ "640x480" "800x600" "1024x768" for 8bpp
+ </verb></tscreen>
+
+ Select <tt/1/ to change the settings for 8bpp and the type
+ <tt/432/ to select the reverse order.
+
+ When you've select the modes, in the order you wish, select
+ option <tt/4/ to continue.
+
+<sect1> Creating the <tt>XF86Config</tt> file
+<p>
+ The program will now ask if you would like to write the
+ configuration settings you've selected to the file
+ <tt/XF86Config/. Answer yes.
+
+<sect1> Some final notes
+<p>
+ Lastly, the program tells you that it's finished its part
+ of this process and counsels you to check the file before
+ using it. The next section covers the changes that are most
+ likely to be needed.
+
+<sect> Fixing the XF86Config file
+<p>
+ Use an editor to look at the <tt/XF86Config/ file. Here are
+ some things that may need to be changed:
+ <itemize>
+ <item>If you are running an operating system which has
+ built-in mouse support, you'll want to change the
+ <tt/Pointer/ section. Specifically, you should set
+ the <tt/Protocol/ to <tt/OSMouse/ (SCO) or <tt/Xqueue/
+ (SVR4, some SVR3) and you should remove the <tt/Device/
+ line.
+ <item>If you are running a system with the Xqueue event driver
+ and would like to use it, change the <tt/Protocol/
+ setting in the <tt/Keyboard/ section to <tt/Xqueue/.
+<!-- What else should be added here? -->
+ </itemize>
+
+ Once you are satisfied that the configuration is correct, copy
+ the XF86Config file to <tt>/usr/X11R6/lib/X11</tt> and run
+ the 'startx' command.
+
+ You should now have a running X server. If it's running but
+ the display doesn't look as good as you think it should (i.e.
+ it doesn't fill the whole screen, it's off-center, it's wrapping
+ around on one side, etc.) see the section on <tt/xvidtune/.
+ If there is some other problem, see the troubleshooting section.
+
+<sect> Running <tt>xvidtune</tt>
+<p>
+ If you need to make adjustments to the video display,
+ <tt/xvidtune/ is the tool to use.
+
+ Simply enter the command <tt/xvidtune/ from a shell prompt
+ within an xterm. Read the warning and click on <tt/OK/.
+ Next click on the <tt/Auto/ button.
+
+ Now click on whatever combination of <tt>Up/Down/Left/Right</tt>
+ <tt>Shorter/Taller/Wider/Narrower</tt> is need to adjust
+ the display to your liking.
+
+ If you are using a recent S3-based card there will be some
+ extra buttons and entries at the bottom (InvertVCLK, EarlySC,
+ and Blank Delays). These can help solve problems of the
+ display wrapping around a few pixels.
+
+ Once the display has been adjusted properly, press the <tt/show/
+ button to printout the correct <tt/ModeLine/ to put in the
+ <tt/XF86Config/ to make the server always use the current
+ display settings. To aid in copying this information to your
+ XF86Config file, the modeline is also made the current
+ selection allowing you to just paste it into your editor.
+
+ If you would like to adjust your other modes, you can click
+ on the <tt/Next/ and <tt/Prev/ buttons to switch modes.
+
+ When you are through using <tt/xvidtune/ simply press on the
+ <tt/Quit/ button.
+
+<sect> Troubleshooting
+<p>
+ Since you're reading this, something must not have gone
+ the way you had hoped (or else you just really enjoy reading).
+
+ Below are listed some common problems that may occur
+ during configuration and some hints for solving them.
+ However, there are just too many different combinations
+ of hardware and software configurations, and, well, just
+ too many things that can go wrong, for this document
+ and the tools it documents, to cover every case.
+
+ If after trying the steps in the previous sections and
+ checking the hints in this section, you still are unable
+ to get your system working, you'll have to read the full
+ documentation. Read the README file for your card and
+ OS (if they exist), the XFree86 Configuration Guide
+ (README.Config), and the XF86Config man page.
+
+<!--
+ You should also look at
+ <url name="the XFree86 FAQ" url="http://www.XFree86.org/FAQ">
+ for more up-to-date information,
+ especially if you are trying to configure a fairly new card.
+-->
+
+ If all else fails, you can try posting a message to
+ comp.windows.x.i386unix or comp.os.linux.x or send email
+ to XFree86@XFree86.org.
+
+<sect1> The mouse doesn't move correctly, it stays in one area of the screen
+<p>
+ You've selected the wrong protocol for your mouse. Try a
+ different one.
+
+<sect1> The server doesn't start, it says the mouse is busy.
+<p>
+ Well, it's probably right. This most often happens on
+ Linux systems that have <tt/gpm/ running. Kill the <tt/gpm/
+ process and try <tt/startx/ again.
+
+<sect1> The middle button doesn't work.
+<p>
+ There's no easy answer to this one. It's a lot of trial
+ and error. You need to make sure you're running the right
+ protocol for your mouse.
+
+ Many three button mice are "dual protocol" which means that
+ they have both a 2-button and 3-button mode. The way to get
+ the mouse to switch into 3-button mode (which usually then
+ uses MouseSystems protocol) varies between different models.
+
+ You may need to slide a switch on the mouse or hold down the
+ middle button when starting the server. Other methods of
+ switching modes can be done by the server, you just have to
+ find the right combination of settings for your mouse. See
+ the Pointer section of the XF86Config man page for a complete
+ list of settings.
+
+<sect1> The display is shifted to the left/right/top/bottom
+<p>
+ See the section on xvidtune.
+
+<sect1> I don't appear to have xf86config or xvidtune on my system
+<p>
+ Hmmm. A couple of possibilities:
+ <enum>
+ <item>Your <tt/PATH/ is not set correctly. Make sure it includes
+ the bin directory for the XFree86 binaries (usually,
+ <tt>/usr/X11R6/bin</tt>
+ <item>You don't have a complete installation of XFree86.
+ Go back to wherever you got XFree86 and get the missing
+ pieces.
+ </enum>
+
+<!-- Lots of things still need to be added -->
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/QuickStart.sgml,v 1.2 2001/08/10 16:38:11 dawes Exp $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/VideoModes.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/VideoModes.sgml
new file mode 100644
index 000000000..05e646dd4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/VideoModes.sgml
@@ -0,0 +1,1428 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<!-- This is the Linux Distribution HOWTO, SGML source -- >
+<!-- Eric S. Raymond, esr@snark.thyrsus.com -- >
+<!-- The submission address is gregh@sunsite.unc.edu -- >
+
+<article>
+
+<title>XFree86 Video Timings HOWTO
+<author>Eric S. Raymond &lt;esr@thyrsus.com&gt;
+<date>Version 3.0, 8 Aug 1997
+
+<abstract>
+How to compose a mode line for your card/monitor combination under XFree86.
+The XFree86 distribution now includes good facilities for configuring most
+standard combinations; this document is mainly useful if you are tuning a
+custom mode line for a high-performance monitor or very unusual hardware.
+It may also help you in using xvidtune to tweak a standard mode that is
+not quite right for your monitor.
+</abstract>
+
+<toc>
+
+<sect>Disclaimer
+<p>
+
+You use the material herein SOLELY AT YOUR OWN RISK. It is possible
+to harm both your monitor and yourself when driving it outside the
+manufacturer's specs. Read <ref id="overd" name="Overdriving Your
+Monitor"> for detailed cautions. Any damages to you or your monitor
+caused by overdriving it are your problem.
+
+The most up-to-date version of this HOWTO can be found at the <url
+url="http://sunsite.unc.edu/LDP"
+name="Linux Documentation Project"> web page.
+
+Please direct comments, criticism, and suggestions for improvement to
+<htmlurl url="mailto:esr@thyrsus.com" name="esr@snark.thyrsus.com">. Please do
+<em>not</em> send email pleading for a magic solution to your
+special monitor problem, as doing so will only burn up my time and
+frustrate you -- everything I know about the subject is already in
+here.
+
+<sect>Introduction<label id="intro">
+<p>
+
+The XFree86 server allows users to configure their video subsystem and thus
+encourages best use of existing hardware. This tutorial is intended to help
+you learn how to generate your own timing numbers to make optimum use of your
+video card and monitor.
+
+We'll present a method for getting something that works, and then show you how
+you can experiment starting from that base to develop settings that optimize
+for your taste.
+
+Starting with XFree86 3.2, XFree86 provides an <bf>XF86Setup</bf>(1)
+program that makes it easy to generate a working monitor mode
+interactively, without messing with video timing number directly. So
+you shouldn't actually need to calculate a base monitor mode in most
+cases. Unfortunately, <bf>XF86Setup</bf>(1) has some limitations; it
+only knows about standard video modes up to 1280x1024. If you have a
+very high-performance monitor capable of 1600x1200 or more you will
+still have to compute your base monitor mode yourself.
+
+Recent versions of XFree86 provide a tool called <bf>xvidtune</bf>(1)
+which you will probably find quite useful for testing and tuning
+monitor modes. It begins with a gruesome warning about the possible
+consequences of mistakes with it. If you pay careful attention to
+this document and learn what is behind the pretty numbers in
+xvidtune's boxes, you will become able to use xvidtune effectively and
+with confidence.
+
+If you already have a mode that almost works (in particular, if one of
+predefined VESA modes gives you a stable display but one that's
+displaced right or left, or too small, or too large) you can go
+straight to the section on <ref id="fixes" name="Fixing Problems with the
+Image">. This will enlighten you on ways to tweak the timing
+numbers to achieve particular effects.
+
+If you have <bf>xvidtune</bf>(1), you'll be able to test new modes on the fly,
+without modifying your X configuration files or even rebooting your X server.
+Otherwise, XFree86 allows you to hot-key between different modes defined in
+Xconfig (see XFree86.man for details). Use this capabilty to save
+yourself hassles! When you want to test a new mode, give it a unique
+mode label and add it to the <EM>end</EM> of your hot-key list. Leave a
+known-good mode as the default to fall back on if the test mode
+doesn't work.
+
+<sect>How Video Displays Work<label id="video">
+<p>
+
+Knowing how the display works is essential to understanding what numbers to put
+in the various fields in the file Xconfig. Those values are used in the lowest
+levels of controlling the display by the XFree86 server.
+
+The display generates a picture from a series of dots. The dots are arranged
+from left to right to form lines. The lines are arranged from top to bottom to
+form the picture. The dots emit light when they are struck by the electron
+beam inside the display. To make the beam strike each dot for an equal amount
+of time, the beam is swept across the display in a constant pattern.
+
+The pattern starts at the top left of the screen, goes across the screen to the
+right in a straight line, and stops temporarily on the right side of the
+screen. Then the beam is swept back to the left side of the display, but down
+one line. The new line is swept from left to right just as the first line was.
+This pattern is repeated until the bottom line on the display has been swept.
+Then the beam is moved from the bottom right corner of the display to the top
+left corner, and the pattern is started over again.
+
+There is one variation of this scheme known as interlacing: here only
+every second line is swept during one half-frame and the others are filled in
+in during a second half-frame.
+
+Starting the beam at the top left of the display is called the beginning of a
+frame. The frame ends when the beam reaches the the top left corner again as
+it comes from the bottom right corner of the display. A frame is made up of
+all of the lines the beam traced from the top of the display to the bottom.
+
+If the electron beam were on all of the time it was sweeping through the frame,
+all of the dots on the display would be illuminated. There would be no black
+border around the edges of the display. At the edges of the display the
+picture would become distorted because the beam is hard to control there. To
+reduce the distortion, the dots around the edges of the display are not
+illuminated by the beam even though the beam may be pointing at them. The
+viewable area of the display is reduced this way.
+
+Another important thing to understand is what becomes of the beam when no spot
+is being painted on the visible area. The time the beam would have been
+illuminating the side borders of the display is used for sweeping the beam back
+from the right edge to the left and moving the beam down to the next line. The
+time the beam would have been illuminating the top and bottom borders of the
+display is used for moving the beam from the bottom-right corner of the display
+to the top-left corner.
+
+The adapter card generates the signals which cause the display to turn on the
+electron beam at each dot to generate a picture. The card also controls when
+the display moves the beam from the right side to the left and down a line by
+generating a signal called the horizontal sync (for synchronization) pulse.
+One horizontal sync pulse occurs at the end of every line. The adapter also
+generates a vertical sync pulse which signals the display to move the beam to
+the top-left corner of the display. A vertical sync pulse is generated near
+the end of every frame.
+
+The display requires that there be short time periods both before and after the
+horizontal and vertical sync pulses so that the position of the electron beam
+can stabilize. If the beam can't stabilize, the picture will not be steady.
+
+In a later section, we'll come back to these basics with definitions,
+formulas and examples to help you use them.
+
+<sect>Basic Things to Know about your Display and Adapter<label id="basic">
+<p>
+
+There are some fundamental things you need to know before hacking an Xconfig
+entry. These are:
+
+<itemize>
+<item>your monitor's horizontal and vertical sync frequency options
+<item>your video adapter's driving clock frequency, or "dot clock"
+<item>your monitor's bandwidth
+</itemize>
+The monitor sync frequencies:
+
+The horizontal sync frequency is just the number of times per second the
+monitor can write a horizontal scan line; it is the single most important
+statistic about your monitor. The vertical sync frequency is the number of
+times per second the monitor can traverse its beam vertically.
+
+Sync frequencies are usually listed on the specifications page of your monitor
+manual. The vertical sync frequency number is typically calibrated in Hz
+(cycles per second), the horizontal one in KHz (kilocycles per second). The
+usual ranges are between 50 and 150Hz vertical, and between 31 and 135KHz
+horizontal.
+
+If you have a multisync monitor, these frequencies will be given as ranges.
+Some monitors, especially lower-end ones, have multiple fixed frequencies.
+These can be configured too, but your options will be severely limited by the
+built-in monitor characteristics. Choose the highest frequency pair for best
+resolution. And be careful --- trying to clock a fixed-frequency monitor at a
+higher speed than it's designed for can easily damage it.
+
+Earlier versions of this guide were pretty cavalier about overdriving
+multisync monitors, pushing them past their nominal highest vertical
+sync frequency in order to get better performance. We have since had more
+reasons pointed out to us for caution on this score; we'll cover those under
+<ref id="overd" name="Overdriving Your Monitor"> below.
+
+The card driving clock frequency:
+
+Your video adapter manual's spec page will usually give you the card's dot
+clock (that is, the total number of pixels per second it can write to the
+screen). If you don't have this information, the X server will get it for
+you. Even if your X locks up your monitor, it will emit a line of clock and
+other info to standard output. If you redirect this to a file, it should be
+saved even if you have to reboot to get your console back. (Recent versions
+of the X servers allsupport a --probeonly option that prints out this
+information and exits without actually starting up X or changing the
+video mode.)
+
+Your X startup message should look something like one of the following
+examples:
+
+If you're using XFree86:
+
+<tscreen><verb>
+Xconfig: /usr/X11R6/lib/X11/Xconfig
+(**) stands for supplied, (--) stands for probed/default values
+(**) Mouse: type: MouseMan, device: /dev/ttyS1, baudrate: 9600
+Warning: The directory "/usr/andrew/X11fonts" does not exist.
+ Entry deleted from font path.
+(**) FontPath set to "/usr/lib/X11/fonts/misc/,/usr/lib/X11/fonts/75dpi/"
+(--) S3: card type: 386/486 localbus
+(--) S3: chipset: 924
+ ---
+ Chipset -- this is the exact chip type; an early mask of the 86C911
+
+(--) S3: chipset driver: s3_generic
+(--) S3: videoram: 1024k
+ -----
+ Size of on-board frame-buffer RAM
+
+(**) S3: clocks: 25.00 28.00 40.00 3.00 50.00 77.00 36.00 45.00
+(**) S3: clocks: 0.00 0.00 79.00 31.00 94.00 65.00 75.00 71.00
+ ------------------------------------------------------
+ Possible driving frequencies in MHz
+
+(--) S3: Maximum allowed dot-clock: 110MHz
+ ------
+ Bandwidth
+(**) S3: Mode "1024x768": mode clock = 79.000, clock used = 79.000
+(--) S3: Virtual resolution set to 1024x768
+(--) S3: Using a banksize of 64k, line width of 1024
+(--) S3: Pixmap cache:
+(--) S3: Using 2 128-pixel 4 64-pixel and 8 32-pixel slots
+(--) S3: Using 8 pages of 768x255 for font caching
+</verb></tscreen>
+
+If you're using SGCS or X/Inside X:
+
+<tscreen><verb>
+WGA: 86C911 (mem: 1024k clocks: 25 28 40 3 50 77 36 45 0 0 79 31 94 65 75 71)
+--- ------ ----- --------------------------------------------
+ | | | Possible driving frequencies in MHz
+ | | +-- Size of on-board frame-buffer RAM
+ | +-- Chip type
+ +-- Server type
+</verb></tscreen>
+
+Note: do this with your machine unloaded (if at all possible). Because X is
+an application, its timing loops can collide with disk activity, rendering the
+numbers above inaccurate. Do it several times and watch for the numbers to
+stabilize; if they don't, start killing processes until they do. SVr4 users:
+the mousemgr process is particularly likely to mess you up.
+
+In order to avoid the clock-probe inaccuracy, you should clip out the clock
+timings and put them in your Xconfig as the value of the Clocks property ---
+this suppresses the timing loop and gives X an exact list of the clock values
+it can try. Using the data from the example above:
+
+<tscreen><verb>
+wga
+ Clocks 25 28 40 3 50 77 36 45 0 0 79 31 94 65 75 71
+</verb></tscreen>
+On systems with a highly variable load, this may help you avoid mysterious X
+startup failures. It's possible for X to come up, get its timings wrong due
+to system load, and then not be able to find a matching dot clock in its
+config database --- or find the wrong one!
+
+<sect1>The monitor's video bandwidth:
+<p>
+
+If you're running XFree86, your server will probe your card and tell you
+what your highest-available dot clock is.
+
+Otherwise, your highest available dot clock is approximately the monitor's
+video bandwidth. There's a lot of give here, though --- some monitors
+can run as much as 30% over their nominal bandwidth. The risks here have
+to do with exceeding the monitor's rated vertical-sync frequency; we'll
+discuss them in detail below.
+
+Knowing the bandwidth will enable you to make more intelligent choices
+between possible configurations. It may affect your display's visual
+quality (especially sharpness for fine details).
+
+Your monitor's video bandwidth should be included on the manual's spec page.
+If it's not, look at the monitor's higest rated resolution. As a rule of
+thumb, here's how to translate these into bandwidth estimates (and thus into
+rough upper bounds for the dot clock you can use):
+
+<tscreen><verb>
+ 640x480 25
+ 800x600 36
+ 1024x768 65
+ 1024x768 interlaced 45
+ 1280x1024 110
+ 1600x1200 185
+</verb></tscreen>
+
+BTW, there's nothing magic about this table; these numbers are just
+the lowest dot clocks per resolution in the standard XFree86 Modes
+database (except for the last, which I interpolated). The bandwidth
+of your monitor may actually be higher than the minimum needed for its
+top resolution, so don't be afraid to try a dot clock a few MHz
+higher.
+
+Also note that bandwidth is seldom an issue for dot clocks under 65MHz
+or so. With an SVGA card and most hi-res monitors, you can't get
+anywhere near the limit of your monitor's video bandwidth. The
+following are examples:
+
+<tscreen><verb>
+ Brand Video Bandwidth
+ ---------- ---------------
+ NEC 4D 75Mhz
+ Nano 907a 50Mhz
+ Nano 9080i 60Mhz
+ Mitsubishi HL6615 110Mhz
+ Mitsubishi Diamond Scan 100Mhz
+ IDEK MF-5117 65Mhz
+ IOCOMM Thinksync-17 CM-7126 136Mhz
+ HP D1188A 100Mhz
+ Philips SC-17AS 110Mhz
+ Swan SW617 85Mhz
+ Viewsonic 21PS 185Mhz
+</verb></tscreen>
+Even low-end monitors usually aren't terribly bandwidth-constrained for their
+rated resolutions. The NEC Multisync II makes a good example --- it can't
+even display 800x600 per its spec. It can only display 800x560. For such low
+resolutions you don't need high dot clocks or a lot of bandwidth; probably the
+best you can do is 32Mhz or 36Mhz, both of them are still not too far from the
+monitor's rated video bandwidth of 30Mhz.
+
+At these two driving frequencies, your screen image may not be as sharp as it
+should be, but definitely of tolerable quality. Of course it would be nicer if
+NEC Multisync II had a video bandwidth higher than, say, 36Mhz. But this is
+not critical for common tasks like text editing, as long as the difference is
+not so significant as to cause severe image distortion (your eyes would tell
+you right away if this were so).
+
+<sect1>What these control:
+<p>
+
+The sync frequency ranges of your monitor, together with your video adapter's
+dot clock, determine the ultimate resolution that you can use. But it's up to
+the driver to tap the potential of your hardware. A superior hardware
+combination without an equally competent device driver is a waste of money.
+On the other hand, with a versatile device driver but less capable hardware,
+you can push the hardware's envelope a little. This is the design philosophy
+of XFree86.
+
+<sect>Interpreting the Basic Specifications<label id="specs">
+<p>
+
+This section explains what the specifications above mean, and some other
+things you'll need to know. First, some definitions. Next to each in parens
+is the variable name we'll use for it when doing calculations
+
+<descrip>
+<tag/horizontal sync frequency (HSF)/
+ Horizontal scans per second (see above).
+
+<tag/vertical sync frequency (VSF) /
+ Vertical scans per second (see above). Mainly important as the upper
+ limit on your refresh rate.
+
+<tag/dot clock (DCF)/
+ More formally, `driving clock frequency'; The frequency of the
+ crystal or VCO on your adaptor --- the maximum dots-per-second it can
+ emit.
+
+<tag/video bandwidth (VB)/
+ The highest frequency you can feed into your monitor's video
+ input and still expect to see anything discernible. If your adaptor
+ produces an alternating on/off pattern, its lowest frequency is half
+ the DCF, so in theory bandwidth starts making sense at DCF/2. For
+ tolerately crisp display of fine details in the video image, however,
+ you don't want it much below your highest DCF, and preferably higher.
+
+<tag/frame length (HFL, VFL)/
+ Horizontal frame length (HFL) is the number of dot-clock ticks
+ needed for your monitor's electron gun to scan one horizontal line,
+ <em>including the inactive left and right borders</em>. Vertical
+ frame length (VFL) is the number of scan lines in the
+ <em>entire</em> image, including the inactive top and bottom
+ borders.
+
+<tag/screen refresh rate (RR)/
+ The number of times per second your screen is repainted (this is
+ also called "frame rate"). Higher frequencies are better, as they
+ reduce flicker. 60Hz is good, VESA-standard 72Hz is better.
+ Compute it as
+<tscreen><verb>
+ RR = DCF / (HFL * VFL)
+</verb></tscreen>
+
+ Note that the product in the denominator is <em>not</em> the same
+ as the monitor's visible resolution, but typically somewhat larger.
+ We'll get to the details of this below.
+
+The rates for which interlaced modes are usually specified (like 87Hz
+interlaced) are actually the half-frame rates: an entire screen seems
+to have about that flicker frequency for typical displays, but every
+single line is refreshed only half as often.
+
+For calculation purposes we reckon an interlaced display at its
+full-frame (refresh) rate, i.e. 43.5Hz. The quality of an interlaced
+mode is better than that of a non-interlaced mode with the same
+full-frame rate, but definitely worse then the non-interlaced one
+corresponding to the half-frame rate.
+</descrip>
+
+<sect1>About Bandwidth:
+<p>
+
+Monitor makers like to advertise high bandwidth because it constrains the
+sharpness of intensity and color changes on the screen. A high bandwidth
+means smaller visible details.
+
+Your monitor uses electronic signals to present an image to
+your eyes. Such signals always come in in wave form once they are converted
+into analog form from digitized form. They can be considered as combinations
+of many simpler wave forms each one of which has a fixed frequency, many of
+them are in the Mhz range, eg, 20Mhz, 40Mhz, or even 70Mhz. Your monitor
+video bandwidth is, effectively, the highest-frequency analog signal it can
+handle without distortion.
+
+For our purposes, bandwidth is mainly important as an approximate cutoff point
+for the highest dot clock you can use.
+
+<sect1>Sync Frequencies and the Refresh Rate:
+<p>
+
+Each horizontal scan line on the display is just the visible portion of a
+frame-length scan. At any instant there is actually only one dot active on
+the screen, but with a fast enough refresh rate your eye's persistence of
+vision enables you to "see" the whole image.
+
+Here are some pictures to help:
+
+<code>
+ _______________________
+ | | The horizontal sync frequency
+ |-&gt;-&gt;-&gt;-&gt;-&gt;-&gt;-&gt;-&gt;-&gt;-&gt;-&gt; | is the number of times per
+ | )| second that the monitor's
+ |&lt;-----&lt;-----&lt;-----&lt;--- | electron beam can trace
+ | | a pattern like this
+ | |
+ | |
+ | |
+ |_______________________|
+ _______________________
+ | ^ | The vertical sync frequency
+ | ^ | | is the number of times per
+ | | v | second that the monitor's
+ | ^ | | electron beam can trace
+ | | | | a pattern like this
+ | ^ | |
+ | | v |
+ | ^ | |
+ |_______|_v_____________|
+</code>
+
+Remember that the actual raster scan is a very tight zigzag pattern; that is,
+the beam moves left-right and at the same time up-down.
+
+Now we can see how the dot clock and frame size relates to refresh rate. By
+definition, one hertz (hz) is one cycle per second. So, if your horizontal
+frame length is HFL and your vertical frame length is VFL, then to cover the
+entire screen takes (HFL * VFL) ticks. Since your card emits DCF ticks per
+second by definition, then obviously your monitor's electron gun(s) can sweep
+the screen from left to right and back and from bottom to top and back DCF /
+(HFL * VFL) times/sec. This is your screen's refresh rate, because it's how
+many times your screen can be updated (thus <em>refreshed</em>) per second!
+
+You need to understand this concept to design a configuration which trades off
+resolution against flicker in whatever way suits your needs.
+
+For those of you who handle visuals better than text, here is one:
+
+<code>
+ RR VB
+ | min HSF max HSF |
+ | | R1 R2 | |
+max VSF -+----|------------/----------/---|------+----- max VSF
+ | |:::::::::::/::::::::::/:::::\ |
+ | \::::::::::/::::::::::/:::::::\ |
+ | |::::::::/::::::::::/:::::::::| |
+ | |:::::::/::::::::::/::::::::::\ |
+ | \::::::/::::::::::/::::::::::::\ |
+ | \::::/::::::::::/::::::::::::::| |
+ | |::/::::::::::/:::::::::::::::| |
+ | \/::::::::::/:::::::::::::::::\|
+ | /\:::::::::/:::::::::::::::::::|
+ | / \:::::::/::::::::::::::::::::|\
+ | / |:::::/:::::::::::::::::::::| |
+ | / \::::/::::::::::::::::::::::| \
+min VSF -+----/-------\--/-----------------------|--\--- min VSF
+ | / \/ | \
+ +--/----------/\------------------------+----\- DCF
+ R1 R2 \ | \
+ min HSF | max HSF
+ VB
+</code>
+
+This is a generic monitor mode diagram. The x axis of the diagram
+shows the clock rate (DCF), the y axis represents the refresh rate
+(RR). The filled region of the diagram describes the monitor's
+capabilities: every point within this region is a possible video
+mode.
+
+The lines labeled `R1' and `R2' represent a fixed resolutions (such as
+640x480); they are meant to illustrate how one resolution can be realized
+by many different combinations of dot clock and refresh rate. The R2
+line would represent a higher resolution than R1.
+
+The top and bottom boundaries of the permitted region are simply
+horizontal lines representing the limiting values for the vertical sync
+frequency. The video bandwidth is an upper limit to the clock rate and
+hence is represented by a vertical line bounding the capability region on
+the right.
+
+Under <ref id="cplot" name="Plotting Monitor Capabilities">) you'll
+find a program that will help you plot a diagram like
+this (but much nicer, with X graphics) for your individual monitor.
+That section also discusses the interesting part; the derivation of
+the boundaries resulting from the limits on the horizontal sync
+frequency.
+
+<sect>Tradeoffs in Configuring your System<label id="trade">
+<p>
+
+Another way to look at the formula we derived above is
+
+<tscreen><verb>
+ DCF = RR * HFL * VFL
+</verb></tscreen>
+That is, your dot clock is fixed. You can use those dots per second to buy
+either refresh rate, horizontal resolution, or vertical resolution. If one
+of those increases, one or both of the others must decrease.
+
+Note, though, that your refresh rate cannot be greater than the maximum
+vertical sync frequency of your monitor. Thus, for any given monitor at a
+given dot clock, there is a minimum product of frame lengths below which you
+can't force it.
+
+In choosing your settings, remember: if you set RR too low, you will get
+mugged by screen flicker.
+
+You probably do not want to pull your refresh rate below 60Hz. This is the
+flicker rate of fluorescent lights; if you're sensitive to those, you need
+to hang with 72Hz, the VESA ergonomic standard.
+
+Flicker is very eye-fatiguing, though human eyes are adaptable and peoples'
+tolerance for it varies widely. If you face your monitor at a 90% viewing
+angle, are using a dark background and a good contrasting color for
+foreground, and stick with low to medium intensity, you *may* be comfortable
+at as little as 45Hz.
+
+The acid test is this: open a xterm with pure white back-ground and black
+foreground using <TT>xterm -bg white -fg black</TT> and make it so large as
+to cover the entire viewable area. Now turn your monitor's intensity to 3/4 of
+its maximum setting, and turn your face away from the monitor. Try peeking at
+your monitor sideways (bringing the more sensitive peripheral-vision cells into
+play). If you don't sense any flicker or if you feel the flickering is
+tolerable, then that refresh rate is fine with you. Otherwise you better
+configure a higher refresh rate, because that semi-invisible flicker is going
+to fatigue your eyes like crazy and give you headaches, even if the screen
+looks OK to normal vision.
+
+For interlaced modes, the amount of flicker depends on more factors
+such as the current vertical resolution and the actual screen
+contents. So just experiment. You won't want to go much below about
+85Hz half frame rate, though.
+
+So let's say you've picked a minimum acceptable refresh rate. In choosing
+your HFL and VFL, you'll have some room for maneuver.
+
+<sect>Memory Requirements<label id="sizes">
+<p>
+
+Available frame-buffer RAM may limit the resolution you can achieve on color or
+gray-scale displays. It probably isn't a factor on displays that have only two
+colors, white and black with no shades of gray in between.
+
+For 256-color displays, a byte of video memory is required for each visible
+dot to be shown. This byte contains the information that determines what mix
+of red, green, and blue is generated for its dot. To get the amount of memory
+required, multiply the number of visible dots per line by the number of
+visible lines. For a display with a resolution of 800x600, this would be 800
+x 600 = 480,000, which is the number of visible dots on the display. This is
+also, at one byte per dot, the number of bytes of video memory that are
+necessary on your adapter card.
+
+Thus, your memory requirement will typically be (HR * VR)/1024 Kbytes of VRAM,
+rounded up. If you have more memory than strictly required, you'll have extra
+for virtual-screen panning.
+
+However, if you only have 512K on board, then you can't use this
+resolution. Even if you have a good monitor, without enough video
+RAM, you can't take advantage of your monitor's potential. On the
+other hand, if your SVGA has one meg, but your monitor can display at
+most 800x600, then high resolution is beyond your reach anyway (see
+<ref id="inter" name="Using Interlaced Modes"> for a possible
+remedy).
+
+Don't worry if you have more memory than required; XFree86 will make
+use of it by allowing you to scroll your viewable area (see the
+Xconfig file documentation on the virtual screen size parameter).
+Remember also that a card with 512K bytes of memory really doesn't
+have 512,000 bytes installed, it has 512 x 1024 = 524,288 bytes.
+
+If you're running SGCS X (now called X/Inside) using an S3 card, and
+are willing to live with 16 colors (4 bits per pixel), you can set
+depth 4 in Xconfig and effectively double the resolution your card can
+handle. S3 cards, for example, normally do 1024x768x256. You can
+make them do 1280x1024x16 with depth 4.
+
+<sect>Computing Frame Sizes<label id="frame">
+<p>
+
+Warning: this method was developed for multisync monitors. It will probably
+work with fixed-frequency monitors as well, but no guarantees!
+
+Start by dividing DCF by your highest available HSF to get a horizontal
+frame length.
+
+For example; suppose you have a Sigma Legend SVGA with a 65MHz dot clock, and
+your monitor has a 55KHz horizontal scan frequency. The quantity (DCF / HSF)
+is then 1181 (65MHz = 65000KHz; 65000/55 = 1181).
+
+Now for our first bit of black magic. You need to round this figure to the
+nearest multiple of 8. This has to do with the VGA hardware controller used by
+SVGA and S3 cards; it uses an 8-bit register, left-shifted 3 bits, for what's
+really an 11-bit quantity. Other card types such as ATI 8514/A may not have
+this requirement, but we don't know and the correction can't hurt. So round
+the usable horizontal frame length figure down to 1176.
+
+This figure (DCF / HSF rounded to a multiple of 8) is the minimum HFL you can
+use. You can get longer HFLs (and thus, possibly, more horizontal dots on the
+screen) by setting the sync pulse to produce a lower HSF. But you'll pay with
+a slower and more visible flicker rate.
+
+As a rule of thumb, 80% of the horizontal frame length is available for
+horizontal resolution, the visible part of the horizontal scan line (this
+allows, roughly, for borders and sweepback time -- that is, the time required
+for the beam to move from the right screen edge to the left edge of the next
+raster line). In this example, that's 944 ticks.
+
+Now, to get the normal 4:3 screen aspect ratio, set your vertical resolution
+to 3/4ths of the horizontal resolution you just calculated. For this
+example, that's 708 ticks. To get your actual VFL, multiply that by 1.05
+to get 743 ticks.
+
+The 4:3 is not technically magic; nothing prevents you from using a
+non-Golden-Section ratio if that will get the best use out of your
+screen real estate. It does make figuring frame height and frame
+width from the diagonal size convenient, you just multiply the
+diagonal by by 0.8 to get width and 0.6 to get height.
+
+So, HFL=1176 and VFL=743. Dividing 65MHz by the product of the two gives
+us a nice, healthy 74.4Hz refresh rate. Excellent! Better than VESA standard!
+And you got 944x708 to boot, more than the 800 by 600 you were probably
+expecting. Not bad at all!
+
+You can even improve the refresh rate further, to almost 76 Hz, by using the
+fact that monitors can often sync horizontally at 2khz or so higher than rated,
+and by lowering VFL somewhat (that is, taking less than 75% of 944 in the
+example above). But before you try this "overdriving" maneuver, if you do,
+make <em>sure</em> that your monitor electron guns can sync up to 76 Hz
+vertical. (the popular NEC 4D, for instance, cannot. It goes only up to 75 Hz
+VSF). (See <ref id="overd" name="Overdriving Your Monitor"> for more general
+discussion of this issue. )
+
+So far, most of this is simple arithmetic and basic facts about raster
+displays. Hardly any black magic at all!
+
+<sect>Black Magic and Sync Pulses<label id="magic">
+<p>
+
+OK, now you've computed HFL/VFL numbers for your chosen dot clock, found the
+refresh rate acceptable, and checked that you have enough VRAM. Now for the
+real black magic -- you need to know when and where to place synchronization
+pulses.
+
+The sync pulses actually control the horizontal and vertical scan frequebcies
+of the monitor. The HSF and VSF you've pulled off the spec sheet are nominal,
+approximate maximum sync frequencies. The sync pulse in the signal from the
+adapter card tells the monitor how fast to actually run.
+
+Recall the two pictures above? Only part of the time required for
+raster-scanning a frame is used for displaying viewable image (ie. your
+resolution).
+
+<sect1>Horizontal Sync:
+<p>
+
+By previous definition, it takes HFL ticks to trace the a horizontal scan line.
+Let's call the visible tick count (your horizontal screen resolution) HR. Then
+Obviously, HR < HFL by definition. For concreteness, let's assume both start
+at the same instant as shown below:
+<code>
+ |___ __ __ __ __ __ __ __ __ __ __ __ __
+ |_ _ _ _ _ _ _ _ _ _ _ _ |
+ |_______________________|_______________|_____
+ 0 ^ ^ unit: ticks
+ | ^ ^ |
+ HR | | HFL
+ | |&lt;-----&gt;| |
+ |&lt;-&gt;| HSP |&lt;-&gt;|
+ HGT1 HGT2
+</code>
+
+Now, we would like to place a sync pulse of length HSP as shown above, ie,
+between the end of clock ticks for display data and the end of clock ticks for
+the entire frame. Why so? because if we can achieve this, then your screen
+image won't shift to the right or to the left. It will be where it supposed to
+be on the screen, covering squarely the monitor's viewable area.
+
+Furthermore, we want about 30 ticks of "guard time" on either side of the sync
+pulse. This is represented by HGT1 and HGT2. In a typical configuration HGT1
+!= HGT2, but if you're building a configuration from scratch, you want to start
+your experimentation with them equal (that is, with the sync pulse centered).
+
+The symptom of a misplaced sync pulse is that the image is displaced on the
+screen, with one border excessively wide and the other side of the image
+wrapped around the screen edge, producing a white edge line and a band of
+"ghost image" on that side. A way-out-of-place vertical sync pulse can
+actually cause the image to roll like a TV with a mis-adjusted vertical hold
+(in fact, it's the same phenomenon at work).
+
+If you're lucky, your monitor's sync pulse widths will be documented on its
+specification page. If not, here's where the real black magic starts...
+
+You'll have to do a little trial and error for this part. But most of the
+time, we can safely assume that a sync pulse is about 3.5 to 4.0 microsecond
+in length.
+
+For concretness again, let's take HSP to be 3.8 microseconds (which btw, is not
+a bad value to start with when experimenting).
+
+Now, using the 65Mhz clock timing above, we know HSP is equivalent to 247 clock
+ticks (= 65 * 10**6 * 3.8 * 10^-6) [recall M=10^6, micro=10^-6]
+
+Some makers like to quote their horizontal framing parameters as timings rather
+than dot widths. You may see the following terms:
+<descrip>
+<tag/active time (HAT)/
+ Corresponds to HR, but in milliseconds. HAT * DCF = HR.
+<tag/blanking time (HBT)/
+ Corresponds to (HFL - HR), but in milliseconds. HBT * DCF = (HFL -
+ HR).
+<tag/front porch (HFP)/
+ This is just HGT1.
+<tag/sync time/
+ This is just HSP.
+<tag/back porch (HBP)/
+ This is just HGT2.
+</descrip>
+
+<sect1>Vertical Sync:
+<p>
+
+Going back to the picture above, how do we place the 247 clock ticks as shown
+in the picture?
+
+Using our example, HR is 944 and HFL is 1176. The difference between the two
+is 1176 - 944=232 < 247! Obviously we have to do some adjustment here. What
+can we do?
+
+The first thing is to raise 1176 to 1184, and lower 944 to 936. Now the
+difference = 1184-936= 248. Hmm, closer.
+
+Next, instead using 3.8, we use 3.5 for calculating HSP; then, we have
+65*3.5=227. Looks better. But 248 is not much higher than 227. It's normally
+necessary to have 30 or so clock ticks between HR and the start of SP, and the
+same for the end of SP and HFL. AND they have to be multiple of eight! Are we
+stuck?
+
+No. Let's do this, 936 % 8 = 0, (936 + 32) % 8 = 0 too. But 936 + 32 = 968,
+968 + 227 = 1195, 1195 + 32 = 1227. Hmm.. this looks not too bad. But it's
+not a multiple of 8, so let's round it up to 1232.
+
+But now we have potential trouble, the sync pulse is no longer placed right in
+the middle between h and H any more. Happily, using our calculator we find
+1232 - 32 = 1200 is also a multiple of 8 and (1232 - 32) - 968 = 232
+corresponding using a sync pulse of 3.57 micro second long, still
+reasonable.
+
+In addition, 936/1232 ~ 0.76 or 76%, still not far from 80%, so it should be
+all right.
+
+Furthermore, using the current horizontal frame length, we basically ask our
+monitor to sync at 52.7khz (= 65Mhz/1232) which is within its capability. No
+problems.
+
+Using rules of thumb we mentioned before, 936*75%=702, This is our new vertical
+resolution. 702 * 1.05 = 737, our new vertical frame length.
+
+Screen refresh rate = 65Mhz/(737*1232)=71.6 Hz. This is still excellent.
+
+Figuring the vertical sync pulse layout is similar:
+<code>
+ |___ __ __ __ __ __ __ __ __ __ __ __ __
+ |_ _ _ _ _ _ _ _ _ _ _ _ |
+ |_______________________|_______________|_____
+ 0 VR VFL unit: ticks
+ ^ ^ ^
+ | | |
+ |&lt;-&gt;|&lt;-----&gt;|
+ VGT VSP
+</code>
+
+We start the sync pulse just past the end of the vertical display data ticks.
+VGT is the vertical guard time required for the sync pulse. Most monitors are
+comfortable with a VGT of 0 (no guard time) and we'll use that in this
+example. A few need two or three ticks of guard time, and it usually doesn't
+hurt to add that.
+
+Returning to the example: since by the defintion of frame length, a vertical
+tick is the time for tracing a complete HORIZONTAL frame, therefore in our
+example, it is 1232/65Mhz=18.95us.
+
+Experience shows that a vertical sync pulse should be in the range of 50us and
+300us. As an example let's use 150us, which translates into 8 vertical clock
+ticks (150us/18.95us~8).
+
+Some makers like to quote their vertical framing parameters as timings rather
+than dot widths. You may see the following terms:
+
+<descrip>
+<tag/active time (VAT)/
+ Corresponds to VR, but in milliseconds. VAT * VSF = VR.
+<tag/blanking time (VBT)/
+ Corresponds to (VFL - VR), but in milliseconds. VBT * VSF = (VFL - VR).
+<tag/front porch (VFP)/
+ This is just VGT.
+<tag/sync time/
+ This is just VSP.
+<tag/back porch (VBP)/
+ This is like a second guard time after the vertical sync pulse. It
+ is often zero.
+</descrip>
+
+<sect>Putting it All Together<label id="synth">
+<p>
+
+The Xconfig file Table of Video Modes contains lines of numbers, with each line
+being a complete specification for one mode of X-server operation. The fields
+are grouped into four sections, the name section, the clock frequency section,
+the horizontal section, and the vertical section.
+
+The name section contains one field, the name of the video mode specified by
+the rest of the line. This name is referred to on the "Modes" line of the
+Graphics Driver Setup section of the Xconfig file. The name field may be
+omitted if the name of a previous line is the same as the current line.
+
+The dot clock section contains only the dot clock (what we've called DCF) field
+of the video mode line. The number in this field specifies what dot clock was
+used to generate the numbers in the following sections.
+
+The horizontal section consists of four fields which specify how each
+horizontal line on the display is to be generated. The first field of the
+section contains the number of dots per line which will be illuminated to form
+the picture (what we've called HR). The second field of the section indicates
+at which dot the horizontal sync pulse will begin. The third field indicates
+at which dot the horizontal sync pulse will end. The fourth field specifies
+the toal horzontal frame length (HFL).
+
+The vertical section also contains four fields. The first field contains the
+number of visible lines which will appear on the display (VR). The second
+field indicates the line number at which the vertical sync pulse will begin.
+The third field specifies the line number at which the vertical sync pulse will
+end. The fourth field contains the total vertical frame length (VFL).
+
+Example:
+<tscreen><verb>
+ #Modename clock horizontal timing vertical timing
+
+ "752x564" 40 752 784 944 1088 564 567 569 611
+ 44.5 752 792 976 1240 564 567 570 600
+</verb></tscreen>
+(Note: stock X11R5 doesn't support fractional dot clocks.)
+
+For Xconfig, all of the numbers just mentioned - the number of illuminated dots
+on the line, the number of dots separating the illuminated dots from the
+beginning of the sync pulse, the number of dots representing the duration of
+the pulse, and the number of dots after the end of the sync pulse - are added
+to produce the number of dots per line. The number of horizontal dots must be
+evenly divisible by eight.
+
+Example horizontal numbers: 800 864 1024 1088
+
+This sample line has the number of illuminated dots (800) followed by the
+number of the dot when the sync pulse starts (864), followed by the number of
+the dot when the sync pulse ends (1024), followed by the number of the last dot
+on the horizontal line (1088).
+
+Note again that all of the horizontal numbers (800, 864, 1024, and 1088) are
+divisible by eight! This is not required of the vertical numbers.
+
+The number of lines from the top of the display to the bottom form the frame.
+The basic timing signal for a frame is the line. A number of lines will
+contain the picture. After the last illuminated line has been displayed, a
+delay of a number of lines will occur before the vertical sync pulse is
+generated. Then the sync pulse will last for a few lines, and finally the last
+lines in the frame, the delay required after the pulse, will be generated. The
+numbers that specify this mode of operation are entered in a manner similar to
+the following example.
+
+Example vertical numbers: 600 603 609 630
+
+This example indicates that there are 600 visible lines on the display, that
+the vertical sync pulse starts with the 603rd line and ends with the 609th, and
+that there are 630 total lines being used.
+
+Note that the vertical numbers don't have to be divisible by eight!
+
+Let's return to the example we've been working. According to the above, all
+we need to do from now on is to write our result into Xconfig as follows:
+<tscreen><verb>
+<name> DCF HR SH1 SH2 HFL VR SV1 SV2 VFL
+</verb></tscreen>
+where SH1 is the start tick of the horizontal sync pulse and SH2 is its end
+tick; similarly, SV1 is the start tick of the vertical sync pulse and SV2 is
+its end tick.
+<tscreen><verb>
+#name clock horizontal timing vertical timing flag
+936x702 65 936 968 1200 1232 702 702 710 737
+</verb></tscreen>
+No special flag necessary; this is a non-interlaced mode. Now we are really
+done.
+
+<sect>Overdriving Your Monitor<label id="overd">
+<p>
+
+You should absolutely <EM>not</EM> try exceeding your monitor's scan
+rates if it's a fixed-frequency type. You can smoke your hardware
+doing this! There are potentially subtler problems with overdriving a
+multisync monitor which you should be aware of.
+
+Having a pixel clock higher than the monitor's maximum bandwidth is
+rather harmless, in contrast. (Note: the theoretical limit of
+discernible features is reached when the pixel clock reaches double
+the monitor's bandwidth. This is a straightforward application of
+Nyquist's Theorem: consider the pixels as a spatially distributed
+series of samples of the drive signals and you'll see why.)
+
+It's exceeding the rated maximum sync frequencies that's problematic.
+Some modern monitors might have protection circuitry that shuts the
+monitor down at dangerous scan rates, but don't rely on it. In
+particular there are older multisync monitors (like the Multisync II)
+which use just one horizontal transformer. These monitors will not
+have much protection against overdriving them. While you necessarily
+have high voltage regulation circuitry (which can be absent in fixed
+frequency monitors), it will not necessarily cover every conceivable
+frequency range, especially in cheaper models. This not only implies
+more wear on the circuitry, it can also cause the screen phosphors to
+age faster, and cause more than the specified radiation (including X-rays)
+to be emitted from the monitor.
+
+Another importance of the bandwidth is that the monitor's input
+impedance is specified only for that range, and using higher
+frequencies can cause reflections probably causing minor screen
+interferences, and radio disturbance.
+
+However, the basic problematic magnitude in question here is the slew
+rate (the steepness of the video signals) of the video output drivers,
+and that is usually independent of the actual pixel frequency, but
+(if your board manufacturer cares about such problems) related
+to the maximum pixel frequency of the board.
+
+So be careful out there...
+
+<sect>Using Interlaced Modes<label id="inter">
+<p>
+
+(This section is largely due to David Kastrup
+&lt;dak@pool.informatik.rwth-aachen.de&gt)
+
+At a fixed dot clock, an interlaced display is going to have
+considerably less noticable flicker than a non-interlaced display, if
+the vertical circuitry of your monitor is able to support it stably.
+It is because of this that interlaced modes were invented in the first
+place.
+
+Interlaced modes got their bad repute because they are inferior to
+their non-interlaced companions at the same vertical scan frequency,
+VSF (which is what is usually given in advertisements). But they are
+definitely superior at the same horizontal scan rate, and that's where
+the decisive limits of your monitor/graphics card usually lie.
+
+At a fixed <EM>refresh rate</EM> (or half frame rate, or VSF) the
+interlaced display will flicker more: a 90Hz interlaced display will
+be inferior to a 90Hz non-interlaced display. It will, however, need
+only half the video bandwidth and half the horizontal scan rate. If
+you compared it to a non-interlaced mode with the same dot clock and
+the same scan rates, it would be vastly superior: 45Hz non-interlaced
+is intolerable. With 90Hz interlaced, I have worked for years with my
+Multisync 3D (at 1024x768) and am very satisfied. I'd guess you'd need
+at least a 70Hz non-interlaced display for similar comfort.
+
+You have to watch a few points, though: use interlaced modes only at
+high resolutions, so that the alternately lighted lines are close
+together. You might want to play with sync pulse widths and positions
+to get the most stable line positions. If alternating lines are bright
+and dark, interlace will <EM>jump</EM> at you. I have one application that
+chooses such a dot pattern for a menu background (XCept, no other
+application I know does that, fortunately). I switch to 800x600 for
+using XCept because it really hurts my eyes otherwise.
+
+For the same reason, use at least 100dpi fonts, or other fonts where
+horizontal beams are at least two lines thick (for high resolutions,
+nothing else will make sense anyhow).
+
+And of course, never use an interlaced mode when your hardware would
+support a non-interlaced one with similar refresh rate.
+
+If, however, you find that for some resolution you are pushing either
+monitor or graphics card to their upper limits, and getting
+dissatisfactorily flickery or outwashed (bandwidth exceeded) display,
+you might want to try tackling the same resolution using an
+interlaced mode. Of course this is useless if the VSF
+of your monitor is already close to its limits.
+
+Design of interlaced modes is easy: do it like a non-interlaced
+mode. Just two more considerations are necessary: you need an odd
+total number of vertical lines (the last number in your mode line), and
+when you specify the "interlace" flag, the actual vertical frame rate
+for your monitor doubles. Your monitor needs to support a 90Hz frame
+rate if the mode you specified looks like a 45Hz mode apart from the
+"Interlace" flag.
+
+As an example, here is my modeline for 1024x768 interlaced: my
+Multisync 3D will support up to 90Hz vertical and 38kHz horizontal.
+
+<tscreen><verb>
+ModeLine "1024x768" 45 1024 1048 1208 1248 768 768 776 807 Interlace
+</verb></tscreen>
+
+Both limits are pretty much exhausted with this mode. Specifying the
+same mode, just without the "Interlace" flag, still is almost at the
+limit of the monitor's horizontal capacity (and strictly speaking, a
+bit under the lower limit of vertical scan rate), but produces an
+intolerably flickery display.
+
+Basic design rules: if you have designed a mode at less than half of
+your monitor's vertical capacity, make the vertical total of lines odd
+and add the "Interlace" flag. The display's quality should vastly
+improve in most cases.
+
+If you have a non-interlaced mode otherwise exhausting your monitor's
+specs where the vertical scan rate lies about 30% or more under the
+maximum of your monitor, hand-designing an interlaced mode (probably
+with somewhat higher resolution) could deliver superior results, but I
+won't promise it.
+
+<sect>Questions and Answers<label id="answe">
+<p>
+
+ Q. The example you gave is not a standard screen size, can I use it?
+
+ A. Why not? There is NO reason whatsover why you have to use 640x480,
+800x600, or even 1024x768. The XFree86 servers let you configure your hardware
+with a lot of freedom. It usually takes two to three tries to come up the
+right one. The important thing to shoot for is high refresh rate with
+reasonable viewing area. not high resolution at the price of eye-tearing
+flicker!
+
+ Q. It this the only resolution given the 65Mhz dot clock and 55Khz HSF?
+
+ A. Absolutely not! You are encouraged to follow the general procedure and
+do some trial-and-error to come up a setting that's really to your liking.
+Experimenting with this can be lots of fun. Most settings may just give you
+nasty video hash, but in practice a modern multi-sync monitor is usually not
+damaged easily. Be sure though, that your monitor can support the frame
+rates of your mode before using it for longer times.
+
+ Beware fixed-frequency monitors! This kind of hacking around can damage
+them rather quickly. Be sure you use valid refresh rates for <EM>every</EM>
+experiment on them.
+
+ Q. You just mentioned two standard resolutions. In Xconfig, there are many
+standard resolutions available, can you tell me whether there's any point in
+tinkering with timings?
+
+ A. Absolutely! Take, for example, the "standard" 640x480 listed in the
+current Xconfig. It employes 25Mhz driving frequency, frame lengths are 800
+and 525 => refresh rate ~ 59.5Hz. Not too bad. But 28Mhz is a commonly
+available driving frequency from many SVGA boards. If we use it to drive
+640x480, following the procedure we discussed above, you would get frame
+lengths like 812 and 505. Now the refresh rate is raised to 68Hz, a
+quite significant improvement over the standard one.
+
+ Q. Can you summarize what we have discussed so far?
+
+ A. In a nutshell:
+
+<enum>
+<item>
+for any fixed driving frequency, raising max resolution incurs the penalty
+of lowering refresh rate and thus introducing more flicker.
+<item>
+if high resolution is desirable and your monitor supports it, try to
+get a SVGA card that provides a matching dot clock or DCF. The higher,
+the better!
+</enum>
+
+<sect>Fixing Problems with the Image.<label id="fixes">
+<p>
+
+OK, so you've got your X configuration numbers. You put them in Xconfig with
+a test mode label. You fire up X, hot-key to the new mode, ... and the image
+doesn't look right. What do you do? Here's a list of common problems and how
+to fix them.
+
+(Fixing these minor distortions is where <bf>xvidtune</bf>(1) really shines.)
+
+You <em>move</em> the image by changing the sync pulse timing. You
+<em>scale</em> it by changing the frame length (you need to move the
+sync pulse to keep it in the same relative position, otherwise scaling will
+move the image as well). Here are some more specific recipes:
+
+The horizontal and vertical positions are independent. That is, moving the
+image horizontally doesn't affect placement vertically, or vice-versa.
+However, the same is not quite true of scaling. While changing the horizontal
+size does nothing to the vertical size or vice versa, the total change in both
+may be limited. In particular, if your image is too large in both dimensions
+you will probably have to go to a higher dot clock to fix it. Since this
+raises the usable resolution, it is seldom a problem!
+
+<sect1>The image is displaced to the left or right
+<p>
+
+To fix this, move the horizontal sync pulse. That is, increment or decrement
+(by a multiple of 8) the middle two numbers of the horizontal timing section
+that define the leading and trailing edge of the horizontal sync pulse.
+
+If the image is shifted left (right border too large, you want to move
+the image to the right) decrement the numbers. If the image is shifted right
+(left border too large, you want it to move left) increment the sync pulse.
+
+<sect1>The image is displaced up or down
+<p>
+
+To fix this, move the vertical sync pulse. That is, increment or decrement the
+middle two numbers of the vertical timing section that define the leading and
+trailing edge of the vertical sync pulse.
+
+If the image is shifted up (lower border too large, you want to move the image
+down) decrement the numbers. If the image is shifted down (top border too
+large, you want it to move up) increment the numbers.
+
+<sect1>The image is too large both horizontally and vertically
+<p>
+
+Switch to a higher card clock speed. If you have multiple modes in your
+clock file, possibly a lower-speed one is being activated by mistake.
+
+<sect1>The image is too wide (too narrow) horizontally
+<p>
+
+To fix this, increase (decrease) the horizontal frame length. That is, change
+the fourth number in the first timing section. To avoid moving the image, also
+move the sync pulse (second and third numbers) half as far, to keep it in the
+same relative position.
+
+<sect1>The image is too deep (too shallow) vertically
+<p>
+
+To fix this, increase (decrease) the vertical frame length. That is, change
+the fourth number in the second timing section. To avoid moving the image,
+also move the sync pulse (second and third numbers) half as far, to keep it in
+the same relative position.
+
+Any distortion that can't be handled by combining these techniques is probably
+evidence of something more basically wrong, like a calculation mistake or a
+faster dot clock than the monitor can handle.
+
+Finally, remember that increasing either frame length will decrease your
+refresh rate, and vice-versa.
+
+<sect>Plotting Monitor Capabilities<label id="cplot">
+<p>
+
+To plot a monitor mode diagram, you'll need the gnuplot package (a
+freeware plotting language for UNIX-like operating systems) and the
+tool <TT>modeplot</TT>, a shell/gnuplot script to plot the diagram from your
+monitor characteristics, entered as command-line options.
+
+Here is a copy of modeplot:
+
+<code>
+#!/bin/sh
+#
+# modeplot -- generate X mode plot of available monitor modes
+#
+# Do `modeplot -?' to see the control options.
+#
+# (Id: video-modes.sgml,v 1.2 1997/08/08 15:07:24 esr Exp $)
+
+# Monitor description. Bandwidth in MHz, horizontal frequencies in kHz
+# and vertical frequencies in Hz.
+TITLE="Viewsonic 21PS"
+BANDWIDTH=185
+MINHSF=31
+MAXHSF=85
+MINVSF=50
+MAXVSF=160
+ASPECT="4/3"
+vesa=72.5 # VESA-recommended minimum refresh rate
+
+while [ "$1" != "" ]
+do
+ case $1 in
+ -t) TITLE="$2"; shift;;
+ -b) BANDWIDTH="$2"; shift;;
+ -h) MINHSF="$2" MAXHSF="$3"; shift; shift;;
+ -v) MINVSF="$2" MAXVSF="$3"; shift; shift;;
+ -a) ASPECT="$2"; shift;;
+ -g) GNUOPTS="$2"; shift;;
+ -?) cat <<EOF
+modeplot control switches:
+
+-t "<description>" name of monitor defaults to "Viewsonic 21PS"
+-b <nn> bandwidth in MHz defaults to 185
+-h <min> <max> min & max HSF (kHz) defaults to 31 85
+-v <min> <max> min & max VSF (Hz) defaults to 50 160
+-a <aspect ratio> aspect ratio defaults to 4/3
+-g "<options>" pass options to gnuplot
+
+The -b, -h and -v options are required, -a, -t, -g optional. You can
+use -g to pass a device type to gnuplot so that (for example) modeplot's
+output can be redirected to a printer. See gnuplot(1) for details.
+
+The modeplot tool was created by Eric S. Raymond <esr@thyrsus.com> based on
+analysis and scratch code by Martin Lottermoser <Martin.Lottermoser@mch.sni.de>
+
+This is modeplot Revision: 1.2 $
+EOF
+ exit;;
+ esac
+ shift
+done
+
+gnuplot $GNUOPTS <<EOF
+set title "$TITLE Mode Plot"
+
+# Magic numbers. Unfortunately, the plot is quite sensitive to changes in
+# these, and they may fail to represent reality on some monitors. We need
+# to fix values to get even an approximation of the mode diagram. These come
+# from looking at lots of values in the ModeDB database.
+F1 = 1.30 # multiplier to convert horizontal resolution to frame width
+F2 = 1.05 # multiplier to convert vertical resolution to frame height
+
+# Function definitions (multiplication by 1.0 forces real-number arithmetic)
+ac = (1.0*$ASPECT)*F1/F2
+refresh(hsync, dcf) = ac * (hsync**2)/(1.0*dcf)
+dotclock(hsync, rr) = ac * (hsync**2)/(1.0*rr)
+resolution(hv, dcf) = dcf * (10**6)/(hv * F1 * F2)
+
+# Put labels on the axes
+set xlabel 'DCF (MHz)'
+set ylabel 'RR (Hz)' 6 # Put it right over the Y axis
+
+# Generate diagram
+set grid
+set label "VB" at $BANDWIDTH+1, ($MAXVSF + $MINVSF) / 2 left
+set arrow from $BANDWIDTH, $MINVSF to $BANDWIDTH, $MAXVSF nohead
+set label "max VSF" at 1, $MAXVSF-1.5
+set arrow from 0, $MAXVSF to $BANDWIDTH, $MAXVSF nohead
+set label "min VSF" at 1, $MINVSF-1.5
+set arrow from 0, $MINVSF to $BANDWIDTH, $MINVSF nohead
+set label "min HSF" at dotclock($MINHSF, $MAXVSF+17), $MAXVSF + 17 right
+set label "max HSF" at dotclock($MAXHSF, $MAXVSF+17), $MAXVSF + 17 right
+set label "VESA $vesa" at 1, $vesa-1.5
+set arrow from 0, $vesa to $BANDWIDTH, $vesa nohead # style -1
+plot [dcf=0:1.1*$BANDWIDTH] [$MINVSF-10:$MAXVSF+20] \
+ refresh($MINHSF, dcf) notitle with lines 1, \
+ refresh($MAXHSF, dcf) notitle with lines 1, \
+ resolution(640*480, dcf) title "640x480 " with points 2, \
+ resolution(800*600, dcf) title "800x600 " with points 3, \
+ resolution(1024*768, dcf) title "1024x768 " with points 4, \
+ resolution(1280*1024, dcf) title "1280x1024" with points 5, \
+ resolution(1600*1280, dcf) title "1600x1200" with points 6
+
+pause 9999
+EOF
+</code>
+
+Once you know you have <TT>modeplot</TT> and the gnuplot package in
+place, you'll need the following monitor characteristics:
+
+<itemize>
+<item> video bandwidth (VB)
+<item> range of horizontal sync frequency (HSF)
+<item> range of vertical sync frequency (VSF)
+</itemize>
+
+The plot program needs to make some simplifying assumptions which are
+not necessarily correct. This is the reason why the resulting diagram is
+only a rough description. These assumptions are:
+
+<enum>
+<item> All resolutions have a single fixed aspect ratio AR = HR/VR.
+Standard resolutions have AR = 4/3 or AR = 5/4. The <TT>modeplot</TT>
+programs assumes 4/3 by default, but you can override this.
+<item> For the modes considered, horizontal and vertical frame lengths are
+fixed multiples of horizontal and vertical resolutions, respectively:
+
+<tscreen><verb>
+ HFL = F1 * HR
+ VFL = F2 * VR
+</verb></tscreen>
+</enum>
+
+As a rough guide, take F1 = 1.30 and F2 = 1.05 (see <ref id=frame>
+"Computing Frame Sizes").
+
+Now take a particular sync frequency, HSF. Given the assumptions just
+presented, every value for the clock rate DCF already determines the
+refresh rate RR, i.e. for every value of HSF there is a function RR(DCF).
+This can be derived as follows.
+
+The refresh rate is equal to the clock rate divided by the product of the
+frame sizes:
+
+<tscreen><verb>
+ RR = DCF / (HFL * VFL) (*)
+</verb></tscreen>
+
+On the other hand, the horizontal frame length is equal to the clock rate
+divided by the horizontal sync frequency:
+
+<tscreen><verb>
+ HFL = DCF / HSF (**)
+</verb></tscreen>
+
+VFL can be reduced to HFL be means of the two assumptions above:
+
+<tscreen><verb>
+ VFL = F2 * VR
+ = F2 * (HR / AR)
+ = (F2/F1) * HFL / AR (***)
+</verb></tscreen>
+
+Inserting (**) and (***) into (*) we obtain:
+
+<tscreen><verb>
+ RR = DCF / ((F2/F1) * HFL**2 / AR)
+ = (F1/F2) * AR * DCF * (HSF/DCF)**2
+ = (F1/F2) * AR * HSF**2 / DCF
+</verb></tscreen>
+
+For fixed HSF, F1, F2 and AR, this is a hyperbola in our diagram. Drawing
+two such curves for minimum and maximum horizontal sync frequencies we
+have obtained the two remaining boundaries of the permitted region.
+
+The straight lines crossing the capability region represent particular
+resolutions. This is based on (*) and the second assumption:
+
+<tscreen><verb>
+ RR = DCF / (HFL * VFL) = DCF / (F1 * HR * F2 * VR)
+</verb></tscreen>
+
+By drawing such lines for all resolutions one is interested in, one
+can immediately read off the possible relations between resolution,
+clock rate and refresh rate of which the monitor is capable. Note that
+these lines do not depend on monitor properties, but they do depend on
+the second assumption.
+
+The <TT>modeplot</TT> tool provides you with an easy way to do this. Do
+<TT>modeplot -?</TT> to see its control options. A typical invocation
+looks like this:
+
+<tscreen><verb>
+ modeplot -t "Swan SW617" -b 85 -v 50 90 -h 31 58
+</verb></tscreen>
+
+The -b option specifies video bandwidth; -v and -h set horizontal and
+vertical sync frequency ranges.
+
+When reading the output of <TT>modeplot</TT>, always bear in mind that
+it gives only an approximate description. For example, it disregards
+limitations on HFL resulting from a minimum required sync pulse width,
+and it can only be accurate as far as the assumptions are. It is
+therefore no substitute for a detailed calculation (involving some
+black magic) as presented in <ref id="synth" name="Putting it All
+Together">. However, it should give you a better feeling for what
+is possible and which tradeoffs are involved.
+
+<sect>Credits<label id="credi">
+<p>
+
+The original ancestor of this document was by Chin Fang
+&lt;fangchin@leland.stanford.edu&gt;.
+
+Eric S. Raymond &lt;esr@snark.thyrsus.com&gt; reworked, reorganized, and
+massively rewrote Chin Fang's original in an attempt to understand it. In
+the process, he merged in most of a different how-to by Bob Crosson
+&lt;crosson@cam.nist.gov&gt;.
+
+The material on interlaced modes is largely by David Kastrup
+&lt;dak@pool.informatik.rwth-aachen.de&gt;
+
+Martin Lottermoser &lt;Martin.Lottermoser@mch.sni.de&gt; contributed
+the idea of using gnuplot to make mode diagrams and did the
+mathematical analysis behind <TT>modeplot</TT>. The distributed
+<TT>modeplot</TT> was redesigned and generalized by ESR from
+Martin's original gnuplot code for one case.
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/VideoModes.sgml,v 1.1 2001/06/04 13:50:16 dawes Exp $
+
+
+
+
+
+$XConsortium: VidModes.sgml /main/7 1996/02/21 17:46:17 kaleb $
+</verb>
+
+</article>
+
+<!--
+The following sets edit modes for GNU EMACS
+Local Variables:
+fill-prefix:"\t"
+fill-column:75
+End:
+-- >
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/s3/Imakefile
new file mode 100644
index 000000000..ffb7ae482
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3/Imakefile
@@ -0,0 +1,60 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3/Imakefile,v 1.9 2001/07/06 07:52:01 keithp Exp $ */
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = s3_driver.c s3_IBMRGB.c s3_Trio64DAC.c s3_accel_newmmio.c \
+ s3_accel_pio.c s3_cursor.c s3_bios.c s3_video.c s3_dga.c \
+ s3_Ti.c
+
+OBJS = s3_driver.o s3_IBMRGB.o s3_Trio64DAC.o s3_accel_newmmio.o \
+ s3_accel_pio.o s3_cursor.o s3_bios.o s3_video.o s3_dga.o \
+ s3_Ti.o
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/fb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/mfb \
+ -I$(XF86SRC)/xaa -I$(SERVERSRC)/cfb \
+ -I$(XF86SRC)/xf1bpp -I$(XF86SRC)/xf4bpp \
+ -I$(XF86SRC)/xf24_32bpp -I$(SERVERSRC)/Xext \
+ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \
+ -I$(XF86SRC)/rac -I$(XF86SRC)/int10 \
+ -I$(XF86SRC)/fbdevhw -I$(XF86SRC)/ddc \
+ -I$(XF86SRC)/i2c -I$(XF86OSSRC)/vbe \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(FONTINCSRC) \
+ -I$(EXTINCSRC) -I$(SERVERSRC)/render
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+NormalAsmObjectRule()
+
+ModuleObjectRule()
+ObjectModuleTarget(s3, $(OBJS))
+
+InstallObjectModule(s3,$(MODULEDIR),drivers)
+
+DependTarget()
+
+ObjectFromSpecialSource(s3_accel_pio, s3_accel, -DS3_GENERIC)
+ObjectFromSpecialSource(s3_accel_newmmio, s3_accel, -DS3_NEWMMIO)
+SpecialCObjectRule(s3_video,$(_NOOP_), -DS3_NEWMMIO)
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/s3)
+InstallDriverSDKNonExecFile(s3.h,$(DRIVERSDKDIR)/drivers/s3)
+InstallDriverSDKNonExecFile(s3_reg.h,$(DRIVERSDKDIR)/drivers/s3)
+InstallDriverSDKNonExecFile(s3_driver.c,$(DRIVERSDKDIR)/drivers/s3)
+InstallDriverSDKNonExecFile(s3_accel.c,$(DRIVERSDKDIR)/drivers/s3)
+InstallDriverSDKNonExecFile(s3_cursor.c,$(DRIVERSDKDIR)/drivers/s3)
+InstallDriverSDKNonExecFile(s3_video.c,$(DRIVERSDKDIR)/drivers/s3)
+InstallDriverSDKNonExecFile(s3_dga.c,$(DRIVERSDKDIR)/drivers/s3)
+InstallDriverSDKNonExecFile(s3_bios.c,$(DRIVERSDKDIR)/drivers/s3)
+InstallDriverSDKNonExecFile(s3_Trio64DAC.c,$(DRIVERSDKDIR)/drivers/s3)
+InstallDriverSDKNonExecFile(s3_IBMRGB.c,$(DRIVERSDKDIR)/drivers/s3)
+InstallDriverSDKNonExecFile(s3_Ti.c,$(DRIVERSDKDIR)/drivers/s3)
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3/newmmio.h b/xc/programs/Xserver/hw/xfree86/drivers/s3/newmmio.h
new file mode 100644
index 000000000..15e7f3c9f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3/newmmio.h
@@ -0,0 +1,263 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3/newmmio.h,v 1.6 2001/07/02 10:46:04 alanh Exp $ */
+
+/*
+ *
+ * Copyright 1995-1997 The XFree86 Project, Inc.
+ *
+ */
+
+#ifndef _NEWMMIO_H_
+#define _NEWMMIO_H_
+
+#include <Xmd.h>
+
+
+#define int16 CARD16
+#define int32 CARD32
+
+#define S3_NEWMMIO_VGABASE (S3_NEWMMIO_REGBASE + 0x8000)
+
+typedef struct { int16 vendor_ID; int16 device_ID; } pci_id;
+typedef struct { int16 cmd; int16 devsel; } cmd_devsel;
+
+typedef struct {
+ pci_id pci_ident;
+ cmd_devsel cmd_device_sel;
+ int32 class_code;
+ int32 dummy5;
+ int32 base0;
+ char dummy1[0x20-sizeof(int32)];
+ int32 bios_base;
+ char dummy2[0x3c - 0x32];
+} pci_conf_regs;
+
+
+typedef struct { int16 filler; int16 adv_f_cntl; } adv_f_cntl;
+
+typedef struct {
+ int32 cur_point;
+ char dummy1[4];
+ int32 dest_stp;
+ char dummy2[4];
+ int32 err_term;
+ char dummy3[4];
+ int32 command;
+ int32 short_stroke;
+ int32 bkgd_color;
+ int32 frgd_color;
+ int32 wrt_mask;
+ int32 rd_mask;
+ int32 color_cmp;
+ int32 col_mix;
+ int32 sciss_topleft;
+ int32 sciss_botright;
+ int32 pix_mult;
+ int32 mult_misc;
+ int32 axis_pcnt;
+} packed_enhanced_regs;
+
+typedef struct {
+ int32 prim_stream_cntl;
+ int32 col_chroma_key_cntl;
+ char dummy1[0x8190 - 0x8184-sizeof(int32)];
+ int32 second_stream_cntl;
+ int32 chroma_key_upper_bound;
+ int32 second_stream_stretch;
+ char dummy2[0x81a0 - 0x8198-sizeof(int32)];
+ int32 blend_cntl;
+ char dummy3[0x81c0 - 0x81a0-sizeof(int32)];
+ int32 prim_fbaddr0;
+ int32 prim_fbaddr1;
+ int32 prim_stream_stride;
+ int32 double_buffer;
+ int32 second_fbaddr0;
+ int32 second_fbaddr1;
+ int32 second_stream_stride;
+ int32 opaq_overlay_cntl;
+ int32 k1;
+ int32 k2;
+ int32 dda_vert;
+ int32 streams_fifo;
+ int32 prim_start_coord;
+ int32 prim_window_size;
+ int32 second_start_coord;
+ int32 second_window_size;
+} streams_proc_regs;
+
+typedef struct { char atr_cntl_ind; char attr_cntl_dat; char misc_out;
+ char viseo_enable; } v3c0;
+typedef struct { char seq_index; char seq_data; char dac_mask;
+ char dac_rd_index; } v3c4;
+typedef struct { char dac_wr_index; char dac_data; char feature_cntl;
+ char filler; } v3c8;
+typedef struct v3cc { char misc_out; char filler; char graph_cntl_index;
+ char graph_cntl_data; } v3cc;
+typedef struct {
+ v3c0 v3c0_regs;
+ v3c4 v3c4_regs;
+ v3c8 v3c8_regs;
+ v3cc v3cc_regs;
+} vga_3c_regs;
+
+typedef struct { char crt_index; char crt_data; int16 filler; } v3d4;
+typedef struct { int16 filler1; char feature_cntl; char filler2;} v3d8;
+
+typedef struct {
+ int32 filler;
+ v3d4 v3d4_regs;
+ v3d8 v3d8_regs;
+} vga_3bd_regs ;
+
+typedef struct {
+ int32 subsystem_csr;
+ int32 dummy;
+ adv_f_cntl adv_func_cntl;
+} subsys_regs;
+
+
+typedef struct {
+ int32 cur_x;
+ char filler1[0x8ae8 - 0x86e8 - sizeof(int32)];
+ int32 dy_axstep;
+ char filler2[0x8ee8 - 0x8ae8 - sizeof(int32)];
+ int32 dx_diastep;
+ char filler3[0x92e8 - 0x8ee8 - sizeof(int32)];
+ int32 line_err;
+ char filler33[0x96e8 - 0x92e8 - sizeof(int32)];
+ int32 mj_ax_pcnt;
+ char filler4[0x9ae8 - 0x96e8 - sizeof(int32)];
+ int32 gp_stat;
+ char filler5[0x9ee8 - 0x9ae8 - sizeof(int32)];
+ int32 stroke_vectrans;
+ char filler6[0xa2e8 - 0x9ee8 - sizeof(int32)];
+ int32 back_color;
+ char filler7[0xa6e8 - 0xa2e8 - sizeof(int32)];
+ int32 fore_col;
+ char filler8[0xaae8 - 0xa6e8 - sizeof(int32)];
+ int32 bitplane_wmask;
+ char filler88[0xaee8 - 0xaae8 - sizeof(int32)];
+ int32 bitplane_rmask;
+ char filler9[0xb2e8 - 0xaee8 - sizeof(int32)];
+ int32 color_compare;
+ char filler10[0xb6e8 - 0xb2e8 - sizeof(int32)];
+ int32 back_mix;
+ char filler101[0xbae8 - 0xb6e8 - sizeof(int32)];
+ int32 fore_mix;
+ char filler11[0xbee8 - 0xbae8 - sizeof(int32)];
+ int32 r_reg_data;
+ char filler12[0xe2e8 - 0xbee8 - sizeof(int32)];
+ int32 pixel_data_transfer;
+} enhanced_regs;
+
+typedef struct {
+ int32 lpb_mode;
+ int32 lpb_fifostat;
+ int32 lpb_intflags;
+ int32 lpb_fb0addr;
+ int32 lpb_fb1addr;
+ int32 lpb_direct_addr;
+ int32 lpb_direct_data;
+ int32 lpb_gpio;
+ int32 lpb_serial_port;
+ int32 lpb_input_winsize;
+ int32 lpb_data_offsets;
+ int32 lpb_hor_decimctl;
+ int32 lpb_vert_decimctl;
+ int32 lpb_line_stride;
+ int32 lpb_output_fifo;
+} lpbus_regs;
+
+typedef struct {
+ int32 img[0x8000/4];
+ union { pci_conf_regs regs;
+ char dummy[0x100];
+ } pci_regs;
+ union { packed_enhanced_regs regs;
+ char dummy[0x80];
+ } pk_enh_regs;
+ union { streams_proc_regs regs;
+ char dummy[0x82e8-0x8180];
+ } streams_regs;
+ union { int32 cur_y;
+ char dummy[0x83b0 - 0x82e8];
+ } cur_y;
+ union { vga_3bd_regs regs;
+ char dummy[0x83c0 - 0x83b0];
+ } v3b_regs;
+ union { vga_3c_regs regs;
+ char dummy[0x83d0 - 0x83c0];
+ } v3c_regs;
+ union { vga_3bd_regs regs;
+ char dummy[0x8504 - 0x83d0];
+ } v3d_regs;
+ union { subsys_regs regs;
+ char dummy[0x86e8 - 0x8504];
+ } subs_regs;
+ union { enhanced_regs regs;
+ char dummy[0xff00 - 0x86e8];
+ } enh_regs;
+ union { lpbus_regs regs;
+ char dummy[0xff5c - 0xff00];
+ } lbp_regs;
+} mm_trio_regs ;
+
+#define mmtr volatile mm_trio_regs *
+
+#define s3MmioMem (pS3->MMIOBase)
+
+#define IMG_TRANS (((mmtr)s3MmioMem)->img)
+
+#define SET_WRT_MASK(msk) ((mmtr)s3MmioMem)->pk_enh_regs.regs.wrt_mask = (msk)
+#define SET_RD_MASK(msk) ((mmtr)s3MmioMem)->pk_enh_regs.regs.rd_mask = (msk)
+#define SET_FRGD_COLOR(col) ((mmtr)s3MmioMem)->pk_enh_regs.regs.frgd_color = (col)
+#define SET_BKGD_COLOR(col) ((mmtr)s3MmioMem)->pk_enh_regs.regs.bkgd_color = (col)
+#define SET_COLOR_CMP(col) ((mmtr)s3MmioMem)->pk_enh_regs.regs.color_cmp = (col)
+#define SET_FRGD_MIX(fmix) ((mmtr)s3MmioMem)->enh_regs.regs.fore_mix = (fmix)
+#define SET_BKGD_MIX(bmix) ((mmtr)s3MmioMem)->enh_regs.regs.back_mix = (bmix)
+#define SET_PIX_CNTL(val) ((mmtr)s3MmioMem)->pk_enh_regs.regs.pix_mult = (val) | (MULT_MISC2 << 16)
+#define SET_MIN_AXIS_PCNT(min) ((mmtr)s3MmioMem)->enh_regs.regs.r_reg_data = (min) & 0xffff
+#define SET_MAJ_AXIS_PCNT(maj) ((mmtr)s3MmioMem)->enh_regs.regs.mj_ax_pcnt = (maj)
+#define SET_CURPT(c_x, c_y) ((mmtr)s3MmioMem)->pk_enh_regs.regs.cur_point = ((c_y)&0xffff) | ((c_x) << 16)
+#define SET_CUR_X(c_x) ((mmtr)s3MmioMem)->enh_regs.regs.cur_x = (c_x)
+#define SET_CUR_Y(c_y) ((mmtr)s3MmioMem)->cur_y.cur_y = (c_y)
+#define SET_DESTSTP(x,y) ((mmtr)s3MmioMem)->pk_enh_regs.regs.dest_stp = ((y)&0xffff) | ((x) << 16)
+#define SET_AXIS_PCNT(maj, min) ((mmtr)s3MmioMem)->pk_enh_regs.regs.axis_pcnt = ((min)&0xffff) | ((maj) << 16)
+#define SET_CMD(c_d) { mem_barrier(); ((mmtr)s3MmioMem)->pk_enh_regs.regs.command = (c_d); }
+#define SET_ERR_TERM(e) ((mmtr)s3MmioMem)->pk_enh_regs.regs.err_term = (e)
+#define SET_SCISSORS(x1,y1,x2,y2) {\
+ ((mmtr)s3MmioMem)->pk_enh_regs.regs.sciss_topleft = ((y1)&0xffff) | ((x1) << 16);\
+ ((mmtr)s3MmioMem)->pk_enh_regs.regs.sciss_botright = ((y2)&0xffff) | ((x2) << 16);\
+ }
+#define SET_SCISSORS_RB(x,y) ((mmtr)s3MmioMem)->pk_enh_regs.regs.sciss_botright = ((y)&0xffff) | ((x) << 16)
+#define SET_SCISSORS_L(l) ((mmtr)s3MmioMem)->pk_enh_regs.regs.sciss_topleft = ((l) << 16);
+#define SET_MULT_MISC(val) ((mmtr)s3MmioMem)->pk_enh_regs.regs.mult_misc = (val)
+
+
+/*
+ * reads from GP_STAT
+ */
+#if !defined(__alpha__)
+#define INB_GP_STAT() ((((mmtr)s3MmioMem)->enh_regs.regs.gp_stat) & 0xff)
+#define INW_GP_STAT() ((((mmtr)s3MmioMem)->enh_regs.regs.gp_stat))
+#else
+#define INB_GP_STAT() inb(GP_STAT)
+#define INW_GP_STAT() inw(GP_STAT)
+#endif
+
+#define SET_PIX_TRANS_L(val) ((mmtr)s3MmioMem)->img[0] = (val)
+#define SET_MIX(b,f) ((mmtr)s3MmioMem)->pk_enh_regs.regs.col_mix = ((b) << 16) | (f)
+
+
+#define WaitQueue(v) \
+ if(!(pS3->PCIRetry)) { \
+ mem_barrier(); \
+ while(inb(GP_STAT) & (0x0100 >> (v))); \
+ }
+
+#define CMD_REG_WIDTH 0x200 /* select 32bit command register */
+
+#define WaitQueue16_32(n16,n32) \
+ if((pS3->s3Bpp) <= 2) { WaitQueue(n16); } \
+ else { WaitQueue(n32); }
+
+#endif /* _NEWMMIO_H_ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3/s3.h b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3.h
new file mode 100644
index 000000000..779d7a567
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3.h
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2001 Ani Joshi <ajoshi@unixbox.com>
+ *
+ * XFree86 4.x driver for S3 chipsets
+ *
+ *
+ * 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 Ani Joshi not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Ani Joshi makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ANI JOSHI 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/xfree86/drivers/s3/s3.h,v 1.12 2001/08/15 11:54:27 tsi Exp $ */
+
+
+#ifndef _S3_H
+#define _S3_H
+
+#include "xf86.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "xf86RamDac.h"
+#include "xaa.h"
+#include "vbe.h"
+#include "xf86_ansic.h"
+#include "vgaHW.h"
+
+
+#include "xf86xv.h"
+#include "Xv.h"
+#include "fourcc.h"
+
+
+#ifndef S3_USEFB
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+#endif
+
+typedef struct _S3RegRec {
+ unsigned char cr31, cr32, cr33, cr34, cr3a, cr3b, cr3c;
+ unsigned char cr3b2, cr3c2;
+ unsigned char cr40, cr42, cr43, cr44, cr45;
+ unsigned char cr50, cr51, cr53, cr54, cr55, cr58, cr59, cr5a,
+ cr5d, cr5e;
+ unsigned char cr60, cr61, cr62, cr65, cr66, cr67, cr6d;
+ unsigned char s3save[10];
+ unsigned char s3syssave[46];
+ unsigned char dacregs[0x101];
+ unsigned char color_stack[8];
+ unsigned char clock;
+} S3RegRec, *S3RegPtr;
+
+
+typedef struct {
+ unsigned char brightness;
+ unsigned char contrast;
+ FBAreaPtr area;
+ RegionRec clip;
+ CARD32 colorKey;
+ CARD32 videoStatus;
+ Time offTime;
+ Time freeTime;
+ int lastPort;
+} S3PortPrivRec, *S3PortPrivPtr;
+
+
+typedef struct {
+ int bitsPerPixel;
+ int depth;
+ int displayWidth;
+ int pixel_code;
+ int pixel_bytes;
+ DisplayModePtr mode;
+} S3FBLayout;
+
+
+typedef struct _S3Rec {
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ EntityInfoPtr pEnt;
+ CARD32 IOAddress;
+ CARD32 FBAddress;
+ unsigned char * FBBase;
+ unsigned char * MMIOBase;
+ unsigned long videoRam;
+ OptionInfoPtr Options;
+ unsigned int Flags;
+ Bool NoAccel;
+ Bool S3NewMMIO;
+ Bool PCIRetry;
+ Bool ColorExpandBug;
+
+ XAAInfoRecPtr pXAA;
+ xf86CursorInfoPtr pCurs;
+ xf86Int10InfoPtr pInt10;
+ vbeInfoPtr pVBE;
+ XF86VideoAdaptorPtr adaptor;
+ S3PortPrivPtr portPrivate;
+
+ DGAModePtr DGAModes;
+ int numDGAModes;
+ Bool DGAactive;
+ int DGAViewportStatus;
+
+ S3FBLayout CurrentLayout;
+
+ RamDacHelperRecPtr RamDac;
+ RamDacRecPtr RamDacRec;
+
+ int vgaCRIndex, vgaCRReg;
+
+ int s3Bpp, s3BppDisplayWidth, HDisplay;
+ int mclk, MaxClock;
+ int pixMuxShift;
+
+ int Chipset, ChipRev;
+ int RefClock;
+
+ int s3ScissB, s3ScissR;
+ unsigned short BltDir;
+ int trans_color;
+ int FBCursorOffset;
+
+ S3RegRec SavedRegs;
+ S3RegRec ModeRegs;
+
+ unsigned char SAM256;
+
+ void (*DacPreInit)(ScrnInfoPtr pScrn);
+ void (*DacInit)(ScrnInfoPtr pScrn,
+ DisplayModePtr mode);
+ void (*DacSave)(ScrnInfoPtr pScrn);
+ void (*DacRestore)(ScrnInfoPtr pScrn);
+ Bool (*CursorInit)(ScreenPtr pScreen);
+
+ void (*LoadPalette)(ScrnInfoPtr pScrn, int numColors,
+ int *indicies, LOCO *colors,
+ VisualPtr pVisual);
+
+ Bool (*CloseScreen)(int, ScreenPtr);
+
+ unsigned char *imageBuffer;
+ int imageWidth;
+ int imageHeight;
+} S3Rec, *S3Ptr;
+
+#define S3PTR(p) ((S3Ptr)((p)->driverPrivate))
+
+
+#define DRIVER_NAME "s3"
+#define DRIVER_VERSION "0.3.4"
+#define VERSION_MAJOR 0
+#define VERSION_MINOR 3
+#define PATCHLEVEL 4
+#define S3_VERSION ((VERSION_MAJOR << 24) | \
+ (VERSION_MINOR << 16) | PATCHLEVEL)
+
+
+
+
+/*
+ * Prototypes
+ */
+
+Bool S3AccelInit(ScreenPtr pScreen);
+Bool S3AccelInitNewMMIO(ScreenPtr pScreen);
+Bool S3AccelInitPIO(ScreenPtr pScreen);
+Bool S3DGAInit(ScreenPtr pScreen);
+Bool S3SwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+int S3GetRefClock(ScrnInfoPtr pScrn);
+
+void S3InitVideo(ScreenPtr pScreen);
+void S3InitStreams(ScrnInfoPtr pScrn, DisplayModePtr mode);
+
+/* IBMRGB */
+extern RamDacSupportedInfoRec IBMRamdacs[];
+Bool S3ProbeIBMramdac(ScrnInfoPtr pScrn);
+void S3IBMRGB_PreInit(ScrnInfoPtr pScrn);
+void S3IBMRGB_Init(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void S3IBMRGB_Save(ScrnInfoPtr pScrn);
+void S3IBMRGB_Restore(ScrnInfoPtr pScrn);
+Bool S3IBMRGB_CursorInit(ScreenPtr pScreen);
+
+/* TRIO64 */
+Bool S3Trio64DACProbe(ScrnInfoPtr pScrn);
+void S3Trio64DAC_PreInit(ScrnInfoPtr pScrn);
+void S3Trio64DAC_Init(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void S3Trio64DAC_Save(ScrnInfoPtr pScrn);
+void S3Trio64DAC_Restore(ScrnInfoPtr pScrn);
+
+/* Ti */
+Bool S3TiDACProbe(ScrnInfoPtr pScrn);
+void S3TiDAC_PreInit(ScrnInfoPtr pScrn);
+void S3TiDAC_Init(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void S3TiDAC_Save(ScrnInfoPtr pScrn);
+void S3TiDAC_Restore(ScrnInfoPtr pScrn);
+void S3TiLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, LOCO *colors,
+ VisualPtr pVisual);
+Bool S3Ti_CursorInit(ScreenPtr pScreen);
+void S3OutTiIndReg(ScrnInfoPtr pScrn, CARD32 reg, unsigned char mask,
+ unsigned char data);
+
+/* s3 gen cursor */
+Bool S3_CursorInit(ScreenPtr pScreen);
+
+#define TRIO64_RAMDAC 0x8811
+#define TI3025_RAMDAC 0x3025
+#define TI3020_RAMDAC 0x3020
+
+#define BIOS_BSIZE 1024
+#define BIOS_BASE 0xc0000
+
+#endif /* _S3_H */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_IBMRGB.c b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_IBMRGB.c
new file mode 100644
index 000000000..798cc24d3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_IBMRGB.c
@@ -0,0 +1,551 @@
+/*
+ * Copyright 2001 Ani Joshi <ajoshi@unixbox.com>
+ *
+ * XFree86 4.x driver for S3 chipsets
+ *
+ *
+ * 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 Ani Joshi not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Ani Joshi makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ANI JOSHI 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/xfree86/drivers/s3/s3_IBMRGB.c,v 1.1 2001/07/02 10:46:04 alanh Exp $ */
+
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "compiler.h"
+
+#include "IBM.h"
+
+#include "s3.h"
+
+
+#define IBMRGB_WRITE_ADDR 0x3C8 /* CR55 low bit == 0 */
+#define IBMRGB_RAMDAC_DATA 0x3C9 /* CR55 low bit == 0 */
+#define IBMRGB_PIXEL_MASK 0x3C6 /* CR55 low bit == 0 */
+#define IBMRGB_READ_ADDR 0x3C7 /* CR55 low bit == 0 */
+#define IBMRGB_INDEX_LOW 0x3C8 /* CR55 low bit == 1 */
+#define IBMRGB_INDEX_HIGH 0x3C9 /* CR55 low bit == 1 */
+#define IBMRGB_INDEX_DATA 0x3C6 /* CR55 low bit == 1 */
+#define IBMRGB_INDEX_CONTROL 0x3C7 /* CR55 low bit == 1 */
+
+
+void S3OutIBMRGBIndReg(ScrnInfoPtr pScrn, CARD32 reg,
+ unsigned char mask, unsigned char data)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ unsigned char tmp, tmp2 = 0x00;
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+
+ outb(vgaCRIndex, 0x55);
+ tmp = inb(vgaCRReg) & 0xfc;
+ outb(vgaCRReg, tmp | 0x01);
+
+ outb(IBMRGB_INDEX_LOW, reg);
+
+ if (mask != 0x00)
+ tmp2 = inb(IBMRGB_INDEX_DATA) & mask;
+ outb(IBMRGB_INDEX_DATA, tmp2 | data);
+
+ outb(vgaCRIndex, 0x55);
+ outb(vgaCRReg, tmp);
+}
+
+
+unsigned char S3InIBMRGBIndReg(ScrnInfoPtr pScrn, CARD32 reg)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ unsigned char tmp, ret;
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+
+ outb(vgaCRIndex, 0x55);
+ tmp = inb(vgaCRReg) & 0xfc;
+ outb(vgaCRReg, tmp | 0x01);
+
+ outb(IBMRGB_INDEX_LOW, reg);
+ ret = inb(IBMRGB_INDEX_DATA);
+
+ outb(vgaCRIndex, 0x55);
+ outb(vgaCRReg, tmp);
+
+ return ret;
+}
+
+
+void S3IBMWriteAddress(ScrnInfoPtr pScrn, CARD32 index)
+{
+ outb(IBMRGB_WRITE_ADDR, index);
+}
+
+void S3IBMWriteData(ScrnInfoPtr pScrn, unsigned char data)
+{
+ outb(IBMRGB_INDEX_DATA, data);
+}
+
+void S3IBMReadAddress(ScrnInfoPtr pScrn, CARD32 index)
+{
+ outb(IBMRGB_READ_ADDR, index);
+}
+
+unsigned char S3IBMReadData(ScrnInfoPtr pScrn)
+{
+ return inb(IBMRGB_RAMDAC_DATA);
+}
+
+
+Bool S3ProbeIBMramdac(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ pS3->RamDacRec = RamDacCreateInfoRec();
+ pS3->RamDacRec->ReadDAC = S3InIBMRGBIndReg;
+ pS3->RamDacRec->WriteDAC = S3OutIBMRGBIndReg;
+ pS3->RamDacRec->ReadAddress = S3IBMReadAddress;
+ pS3->RamDacRec->WriteAddress = S3IBMWriteAddress;
+ pS3->RamDacRec->ReadData = S3IBMReadData;
+ pS3->RamDacRec->WriteData = S3IBMWriteData;
+ pS3->RamDacRec->LoadPalette = NULL;
+
+ if (!RamDacInit(pScrn, pS3->RamDacRec)) {
+ RamDacDestroyInfoRec(pS3->RamDacRec);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RamDacInit failed\n");
+ return;
+ }
+
+ pS3->RamDac = IBMramdacProbe(pScrn, IBMRamdacs);
+ if (pS3->RamDac)
+ return TRUE;
+
+ return FALSE;
+}
+
+void S3ProgramIBMRGBClock(ScrnInfoPtr pScrn, int clk, unsigned char m,
+ unsigned char n, unsigned char df)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ RamDacHWRecPtr pIBM = RAMDACHWPTR(pScrn);
+ RamDacRegRecPtr ramdacReg = &pIBM->ModeReg;
+ int tmp = 1;
+
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_misc_clock, ~1, 1);
+
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_m0+2*clk, 0, (df<<6)|(m&0x3f));
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_n0+2*clk, 0, n);
+
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_pll_ctrl2, 0xf0, clk);
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_pll_ctrl1, 0xf8, 3);
+}
+
+
+void S3IBMRGBSetClock(ScrnInfoPtr pScrn, long freq, int clk, long dacspeed,
+ long fref)
+{
+ volatile double ffreq, fdacspeed, ffref;
+ volatile int df, n, m, max_n, min_df;
+ volatile int best_m=69, best_n=17, best_df=0;
+ volatile double diff, mindiff;
+
+#define FREQ_MIN 16250
+#define FREQ_MAX dacspeed
+
+ if (freq < FREQ_MIN)
+ ffreq = FREQ_MIN / 1000.0;
+ else if (freq > FREQ_MAX)
+ ffreq = FREQ_MAX / 1000.0;
+ else
+ ffreq = freq / 1000.0;
+
+ fdacspeed = dacspeed / 1e3;
+ ffref = fref / 1e3;
+
+ ffreq /= ffref;
+ ffreq *= 16;
+ mindiff = ffreq;
+
+ if (freq <= dacspeed/4)
+ min_df = 0;
+ else if (freq <= dacspeed/2)
+ min_df = 1;
+ else
+ min_df = 2;
+
+ for (df=0; df<4; df++) {
+ ffreq /= 2;
+ mindiff /= 2;
+ if (df < min_df)
+ continue;
+
+ if (df < 3)
+ max_n = fref / 1000 / 2;
+ else
+ max_n = fref / 1000;
+ if (max_n > 31)
+ max_n = 31;
+
+ for (n=2; n <= max_n; n++) {
+ m = (int)(ffreq * n + 0.5) - 65;
+ if (m < 0)
+ m = 0;
+ else if (m > 63)
+ m = 63;
+ diff = (m+65.0)/n-ffreq;
+ if (diff < 0)
+ diff = -diff;
+ if (diff < mindiff) {
+ mindiff = diff;
+ best_n = n;
+ best_m = m;
+ best_df = df;
+ }
+ }
+ }
+
+ S3ProgramIBMRGBClock(pScrn, clk, best_m, best_n, best_df);
+}
+
+void S3IBMRGB_Restore(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ S3RegPtr restore = &pS3->SavedRegs;
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ int i;
+
+ for(i=0; i<0x100; i++)
+ S3OutIBMRGBIndReg(pScrn, i, 0, restore->dacregs[i]);
+
+ outb(vgaCRIndex, 0x22);
+ outb(vgaCRReg, restore->dacregs[0x100]);
+}
+
+
+void S3IBMRGB_Save(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ S3RegPtr save = &pS3->SavedRegs;
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ int i;
+
+ for (i=0; i<0x100; i++)
+ save->dacregs[i] = S3InIBMRGBIndReg(pScrn, i);
+
+ outb(vgaCRIndex, 0x22);
+ save->dacregs[0x100] = inb(vgaCRReg);
+}
+
+
+void S3IBMRGB_PreInit(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ unsigned char cr55, tmp;
+
+ outb(vgaCRIndex, 0x43);
+ tmp = inb(vgaCRReg);
+ outb(vgaCRReg, tmp & ~0x02);
+
+ outb(vgaCRIndex, 0x55);
+ cr55 = inb(vgaCRReg);
+ outb(vgaCRReg, (cr55 & ~0x03) | 0x01); /* set rs2 */
+
+ tmp = inb(IBMRGB_INDEX_CONTROL);
+ outb(IBMRGB_INDEX_CONTROL, tmp & ~1);
+ outb(IBMRGB_INDEX_HIGH, 0);
+
+ outb(vgaCRIndex, 0x55);
+ outb(vgaCRReg, cr55 & ~0x03);
+
+ {
+ int m, n, df, mclk=0;
+
+ m = S3InIBMRGBIndReg(pScrn, IBMRGB_sysclk_vco_div);
+ n = S3InIBMRGBIndReg(pScrn, IBMRGB_sysclk_ref_div) & 0x1f;
+ df = m >> 6;
+ m &= 0x3f;
+ if (!n) {
+ m = 0;
+ n = 1;
+ }
+ mclk = ((pS3->RefClock*100 * (m+65)) / n / (8 >> df) + 50) / 100;
+ pS3->mclk = mclk;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MCLK %1.3f MHz\n",
+ mclk / 1000.0);
+ }
+}
+
+
+void S3IBMRGB_Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ S3RegPtr new = &pS3->ModeRegs;
+ RamDacHWRecPtr pIBM = RAMDACHWPTR(pScrn);
+ RamDacRegRecPtr ramdacReg = &pIBM->ModeReg;
+ unsigned long m=0,n=0,p=0,c=0;
+ unsigned long clock;
+ unsigned char tmp, cr55, blank;
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+
+ S3IBMRGBSetClock(pScrn, mode->Clock, 2, pS3->MaxClock,
+ pS3->RefClock);
+
+ outb(0x3c4, 1);
+ blank = inb(0x3c5);
+ outb(0x3c5, blank | 0x20);
+
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_misc_clock, 0xf0, 0x03);
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_sync, 0, 0);
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_hsync_pos, 0, 0);
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_pwr_mgmt, 0, 0);
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_dac_op, ~8, 0);
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_dac_op, ~2, 2);
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_pal_ctrl, 0, 0);
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_misc1, ~0x43, 1);
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_misc2, 0, 0x47);
+
+ outb(vgaCRIndex, 0x22);
+ tmp = inb(vgaCRReg);
+ if (pS3->s3Bpp == 1)
+ outb(vgaCRReg, tmp | 8);
+ else
+ outb(vgaCRReg, tmp & ~8);
+
+ outb(vgaCRIndex, 0x65);
+ outb(vgaCRReg, 0x00); /* ! 528 */
+
+ outb(vgaCRIndex, 0x40);
+ outb(vgaCRReg, 0x11);
+ outb(vgaCRIndex, 0x55);
+ outb(vgaCRReg, 0x00);
+
+ switch (pScrn->depth) {
+ case 8:
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_pix_fmt, 0xf8, 3);
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_8bpp, 0, 0);
+ break;
+ case 15:
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_pix_fmt, 0xf8, 4);
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_16bpp, 0, 0xc0);
+ break;
+ case 16:
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_pix_fmt, 0xf8, 4);
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_16bpp, 0, 0xc2);
+ break;
+ }
+
+ outb(vgaCRIndex, 0x66);
+ tmp = inb(vgaCRReg) & 0xf8;
+ outb(vgaCRReg, tmp);
+
+ outb(vgaCRIndex, 0x58);
+ tmp = (inb(vgaCRReg) & 0xbf) | 0x40;
+ outb(vgaCRReg, tmp);
+
+ outb(vgaCRIndex, 0x67);
+ outb(vgaCRReg, 0x11);
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ tmp = 0x21;
+ break;
+ case 16:
+ tmp = 0x10;
+ break;
+ }
+ outb(vgaCRIndex, 0x6d);
+ outb(vgaCRReg, tmp);
+
+ outb(0x3c4, 1);
+ outb(0x3c5, blank);
+}
+
+
+/* hardware cursor */
+
+static void S3IBMRGBSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ unsigned char tmp;
+
+ /* unlock sys regs */
+ outb(vgaCRIndex, 0x39);
+ outb(vgaCRReg, 0xa5);
+
+ outb(vgaCRIndex, 0x55);
+ tmp = inb(vgaCRReg) & 0xfc;
+ outb(vgaCRReg, tmp | 0x01);
+
+ outb(IBMRGB_INDEX_LOW, IBMRGB_curs_col1_r);
+ outb(IBMRGB_INDEX_DATA, (bg & 0x00ff0000) >> 16);
+ outb(IBMRGB_INDEX_LOW, IBMRGB_curs_col1_g);
+ outb(IBMRGB_INDEX_DATA, (bg & 0x0000ff00) >> 8);
+ outb(IBMRGB_INDEX_LOW, IBMRGB_curs_col1_b);
+ outb(IBMRGB_INDEX_DATA, (bg & 0x000000ff));
+ outb(IBMRGB_INDEX_LOW, IBMRGB_curs_col2_r);
+ outb(IBMRGB_INDEX_DATA, (fg & 0x00ff0000) >> 16);
+ outb(IBMRGB_INDEX_LOW, IBMRGB_curs_col2_g);
+ outb(IBMRGB_INDEX_DATA, (fg & 0x0000ff00) >> 8);
+ outb(IBMRGB_INDEX_LOW, IBMRGB_curs_col2_b);
+ outb(IBMRGB_INDEX_DATA, (fg & 0x000000ff));
+
+ outb(vgaCRReg, tmp);
+}
+
+
+static void S3IBMRGBSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ unsigned char tmp;
+
+ /* unlock sys regs */
+ outb(vgaCRIndex, 0x39);
+ outb(vgaCRReg, 0xa5);
+
+ outb(vgaCRIndex, 0x55);
+ tmp = inb(vgaCRReg) & 0xfc;
+ outb(vgaCRReg, tmp | 0x01);
+
+ outb(IBMRGB_INDEX_LOW, IBMRGB_curs_xl);
+ outb(IBMRGB_INDEX_DATA, x);
+ outb(IBMRGB_INDEX_LOW, IBMRGB_curs_xh);
+ outb(IBMRGB_INDEX_DATA, x >> 8);
+ outb(IBMRGB_INDEX_LOW, IBMRGB_curs_yl);
+ outb(IBMRGB_INDEX_DATA, y);
+ outb(IBMRGB_INDEX_LOW, IBMRGB_curs_yh);
+ outb(IBMRGB_INDEX_DATA, y >> 8);
+
+ outb(vgaCRReg, tmp);
+}
+
+
+static void S3IBMRGBHideCursor(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+
+ /* unlock sys regs */
+ outb(vgaCRIndex, 0x39);
+ outb(vgaCRReg, 0xa5);
+
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_curs, ~3, 0x00);
+}
+
+
+static void S3IBMRGBShowCursor(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ unsigned char tmp;
+
+ /* unlock sys regs */
+ outb(vgaCRIndex, 0x39);
+ outb(vgaCRReg, 0xa5);
+
+ outb(vgaCRIndex, 0x55);
+ tmp = (inb(vgaCRReg) & 0xdf) | 0x20;
+ outb(vgaCRReg, tmp);
+
+ outb(vgaCRIndex, 0x45);
+ tmp = inb(vgaCRReg) & ~0x20;
+ outb(vgaCRReg, tmp);
+
+ S3OutIBMRGBIndReg(pScrn, IBMRGB_curs, 0, 0x27);
+}
+
+
+static void S3IBMRGBLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ unsigned char tmp, tmp2;
+ register int i;
+
+ /* unlock sys regs */
+ outb(vgaCRIndex, 0x39);
+ outb(vgaCRReg, 0xa5);
+
+ outb(vgaCRIndex, 0x55);
+ tmp = inb(vgaCRReg) & 0xfc;
+ outb(vgaCRReg, tmp | 0x01);
+
+ outb(IBMRGB_INDEX_LOW, IBMRGB_curs_hot_x);
+ outb(IBMRGB_INDEX_DATA, 0);
+ outb(IBMRGB_INDEX_LOW, IBMRGB_curs_hot_y);
+ outb(IBMRGB_INDEX_DATA, 0);
+ outb(IBMRGB_INDEX_LOW, IBMRGB_curs_xl);
+ outb(IBMRGB_INDEX_DATA, 0xff);
+ outb(IBMRGB_INDEX_LOW, IBMRGB_curs_xh);
+ outb(IBMRGB_INDEX_DATA, 0x7f);
+ outb(IBMRGB_INDEX_LOW, IBMRGB_curs_yl);
+ outb(IBMRGB_INDEX_DATA, 0xff);
+ outb(IBMRGB_INDEX_LOW, IBMRGB_curs_yh);
+ outb(IBMRGB_INDEX_DATA, 0x7f);
+
+ tmp2 = inb(IBMRGB_INDEX_CONTROL) & 0xfe;
+ outb(IBMRGB_INDEX_CONTROL, tmp2 | 1); /* enable auto increment */
+
+ outb(IBMRGB_INDEX_HIGH, (unsigned char) (IBMRGB_curs_array >> 8));
+ outb(IBMRGB_INDEX_LOW, (unsigned char) (IBMRGB_curs_array));
+
+ for (i=0; i<1024; i++)
+ outb(IBMRGB_INDEX_DATA, *image++);
+
+ outb(IBMRGB_INDEX_HIGH, 0);
+ outb(IBMRGB_INDEX_CONTROL, tmp2); /* disable auto increment */
+ outb(vgaCRIndex, 0x55);
+ outb(vgaCRReg, tmp);
+}
+
+
+static Bool S3IBMRGBUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ return TRUE;
+}
+
+
+Bool S3IBMRGB_CursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ S3Ptr pS3 = S3PTR(pScrn);
+ xf86CursorInfoPtr pCurs;
+
+ if (!(pCurs = pS3->pCurs = xf86CreateCursorInfoRec()))
+ return FALSE;
+
+ pCurs->MaxWidth = 64;
+ pCurs->MaxHeight = 64;
+ pCurs->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
+ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+ HARDWARE_CURSOR_NIBBLE_SWAPPED |
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST;
+
+ pCurs->SetCursorColors = S3IBMRGBSetCursorColors;
+ pCurs->SetCursorPosition = S3IBMRGBSetCursorPosition;
+ pCurs->LoadCursorImage = S3IBMRGBLoadCursorImage;
+ pCurs->HideCursor = S3IBMRGBHideCursor;
+ pCurs->ShowCursor = S3IBMRGBShowCursor;
+ pCurs->UseHWCursor = S3IBMRGBUseHWCursor;
+
+ return xf86InitCursor(pScreen, pCurs);
+}
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_Ti.c b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_Ti.c
new file mode 100644
index 000000000..8e6b7e6b7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_Ti.c
@@ -0,0 +1,754 @@
+/*
+ * Copyright 2001 Ani Joshi <ajoshi@unixbox.com>
+ *
+ * XFree86 4.x driver for S3 chipsets
+ *
+ *
+ * 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 Ani Joshi not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Ani Joshi makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ANI JOSHI 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/xfree86/drivers/s3/s3_Ti.c,v 1.1 2001/07/02 10:46:04 alanh Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "compiler.h"
+
+#include "TI.h"
+
+#include "s3.h"
+
+
+#define TI_WRITE_ADDR 0x3C8 /* CR55 low bit == 0 */
+#define TI_RAMDAC_DATA 0x3C9 /* CR55 low bit == 0 */
+#define TI_PIXEL_MASK 0x3C6 /* CR55 low bit == 0 */
+#define TI_READ_ADDR 0x3C7 /* CR55 low bit == 0 */
+#define TI_INDEX_REG 0x3C6 /* CR55 low bit == 1 */
+#define TI_DATA_REG 0x3C7 /* CR55 low bit == 1 */
+
+#define TIDAC_output_clock_select 0x1b
+#define TIDAC_auxiliary_ctrl 0x29
+#define TIDAC_general_io_ctrl 0x2a
+#define TIDAC_general_io_data 0x2b
+#define TIDAC_cursor_color_0_red 0x23
+#define TIDAC_cursor_color_0_green 0x24
+#define TIDAC_cursor_color_0_blue 0x25
+#define TIDAC_cursor_color_1_red 0x26
+#define TIDAC_cursor_color_1_green 0x27
+#define TIDAC_cursor_color_1_blue 0x28
+#define TIDAC_cursor_x_low 0x00
+#define TIDAC_cursor_x_high 0x01
+#define TIDAC_cursor_y_low 0x02
+#define TIDAC_cursor_y_high 0x03
+#define TIDAC_cursor_ram_addr_low 0x08
+#define TIDAC_cursor_ram_addr_high 0x09
+#define TIDAC_cursor_ram_data 0x0a
+
+
+#define TI_REF_FREQ 14.31818 /* 3025 only */
+
+#undef FREQ_MIN
+#define FREQ_MIN 12000
+#define FREQ_MAX 220000
+
+
+
+void S3OutTiIndReg(ScrnInfoPtr pScrn, CARD32 reg, unsigned char mask,
+ unsigned char data)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ unsigned char tmp, tmp1, tmp2 = 0x00;
+
+ outb(vgaCRIndex, 0x55);
+ tmp = inb(vgaCRReg) & 0xfc;
+ outb(vgaCRReg, tmp | 0x01);
+ tmp1 = inb(TI_INDEX_REG);
+ outb(TI_INDEX_REG, reg);
+
+ if (mask != 0x00)
+ tmp2 = inb(TI_DATA_REG) & mask;
+ outb(TI_DATA_REG, tmp2 | data);
+
+ outb(TI_INDEX_REG, tmp1);
+ outb(vgaCRReg, tmp);
+}
+
+
+unsigned char S3InTiIndReg(ScrnInfoPtr pScrn, CARD32 reg)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ unsigned char tmp, tmp1, ret;
+
+ outb(vgaCRIndex, 0x55);
+ tmp = inb(vgaCRReg) & 0xfc;
+ outb(vgaCRReg, tmp | 0x01);
+ tmp1 = inb(TI_INDEX_REG);
+ outb(TI_INDEX_REG, reg);
+
+ ret = inb(TI_DATA_REG);
+
+ outb(TI_INDEX_REG, tmp1);
+ outb(vgaCRReg, tmp);
+
+ return ret;
+}
+
+
+Bool S3TiDACProbe(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int found = 0;
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ unsigned char cr55, cr45, cr43, cr5c;
+ unsigned char TIndx, TIndx2, TIdata;
+
+ if ((pS3->Chipset != PCI_CHIP_964_0) &&
+ (pS3->Chipset != PCI_CHIP_964_1))
+ return FALSE;
+
+ outb(vgaCRIndex, 0x43);
+ cr43 = inb(vgaCRReg);
+ outb(vgaCRReg, cr43 & ~0x02);
+
+ outb(vgaCRIndex, 0x55);
+ cr55 = inb(vgaCRReg);
+
+ outb(vgaCRReg, (cr55 & 0xfc) | 0x01);
+
+ TIndx = inb(TI_INDEX_REG);
+ outb(TI_INDEX_REG, TIDAC_id);
+ if(inb(TI_DATA_REG) == 0x20) {
+ found = TI3020_RAMDAC;
+ cr43 &= ~0x02;
+ cr45 &= ~0x20;
+ } else {
+ outb(vgaCRIndex, 0x5c);
+ cr5c = inb(vgaCRReg);
+ outb(vgaCRReg, cr5c & 0xdf);
+ TIndx2 = inb(TI_INDEX_REG);
+ outb(TI_INDEX_REG, TIDAC_ind_curs_ctrl);
+ TIdata = inb(TI_DATA_REG);
+ outb(TI_DATA_REG, TIdata & 0x7f);
+
+ outb(TI_INDEX_REG, TIDAC_id);
+ if (inb(TI_DATA_REG) == 0x25) {
+ found = TI3025_RAMDAC;
+ cr43 &= ~0x02;
+ cr45 &= ~0x20;
+ }
+
+ outb(TI_INDEX_REG, TIDAC_ind_curs_ctrl);
+ outb(TI_DATA_REG, TIdata);
+ outb(TI_INDEX_REG, TIndx2);
+ outb(vgaCRIndex, 0x5c);
+ outb(vgaCRReg, cr5c);
+ }
+
+ outb(TI_INDEX_REG, TIndx);
+ outb(vgaCRIndex, 0x55);
+ outb(vgaCRReg, cr55);
+
+ outb(vgaCRIndex, 0x45);
+ outb(vgaCRReg, cr45);
+
+ outb(vgaCRIndex, 0x43);
+ outb(vgaCRReg, cr43);
+
+ if (found) {
+ RamDacInit(pScrn, pS3->RamDacRec);
+ pS3->RamDac = RamDacHelperCreateInfoRec();
+ pS3->RamDac->RamDacType = found;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+void S3TiDAC_Save(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ S3RegPtr save = &pS3->SavedRegs;
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+
+ if (pS3->RamDac->RamDacType == TI3025_RAMDAC) {
+ unsigned char cr5c;
+
+ outb(vgaCRIndex, 0x5c);
+ cr5c = inb(vgaCRReg);
+ outb(vgaCRReg, cr5c & 0xdf);
+
+ save->dacregs[TIDAC_ind_curs_ctrl] =
+ S3InTiIndReg(pScrn, TIDAC_ind_curs_ctrl);
+ S3OutTiIndReg(pScrn, TIDAC_ind_curs_ctrl, 0x7f, 0x00);
+ }
+
+ save->dacregs[TIDAC_true_color_ctrl] =
+ S3InTiIndReg(pScrn, TIDAC_true_color_ctrl);
+ save->dacregs[TIDAC_multiplex_ctrl] =
+ S3InTiIndReg(pScrn, TIDAC_multiplex_ctrl);
+ save->dacregs[TIDAC_clock_select] =
+ S3InTiIndReg(pScrn, TIDAC_clock_select);
+ save->dacregs[TIDAC_output_clock_select] =
+ S3InTiIndReg(pScrn, TIDAC_output_clock_select);
+ save->dacregs[TIDAC_general_ctrl] =
+ S3InTiIndReg(pScrn, TIDAC_general_ctrl);
+ save->dacregs[TIDAC_auxiliary_ctrl] =
+ S3InTiIndReg(pScrn, TIDAC_auxiliary_ctrl);
+ S3OutTiIndReg(pScrn, TIDAC_general_io_ctrl, 0x00, 0x1f);
+ save->dacregs[TIDAC_general_io_data] =
+ S3InTiIndReg(pScrn, TIDAC_general_io_data);
+
+ if (pS3->RamDac->RamDacType == TI3025_RAMDAC) {
+ save->dacregs[0x0e] = S3InTiIndReg(pScrn, 0x0e);
+ save->dacregs[TIDAC_misc_ctrl] =
+ S3InTiIndReg(pScrn, TIDAC_misc_ctrl);
+ S3OutTiIndReg(pScrn, TIDAC_pll_addr, 0x00, 0x00);
+ save->dacregs[0x40] = S3InTiIndReg(pScrn, TIDAC_pll_pixel_data);
+ S3OutTiIndReg(pScrn, TIDAC_pll_pixel_data, 0x00,
+ save->dacregs[0x40]);
+ save->dacregs[0x41] = S3InTiIndReg(pScrn, TIDAC_pll_pixel_data);
+ S3OutTiIndReg(pScrn, TIDAC_pll_pixel_data, 0x00,
+ save->dacregs[0x41]);
+ save->dacregs[0x42] = S3InTiIndReg(pScrn, TIDAC_pll_pixel_data);
+ S3OutTiIndReg(pScrn, TIDAC_pll_pixel_data, 0x00,
+ save->dacregs[0x42]);
+ save->dacregs[0x43] = S3InTiIndReg(pScrn, TIDAC_pll_memory_data);
+ S3OutTiIndReg(pScrn, TIDAC_pll_memory_data, 0x00,
+ save->dacregs[0x43]);
+ save->dacregs[0x44] = S3InTiIndReg(pScrn, TIDAC_pll_memory_data);
+ S3OutTiIndReg(pScrn, TIDAC_pll_memory_data, 0x00,
+ save->dacregs[0x44]);
+ save->dacregs[0x45] = S3InTiIndReg(pScrn, TIDAC_pll_memory_data);
+ S3OutTiIndReg(pScrn, TIDAC_pll_memory_data, 0x00,
+ save->dacregs[0x45]);
+ save->dacregs[0x46] = S3InTiIndReg(pScrn, TIDAC_pll_loop_data);
+ S3OutTiIndReg(pScrn, TIDAC_pll_loop_data, 0x00,
+ save->dacregs[0x46]);
+ save->dacregs[0x47] = S3InTiIndReg(pScrn, TIDAC_pll_loop_data);
+ S3OutTiIndReg(pScrn, TIDAC_pll_loop_data, 0x00,
+ save->dacregs[0x47]);
+ save->dacregs[0x48] = S3InTiIndReg(pScrn, TIDAC_pll_loop_data);
+ S3OutTiIndReg(pScrn, TIDAC_pll_loop_data, 0x00,
+ save->dacregs[0x48]);
+ }
+}
+
+
+void S3TiDAC_Restore(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ S3RegPtr restore = &pS3->SavedRegs;
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+
+ S3OutTiIndReg(pScrn, TIDAC_multiplex_ctrl, 0x00,
+ restore->dacregs[TIDAC_true_color_ctrl]);
+ S3OutTiIndReg(pScrn, TIDAC_clock_select, 0x00,
+ restore->dacregs[TIDAC_multiplex_ctrl]);
+ S3OutTiIndReg(pScrn, TIDAC_clock_select, 0x00,
+ restore->dacregs[TIDAC_clock_select]);
+ S3OutTiIndReg(pScrn, TIDAC_output_clock_select, 0x00,
+ restore->dacregs[TIDAC_output_clock_select]);
+ S3OutTiIndReg(pScrn, TIDAC_general_ctrl, 0x00,
+ restore->dacregs[TIDAC_general_ctrl]);
+ S3OutTiIndReg(pScrn, TIDAC_auxiliary_ctrl, 0x00,
+ restore->dacregs[TIDAC_auxiliary_ctrl]);
+ S3OutTiIndReg(pScrn, TIDAC_general_io_ctrl, 0x00, 0x1f);
+ S3OutTiIndReg(pScrn, TIDAC_general_io_data, 0x00,
+ restore->dacregs[TIDAC_general_io_data]);
+ if (pS3->RamDac->RamDacType == TI3025_RAMDAC) {
+ S3OutTiIndReg(pScrn, TIDAC_pll_addr, 0x00,
+ restore->dacregs[TIDAC_pll_addr]);
+ S3OutTiIndReg(pScrn, TIDAC_pll_pixel_data, 0x00,
+ restore->dacregs[0x40]);
+ S3OutTiIndReg(pScrn, TIDAC_pll_pixel_data, 0x00,
+ restore->dacregs[0x41]);
+ S3OutTiIndReg(pScrn, TIDAC_pll_pixel_data, 0x00,
+ restore->dacregs[0x42]);
+
+ S3OutTiIndReg(pScrn, TIDAC_pll_memory_data, 0x00,
+ restore->dacregs[0x43]);
+ S3OutTiIndReg(pScrn, TIDAC_pll_memory_data, 0x00,
+ restore->dacregs[0x44]);
+ S3OutTiIndReg(pScrn, TIDAC_pll_memory_data, 0x00,
+ restore->dacregs[0x45] | 0x80);
+
+ S3OutTiIndReg(pScrn, TIDAC_pll_loop_data, 0x00,
+ restore->dacregs[0x46]);
+ S3OutTiIndReg(pScrn, TIDAC_pll_loop_data, 0x00,
+ restore->dacregs[0x47]);
+ S3OutTiIndReg(pScrn, TIDAC_pll_loop_data, 0x00,
+ restore->dacregs[0x48]);
+
+ S3OutTiIndReg(pScrn, 0x0e, 0x00, restore->dacregs[0x0e]);
+ S3OutTiIndReg(pScrn, TIDAC_misc_ctrl, 0x00,
+ restore->dacregs[TIDAC_misc_ctrl]);
+ }
+
+ S3OutTiIndReg(pScrn, TIDAC_ind_curs_ctrl, 0x00,
+ restore->dacregs[TIDAC_ind_curs_ctrl]);
+}
+
+
+void S3TiDAC_PreInit(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ int mclk, m, n, p, mcc, cr5c;
+
+ outb(vgaCRIndex, 0x5c);
+ cr5c = inb(vgaCRReg);
+ outb(vgaCRReg, cr5c & 0xdf);
+
+ S3OutTiIndReg(pScrn, TIDAC_pll_addr, 0x00, 0x00);
+ n = S3InTiIndReg(pScrn, TIDAC_pll_memory_data) & 0x7f;
+ S3OutTiIndReg(pScrn, TIDAC_pll_addr, 0x00, 0x01);
+ m = S3InTiIndReg(pScrn, TIDAC_pll_memory_data) & 0x7f;
+ S3OutTiIndReg(pScrn, TIDAC_pll_addr, 0x00, 0x02);
+ p = S3InTiIndReg(pScrn, TIDAC_pll_memory_data) & 0x03;
+ mcc = S3InTiIndReg(pScrn, TIDAC_clock_ctrl);
+ if (mcc & 0x08)
+ mcc = (mcc & 0x07) * 2 + 2;
+ else
+ mcc = 1;
+
+ mclk = ((1431818 * ((m+2) * 8)) / (n+2) / (1 << p) / mcc + 50) / 100;
+ pS3->mclk = mclk;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MCLK %1.3f MHz\n",
+ mclk / 1000.0);
+
+ outb(vgaCRIndex, 0x5c);
+ outb(vgaCRReg, cr5c);
+}
+
+
+static void S3TiDACCalcNMP(long freq, int *calc_n, int *calc_m, int *calc_p)
+{
+ double ffreq;
+ int n, m, p;
+ int best_n=32, best_m=32;
+ double diff, mindiff;
+
+ if (freq < FREQ_MIN)
+ ffreq = FREQ_MIN / 1000.0;
+ else if (freq > FREQ_MAX)
+ ffreq = FREQ_MAX / 1000.0;
+ else
+ ffreq = freq / 1000.0;
+
+ for (p=0; p<4 && ffreq<110.0; p++)
+ ffreq *= 2;
+#if FREQ_MIN < 110000/8
+ if (p == 4) {
+ ffreq /= 2;
+ p--;
+ }
+#endif
+
+ ffreq /= TI_REF_FREQ;
+
+ mindiff = ffreq;
+
+ for (n=1; n<=(int)(TI_REF_FREQ/0.5 - 2); n++) {
+ m = (int)(ffreq * (n+2) / 8.0 + 0.5) - 2;
+ if (m < 1)
+ m = 1;
+ else if (m > 127)
+ m = 127;
+
+ diff = ((m+2) * 8) / (n+2.0) - ffreq;
+ if (diff < 0)
+ diff = -diff;
+
+ if (diff < mindiff) {
+ mindiff = diff;
+ best_n = n;
+ best_m = m;
+ }
+ }
+
+ *calc_n = best_n;
+ *calc_m = best_m;
+ *calc_p = p;
+}
+
+
+static void S3TiDACProgramClock(ScrnInfoPtr pScrn, int clk,
+ unsigned char n, unsigned char m,
+ unsigned char p)
+{
+ S3OutTiIndReg(pScrn, TIDAC_pll_addr, 0x00, 0x00);
+
+ if (clk != TIDAC_pll_memory_data) {
+ S3OutTiIndReg(pScrn, TIDAC_pll_pixel_data, 0x00, n);
+ S3OutTiIndReg(pScrn, TIDAC_pll_pixel_data, 0x00, m);
+ S3OutTiIndReg(pScrn, TIDAC_pll_pixel_data, 0x00, p | 0x08);
+
+ S3OutTiIndReg(pScrn, TIDAC_pll_loop_data, 0x00, 0x01);
+ S3OutTiIndReg(pScrn, TIDAC_pll_loop_data, 0x00, 0x01);
+ S3OutTiIndReg(pScrn, TIDAC_pll_loop_data, 0x00, p > 0 ? p : 1);
+ S3OutTiIndReg(pScrn, TIDAC_misc_ctrl, 0x00, 0x80 | 0x40 | 0x04);
+
+ S3OutTiIndReg(pScrn, TIDAC_clock_select, 0x00, 0x05);
+ } else {
+ S3OutTiIndReg(pScrn, TIDAC_pll_memory_data, 0x00, n);
+ S3OutTiIndReg(pScrn, TIDAC_pll_memory_data, 0x00, m);
+ S3OutTiIndReg(pScrn, TIDAC_pll_memory_data, 0x00, p | 0x80);
+ }
+}
+
+
+void S3TiDACSetClock(ScrnInfoPtr pScrn, long freq, int clk)
+{
+ int m, n, p;
+
+ S3TiDACCalcNMP(freq, &n, &m, &p);
+
+ S3TiDACProgramClock(pScrn, clk, n, m, p);
+}
+
+
+
+void S3TiDAC_Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ S3RegPtr new = &pS3->ModeRegs;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr pVga = &hwp->ModeReg;
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ unsigned char tmp, tmp1, tmp2;
+
+ S3TiDACSetClock(pScrn, mode->Clock, 2);
+ outb(vgaCRIndex, 0x42);
+ tmp = inb(vgaCRReg) & 0xf0;
+ outb(vgaCRReg, tmp | 0x02);
+ usleep(150000);
+
+ outb(0x3c4, 1);
+ tmp2 = inb(0x3c5);
+ outb(0x3c5, tmp2 | 0x20); /* blank */
+
+ tmp = pVga->MiscOutReg;
+ pVga->MiscOutReg |= 0xc0;
+ tmp1 = 0x00;
+ if (!(tmp & 0x80))
+ tmp1 |= 0x02;
+ if (!(tmp & 0x40))
+ tmp1 |= 0x01;
+
+ S3OutTiIndReg(pScrn, TIDAC_general_ctrl, 0x00, tmp1);
+ S3OutTiIndReg(pScrn, 0x0e, 0x00, 0x00);
+
+ /* XXX do 3020 input_clock_sel */
+
+ outb(vgaCRIndex, 0x65);
+ /* XXX 3025 */
+ outb(vgaCRReg, 0x00);
+
+ /* XXX 3025 */
+ outb(vgaCRIndex, 0x40);
+ outb(vgaCRReg, 0x11);
+ outb(vgaCRIndex, 0x55);
+ outb(vgaCRReg, 0x00);
+
+ if (pScrn->bitsPerPixel > 8)
+ S3OutTiIndReg(pScrn, TIDAC_auxiliary_ctrl, 0x00, 0x00);
+ else
+ S3OutTiIndReg(pScrn, TIDAC_auxiliary_ctrl, 0x00, 0x01);
+
+ switch (pScrn->depth) {
+ case 8:
+ S3OutTiIndReg(pScrn, TIDAC_output_clock_select, 0x00,
+ 0x4b);
+ outb(vgaCRIndex, 0x66);
+ tmp = inb(vgaCRReg);
+ if (mode->Clock > 80000)
+ outb(vgaCRReg, (tmp & 0xf8) | 0x02);
+ else
+ outb(vgaCRReg, (tmp & 0xf8) | 0x03);
+ break;
+ case 16:
+ S3OutTiIndReg(pScrn, TIDAC_output_clock_select, 0x00,
+ 0x4a);
+ outb(vgaCRIndex, 0x66);
+ tmp = inb(vgaCRReg);
+ if (mode->Clock > 80000)
+ outb(vgaCRReg, (tmp & 0xf8) | 0x01);
+ else
+ outb(vgaCRReg, (tmp & 0xf8) | 0x02);
+ break;
+ case 24:
+ S3OutTiIndReg(pScrn, TIDAC_output_clock_select, 0x00,
+ (0x40 | 0x08 | 0x01));
+ outb(vgaCRIndex, 0x66);
+ tmp = inb(vgaCRReg);
+ if (mode->Clock > 80000)
+ outb(vgaCRReg, (tmp & 0xf8) | 0x00);
+ else
+ outb(vgaCRReg, (tmp & 0xf8) | 0x01);
+ break;
+ }
+
+ outb(vgaCRIndex, 0x58);
+ tmp = inb(vgaCRReg);
+ outb(vgaCRReg, (tmp & 0xbf) | 0x40);
+
+ switch(pScrn->depth) {
+ case 8:
+ S3OutTiIndReg(pScrn, TIDAC_true_color_ctrl, 0x00, 0x80);
+ S3OutTiIndReg(pScrn, TIDAC_multiplex_ctrl, 0x00, 0x1c);
+ break;
+ case 15:
+ S3OutTiIndReg(pScrn, TIDAC_true_color_ctrl, 0x00, 0x4c);
+ S3OutTiIndReg(pScrn, TIDAC_multiplex_ctrl, 0x00, 0x04);
+ S3OutTiIndReg(pScrn, TIDAC_key_ctrl, 0x00, 0x01);
+ break;
+ case 16:
+ S3OutTiIndReg(pScrn, TIDAC_true_color_ctrl, 0x00, 0x4d);
+ S3OutTiIndReg(pScrn, TIDAC_multiplex_ctrl, 0x00, 0x04);
+ S3OutTiIndReg(pScrn, TIDAC_key_ctrl, 0x00, 0x01);
+ break;
+ case 24:
+ S3OutTiIndReg(pScrn, TIDAC_true_color_ctrl, 0x00, 0x4e);
+ S3OutTiIndReg(pScrn, TIDAC_multiplex_ctrl, 0x00, 0x04);
+ S3OutTiIndReg(pScrn, TIDAC_key_ctrl, 0x00, 0x01);
+ break;
+ }
+
+ S3OutTiIndReg(pScrn, TIDAC_general_io_ctrl, 0x00, 0x1f);
+ S3OutTiIndReg(pScrn, TIDAC_general_io_data, 0x00, 0x01);
+ S3OutTiIndReg(pScrn, TIDAC_general_io_ctrl, 0x00, 0x00);
+ S3OutTiIndReg(pScrn, TIDAC_misc_ctrl, 0xf0, (0x04 | 0x08));
+
+ outb(vgaCRIndex, 0x6d);
+ if (pS3->s3Bpp == 1)
+ if (mode->Clock > 80000)
+ outb(vgaCRReg, 0x02);
+ else
+ outb(vgaCRReg, 0x03);
+ else if (pS3->s3Bpp == 2)
+ if (mode->Clock > 80000)
+ outb(vgaCRReg, 0x00);
+ else
+ outb(vgaCRReg, 0x01);
+ else
+ outb(vgaCRReg, 0x00);
+
+ S3OutTiIndReg(pScrn, TIDAC_sense_test, 0x00, 0x00);
+
+
+ if (pS3->s3Bpp > 1)
+ {
+ int j;
+
+ outb(0x3c6, 0xff);
+ outb(0x3c8, 0x00);
+ for(j=0; j<768; j++) {
+ outb(0x3c9, j);
+ outb(0x3c9, j);
+ outb(0x3c9, j);
+ }
+ }
+
+ outb(0x3c4, 1);
+ outb(0x3c5, tmp2); /* unblank */
+}
+
+
+void S3TiLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, LOCO *colors,
+ VisualPtr pVisual)
+{
+ int i;
+
+ outb(0x3c6, 0xff);
+ outb(0x3c8, 0x00);
+
+ for (i=0; i<768; i++) {
+ outb(0x3c9, i);
+ usleep(1000);
+ outb(0x3c9, i);
+ usleep(1000);
+ outb(0x3c9, i);
+ usleep(1000);
+ }
+}
+
+
+
+/* hardware cursor */
+
+static void S3TiSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ unsigned char tmp;
+
+ /* unlock sys regs */
+ outb(vgaCRIndex, 0x39);
+ outb(vgaCRReg, 0xa5);
+
+ S3OutTiIndReg(pScrn, TIDAC_cursor_color_0_red, 0x00,
+ (bg & 0x00FF0000) >> 16);
+ S3OutTiIndReg(pScrn, TIDAC_cursor_color_0_green, 0x00,
+ (bg & 0x0000FF00) >> 8);
+ S3OutTiIndReg(pScrn, TIDAC_cursor_color_0_blue, 0x00,
+ (bg & 0x000000FF));
+
+ S3OutTiIndReg(pScrn, TIDAC_cursor_color_1_red, 0x00,
+ (fg & 0x00FF0000) >> 16);
+ S3OutTiIndReg(pScrn, TIDAC_cursor_color_1_green, 0x00,
+ (fg & 0x0000FF00) >> 8);
+ S3OutTiIndReg(pScrn, TIDAC_cursor_color_1_blue, 0x00,
+ (fg & 0x000000FF));
+
+}
+
+
+static void S3TiSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+
+ /* unlock sys regs */
+ outb(vgaCRIndex, 0x39);
+ outb(vgaCRReg, 0xa5);
+
+ S3OutTiIndReg(pScrn, TIDAC_cursor_x_low, 0x00, x & 0xff);
+ S3OutTiIndReg(pScrn, TIDAC_cursor_x_high, 0x00, (x >> 8) & 0x0f);
+ S3OutTiIndReg(pScrn, TIDAC_cursor_y_low, 0x00, y & 0xff);
+ S3OutTiIndReg(pScrn, TIDAC_cursor_y_high, 0x00, (y >> 8) & 0x0f);
+}
+
+
+static void S3TiHideCursor(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+
+ /* unlock sys regs */
+ outb(vgaCRIndex, 0x39);
+ outb(vgaCRReg, 0xa5);
+
+ S3OutTiIndReg(pScrn, TIDAC_ind_curs_ctrl, (unsigned char)
+ ~(0x40 | 0x10), 0x00);
+}
+
+
+static void S3TiShowCursor(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ unsigned char tmp;
+
+ /* unlock sys regs */
+ outb(vgaCRIndex, 0x39);
+ outb(vgaCRReg, 0xa5);
+
+ outb(vgaCRIndex, 0x55);
+ tmp = inb(vgaCRReg) & 0xdf;
+ outb(vgaCRReg, tmp | 0x20);
+
+ outb(vgaCRIndex, 0x45);
+ tmp = inb(vgaCRReg) & 0xdf;
+ outb(vgaCRReg, tmp | 0x20);
+
+ S3OutTiIndReg(pScrn, TIDAC_ind_curs_ctrl, (unsigned char)
+ ~(0x40 | 0x10), (0x40 | 0x10));
+}
+
+
+static void S3TiLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ unsigned char tmp, tmp1;
+ register int i;
+ register unsigned char *mask = image + 1;
+
+ /* unlock sys regs */
+ outb(vgaCRIndex, 0x39);
+ outb(vgaCRReg, 0xa5);
+
+ outb(vgaCRIndex, 0x55);
+ tmp = inb(vgaCRReg) & 0xfc;
+ outb(vgaCRReg, tmp | 0x01);
+ tmp1 = inb(TI_INDEX_REG);
+
+ outb(TI_INDEX_REG, TIDAC_cursor_ram_addr_low);
+ outb(TI_DATA_REG, 0x00);
+ outb(TI_INDEX_REG, TIDAC_cursor_ram_addr_high);
+ outb(TI_DATA_REG, 0x00);
+ outb(TI_INDEX_REG, TIDAC_cursor_ram_data);
+
+#if 0
+ for (i=0; i<512; i++, mask+=2)
+ outb(TI_DATA_REG, *mask);
+ for (i=0; i<512; i++, image+=2)
+ outb(TI_DATA_REG, *image);
+#else
+ for (i=0; i<1024; i++) {
+ outb(TI_DATA_REG, *image);
+ image++;
+ }
+#endif
+
+ outb(TI_INDEX_REG, tmp1);
+
+ outb(vgaCRIndex, 0x55);
+ outb(vgaCRReg, tmp);
+}
+
+
+
+static Bool S3TiUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ return TRUE;
+}
+
+
+
+Bool S3Ti_CursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ S3Ptr pS3 = S3PTR(pScrn);
+ xf86CursorInfoPtr pCurs;
+
+ if (!(pCurs = pS3->pCurs = xf86CreateCursorInfoRec()))
+ return FALSE;
+
+ pCurs->MaxWidth = 64;
+ pCurs->MaxHeight = 64;
+ pCurs->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
+ HARDWARE_CURSOR_NIBBLE_SWAPPED |
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST;
+
+ pCurs->SetCursorColors = S3TiSetCursorColors;
+ pCurs->SetCursorPosition = S3TiSetCursorPosition;
+ pCurs->LoadCursorImage = S3TiLoadCursorImage;
+ pCurs->HideCursor = S3TiHideCursor;
+ pCurs->ShowCursor = S3TiShowCursor;
+ pCurs->UseHWCursor = S3TiUseHWCursor;
+
+ return xf86InitCursor(pScreen, pCurs);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_Trio64DAC.c b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_Trio64DAC.c
new file mode 100644
index 000000000..e4d94332b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_Trio64DAC.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright 2001 Ani Joshi <ajoshi@unixbox.com>
+ *
+ * XFree86 4.x driver for S3 chipsets
+ *
+ *
+ * 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 Ani Joshi not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Ani Joshi makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ANI JOSHI 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/xfree86/drivers/s3/s3_Trio64DAC.c,v 1.1 2001/07/02 10:46:04 alanh Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "compiler.h"
+
+#include "s3.h"
+
+/* this is really quite dumb */
+Bool S3Trio64DACProbe(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ if (pS3->Chipset != PCI_CHIP_TRIO)
+ return FALSE;
+
+ RamDacInit(pScrn, pS3->RamDacRec);
+
+ pS3->RamDac = RamDacHelperCreateInfoRec();
+ pS3->RamDac->RamDacType = TRIO64_RAMDAC;
+
+ return TRUE;
+}
+
+
+void S3Trio64DAC_Save(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ S3RegPtr save = &pS3->SavedRegs;
+
+ outb(0x3c4, 0x08);
+ save->dacregs[1] = inb(0x3c5);
+ outb(0x3c5, 0x06);
+
+ outb(0x3c4, 0x09);
+ save->dacregs[2] = inb(0x3c5);
+ outb(0x3c4, 0x0a);
+ save->dacregs[3] = inb(0x3c5);
+ outb(0x3c4, 0x0b);
+ save->dacregs[4] = inb(0x3c5);
+ outb(0x3c4, 0x0d);
+ save->dacregs[5] = inb(0x3c5);
+ outb(0x3c4, 0x15);
+ save->dacregs[6] = inb(0x3c5) & 0xfe;
+
+ outb(0x3c4, 0x18);
+ save->dacregs[7] = inb(0x3c5);
+ outb(0x3c4, 0x10);
+ save->dacregs[8] = inb(0x3c5);
+ outb(0x3c4, 0x11);
+ save->dacregs[9] = inb(0x3c5);
+ outb(0x3c4, 0x12);
+ save->dacregs[10] = inb(0x3c5);
+ outb(0x3c4, 0x13);
+ save->dacregs[11] = inb(0x3c5);
+ outb(0x3c4, 0x1a);
+ save->dacregs[12] = inb(0x3c5);
+ outb(0x3c4, 0x1b);
+ save->dacregs[13] = inb(0x3c5);
+
+ outb(0x3c4, 0x08);
+ outb(0x3c5, 0x00);
+}
+
+
+void S3Trio64DAC_Restore(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ S3RegPtr restore = &pS3->SavedRegs;
+ unsigned char tmp;
+
+ outb(0x3c2, restore->dacregs[0]);
+ outb(0x3c4, 0x08);
+ outb(0x3c5, 0x06);
+
+ outb(0x3c4, 0x09);
+ outb(0x3c5, restore->dacregs[2]);
+ outb(0x3c4, 0x0a);
+ outb(0x3c5, restore->dacregs[3]);
+ outb(0x3c4, 0x0b);
+ outb(0x3c5, restore->dacregs[4]);
+ outb(0x3c4, 0x0d);
+ outb(0x3c5, restore->dacregs[5]);
+
+ outb(0x3c4, 0x10);
+ outb(0x3c5, restore->dacregs[8]);
+ outb(0x3c4, 0x11);
+ outb(0x3c5, restore->dacregs[9]);
+ outb(0x3c4, 0x12);
+ outb(0x3c5, restore->dacregs[10]);
+ outb(0x3c4, 0x13);
+ outb(0x3c5, restore->dacregs[11]);
+ outb(0x3c4, 0x1a);
+ outb(0x3c5, restore->dacregs[12]);
+ outb(0x3c4, 0x01b);
+ outb(0x3c5, restore->dacregs[13]);
+ outb(0x3c4, 0x15);
+ tmp = inb(0x3c5);
+ outb(0x3c4, tmp & ~0x20);
+ outb(0x3c4, tmp | 0x20);
+ outb(0x3c4, tmp & ~0x20);
+
+ outb(0x3c4, 0x15);
+ outb(0x3c5, restore->dacregs[6]);
+ outb(0x3c4, 0x18);
+ outb(0x3c5, restore->dacregs[7]);
+
+ outb(0x3c4, 0x08);
+ outb(0x3c5, restore->dacregs[1]);
+}
+
+
+int S3TrioCalcClock(long freq, int min_m, int min_n1, int max_n1, int min_n2,
+ int max_n2, long freq_min, long freq_max,
+ unsigned char *mdiv, unsigned char *ndiv)
+{
+ double ffreq, ffreq_min, ffreq_max;
+ double div, diff, best_diff;
+ unsigned int m;
+ unsigned char n1, n2, best_n1=18, best_n2=2, best_m=127;
+
+#define BASE_FREQ 14.31818
+ ffreq = freq / 1000.0 / BASE_FREQ;
+ ffreq_min = freq_min / 1000.0 / BASE_FREQ;
+ ffreq_max = freq_max / 1000.0 / BASE_FREQ;
+
+ if (ffreq < ffreq_min / (1<<max_n2)) {
+ ErrorF("invalid frequency %1.3f Mhz [freq >= %1.3f Mhz]\n",
+ ffreq*BASE_FREQ, ffreq_min*BASE_FREQ/(1<<max_n2));
+ ffreq = ffreq_min / (1<<max_n2);
+ }
+ if (ffreq > ffreq_max / (1<<min_n2)) {
+ ErrorF("invalid frequency %1.3F Mhz [freq <= %1.3f Mhz]\n",
+ ffreq*BASE_FREQ, ffreq_max*BASE_FREQ/(1<<min_n2));
+ ffreq = ffreq_max / (1<<min_n2);
+ }
+
+ best_diff = ffreq;
+
+ for(n2=min_n2; n2<=max_n2; n2++) {
+ for(n1=min_n1+2; n1<=max_n1+2; n1++) {
+ m = (int)(ffreq*n1*(1<<n2)+0.5);
+ if (m<min_m+2 || m > 127+2)
+ continue;
+ div = (double)(m)/(double)(n1);
+ if ((div >= ffreq_min) &&
+ (div <= ffreq_max)) {
+ diff = ffreq - div / (1<<n2);
+ if (diff < 0.0)
+ diff = -diff;
+ if (diff < best_diff) {
+ best_diff = diff;
+ best_m = m;
+ best_n1 = n1;
+ best_n2 = n2;
+ }
+ }
+ }
+ }
+
+ if (max_n1 == 63)
+ *ndiv = (best_n1 - 2) | (best_n2 << 6);
+ else
+ *ndiv = (best_n1 - 2) | (best_n2 << 5);
+ *mdiv = best_m - 2;
+}
+
+
+void S3TrioSetPLL(ScrnInfoPtr pScrn, int clk, unsigned char m,
+ unsigned char n)
+{
+ unsigned char tmp;
+ int index2;
+
+ErrorF("clk = %d, m = 0x%x, n = 0x%x\n", clk, m, n);
+
+ if (clk < 2) {
+ tmp = inb(0x3cc);
+ outb(0x3c2, (tmp & 0xf3) | (clk << 2));
+ } else {
+ tmp = inb(0x3cc);
+ outb(0x3c2, tmp | 0x0c);
+
+ outb(0x3c4, 0x08);
+ outb(0x3c5, 0x06); /* unlock extended CR9-18 */
+
+ if (clk != 10) {
+ outb(0x3c4, 0x12);
+ outb(0x3c5, n);
+ outb(0x3c4, 0x13);
+ outb(0x3c5, m);
+
+ outb(0x3c4, 0x15);
+ tmp = inb(0x3c5) & ~0x21;
+ outb(0x3c5, tmp | 0x02);
+ outb(0x3c5, tmp | 0x22);
+ outb(0x3c5, tmp | 0x02);
+ } else {
+ index2 = 0x10;
+ outb(0x3c4, 0x10);
+ outb(0x3c5, n);
+ outb(0x3c4, 0x11);
+ outb(0x3c5, m);
+ outb(0x3c4, 0x1a);
+ outb(0x3c5, n);
+
+ outb(0x3c4, 0x15);
+ tmp = inb(0x3c5) & ~0x21;
+ outb(0x3c5, tmp | 0x01);
+ outb(0x3c5, tmp | 0x21);
+ outb(0x3c5, tmp | 0x01);
+ outb(0x3c5, tmp);
+ }
+
+ outb(0x3c4, 0x08);
+ outb(0x3c5, 0x00); /* lock em */
+ }
+}
+
+
+void S3TrioSetClock(ScrnInfoPtr pScrn, long freq, int clk, int min_m,
+ int min_n1, int max_n1, int min_n2, int max_n2,
+ int pll_type, long freq_min, long freq_max)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ unsigned char m, n;
+
+ S3TrioCalcClock(freq, min_m, min_n1, max_n1, min_n2, max_n2,
+ freq_min, freq_max, &m, &n);
+
+ /* XXX for pll_type == TRIO */
+ S3TrioSetPLL(pScrn, clk, m, n);
+}
+
+void S3Trio64DAC_PreInit(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ unsigned char SR8, SR27, SR28;
+ int m, n, n1, n2, mclk;
+
+ outb(0x3c4, 0x08);
+ SR8 = inb(0x3c5);
+ outb(0x3c5, 0x06);
+
+ outb(0x3c4, 0x11);
+ m = inb(0x3c5);
+ outb(0x3c4, 0x10);
+ n = inb(0x3c5);
+
+ m &= 0x7f;
+ n1 = n & 0x1f;
+ n2 = (n >> 5) & 0x03;
+ mclk = ((1431818 * (m+2)) / (n1+2) / (1<<n2)+50)/100;
+ pS3->mclk = mclk;
+
+ outb(0x3c4, 0x08);
+ outb(0x3c5, SR8);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MCLK %1.3f Mhz\n",
+ mclk / 1000.0);
+}
+
+
+void S3Trio64DAC_Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ S3RegPtr new = &pS3->ModeRegs;
+ int pixmux=0, invert_vclk=0, sr8, sr15, sr18, cr33;
+ unsigned char blank, tmp;
+
+ S3TrioSetClock(pScrn, mode->Clock, 2, 1, 1, 31, 0, 3, 2,
+ 135000, 270000);
+
+ outb(0x3c4, 1);
+ blank = inb(0x3c5);
+ outb(0x3c5, blank | 0x20); /* blank the screen */
+
+ outb(0x3c4, 0x08);
+ sr8 = inb(0x3c5);
+ outb(0x3c5, 0x06);
+
+ outb(0x3c4, 0x0d0);
+ tmp = inb(0x3c5) & ~1;
+ outb(0x3c5, tmp);
+
+ outb(0x3c4, 0x15);
+ sr15 = inb(0x3c5) & ~0x10;
+
+ outb(0x3c4, 0x18);
+ sr18 = inb(0x3c5) & ~0x80;
+ outb(pS3->vgaCRIndex, 0x33);
+ cr33 = inb(pS3->vgaCRReg) & ~0x28;
+
+ /* ! pixmux */
+ switch (pScrn->depth) {
+ case 8:
+ break;
+ case 15:
+ cr33 |= 0x08;
+ pixmux = 0x30;
+ break;
+ case 16:
+ cr33 |= 0x08;
+ pixmux = 0x50;
+ break;
+ case 32:
+ pixmux = 0xd0;
+ break;
+ }
+
+ outb(pS3->vgaCRReg, cr33);
+
+ outb(pS3->vgaCRIndex, 0x67);
+ outb(pS3->vgaCRReg, pixmux | invert_vclk);
+
+ outb(0x3c4, 0x15);
+ outb(0x3c5, sr15);
+ outb(0x3c4, 0x18);
+ outb(0x3c5, sr18);
+
+ outb(0x3c4, 0x08);
+ outb(0x3c5, sr8);
+
+ outb(0x3c4, 1);
+ outb(0x3c5, blank); /* unblank the screen */
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_accel.c
new file mode 100644
index 000000000..5b6d6208e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_accel.c
@@ -0,0 +1,605 @@
+/*
+ * Copyright 2001 Ani Joshi <ajoshi@unixbox.com>
+ *
+ * XFree86 4.x driver for S3 chipsets
+ *
+ *
+ * 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 Ani Joshi not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Ani Joshi makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ANI JOSHI 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/xfree86/drivers/s3/s3_accel.c,v 1.1 2001/07/02 10:46:04 alanh Exp $ */
+
+
+#include "xf86.h"
+
+#include "miline.h"
+
+#include "s3.h"
+#include "s3_reg.h"
+
+
+static Bool NicePattern;
+static int DashPatternSize;
+#define MAX_LINE_PATTERN_LENGTH 512
+#define LINE_PATTERN_START ((MAX_LINE_PATTERN_LENGTH >> 5) - 1)
+static CARD32 DashPattern[MAX_LINE_PATTERN_LENGTH >> 5];
+
+
+static void S3Sync(ScrnInfoPtr pScrn)
+{
+ WaitIdle();
+}
+
+static void S3SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ WaitQueue16_32(4,6);
+ SET_PIX_CNTL(0);
+ SET_FRGD_COLOR(color);
+ SET_FRGD_MIX(FSS_FRGDCOL | s3alu[rop]);
+ SET_WRT_MASK(planemask);
+}
+
+static void S3SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ WaitQueue(5);
+ SET_CURPT((short)x, (short)y);
+ SET_AXIS_PCNT(w - 1, h - 1);
+ SET_CMD(CMD_RECT | DRAW | INC_X | INC_Y | WRTDATA);
+}
+
+
+static void S3SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
+ int ydir, int rop,
+ unsigned int planemask,
+ int trans_color)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ pS3->BltDir = CMD_BITBLT | DRAW | WRTDATA;
+
+ if (xdir == 1)
+ pS3->BltDir |= INC_X;
+ if (ydir == 1)
+ pS3->BltDir |= INC_Y;
+
+ pS3->trans_color = trans_color;
+
+ WaitQueue16_32(3,4);
+ SET_PIX_CNTL(0);
+ SET_FRGD_MIX(FSS_BITBLT | s3alu[rop]);
+ SET_WRT_MASK(planemask);
+}
+
+
+static void S3SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int dstx, int dsty,
+ int w, int h)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ w--;
+ h--;
+
+ if (!(pS3->BltDir & INC_Y)) {
+ srcy += h;
+ dsty += h;
+ }
+
+ if (!(pS3->BltDir & INC_X)) {
+ srcx += w;
+ dstx += w;
+ }
+
+ if (pS3->trans_color == -1) {
+ WaitQueue(7);
+ SET_CURPT((short)srcx, (short)srcy);
+ SET_DESTSTP((short)dstx, (short)dsty);
+ SET_AXIS_PCNT((short)w, (short)h);
+ SET_CMD(pS3->BltDir);
+ } else {
+ WaitQueue16_32(2,3);
+ SET_MULT_MISC(CMD_REG_WIDTH | 0x0100);
+ SET_COLOR_CMP(pS3->trans_color);
+
+ WaitQueue(8);
+ SET_CURPT((short)srcx, (short)srcy);
+ SET_DESTSTP((short)dstx, (short)dsty);
+ SET_AXIS_PCNT((short)w, (short)h);
+ SET_CMD(pS3->BltDir);
+ SET_MULT_MISC(CMD_REG_WIDTH);
+ }
+}
+
+
+static void S3SetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int rop, unsigned int planemask,
+ int trans_color)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ pS3->trans_color = trans_color;
+
+ WaitQueue16_32(3,4);
+ SET_PIX_CNTL(0);
+ SET_FRGD_MIX(FSS_BITBLT | s3alu[rop]);
+ SET_WRT_MASK(planemask);
+}
+
+static void S3SubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y,
+ int w, int h)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ if (pS3->trans_color == -1) {
+ WaitQueue(7);
+ SET_CURPT((short)patx, (short)paty);
+ SET_DESTSTP((short)x, (short)y);
+ SET_AXIS_PCNT(w - 1, h - 1);
+ SET_CMD(CMD_PFILL | DRAW | INC_Y | INC_X | WRTDATA);
+ } else {
+ WaitQueue16_32(2,3);
+ SET_MULT_MISC(CMD_REG_WIDTH | 0x0100);
+ SET_COLOR_CMP(pS3->trans_color);
+
+ WaitQueue(8);
+ SET_CURPT((short)patx, (short)paty);
+ SET_DESTSTP((short)x, (short)y);
+ SET_AXIS_PCNT(w - 1, h - 1);
+ SET_CMD(CMD_PFILL | DRAW | INC_Y | INC_X | WRTDATA);
+ SET_MULT_MISC(CMD_REG_WIDTH);
+ }
+}
+
+#ifdef S3_NEWMMIO
+static void S3SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ WaitQueue16_32(3,4);
+ if (bg == -1) {
+ if (pS3->ColorExpandBug) {
+ SET_MIX(FSS_FRGDCOL | s3alu[rop], BSS_BKGDCOL | MIX_XOR);
+ SET_BKGD_COLOR(0);
+ } else
+ SET_MIX(FSS_FRGDCOL | s3alu[rop], BSS_BKGDCOL | MIX_DST);
+ } else {
+ SET_MIX(FSS_FRGDCOL | s3alu[rop], BSS_BKGDCOL | s3alu[rop]);
+ SET_BKGD_COLOR(bg);
+ }
+
+ WaitQueue16_32(3,5);
+ SET_FRGD_COLOR(fg);
+ SET_WRT_MASK(planemask);
+ SET_PIX_CNTL(MIXSEL_EXPPC);
+}
+
+
+static void S3SubsequentCPUToScreenColorExpandFill32(ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h,
+ int skipleft)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ WaitQueue(4);
+ SET_CURPT((short)x, (short)y);
+ SET_AXIS_PCNT((short)w-1, (short)h-1);
+
+ WaitIdle();
+ SET_CMD(CMD_RECT | BYTSEQ | _32BIT | PCDATA | DRAW |
+ PLANAR | INC_Y | INC_X | WRTDATA);
+}
+#endif
+
+#ifndef S3_NEWMMIO
+
+static void S3SetupForScanlineImageWriteNoMMIO(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask,
+ int trans_color,
+ int bpp, int depth)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ WaitQueue16_32(3,4)
+ SET_FRGD_MIX(FSS_PCDATA | s3alu[rop]);
+ SET_WRT_MASK(planemask);
+ SET_PIX_CNTL(0);
+}
+
+static void S3SubsequentScanlineImageWriteRectNoMMIO(ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h,
+ int skipleft)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ pS3->imageWidth = w;
+ pS3->imageHeight = h;
+
+ WaitQueue(5);
+ SET_CURPT((short)x, (short)y);
+ SET_AXIS_PCNT((short)w-1, (short)h-1);
+ WaitIdle();
+ SET_CMD(CMD_RECT | BYTSEQ | _16BIT | INC_Y | INC_X | DRAW |
+ PCDATA | WRTDATA);
+}
+
+
+static void S3SubsequentImageWriteScanlineNoMMIO(ScrnInfoPtr pScrn,
+ int bufno)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int i, j;
+ int w, h;
+ CARD16 *src = (CARD16 *)&pS3->imageBuffer;
+
+ w = pS3->imageWidth * pS3->s3Bpp;
+ h = pS3->imageHeight;
+
+ for(j=0; j<h; j++) {
+ for(i=0; i<(w & ~1); ) {
+ /* XXX not for 32bpp */
+ SET_PIX_TRANS_W(ldw_u(src));
+ src++;
+ i += 2;
+ }
+ }
+}
+
+#endif
+
+
+static void S3SetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ WaitQueue16_32(4,6);
+ SET_PIX_CNTL(0);
+ SET_FRGD_COLOR(color);
+ SET_FRGD_MIX(FSS_FRGDCOL | s3alu[rop]);
+ SET_WRT_MASK(planemask);
+}
+
+
+static void S3SubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
+ int x, int y,
+ int major, int minor,
+ int err, int len, int octant)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ unsigned short cmd;
+ int error, e1, e2;
+
+ error = minor + err;
+ e1 = major;
+ e2 = minor - major;
+
+ if (major) {
+ cmd = CMD_LINE | DRAW | WRTDATA | LASTPIX;
+
+ if (octant & YMAJOR)
+ cmd |= YMAJAXIS;
+ if (!(octant & XDECREASING))
+ cmd |= INC_X;
+ if (!(octant & YDECREASING))
+ cmd |= INC_Y;
+
+ WaitQueue(7);
+ SET_CURPT((short)x, (short)y);
+ SET_ERR_TERM((short)error);
+ SET_DESTSTP((short)e2, (short)e1);
+ SET_MAJ_AXIS_PCNT((short)len);
+ SET_CMD(cmd);
+ } else {
+ WaitQueue(4);
+ SET_CURPT((short)x, (short)y);
+ SET_MAJ_AXIS_PCNT((short)len-1);
+ SET_CMD(CMD_LINE | DRAW | LINETYPE | WRTDATA | VECDIR_270);
+ }
+}
+
+
+
+static void S3SubsequentSolidHorVertLine(ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ if (dir == DEGREES_0)
+ S3SubsequentSolidFillRect(pScrn, x, y, len, 1);
+ else
+ S3SubsequentSolidFillRect(pScrn, x, y, 1, len);
+}
+
+
+
+static void S3SetupForDashedLine(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop, unsigned int planemask,
+ int len, unsigned char *pattern)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+#ifdef S3_NEWMMIO
+ S3SetupForCPUToScreenColorExpandFill(pScrn, bg, fg, rop, planemask);
+#endif
+
+ WaitQueue(4);
+
+ NicePattern = FALSE;
+
+ if (len <= 32) {
+ register CARD32 scratch = DashPattern[LINE_PATTERN_START];
+
+ if (len & (len - 1)) {
+ while (len < 16) {
+ scratch |= (scratch >> len);
+ len <<= 1;
+ }
+ scratch |= (scratch >> len);
+ DashPattern[LINE_PATTERN_START] = scratch;
+ } else {
+ switch (len) {
+ case 2:
+ scratch |= scratch >> 2;
+ case 4:
+ scratch |= scratch >> 4;
+ case 8:
+ scratch |= scratch >> 8;
+ case 16:
+ scratch |= scratch >> 16;
+ DashPattern[LINE_PATTERN_START] = scratch;
+ case 32:
+ NicePattern = TRUE;
+ default:
+ break;
+ }
+ }
+ }
+
+ DashPatternSize = len;
+}
+
+
+
+static void S3SubsequentDashedBresenhamLine32(ScrnInfoPtr pScrn,
+ int x, int y,
+ int absmaj, int absmin,
+ int err, int len,
+ int octant, int phase)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ register int count = (len + 31) >> 5;
+ register CARD32 pattern;
+ int error, e1, e2;
+
+ error = absmin + err;
+ e1 = absmaj;
+ e2 = absmin - absmaj;
+
+ if (err) {
+ unsigned short cmd = _32BIT | PLANAR | WRTDATA | DRAW |
+ PCDATA | LASTPIX | CMD_LINE;
+
+ if (octant & YMAJOR)
+ cmd |= YMAJAXIS;
+ if (!(octant & XDECREASING))
+ cmd |= INC_X;
+ if (!(octant & YDECREASING))
+ cmd |= INC_Y;
+
+ WaitQueue(7);
+ SET_CURPT((short)x, (short)y);
+ SET_ERR_TERM((short)error);
+ SET_DESTSTP((short)e2, (short)e1);
+ SET_MAJ_AXIS_PCNT((short)len);
+ SET_CMD(cmd);
+ } else {
+ if (octant & YMAJOR) {
+ WaitQueue(4);
+ SET_CURPT((short)x, (short)y);
+ SET_MAJ_AXIS_PCNT((short)len - 1);
+
+ if (octant & YDECREASING) {
+ SET_CMD(_32BIT | PLANAR | WRTDATA | DRAW |
+ CMD_LINE | LINETYPE | VECDIR_090);
+ } else {
+ SET_CMD(_32BIT | PLANAR | WRTDATA | DRAW |
+ CMD_LINE | LINETYPE | VECDIR_270);
+ }
+ } else {
+ if (octant & XDECREASING) {
+ WaitQueue(4);
+ SET_CURPT((short)x, (short)y);
+ SET_MAJ_AXIS_PCNT((short)len - 1);
+ SET_CMD(_32BIT | PLANAR | WRTDATA | DRAW |
+ PCDATA | CMD_LINE | LINETYPE | VECDIR_180);
+ } else {
+ WaitQueue(4);
+ SET_CURPT((short)x, (short)y);
+ SET_MAJ_AXIS_PCNT((short)len - 1);
+ SET_CMD(_32BIT | PLANAR | WRTDATA | DRAW |
+ PCDATA | CMD_RECT | INC_Y | INC_X);
+ }
+ }
+ }
+
+ if (NicePattern) {
+#ifdef S3_NEWMMIO
+ register CARD32 *dest = (CARD32*)&IMG_TRANS;
+#endif
+
+ pattern = (phase) ? (DashPattern[LINE_PATTERN_START] << phase) |
+ (DashPattern[LINE_PATTERN_START] >> (32 - phase)) :
+ DashPattern[LINE_PATTERN_START];
+
+#ifdef S3_NEWMMIO
+ while (count & ~0x03) {
+ dest[0] = dest[1] = dest[2] = dest[3] = pattern;
+ dest += 4;
+ count -= 4;
+ }
+ switch (count) {
+ case 1:
+ dest[0] = pattern;
+ break;
+ case 2:
+ dest[0] = dest[1] = pattern;
+ break;
+ case 3:
+ dest[0] = dest[1] = dest[2] = pattern;
+ break;
+ }
+#else
+
+ while (count--)
+ SET_PIX_TRANS_L(pattern);
+#endif
+ } else if (DashPatternSize < 32) {
+ register int offset = phase;
+
+ while (count--) {
+ SET_PIX_TRANS_L((DashPattern[LINE_PATTERN_START] << offset) |
+ (DashPattern[LINE_PATTERN_START] >>
+ (DashPatternSize - offset)));
+ offset += 32;
+ while (offset > DashPatternSize)
+ offset -= DashPatternSize;
+ }
+ } else {
+ int offset = phase;
+ register unsigned char *srcp = (unsigned char *)(DashPattern) +
+ (MAX_LINE_PATTERN_LENGTH >> 3) - 1;
+ register CARD32 *scratch;
+ int scratch2, shift;
+
+ while (count--) {
+ shift = DashPatternSize - offset;
+ scratch = (CARD32*)(srcp - (offset >> 3) - 3);
+ scratch2 = offset & 0x07;
+
+ if (shift & ~31) {
+ if (scratch2) {
+ pattern = (*scratch << scratch2) |
+ (*(scratch - 1) >> (32 - scratch2));
+ } else
+ pattern = *scratch;
+ } else {
+ pattern = (*((CARD32*)(srcp - 3)) >> shift) |
+ (*scratch << scratch2);
+ }
+ SET_PIX_TRANS_L(pattern);
+ offset += 32;
+ while (offset >= DashPatternSize)
+ offset -= DashPatternSize;
+ }
+ }
+}
+
+#ifdef S3_NEWMMIO
+Bool S3AccelInitNewMMIO(ScreenPtr pScreen)
+#else
+Bool S3AccelInitPIO(ScreenPtr pScreen)
+#endif
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ S3Ptr pS3 = S3PTR(pScrn);
+ XAAInfoRecPtr pXAA;
+
+ if (pS3->Chipset == PCI_CHIP_968)
+ pS3->ColorExpandBug = TRUE;
+ else
+ pS3->ColorExpandBug = FALSE;
+
+ if (!(pXAA = XAACreateInfoRec()))
+ return FALSE;
+
+ pS3->pXAA = pXAA;
+
+ pXAA->Flags = (PIXMAP_CACHE | OFFSCREEN_PIXMAPS |
+ LINEAR_FRAMEBUFFER);
+
+ pXAA->Sync = S3Sync;
+
+ pXAA->SetupForSolidFill = S3SetupForSolidFill;
+ pXAA->SubsequentSolidFillRect = S3SubsequentSolidFillRect;
+
+ pXAA->SetupForScreenToScreenCopy = S3SetupForScreenToScreenCopy;
+ pXAA->SubsequentScreenToScreenCopy = S3SubsequentScreenToScreenCopy;
+
+ pXAA->SetupForColor8x8PatternFill = S3SetupForColor8x8PatternFill;
+ pXAA->SubsequentColor8x8PatternFillRect = S3SubsequentColor8x8PatternFillRect;
+
+#ifdef S3_NEWMMIO
+ pXAA->SetupForCPUToScreenColorExpandFill =
+ S3SetupForCPUToScreenColorExpandFill;
+ pXAA->SubsequentCPUToScreenColorExpandFill =
+ S3SubsequentCPUToScreenColorExpandFill32;
+ pXAA->ColorExpandBase = (void *) &IMG_TRANS;
+ pXAA->ColorExpandRange = 0x8000;
+ pXAA->CPUToScreenColorExpandFillFlags = CPU_TRANSFER_PAD_DWORD |
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ SCANLINE_PAD_DWORD;
+#endif
+
+#if 0
+#ifndef S3_NEWMMIO
+ pXAA->ScanlineImageWriteFlags = NO_TRANSPARENCY;
+ pXAA->SetupForScanlineImageWrite =
+ S3SetupForScanlineImageWriteNoMMIO;
+ pXAA->SubsequentScanlineImageWriteRect =
+ S3SubsequentScanlineImageWriteRectNoMMIO;
+ pXAA->SubsequentImageWriteScanline =
+ S3SubsequentImageWriteScanlineNoMMIO;
+ pXAA->NumScanlineImageWriteBuffers = 1;
+ pXAA->ScanlineImageWriteBuffers = &pS3->imageBuffer;
+#endif
+#endif
+
+ pXAA->SetupForSolidLine = S3SetupForSolidLine;
+ pXAA->SubsequentSolidBresenhamLine = S3SubsequentSolidBresenhamLine;
+ pXAA->SubsequentSolidHorVertLine = S3SubsequentSolidHorVertLine;
+ pXAA->SolidBresenhamLineErrorTermBits = 12;
+#if 0
+ /* kinda buggy... and its faster without it */
+ pXAA->SetupForDashedLine = S3SetupForDashedLine;
+ pXAA->SubsequentDashedBresenhamLine = S3SubsequentDashedBresenhamLine32;
+ pXAA->DashPatternMaxLength = MAX_LINE_PATTERN_LENGTH;
+#endif
+
+ return XAAInit(pScreen, pXAA);
+}
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_bios.c b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_bios.c
new file mode 100644
index 000000000..aa598bd29
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_bios.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2001 Ani Joshi <ajoshi@unixbox.com>
+ *
+ * XFree86 4.x driver for S3 chipsets
+ *
+ *
+ * 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 Ani Joshi not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Ani Joshi makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ANI JOSHI 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/xfree86/drivers/s3/s3_bios.c,v 1.2 2001/07/11 07:45:35 alanh Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+#include "s3.h"
+
+
+static unsigned char *find_bios_string(int BIOSbase, char *match1, char *match2)
+{
+ static unsigned char bios[BIOS_BSIZE];
+ static int init=0;
+ int i, j, l1, l2;
+
+ if (!init) {
+ init = 1;
+ if (xf86ReadBIOS(BIOSbase, 0, bios, BIOS_BSIZE) != BIOS_BSIZE)
+ return NULL;
+ if ((bios[0] != 0x55) || (bios[1] != 0xaa))
+ return NULL;
+ }
+ if (match1 == NULL)
+ return NULL;
+
+ l1 = strlen(match1);
+ if (match2 != NULL)
+ l2 = strlen(match2);
+ else
+ l2 = 0;
+
+ for (i=0; i<BIOS_BSIZE; i++)
+ if (bios[i] == match1[0] && !memcmp(&bios[i], match1, l1)) {
+ if (match2 == NULL)
+ return &bios[i+l1];
+ else
+ for(j=i+l1; (j<BIOS_BSIZE-l2) && bios[j]; j++)
+ if (bios[j] == match2[0] &&
+ !memcmp(&bios[j], match2, l2))
+ return &bios[j+l2];
+ }
+
+ return NULL;
+}
+
+
+int S3GetRefClock(ScrnInfoPtr pScrn)
+{
+ int RefClock = 16000; /* default */
+
+ if (find_bios_string(BIOS_BASE, "Number Nine Visual Technology",
+ "Motion 771") != NULL)
+ RefClock = 16000;
+
+ return RefClock;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_cursor.c
new file mode 100644
index 000000000..6400874ac
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_cursor.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2001 Ani Joshi <ajoshi@unixbox.com>
+ *
+ * XFree86 4.x driver for S3 chipsets
+ *
+ *
+ * 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 Ani Joshi not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Ani Joshi makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ANI JOSHI 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/xfree86/drivers/s3/s3_cursor.c,v 1.1 2001/07/02 10:46:04 alanh Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "compiler.h"
+
+#include "s3.h"
+#include "s3_reg.h"
+
+
+static void S3SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ unsigned short packfg, packbg;
+
+ switch (pS3->s3Bpp) {
+ case 1:
+ /* XXX Trio series only */
+ outb(vgaCRIndex, 0x45);
+ inb(vgaCRReg);
+ outb(vgaCRIndex, 0x4a);
+ outb(vgaCRReg, fg);
+ outb(vgaCRReg, fg);
+
+ outb(vgaCRIndex, 0x45);
+ inb(vgaCRReg);
+ outb(vgaCRIndex, 0x4b);
+ outb(vgaCRReg, bg);
+ outb(vgaCRReg, bg);
+
+ break;
+ case 2:
+ /* XXX depth 16 */
+ packfg = ((fg & 0x00f80000) >> 19) | ((fg & 0x0000fc00) >> 5) |
+ ((fg & 0x000000f8) << 8);
+ packbg = ((bg & 0x00f80000) >> 19) | ((bg & 0x0000fc00) >> 5) |
+ ((bg & 0x000000f8) << 8);
+
+ outb(vgaCRIndex, 0x45);
+ inb(vgaCRReg);
+ outb(vgaCRIndex, 0x4a);
+ outb(vgaCRReg, packfg);
+ outb(vgaCRReg, packfg >> 8);
+
+ outb(vgaCRIndex, 0x45);
+ inb(vgaCRReg);
+ outb(vgaCRIndex, 0x4b);
+ outb(vgaCRReg, packbg);
+ outb(vgaCRReg, packbg >> 8);
+
+ break;
+ default:
+ outb(vgaCRIndex, 0x45);
+ inb(vgaCRReg);
+ outb(vgaCRIndex, 0x4a);
+ outb(vgaCRReg, (fg & 0x00ff0000) >> 16);
+ outb(vgaCRReg, (fg & 0x0000ff00) >> 8);
+ outb(vgaCRReg, (fg & 0x000000ff));
+
+ outb(vgaCRIndex, 0x45);
+ inb(vgaCRReg);
+ outb(vgaCRIndex, 0x4b);
+ outb(vgaCRReg, (bg & 0x00ff0000) >> 16);
+ outb(vgaCRReg, (bg & 0x0000ff00) >> 8);
+ outb(vgaCRReg, (bg & 0x000000ff));
+
+ break;
+ }
+}
+
+
+static void S3SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+
+ outb(vgaCRIndex, 0x39);
+ outb(vgaCRReg, 0xa5);
+
+ outb(vgaCRIndex, 0x46);
+ outb(vgaCRReg, x >> 8);
+ outb(vgaCRIndex, 0x47);
+ outb(vgaCRReg, x);
+
+ outb(vgaCRIndex, 0x49);
+ outb(vgaCRReg, y);
+ outb(vgaCRIndex, 0x48);
+ outb(vgaCRReg, y >> 8);
+}
+
+
+static void S3HideCursor(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ unsigned char tmp;
+
+ outb(vgaCRIndex, 0x45);
+ tmp = inb(vgaCRReg);
+ outb(vgaCRReg, tmp & ~0x01);
+}
+
+
+static void S3ShowCursor(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ unsigned char tmp;
+
+ outb(vgaCRIndex, 0x39);
+ outb(vgaCRReg, 0xa5);
+
+ outb(vgaCRIndex, 0x55);
+ tmp = inb(vgaCRReg);
+ outb(vgaCRReg, tmp | 0x10);
+
+ outb(vgaCRIndex, 0x4c);
+ outb(vgaCRReg, pS3->FBCursorOffset >> 8);
+ outb(vgaCRIndex, 0x4d);
+ outb(vgaCRReg, pS3->FBCursorOffset);
+
+ outb(vgaCRIndex, 0x45);
+ tmp = inb(vgaCRReg);
+ outb(vgaCRReg, tmp | 0x01);
+}
+
+
+static void S3LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ unsigned char cr45;
+
+ outb(vgaCRIndex, 0x39);
+ outb(vgaCRReg, 0xa5);
+
+ WaitIdle();
+
+ VerticalRetraceWait();
+
+ outb(vgaCRIndex, 0x45);
+ cr45 = inb(vgaCRReg);
+ outb(vgaCRReg, cr45 & 0xfe);
+
+ outb(vgaCRIndex, 0x46);
+ outb(vgaCRReg, 0xff);
+ outb(vgaCRIndex, 0x47);
+ outb(vgaCRReg, 0x7f);
+ outb(vgaCRIndex, 0x49);
+ outb(vgaCRReg, 0xff);
+ outb(vgaCRIndex, 0x4e);
+ outb(vgaCRReg, 0x3f);
+ outb(vgaCRIndex, 0x4f);
+ outb(vgaCRReg, 0x3f);
+ outb(vgaCRIndex, 0x48);
+ outb(vgaCRReg, 0x7f);
+
+ memcpy(pS3->FBBase + (pS3->FBCursorOffset * 1024), image, 1024);
+
+ VerticalRetraceWait();
+
+ outb(vgaCRIndex, 0x45);
+ outb(vgaCRReg, cr45);
+}
+
+
+static Bool S3UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ return TRUE;
+}
+
+
+Bool S3_CursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ S3Ptr pS3 = S3PTR(pScrn);
+ xf86CursorInfoPtr pCurs;
+
+ if (!(pCurs = pS3->pCurs = xf86CreateCursorInfoRec()))
+ return FALSE;
+
+ pCurs->MaxWidth = 64;
+ pCurs->MaxHeight = 64;
+ pCurs->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST;
+
+ pCurs->SetCursorColors = S3SetCursorColors;
+ pCurs->SetCursorPosition = S3SetCursorPosition;
+ pCurs->LoadCursorImage = S3LoadCursorImage;
+ pCurs->HideCursor = S3HideCursor;
+ pCurs->ShowCursor = S3ShowCursor;
+ pCurs->UseHWCursor = S3UseHWCursor;
+
+ return xf86InitCursor(pScreen, pCurs);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_dga.c
new file mode 100644
index 000000000..a8e6560a6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_dga.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2001 Ani Joshi <ajoshi@unixbox.com>
+ *
+ * XFree86 4.x driver for S3 chipsets
+ *
+ *
+ * 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 Ani Joshi not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Ani Joshi makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ANI JOSHI 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/xfree86/drivers/s3/s3_dga.c,v 1.1 2001/07/02 10:46:04 alanh Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "dgaproc.h"
+
+#include "s3.h"
+#include "s3_reg.h"
+
+
+static Bool S3_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode);
+static int S3_GetViewport(ScrnInfoPtr pScrn);
+static void S3_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags);
+static void S3_FillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned long color);
+static void S3_BltRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h,
+ int dstx, int dsty);
+static Bool S3_OpenFramebuffer(ScrnInfoPtr pScrn, char **name,
+ unsigned char **mem, int *size, int *offset,
+ int *flags);
+static void S3_Sync(ScrnInfoPtr pScrn);
+
+
+static DGAFunctionRec S3_DGAFuncs = {
+ S3_OpenFramebuffer,
+ NULL,
+ S3_SetMode,
+ S3_SetViewport,
+ S3_GetViewport,
+ S3_Sync,
+ S3_FillRect,
+ S3_BltRect,
+ NULL
+};
+
+
+static DGAModePtr S3SetupDGAMode(ScrnInfoPtr pScrn, DGAModePtr modes,
+ int *num, int bitsPerPixel, int depth,
+ Bool pixmap, int secondPitch,
+ unsigned long red, unsigned long green,
+ unsigned long blue, short visualClass)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ DGAModePtr newmodes = NULL, currentMode;
+ DisplayModePtr pMode, firstMode;
+ int otherPitch, Bpp = bitsPerPixel >> 3;
+ Bool oneMore;
+
+ pMode = firstMode = pScrn->modes;
+
+ while (pMode) {
+ otherPitch = secondPitch ? secondPitch : pMode->HDisplay;
+
+ if (pMode->HDisplay != otherPitch) {
+ newmodes = xrealloc(modes, (*num + 2) * sizeof(DGAModeRec));
+ oneMore = TRUE;
+ } else {
+ newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec));
+ oneMore = FALSE;
+ }
+
+ if (!newmodes) {
+ xfree(modes);
+ return NULL;
+ }
+
+ modes = newmodes;
+
+SECOND_PASS:
+
+ currentMode = modes + *num;
+ (*num)++;
+
+ currentMode->mode = pMode;
+ currentMode->flags = DGA_CONCURRENT_ACCESS;
+ if (pixmap)
+ currentMode->flags |= DGA_PIXMAP_AVAILABLE;
+ if (pS3->pXAA)
+ currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
+ if (pMode->Flags & V_DBLSCAN)
+ currentMode->flags |= DGA_DOUBLESCAN;
+ if (pMode->Flags & V_INTERLACE)
+ currentMode->flags |= DGA_INTERLACED;
+ currentMode->byteOrder = pScrn->imageByteOrder;
+ currentMode->depth = depth;
+ currentMode->bitsPerPixel = bitsPerPixel;
+ currentMode->red_mask = red;
+ currentMode->green_mask = green;
+ currentMode->blue_mask = blue;
+ currentMode->visualClass = visualClass;
+ currentMode->viewportWidth = pMode->HDisplay;
+ currentMode->viewportHeight = pMode->VDisplay;
+ currentMode->xViewportStep = 8;
+ currentMode->yViewportStep = 1;
+ currentMode->viewportFlags = DGA_FLIP_RETRACE;
+ currentMode->offset = 0;
+ currentMode->address = (unsigned char*)pS3->FBAddress;
+
+ if (oneMore) {
+ currentMode->bytesPerScanline = (((pMode->HDisplay * Bpp) + 3) & ~3L);
+
+ currentMode->imageWidth = pMode->HDisplay;
+ currentMode->imageHeight = pMode->VDisplay;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+
+ oneMore = FALSE;
+ goto SECOND_PASS;
+ } else {
+ currentMode->bytesPerScanline = (((otherPitch * Bpp) + 3) & ~3L);
+
+ currentMode->imageWidth = otherPitch;
+ currentMode->imageHeight = pMode->VDisplay;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+
+ }
+
+ pMode = pMode->next;
+
+ if (pMode == firstMode)
+ break;
+
+ }
+
+ return modes;
+}
+
+
+
+Bool S3DGAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ S3Ptr pS3 = S3PTR(pScrn);
+ DGAModePtr modes = NULL;
+ int num = 0;
+
+ modes = S3SetupDGAMode(pScrn, modes, &num, 8, 8,
+ (pScrn->bitsPerPixel == 8),
+ ((pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth),
+ 0, 0, 0, PseudoColor);
+
+ modes = S3SetupDGAMode(pScrn, modes, &num, 16, 15,
+ (pScrn->bitsPerPixel == 16),
+ ((pScrn->depth != 15)
+ ? 0 : pScrn->displayWidth),
+ 0x7c00, 0x03e0, 0x001f, TrueColor);
+
+ modes = S3SetupDGAMode(pScrn, modes, &num, 16, 15,
+ (pScrn->bitsPerPixel == 16),
+ ((pScrn->depth != 15)
+ ? 0 : pScrn->displayWidth),
+ 0x7c00, 0x03e0, 0x001f, DirectColor);
+
+ modes = S3SetupDGAMode(pScrn, modes, &num, 16, 16,
+ (pScrn->bitsPerPixel == 16),
+ ((pScrn->depth != 16)
+ ? 0 : pScrn->displayWidth),
+ 0xf800, 0x07e0, 0x001f, TrueColor);
+
+ modes = S3SetupDGAMode(pScrn, modes, &num, 16, 16,
+ (pScrn->bitsPerPixel == 16),
+ ((pScrn->depth != 16)
+ ? 0 : pScrn->displayWidth),
+ 0xf800, 0x07e0, 0x001f, DirectColor);
+
+ modes = S3SetupDGAMode(pScrn, modes, &num, 32, 24,
+ (pScrn->bitsPerPixel == 32),
+ ((pScrn->bitsPerPixel != 32)
+ ? 0 : pScrn->displayWidth),
+ 0xff0000, 0x00ff00, 0x0000ff, TrueColor);
+
+ modes = S3SetupDGAMode(pScrn, modes, &num, 32, 24,
+ (pScrn->bitsPerPixel == 32),
+ ((pScrn->bitsPerPixel != 32)
+ ? 0 : pScrn->displayWidth),
+ 0xff0000, 0x00ff00, 0x0000ff, DirectColor);
+
+ pS3->numDGAModes = num;
+ pS3->DGAModes = modes;
+
+ return DGAInit(pScreen, &S3_DGAFuncs, modes, num);
+}
+
+
+static Bool S3_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ static S3FBLayout SavedLayouts[MAXSCREENS];
+ int indx = pScrn->pScreen->myNum;
+
+ if (!pMode) {
+ if (pS3->DGAactive) {
+ memcpy(&pS3->CurrentLayout, &SavedLayouts[indx],
+ sizeof(S3FBLayout));
+ pS3->DGAactive = TRUE;
+ }
+
+ pS3->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel;
+ pS3->CurrentLayout.depth = pMode->depth;
+ pS3->CurrentLayout.displayWidth = (pMode->bytesPerScanline /
+ (pMode->bitsPerPixel >> 3));
+ pS3->CurrentLayout.pixel_bytes = pMode->bitsPerPixel / 8;
+ pS3->CurrentLayout.pixel_code = (pMode->bitsPerPixel != 16 ?
+ pMode->bitsPerPixel :
+ pMode->depth);
+
+ S3SwitchMode(indx, pMode->mode, 0);
+ }
+
+ return TRUE;
+}
+
+
+static int S3_GetViewport(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ return pS3->DGAViewportStatus;
+}
+
+
+static void S3_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ pScrn->AdjustFrame(pScrn->pScreen->myNum, x, y, flags);
+ pS3->DGAViewportStatus = 0;
+}
+
+
+static void S3_FillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned long color)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ if (pS3->pXAA) {
+ (*pS3->pXAA->SetupForSolidFill)(pScrn, color, GXcopy, (CARD32)(~0));
+ (*pS3->pXAA->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ SET_SYNC_FLAG(pS3->pXAA);
+ }
+}
+
+
+static void S3_BltRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h,
+ int dstx, int dsty)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ if (pS3->pXAA) {
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ (*pS3->pXAA->SetupForScreenToScreenCopy)(pScrn, xdir, ydir,
+ GXcopy, (CARD32)(~0), -1);
+ (*pS3->pXAA->SubsequentScreenToScreenCopy)(pScrn, srcx, srcy,
+ dstx, dsty, w, h);
+ SET_SYNC_FLAG(pS3->pXAA);
+ }
+}
+
+
+static Bool S3_OpenFramebuffer(ScrnInfoPtr pScrn, char **name,
+ unsigned char **mem, int *size, int *offset,
+ int *flags)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ *name = NULL;
+ *mem = (unsigned char*)pS3->FBAddress;
+ *size = (pScrn->videoRam * 1024);
+ *offset = 0;
+ *flags = 0;
+
+ return TRUE;
+}
+
+
+static void S3_Sync(ScrnInfoPtr pScrn)
+{
+ WaitIdle();
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_driver.c
new file mode 100644
index 000000000..3cc05c11b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_driver.c
@@ -0,0 +1,1759 @@
+/*
+ * Copyright 2001 Ani Joshi <ajoshi@unixbox.com>
+ *
+ * XFree86 4.x driver for S3 chipsets
+ *
+ *
+ * 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 Ani Joshi not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Ani Joshi makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ANI JOSHI 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.
+ *
+ *
+ * Credits:
+ * Thomas Roell <roell@informatik.tu-muenchen.de>
+ * Mark Vojkovich <markv@valinux.com>
+ * Kevin E. Martin <martin@valinux.com>
+ * - and others for their work on the 3.x S3 driver
+ *
+ * Dominik Behr
+ * - for various hardware donations
+ *
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3/s3_driver.c,v 1.3 2001/08/15 11:54:27 tsi Exp $ */
+
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "xf86Version.h"
+#include "xf86Resources.h"
+#include "xf86fbman.h"
+#include "xf86cmap.h"
+#include "compiler.h"
+#include "xaa.h"
+#include "mipointer.h"
+#include "micmap.h"
+#include "mibstore.h"
+#include "fb.h"
+
+#include "IBM.h"
+#include "TI.h"
+
+#include "s3.h"
+#include "s3_reg.h"
+
+#define TRIO64_RAMDAC 0x8811
+
+
+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,
+};
+
+
+/*
+ * Prototypes
+ */
+static const OptionInfoRec * S3AvailableOptions(int chipid, int busid);
+static void S3Identify(int flags);
+static Bool S3Probe(DriverPtr drv, int flags);
+static Bool S3PreInit(ScrnInfoPtr pScrn, int flags);
+static Bool S3EnterVT(int scrnIndex, int flags);
+static void S3LeaveVT(int scrnIndex, int flags);
+static void S3Save(ScrnInfoPtr pScrn);
+static Bool S3ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool S3MapMem(ScrnInfoPtr pScrn);
+static void S3UnmapMem(ScrnInfoPtr pScrn);
+static Bool S3ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static void S3AdjustFrame(int scrnIndex, int x, int y, int flags);
+Bool S3CloseScreen(int scrnIndex, ScreenPtr pScreen);
+Bool S3SaveScreen(ScreenPtr pScreen, int mode);
+static void S3FreeScreen(int scrnIndex, int flags);
+static void S3GenericLoadPalette(ScrnInfoPtr pScrn, int numColors,
+ int *indicies, LOCO *colors,
+ VisualPtr pVisual);
+static void S3Restore(ScrnInfoPtr pScrn);
+void S3BankZero(ScrnInfoPtr pScrn);
+void S3Regdump(ScrnInfoPtr pScrn);
+static void S3DisplayPowerManagementSet(ScrnInfoPtr pScrn,
+ int PowerManagementMode, int flags);
+
+
+
+DriverRec S3 =
+{
+ S3_VERSION,
+ DRIVER_NAME,
+ S3Identify,
+ S3Probe,
+ S3AvailableOptions,
+ NULL,
+ 0
+};
+
+/* supported chipsets */
+static SymTabRec S3Chipsets[] = {
+ { PCI_CHIP_964_0, "964-0"},
+ { PCI_CHIP_964_1, "964-1"},
+ { PCI_CHIP_968, "968" },
+ { PCI_CHIP_TRIO, "Trio32/64" },
+ { -1, NULL }
+};
+
+
+static PciChipsets S3PciChipsets[] = {
+ { PCI_CHIP_964_0, PCI_CHIP_964_0, RES_SHARED_VGA },
+ { PCI_CHIP_964_1, PCI_CHIP_964_1, RES_SHARED_VGA },
+ { PCI_CHIP_968, PCI_CHIP_968, RES_SHARED_VGA },
+ { PCI_CHIP_TRIO, PCI_CHIP_TRIO, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED }
+};
+
+typedef enum {
+ OPTION_NOACCEL,
+ OPTION_SWCURS
+} S3Opts;
+
+static OptionInfoRec S3Options[] = {
+ { OPTION_NOACCEL, "noaccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SWCURS, "swcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+RamDacSupportedInfoRec IBMRamdacs[] = {
+ { IBM524_RAMDAC },
+ { IBM524A_RAMDAC },
+ { -1 }
+};
+
+#define S3_USEFB
+
+#ifdef S3_USEFB
+static const char *fbSymbols[] = {
+ "fbScreenInit",
+ NULL
+};
+#else
+static const char *cfbSymbols[] = {
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb24ScreenInit",
+ "cfb32ScreenInit",
+ NULL
+};
+#endif
+
+static const char *vgaHWSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWFreeHWRec",
+ "vgaHWGetIOBase",
+ "vgaHWSave",
+ "vgaHWProtect",
+ "vgaHWRestore",
+ "vgaHWMapMem",
+ "vgaHWUnmapMem",
+ "vgaHWSaveScreen",
+ "vgaHWLock",
+ "vgaHWInit",
+ "vgaHWDPMSSet",
+ NULL
+};
+
+static const char *vbeSymbols[] = {
+ "VBEInit",
+ "vbeDoEDID",
+ "vbeFree",
+ NULL
+};
+
+static const char *int10Symbols[] = {
+ "xf86ExecX86int10",
+ "xf86FreeInt10",
+ "xf86InitInt10",
+ "xf86Int10AllocPages",
+ "xf86Int10FreePages",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86InitCursor",
+ "xf86CreateCursorInfoRec",
+ "RamDacInit",
+ "RamDacCreateInfoRec",
+ "RamDacDestroyInfoRec",
+ "RamDacHelperCreateInfoRec",
+ "RamDacGetHWIndex",
+ "IBMramdacProbe",
+ "IBMramdac526CalculateMNPCForClock",
+ "IBMramdac526SetBpp",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAADestroyInfoRec",
+ "XAACreateInfoRec",
+ "XAAInit",
+ NULL
+};
+
+
+#ifdef XFree86LOADER
+
+MODULESETUPPROTO(S3Setup);
+
+static XF86ModuleVersionInfo S3VersRec = {
+ "s3",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0, 0, 0, 0}
+};
+
+
+XF86ModuleData s3ModuleData = { &S3VersRec, S3Setup, NULL };
+
+pointer S3Setup (pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&S3, module, 0);
+ LoaderRefSymLists(vgaHWSymbols,
+ vbeSymbols, int10Symbols, ramdacSymbols,
+#ifdef S3_USEFB
+ fbSymbols,
+#else
+ cfbSymbols,
+#endif
+ xaaSymbols,
+ NULL);
+ return (pointer) 1;
+ } else {
+ if (errmaj)
+ *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+#endif /* XFree86LOADER */
+
+
+static Bool S3GetRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(S3Rec), 1);
+
+ return TRUE;
+}
+
+static void S3FreeRec(ScrnInfoPtr pScrn)
+{
+ if (!pScrn->driverPrivate)
+ return;
+
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+static const OptionInfoRec * S3AvailableOptions(int chipid, int busid)
+{
+ return S3Options;
+}
+
+static void S3Identify(int flags)
+{
+ xf86PrintChipsets("s3", "driver (version " DRIVER_VERSION " for S3 chipset",
+ S3Chipsets);
+}
+
+static Bool S3Probe(DriverPtr drv, int flags)
+{
+ GDevPtr *devSections;
+ int i, *usedChips, numDevSections, numUsed;
+ Bool foundScreen = FALSE;
+
+ /* sanity check */
+ if ((numDevSections = xf86MatchDevice("s3", &devSections)) <= 0)
+ return FALSE;
+
+ /* XXX do ISA later... some day in the distant future... */
+ numUsed = xf86MatchPciInstances("s3", PCI_VENDOR_S3,
+ S3Chipsets, S3PciChipsets,
+ devSections, numDevSections,
+ drv, &usedChips);
+
+ xfree(devSections);
+
+ if (numUsed <= 0)
+ return FALSE;
+
+ if (flags & PROBE_DETECT)
+ foundScreen = TRUE;
+ else for (i=0; i<numUsed; i++) {
+ ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0);
+
+ pScrn->driverVersion = VERSION_MAJOR;
+ pScrn->driverName = DRIVER_NAME;
+ pScrn->name = "s3";
+ pScrn->Probe = S3Probe;
+ pScrn->PreInit = S3PreInit;
+ pScrn->ScreenInit = S3ScreenInit;
+ pScrn->SwitchMode = S3SwitchMode;
+ pScrn->AdjustFrame = S3AdjustFrame;
+ pScrn->EnterVT = S3EnterVT;
+ pScrn->LeaveVT = S3LeaveVT;
+ pScrn->FreeScreen = S3FreeScreen;
+
+ foundScreen = TRUE;
+
+ xf86ConfigActivePciEntity(pScrn, usedChips[i], S3PciChipsets,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+
+ xfree(usedChips);
+
+ return foundScreen;
+}
+
+static Bool S3PreInit(ScrnInfoPtr pScrn, int flags)
+{
+ EntityInfoPtr pEnt;
+ S3Ptr pS3;
+ vgaHWPtr hwp;
+ ClockRangePtr clockRanges;
+ rgb zeros = {0, 0, 0};
+ Gamma gzeros = {0.0, 0.0, 0.0};
+ int i, vgaCRIndex, vgaCRReg;
+ unsigned char tmp;
+
+ if (flags & PROBE_DETECT)
+ return FALSE;
+
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(vgaHWSymbols, NULL);
+
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ hwp = VGAHWPTR(pScrn);
+ vgaHWGetIOBase(hwp);
+
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb | Support32bppFb))
+ return FALSE;
+
+ switch (pScrn->depth) {
+ case 8:
+ case 15:
+ case 16:
+ case 24:
+ case 32:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+
+ xf86PrintDepthBpp(pScrn);
+
+ if (pScrn->depth > 8) {
+ if (!xf86SetWeight(pScrn, zeros, zeros))
+ return FALSE;
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1))
+ return FALSE;
+
+ pScrn->progClock = TRUE;
+
+ if (!S3GetRec(pScrn))
+ return FALSE;
+
+ pS3 = S3PTR(pScrn);
+
+ pS3->s3Bpp = (pScrn->bitsPerPixel >> 3);
+
+#if 0
+ xf86CollectOptions(pScrn, NULL);
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, S3Options);
+
+ if (xf86ReturnOptValBool(S3Options, OPTION_NOACCEL, FALSE)) {
+ pS3->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: NoAccel - acceleration disabled\n");
+ } else
+ pS3->NoAccel = FALSE;
+#endif
+
+ if (pScrn->numEntities > 1) {
+ S3FreeRec(pScrn);
+ return FALSE;
+ }
+
+ pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pEnt->resources) {
+ xfree(pEnt);
+ S3FreeRec(pScrn);
+ return FALSE;
+ }
+
+ if (xf86LoadSubModule(pScrn, "int10")) {
+ xf86LoaderReqSymLists(int10Symbols, NULL);
+ pS3->pInt10 = xf86InitInt10(pEnt->index);
+ }
+
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ xf86LoaderReqSymLists(vbeSymbols, NULL);
+ pS3->pVBE = VBEInit(pS3->pInt10, pEnt->index);
+ }
+
+ if (!xf86SetGamma(pScrn, gzeros))
+ return FALSE;
+
+ pS3->PciInfo = xf86GetPciInfoForEntity(pEnt->index);
+ xf86RegisterResources(pEnt->index, NULL, ResNone);
+ xf86SetOperatingState(RES_SHARED_VGA, pEnt->index, ResUnusedOpr);
+ xf86SetOperatingState(resVgaMemShared, pEnt->index, ResDisableOpr);
+
+ if (pEnt->device->chipset && *pEnt->device->chipset) {
+ pScrn->chipset = pEnt->device->chipset;
+ pS3->Chipset = xf86StringToToken(S3Chipsets, pScrn->chipset);
+ } else if (pEnt->device->chipID >= 0) {
+ pS3->Chipset = pEnt->device->chipID;
+ pScrn->chipset = (char *)xf86TokenToString(S3Chipsets,
+ pS3->Chipset);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pS3->Chipset);
+ } else {
+ pS3->Chipset = pS3->PciInfo->chipType;
+ pScrn->chipset = (char *)xf86TokenToString(S3Chipsets,
+ pS3->Chipset);
+ }
+ if (pEnt->device->chipRev >= 0) {
+ pS3->ChipRev = pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pS3->ChipRev);
+ } else
+ pS3->ChipRev = pS3->PciInfo->chipRev;
+
+ xfree(pEnt);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Chipset: \"%s\"\n", pScrn->chipset);
+
+ pS3->PciTag = pciTag(pS3->PciInfo->bus, pS3->PciInfo->device,
+ pS3->PciInfo->func);
+
+ switch (pS3->Chipset) {
+ case PCI_CHIP_964_0:
+ case PCI_CHIP_964_1:
+ case PCI_CHIP_TRIO:
+ pS3->S3NewMMIO = FALSE;
+ break;
+ case PCI_CHIP_968:
+ pS3->S3NewMMIO = TRUE;
+ break;
+ }
+
+ pS3->FBAddress = pS3->PciInfo->memBase[0];
+ if (pS3->S3NewMMIO)
+ pS3->IOAddress = pS3->FBAddress + S3_NEWMMIO_REGBASE;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Framebuffer @ 0x%x\n",
+ pS3->FBAddress);
+ if (pS3->S3NewMMIO)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MMIO @ 0x%x\n",
+ pS3->IOAddress);
+
+ pS3->PCIRetry = FALSE; /* not supported yet */
+
+ pS3->vgaCRIndex = vgaCRIndex = hwp->IOBase + 4;
+ pS3->vgaCRReg = vgaCRReg = hwp->IOBase + 5;
+
+ /* unlock sys regs */
+ outb(vgaCRIndex, 0x38);
+ outb(vgaCRReg, 0x48);
+ outb(vgaCRIndex, 0x39);
+ outb(vgaCRReg, 0xa5);
+
+ outb(vgaCRIndex, 0x40);
+ tmp = inb(vgaCRReg) | 0x01;
+ outb(vgaCRReg, tmp);
+ outb(vgaCRIndex, 0x35);
+ tmp = inb(vgaCRReg) & ~0x30;
+ outb(vgaCRReg, tmp);
+
+ outb(0x3c4, 0x08);
+ outb(0x3c5, 0x06);
+ outb(vgaCRIndex, 0x33);
+ tmp = (inb(vgaCRReg) & ~(0x2 | 0x10 | 0x40)) | 0x20;
+ outb(vgaCRReg, tmp);
+
+ /* unprotect CRTC[0-7] */
+ outb(vgaCRIndex, 0x11);
+ tmp = inb(vgaCRReg) & 0x7f;
+ outb(vgaCRReg, tmp);
+
+ /* wake up */
+ outb(0x46e8, 0x10);
+ outb(0x102, 0x01);
+ outb(0x46e8, 0x08);
+
+ if (!pScrn->videoRam) {
+ /* probe videoram */
+ outb(vgaCRIndex, 0x36);
+ tmp = inb(vgaCRReg);
+
+ switch ((tmp & 0xe0) >> 5) {
+ case 0:
+ pScrn->videoRam = 4096;
+ break;
+ case 2:
+ pScrn->videoRam = 3072;
+ break;
+ case 3:
+ pScrn->videoRam = 8192;
+ break;
+ case 4:
+ pScrn->videoRam = 2048;
+ break;
+ case 5:
+ pScrn->videoRam = 6144;
+ break;
+ case 6:
+ pScrn->videoRam = 1024;
+ break;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "videoRam = %d Kb\n", pScrn->videoRam);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "videoRam = %d Kb\n", pScrn->videoRam);
+ }
+
+ if (!xf86LoadSubModule(pScrn, "ramdac"))
+ return FALSE;
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+
+ pScrn->rgbBits = 8; /* set default */
+
+ /* probe for dac */
+ if ((pS3->Chipset == PCI_CHIP_964_0) ||
+ (pS3->Chipset == PCI_CHIP_964_1)) {
+ if (S3TiDACProbe(pScrn)) {
+ pS3->DacPreInit = S3TiDAC_PreInit;
+ pS3->DacInit = S3TiDAC_Init;
+ pS3->DacSave = S3TiDAC_Save;
+ pS3->DacRestore = S3TiDAC_Restore;
+ pS3->CursorInit = S3Ti_CursorInit;
+ pS3->MaxClock = 135000;
+ pScrn->rgbBits = 8;
+ if (pScrn->bitsPerPixel > 8)
+ pS3->LoadPalette = S3TiLoadPalette;
+ else
+ pS3->LoadPalette = S3GenericLoadPalette;
+
+ pS3->LoadPalette = S3GenericLoadPalette;
+ }
+ }
+ if (pS3->Chipset == PCI_CHIP_968) {
+ if (S3ProbeIBMramdac(pScrn)) {
+ pS3->DacPreInit = S3IBMRGB_PreInit;
+ pS3->DacInit = S3IBMRGB_Init;
+ pS3->DacSave = S3IBMRGB_Save;
+ pS3->DacRestore = S3IBMRGB_Restore;
+ pS3->CursorInit = S3IBMRGB_CursorInit;
+ pS3->RamDac->SetBpp = IBMramdac526SetBpp;
+ pS3->MaxClock = 170000;
+ pScrn->rgbBits = 8;
+ pS3->LoadPalette = S3GenericLoadPalette;
+ }
+ }
+ if (S3Trio64DACProbe(pScrn)) {
+ pS3->DacPreInit = S3Trio64DAC_PreInit;
+ pS3->DacInit = S3Trio64DAC_Init;
+ pS3->DacSave = S3Trio64DAC_Save;
+ pS3->DacRestore = S3Trio64DAC_Restore;
+#if 0
+ pS3->CursorInit = S3_CursorInit; /* FIXME broken */
+#endif
+ switch(pScrn->bitsPerPixel) {
+ case 8:
+ pS3->MaxClock = 135000;
+ break;
+ case 16:
+ pS3->MaxClock = 80000;
+ break;
+ case 24:
+ case 32:
+ pS3->MaxClock = 50000;
+ break;
+ }
+ pScrn->rgbBits = 6;
+ pS3->LoadPalette = S3GenericLoadPalette;
+ }
+
+ if (pS3->RamDac == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Ramdac probe failed\n");
+ return FALSE;
+ }
+
+ pS3->RefClock = S3GetRefClock(pScrn);
+
+ if (pS3->DacPreInit)
+ pS3->DacPreInit(pScrn);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "RefClock: %d\n",
+ pS3->RefClock);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Max pixel clock at this depth is %d Mhz\n",
+ pS3->MaxClock / 1000);
+
+ clockRanges = xnfcalloc(sizeof(ClockRange), 1);
+ clockRanges->next = NULL;
+ clockRanges->minClock = 16000; /* guess */
+ clockRanges->maxClock = pS3->MaxClock;
+ clockRanges->clockIndex = -1;
+ clockRanges->interlaceAllowed = FALSE; /* not yet */
+ clockRanges->doubleScanAllowed = FALSE; /* not yet */
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, 256, 2048, pScrn->bitsPerPixel,
+ 128, 2048, pScrn->virtualX,
+ pScrn->display->virtualY, pScrn->videoRam * 1024,
+ LOOKUP_BEST_REFRESH);
+
+ if (i == -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes left\n");
+ S3FreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes found\n");
+ S3FreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86SetCrtcForModes(pScrn, 0);
+ pScrn->currentMode = pScrn->modes;
+ xf86PrintModes(pScrn);
+ xf86SetDpi(pScrn, 0, 0);
+
+#ifdef S3_USEFB
+ xf86LoadSubModule(pScrn, "fb");
+ xf86LoaderReqSymbols("fbScreenInit", NULL);
+#else
+ {
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ xf86LoadSubModule(pScrn, "cfb");
+ xf86LoaderReqSymbols("cfbScreenInit", NULL);
+ break;
+ case 16:
+ xf86LoadSubModule(pScrn, "cfb16");
+ xf86LoaderReqSymbols("cfb16ScreenInit", NULL);
+ break;
+ case 24:
+ xf86LoadSubModule(pScrn, "cfb24");
+ xf86LoaderReqSymbols("cfb24ScreenInit", NULL);
+ break;
+ case 32:
+ xf86LoadSubModule(pScrn, "cfb32");
+ xf86LoaderReqSymbols("cfb32ScreenInit", NULL);
+ break;
+ }
+ }
+#endif
+
+ if (!xf86LoadSubModule(pScrn, "xaa"))
+ return FALSE;
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+
+ return TRUE;
+}
+
+
+static Bool S3ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
+ char **argv)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ pScrn->fbOffset = 0;
+
+ if (!S3MapMem(pScrn)) {
+ S3FreeRec(pScrn);
+ return FALSE;
+ }
+
+ S3Save(pScrn);
+
+ vgaHWBlankScreen(pScrn, TRUE);
+
+ if (!S3ModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+#if 0
+ S3Regdump(pScrn);
+#endif
+
+ S3SaveScreen(pScreen, SCREEN_SAVER_ON);
+
+ miClearVisualTypes();
+ if (pScrn->bitsPerPixel > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+ miSetPixmapDepths ();
+
+#ifdef S3_USEFB
+ if (!fbScreenInit(pScreen, pS3->FBBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth, pScrn->bitsPerPixel))
+ return FALSE;
+#else
+ {
+ int ret;
+
+ switch(pScrn->bitsPerPixel) {
+ case 8:
+ ret = cfbScreenInit(pScreen, pS3->FBBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 16:
+ ret = cfb16ScreenInit(pScreen, pS3->FBBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 24:
+ ret = cfb24ScreenInit(pScreen, pS3->FBBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 32:
+ ret = cfb32ScreenInit(pScreen, pS3->FBBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ }
+ if (!ret)
+ return FALSE;
+ }
+#endif
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ if (pScrn->bitsPerPixel > 8) {
+ VisualPtr pVis;
+
+ pVis = pScreen->visuals + pScreen->numVisuals;
+ while (--pVis >= pScreen->visuals) {
+ if ((pVis->class | DynamicClass) == DirectColor) {
+ pVis->offsetRed = pScrn->offset.red;
+ pVis->offsetGreen = pScrn->offset.green;
+ pVis->offsetBlue = pScrn->offset.blue;
+ pVis->redMask = pScrn->mask.red;
+ pVis->greenMask = pScrn->mask.green;
+ pVis->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ S3DGAInit(pScreen);
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ if (pS3->S3NewMMIO) {
+ if (S3AccelInitNewMMIO(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration enabled\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using NewMMIO\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Acceleration initialization failed\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration disabled\n");
+ }
+ } else {
+ if (S3AccelInitPIO(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration enabled\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using PIO\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Acceleration initialization failed\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration disabled\n");
+ }
+ }
+
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ /* hw cursor setup */
+ if (pS3->CursorInit) {
+ if (pS3->CursorInit(pScreen))
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using HW cursor\n");
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "HW cursor initialization failed\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using SW cursor\n");
+ }
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using SW cursor\n");
+
+
+
+
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, pS3->LoadPalette, NULL,
+ CMAP_RELOAD_ON_MODE_SWITCH))
+ return FALSE;
+
+ vgaHWBlankScreen(pScrn, FALSE);
+
+ pScreen->SaveScreen = S3SaveScreen;
+ pS3->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = S3CloseScreen;
+
+ xf86DPMSInit(pScreen, S3DisplayPowerManagementSet, 0);
+
+#if 0
+ S3InitVideo(pScreen);
+#endif
+ return TRUE;
+}
+
+
+
+
+static void S3Save(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ S3RegPtr save = &pS3->SavedRegs;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr pVga = &hwp->SavedReg;
+ RamDacHWRecPtr pRAMDAC;
+ RamDacRegRecPtr RAMDACreg;
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ int i;
+ unsigned char cr5c;
+
+ pRAMDAC = RAMDACHWPTR(pScrn);
+ RAMDACreg = &pRAMDAC->SavedReg;
+
+ S3BankZero(pScrn);
+
+ save->clock = inb(0x3cc);
+
+ vgaHWSave(pScrn, pVga, VGA_SR_ALL);
+
+ if (pS3->RamDac->RamDacType == TI3025_RAMDAC) {
+ outb(vgaCRIndex, 0x5c);
+ cr5c = inb(vgaCRReg);
+ }
+
+ pS3->DacSave(pScrn);
+
+ for(i=0; i<5; i++) {
+ outb(vgaCRIndex, 0x30 + i);
+ save->s3save[i] = inb(vgaCRReg);
+ outb(vgaCRIndex, 0x38 + i);
+ save->s3save[5 + i] = inb(vgaCRReg);
+ }
+
+ for (i=0; i<16; i++) {
+ outb(vgaCRIndex, 0x40 + i);
+ save->s3syssave[i] = inb(vgaCRReg);
+ }
+
+ outb(vgaCRIndex, 0x45);
+ inb(vgaCRReg);
+ outb(vgaCRIndex, 0x4a);
+ for(i=0; i<4; i++) {
+ save->color_stack[i] = inb(vgaCRReg);
+ outb(vgaCRReg, save->color_stack[i]);
+ }
+
+ outb(vgaCRIndex, 0x45);
+ inb(vgaCRReg);
+ outb(vgaCRIndex, 0x4b);
+ for(i=4; i<8; i++) {
+ save->color_stack[i] = inb(vgaCRReg);
+ outb(vgaCRReg, save->color_stack[i]);
+ }
+
+ for(i=0; i<16; i++) {
+ for (i=0; i<16; i++) {
+ if (!((1 << i) & 0x673b))
+ continue;
+ outb(vgaCRIndex, 0x50 + i);
+ save->s3syssave[i + 16] = inb(vgaCRReg);
+ }
+ }
+
+ if (pS3->RamDac->RamDacType == TI3025_RAMDAC)
+ save->s3syssave[0x0c + 16] = cr5c;
+
+ for(i=32; i<46; i++) {
+ outb(vgaCRIndex, 0x40 + i);
+ save->s3syssave[i] = inb(vgaCRReg);
+ }
+}
+
+
+Bool S3SaveScreen(ScreenPtr pScreen, int mode)
+{
+ return vgaHWSaveScreen(pScreen, mode);
+}
+
+
+static void S3FreeScreen(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ vgaHWFreeHWRec(pScrn);
+
+ S3FreeRec(pScrn);
+}
+
+
+Bool S3CloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ S3Ptr pS3 = S3PTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ if (pScrn->vtSema) {
+ vgaHWUnlock(hwp);
+ S3Restore(pScrn);
+ vgaHWLock(hwp);
+ S3UnmapMem(pScrn);
+ }
+
+ if (pS3->DGAModes)
+ xfree(pS3->DGAModes);
+ pS3->DGAModes = NULL;
+
+ pScrn->vtSema = FALSE;
+ pScreen->CloseScreen = pS3->CloseScreen;
+
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+
+Bool S3SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return S3ModeInit(xf86Screens[scrnIndex], mode);
+}
+
+
+static void S3GenericLoadPalette(ScrnInfoPtr pScrn, int numColors,
+ int *indicies, LOCO *colors,
+ VisualPtr pVisual)
+{
+ int i, index;
+
+ for (i=0; i<numColors; i++) {
+ index = indicies[i];
+ outb(0x3c8, index);
+ outb(0x3c9, colors[index].red);
+ outb(0x3c9, colors[index].green);
+ outb(0x3c9, colors[index].blue);
+ }
+}
+
+
+static Bool S3MapMem(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ if (pS3->S3NewMMIO) {
+ pS3->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pS3->PciTag, pS3->IOAddress,
+ S3_NEWMMIO_REGSIZE);
+ if (!pS3->MMIOBase) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not map MMIO\n");
+ return FALSE;
+ }
+ }
+
+ pS3->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pS3->PciTag, pS3->FBAddress,
+ pScrn->videoRam * 1024);
+ if (!pS3->FBBase) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not map framebuffer\n");
+ return FALSE;
+ }
+
+ pS3->FBCursorOffset = pScrn->videoRam - 1;
+
+ return TRUE;
+}
+
+
+static void S3UnmapMem(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+
+ if (pS3->S3NewMMIO)
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pS3->MMIOBase,
+ S3_NEWMMIO_REGSIZE);
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pS3->FBBase,
+ pScrn->videoRam * 1024);
+
+ return;
+}
+
+
+static int S3GetPixMuxShift(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ int shift = 0;
+
+ if (pS3->Chipset == PCI_CHIP_968)
+ shift = 1; /* XXX IBMRGB */
+ else if (pS3->Chipset == PCI_CHIP_TRIO)
+ shift = -(pS3->s3Bpp >> 1);
+
+ return shift;
+}
+
+static Bool S3ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ S3RegPtr new = &pS3->ModeRegs;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr pVga = &hwp->ModeReg;
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ int vgaIOBase = hwp->IOBase;
+ int r, n, m;
+ unsigned char tmp;
+
+ pS3->pixMuxShift = S3GetPixMuxShift(pScrn);
+
+ pS3->s3BppDisplayWidth = pScrn->displayWidth * pS3->s3Bpp;
+ pS3->HDisplay = mode->HDisplay;
+
+ pS3->s3ScissB = ((pScrn->videoRam * 1024) / pS3->s3BppDisplayWidth) - 1;
+ pS3->s3ScissR = pScrn->displayWidth - 1;
+
+ if (mode->HTotal == mode->CrtcHTotal) {
+ if (pS3->pixMuxShift > 0) {
+ /* XXX hack */
+ mode->Flags |= V_PIXMUX;
+
+ mode->CrtcHTotal >>= pS3->pixMuxShift;
+ mode->CrtcHDisplay >>= pS3->pixMuxShift;
+ mode->CrtcHSyncStart >>= pS3->pixMuxShift;
+ mode->CrtcHSyncEnd >>= pS3->pixMuxShift;
+ mode->CrtcHSkew >>= pS3->pixMuxShift;
+ } else if (pS3->pixMuxShift < 0) {
+ mode->Flags |= V_PIXMUX;
+
+ mode->CrtcHTotal <<= -pS3->pixMuxShift;
+ mode->CrtcHDisplay <<= -pS3->pixMuxShift;
+ mode->CrtcHSyncStart <<= -pS3->pixMuxShift;
+ mode->CrtcHSyncEnd <<= -pS3->pixMuxShift;
+ mode->CrtcHSkew <<= -pS3->pixMuxShift;
+ }
+ }
+
+ if (!vgaHWInit(pScrn, mode))
+ return FALSE;
+
+ pVga->MiscOutReg |= 0x0c;
+ pVga->Sequencer[0] = 0x03;
+ pVga->CRTC[19] = pS3->s3BppDisplayWidth >> 3;
+ pVga->CRTC[23] = 0xe3;
+ pVga->Attribute[0x11] = 0xff;
+
+ if (vgaIOBase == 0x3b0)
+ pVga->MiscOutReg &= 0xfe;
+ else
+ pVga->MiscOutReg |= 0x01;
+
+ /* ok i give up also, i'm writing in here */
+
+ vgaHWProtect(pScrn, TRUE);
+
+ if (pS3->RamDac->RamDacType == TI3025_RAMDAC) {
+ outb(vgaCRIndex, 0x5c);
+ tmp = inb(vgaCRReg);
+ outb(vgaCRReg, tmp & 0xdf);
+
+ S3OutTiIndReg(pScrn, TIDAC_ind_curs_ctrl, 0x7f, 0x00);
+ }
+
+ pS3->DacInit(pScrn, mode);
+
+ outb(0x3c2, pVga->MiscOutReg);
+
+ for(r=1; r<5; r++) {
+ outw(0x3c4, (pVga->Sequencer[r] << 8) | r);
+ }
+
+ for(r=0; r<25; r++)
+ outw(vgaCRIndex, (pVga->CRTC[r] << 8) | r);
+
+ for(r=0; r<9; r++) {
+ outw(0x3ce, (pVga->Graphics[r] << 8) | r);
+ }
+
+ inb(vgaIOBase + 0x0a);
+
+ for(r=0; r<16; r++) {
+ outb(0x3c0, r);
+ outb(0x3c0, pVga->Attribute[r]);
+ }
+ for(r=16; r<21; r++) {
+ outb(0x3c0, r | 0x20);
+ outb(0x3c0, pVga->Attribute[r]);
+ }
+
+
+ new->cr31 = 0x8d;
+ outb(vgaCRIndex, 0x31);
+ outb(vgaCRReg, new->cr31);
+
+ new->cr32 = 0x00;
+ outb(vgaCRIndex, 0x32);
+ outb(vgaCRReg, new->cr32);
+
+ outb(vgaCRIndex, 0x33);
+ new->cr33 = inb(vgaCRReg) | 0x20;
+ if ((pS3->Chipset == PCI_CHIP_964_0) ||
+ (pS3->Chipset == PCI_CHIP_964_1))
+ new->cr33 = 0x20;
+ outb(vgaCRReg, new->cr33);
+
+ new->cr34 = 0x10;
+ outb(vgaCRIndex, 0x34);
+ outb(vgaCRReg, new->cr34);
+
+ new->cr3a = 0xb5;
+ outb(vgaCRIndex, 0x3a);
+ outb(vgaCRReg, new->cr3a);
+
+ new->cr3b = (pVga->CRTC[0] + pVga->CRTC[4] + 1) / 2;
+ outb(vgaCRIndex, 0x3b);
+ outb(vgaCRIndex, 0x3b);
+ outb(vgaCRReg, new->cr3b);
+
+ new->cr3c = pVga->CRTC[0] / 2;
+ outb(vgaCRIndex, 0x3c);
+ outb(vgaCRReg, new->cr3c);
+
+ outb(vgaCRIndex, 0x40);
+ tmp = inb(vgaCRReg);
+ new->cr40 = (tmp & 0xf2) | 0x05;
+ outb(vgaCRReg, new->cr40);
+
+ outb(vgaCRIndex, 0x43);
+ switch (pScrn->bitsPerPixel) {
+ case 24:
+ case 32:
+ new->cr43 = inb(vgaCRReg);
+ break;
+ case 15:
+ case 16:
+ if ((pS3->RamDac->RamDacType == IBM524_RAMDAC) ||
+ (pS3->RamDac->RamDacType == IBM524A_RAMDAC) ||
+ (pS3->RamDac->RamDacType == TI3025_RAMDAC))
+ new->cr43 = 0x10;
+ else if (pS3->RamDac->RamDacType == TRIO64_RAMDAC)
+ new->cr43 = 0x09;
+ break;
+ case 8:
+ default:
+ new->cr43 = 0x00;
+ break;
+ }
+ outb(vgaCRReg, new->cr43);
+
+ new->cr44 = 0x00;
+ outb(vgaCRIndex, 0x44);
+ outb(vgaCRReg, new->cr44);
+
+ outb(vgaCRIndex, 0x45);
+ new->cr45 = inb(vgaCRReg) & 0xf2;
+ outb(vgaCRReg, new->cr45);
+
+ outb(vgaCRIndex, 0x50);
+ tmp = inb(vgaCRReg) & ~0xf1;
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ break;
+ case 16:
+ tmp |= 0x10;
+ break;
+ case 24:
+ tmp |= 0x20;
+ break;
+ case 32:
+ tmp |= 0x30;
+ break;
+ }
+
+ switch (pScrn->displayWidth) {
+ case 640:
+ tmp |= 0x40;
+ break;
+ case 800:
+ tmp |= 0x80;
+ break;
+ case 1152:
+ tmp |= 0x01;
+ break;
+ case 1280:
+ tmp |= 0xc0;
+ break;
+ case 1600:
+ tmp |= 0x81;
+ break;
+ }
+ new->cr50 = tmp;
+ outb(vgaCRReg, new->cr50);
+
+
+ outb(vgaCRIndex, 0x51);
+ new->cr51 = (inb(vgaCRReg) & 0xc0) |
+ ((pS3->s3BppDisplayWidth >> 7) & 0x30);
+ outb(vgaCRReg, new->cr51);
+
+ outb(vgaCRIndex, 0x53);
+ new->cr53 = inb(vgaCRReg);
+ if (pS3->S3NewMMIO)
+ new->cr53 |= 0x18;
+ else
+ new->cr53 &= ~0x18;
+ outb(vgaCRReg, new->cr53);
+
+ n = 255;
+ outb(vgaCRIndex, 0x54);
+ {
+ int clock2, mclk;
+
+ clock2 = mode->Clock * pS3->s3Bpp;
+ if (pScrn->videoRam < 2048)
+ clock2 *= 2;
+ mclk = pS3->mclk;
+ m = (int)((mclk/1000.0*.72+16.867)*89.736/(clock2/1000.0+39)-21.1543);
+ if (pScrn->videoRam < 2048)
+ m /= 2;
+ if (m >31)
+ m = 31;
+ else if (m < 0) {
+ m = 0;
+ n = 16;
+ }
+ }
+ new->cr54 = m << 3;
+ outb(vgaCRReg, new->cr54);
+
+ if (n < 0)
+ n = 0;
+ else if (n > 255)
+ n = 255;
+ outb(vgaCRIndex, 0x60);
+ new->cr60 = n;
+ outb(vgaCRReg, new->cr60);
+
+ outb(vgaCRIndex, 0x55);
+ new->cr55 = (inb(vgaCRReg) & 0x08) | 0x40;
+ outb(vgaCRReg, new->cr55);
+
+ outb(vgaCRIndex, 0x5e);
+ new->cr5e = (((mode->CrtcVTotal - 2) & 0x400) >> 10) |
+ (((mode->CrtcVDisplay - 1) & 0x400) >> 9) |
+ (((mode->CrtcVSyncStart) & 0x400) >> 8) |
+ (((mode->CrtcVSyncStart) & 0x400) >> 6) | 0x40;
+ outb(vgaCRReg, new->cr5e);
+
+ {
+ int i;
+ unsigned int j;
+
+ i = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8) |
+ ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7) |
+ ((((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6) |
+ ((mode->CrtcHSyncStart & 0x800) >> 7);
+ if ((mode->CrtcHSyncEnd >> 3) - (mode->CrtcHSyncStart >> 3) > 64)
+ i |= 0x08;
+ if ((mode->CrtcHSyncEnd >> 3) - (mode->CrtcHSyncStart >> 3) > 32)
+ i |= 0x20;
+
+ outb(vgaCRIndex, 0x3b);
+ j = ((pVga->CRTC[0] + ((i & 0x01) << 8) +
+ pVga->CRTC[4] + ((i & 0x10) << 4) + 1) / 2);
+
+ if (j - (pVga->CRTC[4] + ((i & 0x10) << 4)) < 4) {
+ if (pVga->CRTC[4] + ((i & 0x10) << 4) + 4 <= pVga->CRTC[0] + ((i & 0x01) << 8))
+ j = pVga->CRTC[4] + ((i & 0x10) << 4) + 4;
+ else
+ j = pVga->CRTC[0] + ((i & 0x01) << 8) + 1;
+ }
+
+ new->cr3b = j & 0xff;
+ outb(vgaCRReg, new->cr3b);
+ i |= (j & 0x100) >> 2;
+
+ outb(vgaCRIndex, 0x3c);
+ new->cr3c = (pVga->CRTC[0] + ((i & 0x01) << 8)) / 2;
+ outb(vgaCRReg, new->cr3c);
+
+ outb(vgaCRIndex, 0x5d);
+ new->cr5d = (inb(vgaCRReg) & 0x80) | i;
+ outb(vgaCRReg, new->cr5d);
+ }
+
+ {
+ int i;
+
+ if (pScrn->videoRam > 1024)
+ i = mode->HDisplay * pS3->s3Bpp / 8 + 1;
+ else
+ i = mode->HDisplay * pS3->s3Bpp / 4 + 1;
+
+ outb(vgaCRIndex, 0x61);
+ tmp = 0x80 | (inb(vgaCRReg) & 0x60) | (i >> 8);
+ new->cr61 = tmp;
+ outb(vgaCRReg, new->cr61);
+ outb(vgaCRIndex, 0x62);
+ new->cr62 = i & 0xff;
+ outb(vgaCRReg, new->cr62);
+ }
+
+ outb(vgaCRIndex, 0x42);
+ new->cr42 = inb(vgaCRReg) & ~0x20;
+ outb(vgaCRReg, new->cr42);
+
+ if (pS3->Chipset == PCI_CHIP_968) {
+ unsigned char a;
+
+ outb(vgaCRIndex, 0x67);
+ a = inb(vgaCRReg) & 0xfe;
+#if 0
+ switch (pScrn->depth) {
+ case 8:
+ break;
+ case 15:
+ a |= (3 << 4);
+ break;
+ case 16:
+ a |= (5 << 4);
+ a |= (3 << 2); /* streams */
+ break;
+ case 24:
+ a |= (13 << 4);
+ a |= (3 << 2); /* streams */
+ break;
+ }
+#endif
+ outb(vgaCRReg, a);
+
+ outb(vgaCRIndex, 0x6d);
+ outb(vgaCRReg, 0x00);
+ }
+
+ if ((pS3->Chipset == PCI_CHIP_964_0) ||
+ (pS3->Chipset == PCI_CHIP_964_1)) {
+ unsigned char bdelay;
+
+ outb(vgaCRIndex, 0x6d);
+ bdelay = inb(vgaCRReg);
+
+ if (pS3->RamDac->RamDacType == TI3025_RAMDAC) {
+ if (pS3->s3Bpp == 1) {
+ if (mode->Clock > 80000)
+ bdelay = 0x02;
+ else
+ bdelay = 0x03;
+ } else if (pS3->s3Bpp == 2) {
+ if (mode->Clock > 80000)
+ bdelay = 0x00;
+ else
+ bdelay = 0x01;
+ } else
+ bdelay = 0x00;
+ }
+
+ outb(vgaCRReg, bdelay);
+ }
+
+ outb(vgaCRIndex, 0x66);
+ new->cr66 = inb(vgaCRReg) | 0x80; /* XXX no newmmio */
+ outb(vgaCRReg, new->cr66);
+
+ pScrn->AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ vgaHWProtect(pScrn, FALSE);
+
+ if (pScrn->displayWidth == 1024)
+ outw(ADVFUNC_CNTL, 0x0007);
+ else
+ outw(ADVFUNC_CNTL, 0x0003);
+
+ outb(0x3c6, 0x00);
+
+ outw(SUBSYS_CNTL, 0x8000 | 0x1000);
+ outw(SUBSYS_CNTL, 0x4000 | 0x1000);
+
+ inw(SUBSYS_STAT);
+
+ outw(0xbee8, 0x5000 | 0x0004 | 0x000c);
+
+ outb(0x3c6, 0xff);
+
+ new->cr59 = pS3->FBAddress >> 24;
+ new->cr5a = pS3->FBAddress >> 16;
+
+ if (pScrn->videoRam <= 1024)
+ new->cr58 = 0x15;
+ else if (pScrn->videoRam <= 2048)
+ new->cr58 = 0x16;
+ else
+ new->cr58 = 0x17;
+
+ if (pS3->Chipset == PCI_CHIP_968)
+ new->cr58 = 0x52;
+ else if ((pS3->Chipset == PCI_CHIP_964_0) ||
+ (pS3->Chipset == PCI_CHIP_964_1))
+ new->cr58 |= 0x40;
+
+ outb(vgaCRIndex, 0x59);
+ outb(vgaCRReg, new->cr59);
+ outb(vgaCRIndex, 0x5a);
+ outb(vgaCRReg, new->cr5a);
+ outb(vgaCRIndex, 0x58);
+ outb(vgaCRReg, new->cr58);
+
+ WaitQueue(5);
+ SET_SCISSORS(0, 0, pS3->s3ScissR, pS3->s3ScissB);
+
+ outb(vgaCRIndex, 0x6f);
+
+#if 0
+ if (((pScrn->bitsPerPixel == 16) ||
+ (pScrn->bitsPerPixel == 24)) && (pS3->S3NewMMIO))
+ S3InitStreams(pScrn, mode);
+#endif
+
+ return TRUE;
+}
+
+
+static Bool S3EnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ if (!S3ModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+static void S3Restore(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ S3RegPtr restore = &pS3->SavedRegs;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ int i;
+
+ vgaHWProtect(pScrn, TRUE);
+
+ WaitQueue(8);
+
+ S3BankZero(pScrn);
+
+ outw(ADVFUNC_CNTL, 0x0000);
+
+ if (pS3->S3NewMMIO) {
+ outb(vgaCRIndex, 0x53);
+ outb(vgaCRReg, 0x00);
+ }
+
+ if (pS3->RamDac->RamDacType == TI3025_RAMDAC) {
+ outb(vgaCRIndex, 0x5c);
+ outb(vgaCRReg, restore->s3syssave[0x0c + 16]);
+ }
+
+ pS3->DacRestore(pScrn);
+
+ for(i=32; i<46; i++) {
+ outb(vgaCRIndex, 0x40 + i);
+ outb(vgaCRReg, restore->s3syssave[i]);
+ }
+
+ for(i=0; i<16; i++) {
+ if (!((1 << i) & 0x673b))
+ continue;
+ outb(vgaCRIndex, 0x50 + i);
+ outb(vgaCRReg, restore->s3syssave[i+16]);
+ }
+
+ for(i=0; i<5; i++) {
+ outb(vgaCRIndex, 0x30 + i);
+ outb(vgaCRReg, restore->s3save[i]);
+ outb(vgaCRIndex, 0x38 + i);
+ outb(vgaCRReg, restore->s3save[i + 5]);
+ }
+
+ for(i=0; i<16; i++) {
+ outb(vgaCRIndex, 0x40 + i);
+ outb(vgaCRReg, restore->s3syssave[i]);
+ }
+
+ outb(vgaCRIndex, 0x45);
+ inb(vgaCRReg);
+ outb(vgaCRIndex, 0x4a);
+ for(i=0; i<4; i++)
+ outb(vgaCRReg, restore->color_stack[i]);
+
+ outb(vgaCRIndex, 0x45);
+ inb(vgaCRReg);
+ outb(vgaCRIndex, 0x4b);
+ for(i=4; i<8; i++)
+ outb(vgaCRReg, restore->color_stack[i]);
+
+ vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_ALL);
+
+ outb(0x3c2, restore->clock);
+
+ vgaHWProtect(pScrn, FALSE);
+
+}
+
+
+static void S3LeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ S3Restore(pScrn);
+
+ return;
+}
+
+
+static void S3AdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ S3Ptr pS3 = S3PTR(pScrn);
+ S3RegPtr regs = &pS3->ModeRegs;
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+ int base, orig_base;
+ unsigned char tmp;
+
+ if (x > pScrn->displayWidth - pS3->HDisplay)
+ x = pScrn->displayWidth - pS3->HDisplay;
+
+ orig_base = (y * pScrn->displayWidth + x) * pS3->s3Bpp;
+ base = (orig_base >> 2) & ~1;
+
+ /* for IBMRGB and TI only */
+ if (pS3->RamDac->RamDacType == IBM524A_RAMDAC)
+ {
+ int px, py, a;
+
+ miPointerPosition(&px, &py);
+
+ if (pS3->s3Bpp == 1)
+ a = 4 - 1;
+ else
+ a = 8 - 1;
+ if (px-x > pS3->HDisplay/2)
+ base = ((orig_base + a*4) >> 2) & ~1;
+ base &= ~a;
+ }
+
+ outb(vgaCRIndex, 0x31);
+ outb(vgaCRReg, ((base & 0x030000) >> 12) | regs->cr31);
+ regs->cr51 &= ~0x03;
+ regs->cr51 |= ((base & 0x0c0000) >> 18);
+ outb(vgaCRIndex, 0x51);
+ tmp = (inb(vgaCRReg) & ~0x03) | (regs->cr51 & 0x03);
+ outb(vgaCRReg, tmp);
+
+ outw(vgaCRIndex, (base & 0x00ff00) | 0x0c);
+ outw(vgaCRIndex, ((base & 0x00ff) << 8) | 0x0d);
+}
+
+
+void S3Regdump(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ S3RegPtr regs = &pS3->ModeRegs;
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+
+#if 1
+ outb(vgaCRIndex, 0x31);
+ ErrorF("cr31 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x32);
+ ErrorF("cr32 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x33);
+ ErrorF("cr33 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x34);
+ ErrorF("cr34 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x3a);
+ ErrorF("cr3a = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x3b);
+ ErrorF("cr3b = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x3c);
+ ErrorF("cr3c = 0x%x\n", inb(vgaCRReg));
+
+ outb(vgaCRIndex, 0x40);
+ ErrorF("cr40 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x42);
+ ErrorF("cr42 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x43);
+ ErrorF("cr43 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x44);
+ ErrorF("cr44 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x45);
+ ErrorF("cr45 = 0x%x\n", inb(vgaCRReg));
+
+ outb(vgaCRIndex, 0x50);
+ ErrorF("cr50 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x51);
+ ErrorF("cr51 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x53);
+ ErrorF("cr53 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x54);
+ ErrorF("cr54 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x55);
+ ErrorF("cr55 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x58);
+ ErrorF("cr58 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x59);
+ ErrorF("cr59 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x5a);
+ ErrorF("cr5a = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x5d);
+ ErrorF("cr5d = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x5e);
+ ErrorF("cr5e = 0x%x\n", inb(vgaCRReg));
+
+ outb(vgaCRIndex, 0x60);
+ ErrorF("cr60 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x61);
+ ErrorF("cr61 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x62);
+ ErrorF("cr62 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x65);
+ ErrorF("cr65 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x66);
+ ErrorF("cr66 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x67);
+ ErrorF("cr67 = 0x%x\n", inb(vgaCRReg));
+ outb(vgaCRIndex, 0x6d);
+ ErrorF("cr6d = 0x%x\n", inb(vgaCRReg));
+
+#else
+ {
+ int j;
+
+ for(j=0; j<0x100; j++) {
+ outb(vgaCRIndex, j);
+ ErrorF("CRTC 0x%x = 0x%x\n", j, inb(vgaCRReg));
+ }
+ }
+#endif
+
+#if 0
+ ErrorF("DAC regs\n");
+
+ {
+ int j;
+
+ for(j=0; j<0x100; j++)
+ ErrorF("0x%x = 0x%x\n", j, S3InTiIndReg(pScrn, j));
+#if 0
+ outb(vgaCRIndex, 0x22);
+ ErrorF("cr22 = 0x%x\n", inb(vgaCRReg));
+#endif
+ }
+#endif
+}
+
+
+void S3BankZero(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ unsigned char tmp;
+ int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
+
+ outb(vgaCRIndex, 0x35);
+ tmp = inb(vgaCRReg) & 0xf0;
+ outb(vgaCRReg, tmp);
+
+ outb(vgaCRIndex, 0x51);
+ tmp = inb(vgaCRReg) & 0xf3;
+ outb(vgaCRReg, tmp);
+}
+
+
+
+static void S3DisplayPowerManagementSet(ScrnInfoPtr pScrn,
+ int PowerManagementMode, int flags)
+{
+ vgaHWDPMSSet(pScrn, PowerManagementMode, flags);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_reg.h
new file mode 100644
index 000000000..63646d99b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_reg.h
@@ -0,0 +1,262 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3/s3_reg.h,v 1.1 2001/07/02 10:46:04 alanh Exp $ */
+
+#ifndef _S3_REG_H
+#define _S3_REG_H
+
+#include "compiler.h"
+
+extern short s3alu[16];
+
+#define S3_NEWMMIO_REGBASE 0x1000000 /* 16MB */
+#define S3_NEWMMIO_REGSIZE 0x10000 /* 64KB */
+
+#define ADVFUNC_CNTL 0x4ae8
+#define SUBSYS_STAT 0x42e8
+#define SUBSYS_CNTL 0x42e8
+#define CUR_Y 0x82e8
+#define CUR_X 0x86e8
+#define CUR_Y2 0x82ea
+#define CUR_X2 0x86ea
+#define DESTY_AXSTP 0x8ae8
+#define DESTX_DIASTP 0x8ee8
+#define DESTY_AXSTP2 0x8aea
+#define DESTX_DIASTP2 0x8eea
+#define ERR_TERM 0x92e8
+#define ERR_TERM2 0x92ea
+#define MAJ_AXIS_PCNT 0x96e8
+#define MAJ_AXIS_PCNT2 0x96ea
+#define GP_STAT 0x9ae8
+#define CMD 0x9ae8
+#define CMD2 0x9aea
+#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 PIX_TRANS 0xe2e8
+#define PIX_TRANS_EXT 0xe2ea
+
+/* Graphics Processor Status Register */
+#define GPBUSY 0x0200
+
+/* 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_PFILL 0xe000
+#define CMD_OP_MSK 0xf000
+#define BYTSEQ 0x1000
+#define _16BIT 0x0200
+#define _32BIT 0x0400
+#define PCDATA 0x0100
+#define INC_Y 0x0080
+#define YMAJAXIS 0x0040
+#define INC_X 0x0020
+#define DRAW 0x0010
+#define LINETYPE 0x0008
+#define LASTPIX 0x0004
+#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
+
+#define PIX_CNTL 0xa000
+#define MIN_AXIS_PCNT 0x0000
+
+/* Pixel Control Register */
+#define MIXSEL_EXPPC 0x0080
+
+#define SCISSORS_T 0x1000
+#define SCISSORS_L 0x2000
+#define SCISSORS_B 0x3000
+#define SCISSORS_R 0x4000
+#define MULT_MISC2 0xd000
+#define MULT_MISC 0xe000
+
+
+#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
+
+/*
+ * Short Stroke Vector Transfer Register (The angular Defs also apply to
+the
+ * Command Register
+ */
+#define VECDIR_000 0x0000
+#define VECDIR_045 0x0020
+#define VECDIR_090 0x0040
+#define VECDIR_135 0x0060
+#define VECDIR_180 0x0080
+#define VECDIR_225 0x00a0
+#define VECDIR_270 0x00c0
+#define VECDIR_315 0x00e0
+#define SSVDRAW 0x0010
+
+
+#define S3_OUTW(p,n) outw(p, n)
+#define S3_OUTL(p,n) outl(p, n)
+#define S3_OUTW32(p,n) if (pS3->s3Bpp > 2) { \
+ outw(p, n); \
+ outw(p, (n) >> 16); \
+ } else outw(p, n)
+
+
+#define WaitIdle() do { \
+ mem_barrier(); \
+ while(inw(GP_STAT) & GPBUSY); \
+ } while(0)
+
+
+#ifdef S3_NEWMMIO
+#include "newmmio.h"
+
+/*
+ * streams regs
+ */
+#define SET_BLEND_CNTL(val) ((mmtr)s3MmioMem)->streams_regs.regs.blend_cntl = (val)
+#define SET_PSTREAM_CNTL(val) ((mmtr)s3MmioMem)->streams_regs.regs.prim_stream_cntl = (val)
+#define SET_PSTREAM_FBADDR(val) ((mmtr)s3MmioMem)->streams_regs.regs.prim_fbaddr0 = (val)
+#define SET_PSTREAM_STRIDE(val) ((mmtr)s3MmioMem)->streams_regs.regs.prim_stream_stride = (val)
+#define SET_PSTREAM_START(val) ((mmtr)s3MmioMem)->streams_regs.regs.prim_start_coord = (val)
+#define SET_PSTREAM_WIND(val) ((mmtr)s3MmioMem)->streams_regs.regs.prim_window_size = (val)
+#define SET_SSTREAM_CNTL(val) ((mmtr)s3MmioMem)->streams_regs.regs.second_stream_cntl = (val)
+#define SET_SSTRETCH(val) ((mmtr)s3MmioMem)->streams_regs.regs.second_stream_stretch = (val)
+#define SET_SSTREAM_FBADDR(val) ((mmtr)s3MmioMem)->streams_regs.regs.second_fbaddr0 = (val)
+#define SET_SSTREAM_STRIDE(val) ((mmtr)s3MmioMem)->streams_regs.regs.second_stream_stride = (val)
+#define SET_SSTREAM_START(val) ((mmtr)s3MmioMem)->streams_regs.regs.second_start_coord = (val)
+#define SET_SSTREAM_WIND(val) ((mmtr)s3MmioMem)->streams_regs.regs.second_window_size = (val)
+#define SET_K1_VSCALE(val) ((mmtr)s3MmioMem)->streams_regs.regs.k1 = (val)
+#define SET_K2_VSCALE(val) ((mmtr)s3MmioMem)->streams_regs.regs.k2 = (val)
+#define SET_DDA_VERT(val) ((mmtr)s3MmioMem)->streams_regs.regs.dda_vert = (val)
+#define SET_CHROMA_KEY(val) ((mmtr)s3MmioMem)->streams_regs.regs.col_chroma_key_cntl = (val)
+#define SET_DOUBLE_BUFFER(val) ((mmtr)s3MmioMem)->streams_regs.regs.double_buffer = (val)
+#define SET_OPAQUE_OVERLAY(val) ((mmtr)s3MmioMem)->streams_regs.regs.opaq_overlay_cntl = (val)
+
+#else
+
+#define CMD_REG_WIDTH 0x0000
+
+#define WaitQueue(n) do { \
+ mem_barrier(); \
+ while(inb(GP_STAT) & (0x0100 >> (n))); \
+ } while (0)
+
+#define WaitQueue16_32(n16,n32) \
+ if (pS3->s3Bpp <= 2) { \
+ WaitQueue(n16); \
+ } else { \
+ WaitQueue(n32); \
+ }
+
+#define VerticalRetraceWait() \
+ { \
+ outb(vgaCRIndex, 0x17); \
+ if (inb(vgaCRReg) & 0x80) { \
+ while ((inb(vgaCRIndex-4+0x0a) & 0x08) == 0x00); \
+ while ((inb(vgaCRIndex-4+0x0a) & 0x08) == 0x08); \
+ } \
+ }
+
+/* accel commands */
+
+#define SET_PIX_CNTL(val) S3_OUTW(MULTIFUNC_CNTL, PIX_CNTL | (val))
+
+#define SET_FRGD_COLOR(col) S3_OUTW32(FRGD_COLOR, col)
+#define SET_BKGD_COLOR(col) S3_OUTW32(BKGD_COLOR, col)
+
+#define SET_FRGD_MIX(fmix) S3_OUTW(FRGD_MIX, (fmix))
+#define SET_WRT_MASK(mask) S3_OUTW32(WRT_MASK, mask)
+
+#define SET_CUR_X(cur_x) S3_OUTW(CUR_X, cur_x)
+#define SET_CUR_Y(cur_y) S3_OUTW(CUR_Y, cur_y)
+#define SET_CUR_X2(cur_x) S3_OUTW(CUR_X2, cur_x)
+#define SET_CUR_Y2(cur_y) S3_OUTW(CUR_Y2, cur_y)
+
+#define SET_CURPT(cur_x, cur_y) { \
+ SET_CUR_X(cur_x); \
+ SET_CUR_Y(cur_y); \
+ }
+
+#define SET_DESTSTP(x,y) { \
+ S3_OUTW(DESTX_DIASTP, x); \
+ S3_OUTW(DESTY_AXSTP, y); \
+ }
+
+#define SET_AXIS_PCNT(maj, min) { \
+ S3_OUTW(MAJ_AXIS_PCNT, maj); \
+ S3_OUTW(MULTIFUNC_CNTL, MIN_AXIS_PCNT | (min)); \
+ }
+
+#define SET_CMD(cmd) S3_OUTW(CMD, cmd)
+
+#define SET_SCISSORS(x1,y1,x2,y2) { \
+ S3_OUTW(MULTIFUNC_CNTL, SCISSORS_T | (y1)); \
+ S3_OUTW(MULTIFUNC_CNTL, SCISSORS_L | (x1)); \
+ S3_OUTW(MULTIFUNC_CNTL, SCISSORS_R | (x2)); \
+ S3_OUTW(MULTIFUNC_CNTL, SCISSORS_B | (y2)); \
+ }
+
+#define SET_MULT_MISC(val) S3_OUTW(MULTIFUNC_CNTL, MULT_MISC | (val))
+
+#define SET_COLOR_CMP(color) S3_OUTW32(COLOR_CMP, color)
+
+#define SET_PIX_TRANS_W(val) S3_OUTW(PIX_TRANS, val)
+
+#define SET_PIX_TRANS_L(val) outl(PIX_TRANS, val)
+
+#define SET_ERR_TERM(err) S3_OUTW(ERR_TERM, err)
+#define SET_ERR_TERM2(err) S3_OUTW(ERR_TERM2, err)
+
+#define SET_MAJ_AXIS_PCNT(maj) S3_OUTW(MAJ_AXIS_PCNT, maj)
+#endif
+
+
+#endif /* _S3_REG_H */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_video.c b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_video.c
new file mode 100644
index 000000000..2a60366c6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_video.c
@@ -0,0 +1,669 @@
+/*
+ * Copyright 2001 Ani Joshi <ajoshi@unixbox.com>
+ *
+ * XFree86 4.x driver for S3 chipsets
+ *
+ *
+ * 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 Ani Joshi not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Ani Joshi makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ANI JOSHI 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/xfree86/drivers/s3/s3_video.c,v 1.2 2001/08/15 11:54:27 tsi Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "compiler.h"
+
+#include "s3.h"
+#include "s3_reg.h"
+
+
+#define CLIENT_VIDEO_ON 0x04
+#define S3_MAX_PORTS 1
+#define NUM_FORMATS_OVERLAY 4
+#define NUM_FORMATS_TEXTURE 4
+
+
+static XF86VideoAdaptorPtr S3AllocAdaptor(ScrnInfoPtr pScrn);
+static XF86VideoAdaptorPtr S3SetupImageVideoOverlay(ScreenPtr);
+static int S3SetPortAttributeOverlay(ScrnInfoPtr, Atom, INT32, pointer);
+static int S3GetPortAttributeOverlay(ScrnInfoPtr, Atom ,INT32 *, pointer);
+static void S3StopVideo(ScrnInfoPtr, pointer, Bool);
+static void S3QueryBestSize(ScrnInfoPtr, Bool, short, short, short, short,
+ unsigned int *, unsigned int *, pointer);
+static int S3PutImage(ScrnInfoPtr, short, short, short, short, short,
+ short, short, short, int, unsigned char*, short,
+ short, Bool, RegionPtr, pointer);
+static int S3QueryImageAttributes(ScrnInfoPtr, int, unsigned short *,
+ unsigned short *, int *, int *);
+static void S3ResetVideoOverlay(ScrnInfoPtr);
+
+
+
+void S3InitVideo(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ S3Ptr pS3 = S3PTR(pScrn);
+ XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
+ XF86VideoAdaptorPtr newAdaptor = NULL;
+ int num_adaptors;
+
+ if (((pScrn->bitsPerPixel == 16) ||
+ (pScrn->bitsPerPixel == 24)) && (pS3->S3NewMMIO)) {
+ newAdaptor = S3SetupImageVideoOverlay(pScreen);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using overlay video\n");
+ } else
+ return;
+
+ num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
+
+ if(newAdaptor) {
+ if(!num_adaptors) {
+ num_adaptors = 1;
+ adaptors = &newAdaptor;
+ } else {
+ newAdaptors = /* need to free this someplace */
+ xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*));
+ if(newAdaptors) {
+ memcpy(newAdaptors, adaptors, num_adaptors *
+ sizeof(XF86VideoAdaptorPtr));
+ newAdaptors[num_adaptors] = newAdaptor;
+ adaptors = newAdaptors;
+ num_adaptors++;
+ }
+ }
+ }
+
+ if(num_adaptors)
+ xf86XVScreenInit(pScreen, adaptors, num_adaptors);
+
+ if(newAdaptors)
+ xfree(newAdaptors);
+}
+
+
+/* client libraries expect an encoding */
+static XF86VideoEncodingRec DummyEncoding[2] =
+{
+ { /* overlay limit */
+ 0,
+ "XV_IMAGE",
+ 1024, 1024,
+ {1, 1}
+ },
+ { /* texture limit */
+ 0,
+ "XV_IMAGE",
+ 2046, 2046,
+ {1, 1}
+ }
+};
+
+
+
+
+static XF86VideoFormatRec Formats[NUM_FORMATS_TEXTURE] =
+{
+ /*{15, TrueColor},*/ {16, TrueColor}, {24, TrueColor} /* ,
+ {15, DirectColor}*/, {16, DirectColor}, {24, DirectColor}
+};
+
+
+
+#define NUM_IMAGES 3
+
+static XF86ImageRec Images[NUM_IMAGES] =
+{
+ XVIMAGE_YUY2,
+ /* As in mga, YV12 & I420 are converted to YUY2 on the fly by */
+ /* copy over conversion. */
+ XVIMAGE_YV12,
+ XVIMAGE_I420
+ /* XVIMAGE_UYVY */
+};
+
+
+
+static int S3SetPortAttributeOverlay(ScrnInfoPtr pScrn, Atom attribute,
+ INT32 value, pointer data)
+{
+ return BadMatch;
+}
+
+
+static int S3GetPortAttributeOverlay(ScrnInfoPtr pScrn, Atom attribute,
+ INT32 *value, pointer data)
+{
+ return BadMatch;
+}
+
+
+
+static void S3QueryBestSize(ScrnInfoPtr pScrn, Bool motion, short vid_w,
+ short vid_h, short drw_w, short drw_h,
+ unsigned int *p_w, unsigned int *p_h,
+ pointer data)
+{
+ *p_w = drw_w;
+ *p_h = drw_h;
+}
+
+
+
+static void S3CopyData(unsigned char *src, unsigned char *dst,
+ int srcPitch, int dstPitch, int h, int w)
+{
+ w <<= 1;
+ while (h--) {
+ memcpy(dst, src, w);
+ src += srcPitch;
+ dst += dstPitch;
+ }
+}
+
+
+static void S3CopyMungedData(unsigned char *src1, unsigned char *src2,
+ unsigned char *src3, unsigned char *dst1,
+ int srcPitch, int srcPitch2, int dstPitch,
+ int h, int w)
+{
+ CARD32 *dst = (CARD32*)dst1;
+ int i, j;
+
+ dstPitch >>= 2;
+ w >>= 1;
+
+ for(j = 0; j < h; j++) {
+ for(i = 0; i < w; i++) {
+ dst[i] = src1[i << 1] | (src1[(i << 1) + 1] << 16) |
+ (src3[i] << 8) | (src2[i] << 24);
+ }
+ dst += dstPitch;
+ src1 += srcPitch;
+ if(j & 1) {
+ src2 += srcPitch2;
+ src3 += srcPitch2;
+ }
+ }
+}
+
+
+
+static void S3ResetVideoOverlay(ScrnInfoPtr pScrn)
+{
+}
+
+
+static XF86VideoAdaptorPtr S3AllocAdaptor(ScrnInfoPtr pScrn)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ XF86VideoAdaptorPtr adapt;
+ S3PortPrivPtr pPriv;
+ int i;
+
+ if(!(adapt = xf86XVAllocateVideoAdaptorRec(pScrn)))
+ return NULL;
+
+ if(!(pPriv = xcalloc(1, sizeof(S3PortPrivRec) +
+ (sizeof(DevUnion) * S3_MAX_PORTS))))
+ {
+ xfree(adapt);
+ return NULL;
+ }
+
+ adapt->pPortPrivates = (DevUnion*)(&pPriv[1]);
+
+ for(i = 0; i < S3_MAX_PORTS; i++)
+ adapt->pPortPrivates[i].val = i;
+
+ pPriv->colorKey = (1 << pScrn->offset.red) | (1 << pScrn->offset.green) |
+ (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue);
+
+ pPriv->videoStatus = 0;
+ pPriv->lastPort = -1;
+
+ pS3->adaptor = adapt;
+ pS3->portPrivate = pPriv;
+
+ return adapt;
+}
+
+
+static XF86VideoAdaptorPtr S3SetupImageVideoOverlay(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ S3Ptr pS3 = S3PTR(pScrn);
+ XF86VideoAdaptorPtr adapt;
+
+ adapt = S3AllocAdaptor(pScrn);
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ adapt->name = "S3 Backend Scaler";
+ adapt->nEncodings = 1;
+ adapt->pEncodings = &DummyEncoding[0];
+ adapt->nFormats = NUM_FORMATS_OVERLAY;
+ adapt->pFormats = Formats;
+ adapt->nPorts = 1;
+ adapt->pAttributes = NULL /*Attributes*/;
+ adapt->nImages = 3;
+ adapt->nAttributes = 0;
+
+ adapt->pImages = Images;
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+ adapt->StopVideo = S3StopVideo;
+ /* Empty Attrib functions - required anyway */
+ adapt->SetPortAttribute = S3SetPortAttributeOverlay;
+ adapt->GetPortAttribute = S3GetPortAttributeOverlay;
+ adapt->QueryBestSize = S3QueryBestSize;
+ adapt->PutImage = S3PutImage;
+ adapt->QueryImageAttributes = S3QueryImageAttributes;
+
+ /* gotta uninit this someplace */
+ REGION_INIT(pScreen, &(pS3->portPrivate->clip), NullBox, 0);
+
+ S3ResetVideoOverlay(pScrn);
+
+ return adapt;
+}
+
+
+
+static Bool
+RegionsEqual(RegionPtr A, RegionPtr B)
+{
+ int *dataA, *dataB;
+ int num;
+
+ num = REGION_NUM_RECTS(A);
+ if(num != REGION_NUM_RECTS(B))
+ return FALSE;
+
+ if((A->extents.x1 != B->extents.x1) ||
+ (A->extents.x2 != B->extents.x2) ||
+ (A->extents.y1 != B->extents.y1) ||
+ (A->extents.y2 != B->extents.y2))
+ return FALSE;
+
+ dataA = (int*)REGION_RECTS(A);
+ dataB = (int*)REGION_RECTS(B);
+
+ while(num--) {
+ if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1]))
+ return FALSE;
+ dataA += 2;
+ dataB += 2;
+ }
+
+ return TRUE;
+}
+
+
+
+static Bool S3ClipVideo(BoxPtr dst, INT32 *x1, INT32 *x2, INT32 *y1, INT32 *y2,
+ RegionPtr reg, INT32 width, INT32 height)
+{
+ INT32 vscale, hscale, delta;
+ BoxPtr extents = REGION_EXTENTS(DummyScreen, reg);
+ int diff;
+
+ hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1);
+ vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1);
+
+ *x1 <<= 16; *x2 <<= 16;
+ *y1 <<= 16; *y2 <<= 16;
+
+ diff = extents->x1 - dst->x1;
+ if(diff > 0) {
+ dst->x1 = extents->x1;
+ *x1 += diff * hscale;
+ }
+ diff = dst->x2 - extents->x2;
+ if(diff > 0) {
+ dst->x2 = extents->x2;
+ *x2 -= diff * hscale;
+ }
+ diff = extents->y1 - dst->y1;
+ if(diff > 0) {
+ dst->y1 = extents->y1;
+ *y1 += diff * vscale;
+ }
+ diff = dst->y2 - extents->y2;
+ if(diff > 0) {
+ dst->y2 = extents->y2;
+ *y2 -= diff * vscale;
+ }
+
+ if(*x1 < 0) {
+ diff = (- *x1 + hscale - 1)/ hscale;
+ dst->x1 += diff;
+ *x1 += diff * hscale;
+ }
+ delta = *x2 - (width << 16);
+ if(delta > 0) {
+ diff = (delta + hscale - 1)/ hscale;
+ dst->x2 -= diff;
+ *x2 -= diff * hscale;
+ }
+ if(*x1 >= *x2) return FALSE;
+
+ if(*y1 < 0) {
+ diff = (- *y1 + vscale - 1)/ vscale;
+ dst->y1 += diff;
+ *y1 += diff * vscale;
+ }
+ delta = *y2 - (height << 16);
+ if(delta > 0) {
+ diff = (delta + vscale - 1)/ vscale;
+ dst->y2 -= diff;
+ *y2 -= diff * vscale;
+ }
+ if(*y1 >= *y2) return FALSE;
+
+ if((dst->x1 != extents->x1) || (dst->x2 != extents->x2) ||
+ (dst->y1 != extents->y1) || (dst->y2 != extents->y2))
+ {
+ RegionRec clipReg;
+ REGION_INIT(DummyScreen, &clipReg, dst, 1);
+ REGION_INTERSECT(DummyScreen, reg, reg, &clipReg);
+ REGION_UNINIT(DummyScreen, &clipReg);
+ }
+ return TRUE;
+}
+
+
+static void S3StopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ S3PortPrivPtr pPriv = pS3->portPrivate;
+
+ REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+
+ if (exit) {
+ if (pPriv->videoStatus & CLIENT_VIDEO_ON)
+ SET_BLEND_CNTL(0x01000000);
+
+ if (pPriv->area) {
+ xf86FreeOffscreenArea(pPriv->area);
+ pPriv->area = NULL;
+ }
+
+ pPriv->videoStatus = 0;
+ }
+}
+
+
+static FBAreaPtr S3AllocateMemory(ScrnInfoPtr pScrn, FBAreaPtr area,
+ int numlines)
+{
+ ScreenPtr pScreen;
+ FBAreaPtr new_area;
+
+ if(area) {
+ if((area->box.y2 - area->box.y1) >= numlines)
+ return area;
+
+ if(xf86ResizeOffscreenArea(area, pScrn->displayWidth, numlines))
+ return area;
+
+ xf86FreeOffscreenArea(area);
+ }
+
+ pScreen = screenInfo.screens[pScrn->scrnIndex];
+
+ new_area = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth,
+ numlines, 0, NULL, NULL, NULL);
+
+ if(!new_area) {
+ int max_w, max_h;
+
+ xf86QueryLargestOffscreenArea(pScreen, &max_w, &max_h, 0,
+ FAVOR_WIDTH_THEN_AREA, PRIORITY_EXTREME);
+
+ if((max_w < pScrn->displayWidth) || (max_h < numlines))
+ return NULL;
+
+ xf86PurgeUnlockedOffscreenAreas(pScreen);
+ new_area = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth,
+ numlines, 0, NULL, NULL, NULL);
+ }
+
+ return new_area;
+}
+
+
+
+static void S3DisplayVideoOverlay(ScrnInfoPtr pScrn, int id, int offset,
+ short width, short height, int pitch,
+ int x1, int y1, int x2, int y2,
+ BoxPtr dstBox, short src_w, short src_h,
+ short drw_w, short drw_h)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ S3PortPrivPtr pPriv = pS3->portPrivate;
+ int tmp;
+
+ if (drw_w == src_w)
+ tmp = 0;
+ else
+ tmp = 2;
+
+ SET_SSTREAM_CNTL(tmp << 28 | 0x01000000 |
+ ((((src_w-1)<<1)-(drw_w-1)) & 0xfff));
+ SET_SSTRETCH(((src_w - 1) & 0x7ff) | (((src_w-drw_w) & 0x7ff) << 16));
+ SET_BLEND_CNTL(0x05000000);
+ SET_SSTREAM_FBADDR(offset & 0x3fffff);
+ SET_SSTREAM_STRIDE(pitch & 0xfff);
+
+ SET_K1_VSCALE(src_h - 1);
+ SET_K2_VSCALE((src_h - drw_h) & 0x7ff);
+
+ SET_DDA_VERT((((~drw_h)-1)) & 0xfff);
+
+ SET_SSTREAM_START(((dstBox->x1 +1) << 16) | (dstBox->y1 +1));
+ SET_SSTREAM_WIND(( ((drw_w-1) << 16) | (drw_h ) ) & 0x7ff07ff);
+
+ SET_CHROMA_KEY(0x10000000 |
+ ((pScrn->weight.red-1) << 24) |
+ ((pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red) <<
+ (16 + 8-pScrn->weight.red) |
+ ((pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green) <<
+ (8 + 8-pScrn->weight.green) |
+ ((pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue) <<
+ (8-pScrn->weight.blue));
+}
+
+
+static int S3PutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
+ short drw_x, short drw_y, short src_w, short src_h,
+ short drw_w, short drw_h, int id, unsigned char *buf,
+ short width, short height, Bool sync, RegionPtr clipBoxes,
+ pointer data)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ S3PortPrivPtr pPriv = pS3->portPrivate;
+ INT32 x1, x2, y1, y2;
+ unsigned char *dst_start;
+ int pitch, new_h, offset, offset2=0, offset3=0;
+ int srcPitch, srcPitch2=0, dstPitch;
+ int top, left, npixels, nlines;
+ BoxRec dstBox;
+ CARD32 tmp;
+ static int once = 1;
+ static int once2 = 1;
+
+ /* Clip */
+ x1 = src_x;
+ x2 = src_x + src_w;
+ y1 = src_y;
+ y2 = src_y + src_h;
+
+ dstBox.x1 = drw_x;
+ dstBox.x2 = drw_x + drw_w;
+ dstBox.y1 = drw_y;
+ dstBox.y2 = drw_y + drw_h;
+
+ if(!S3ClipVideo(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height))
+ return Success;
+
+ /*if(!pMga->TexturedVideo) {*/
+ dstBox.x1 -= pScrn->frameX0;
+ dstBox.x2 -= pScrn->frameX0;
+ dstBox.y1 -= pScrn->frameY0;
+ dstBox.y2 -= pScrn->frameY0;
+ /*}*/
+
+ pitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3;
+ dstPitch = ((width << 1) + 15) & ~15;
+ new_h = ((dstPitch * height) + pitch - 1) / pitch;
+
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ srcPitch = (width + 3) & ~3;
+ offset2 = srcPitch * height;
+ srcPitch2 = ((width >> 1) + 3) & ~3;
+ offset3 = (srcPitch2 * (height >> 1)) + offset2;
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ srcPitch = (width << 1);
+ break;
+ }
+
+ if(!(pPriv->area = S3AllocateMemory(pScrn, pPriv->area, new_h)))
+ return BadAlloc;
+
+ /* copy data */
+ top = y1 >> 16;
+ left = (x1 >> 16) & ~1;
+ npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left;
+ left <<= 1;
+
+ offset = pPriv->area->box.y1 * pitch;
+ dst_start = pS3->FBBase + offset + left + (top * dstPitch);
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ top &= ~1;
+ tmp = ((top >> 1) * srcPitch2) + (left >> 2);
+ offset2 += tmp;
+ offset3 += tmp;
+ if(id == FOURCC_I420) {
+ tmp = offset2;
+ offset2 = offset3;
+ offset3 = tmp;
+ }
+ nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
+ S3CopyMungedData(buf + (top * srcPitch) + (left >> 1),
+ buf + offset2, buf + offset3, dst_start,
+ srcPitch, srcPitch2, dstPitch, nlines, npixels);
+ once2 = 0;
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ buf += (top * srcPitch) + left;
+ nlines = ((y2 + 0xffff) >> 16) - top;
+ S3CopyData(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
+ once = 0;
+ break;
+ }
+
+ /* update cliplist */
+ if(!RegionsEqual(&pPriv->clip, clipBoxes)) {
+ REGION_COPY(pScreen, &pPriv->clip, clipBoxes);
+ /* draw these */
+ (*pS3->pXAA->FillSolidRects)(pScrn, pPriv->colorKey, GXcopy, ~0,
+ REGION_NUM_RECTS(clipBoxes),
+ REGION_RECTS(clipBoxes));
+ }
+
+ offset += left + (top * dstPitch);
+ S3DisplayVideoOverlay(pScrn, id, offset, width, height, dstPitch,
+ x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
+
+ pPriv->videoStatus = CLIENT_VIDEO_ON;
+ return Success;
+}
+
+
+
+static int S3QueryImageAttributes(ScrnInfoPtr pScrn, int id,
+ unsigned short *w, unsigned short *h,
+ int *pitches, int *offsets)
+{
+ int size, tmp;
+
+ *w = (*w + 1) & ~1;
+ if(offsets) offsets[0] = 0;
+
+ switch(id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
+ *h = (*h + 1) & ~1;
+ size = (*w + 3) & ~3;
+ if(pitches) pitches[0] = size;
+ size *= *h;
+ if(offsets) offsets[1] = size;
+ tmp = ((*w >> 1) + 3) & ~3;
+ if(pitches) pitches[1] = pitches[2] = tmp;
+ tmp *= (*h >> 1);
+ size += tmp;
+ if(offsets) offsets[2] = size;
+ size += tmp;
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ size = *w << 1;
+ if(pitches) pitches[0] = size;
+ size *= *h;
+ break;
+ }
+
+ return size;
+}
+
+
+
+void S3InitStreams(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ S3Ptr pS3 = S3PTR(pScrn);
+ unsigned int pst_wind = (mode->HDisplay-1) << 16 | (mode->VDisplay);
+
+ SET_PSTREAM_CNTL(0x05000000 & 0x77000000);
+ SET_CHROMA_KEY(0x00);
+ SET_SSTREAM_CNTL(0x03000000);
+ SET_BLEND_CNTL(0x01000000);
+ SET_PSTREAM_STRIDE((pScrn->displayWidth * 2) & 0x0fff);
+ SET_SSTREAM_STRIDE(0x01);
+ SET_OPAQUE_OVERLAY(0x40000000);
+ SET_PSTREAM_START(0x00010001);
+ SET_PSTREAM_WIND(pst_wind & 0x07ff07ff);
+ SET_SSTREAM_START(0x07ff07ff);
+ SET_SSTREAM_WIND(0x00010001);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/bin-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/bin-excl
new file mode 100644
index 000000000..c24fdf318
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/bin-excl
@@ -0,0 +1,6 @@
+bin/Xnest.exe
+bin/Xprt.exe
+bin/Xvfb.exe
+bin/X
+bin/xfs.exe
+bin/XWin.exe
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/bin-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/bin-list
new file mode 100644
index 000000000..23aa7b747
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/bin-list
@@ -0,0 +1,36 @@
+.XFree86_Version
+bin
+lib/libdps.a
+lib/libdpstk.a
+lib/libfntstubs.a
+lib/libfreetype.a
+lib/libFS.a
+lib/libGL.a
+lib/libGLU.a
+lib/libGLw.a
+lib/libICE.a
+lib/liboldX.a
+lib/libpsres.a
+lib/libSM.a
+lib/libX11.a
+lib/libXau.a
+lib/libXaw.a
+lib/libXdmcp.a
+lib/libXext.a
+lib/libXfont.a
+lib/libXfontcache.a
+lib/libXft.a
+lib/libXi.a
+lib/libxkbfile.a
+lib/libxkbui.a
+lib/libXmu.a
+lib/libXmuu.a
+lib/libXp.a
+lib/libXpm.a
+lib/libXrandr.a
+lib/libXrender.a
+lib/libXt.a
+lib/libXtst.a
+lib/libXv.a
+lib/libXxf86misc.a
+lib/libXxf86vm.a
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/build-bindist b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/build-bindist
new file mode 100755
index 000000000..edd8e3365
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/build-bindist
@@ -0,0 +1,148 @@
+#!/bin/sh
+#
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/build-bindist,v 1.1 2001/07/02 09:37:18 alanh Exp $
+#
+
+Usage()
+{
+ echo `basename $0` [-l] [-t type] [prefix] from-dir to-dir
+ exit 1
+}
+
+args=
+createlist=NO
+type=list
+
+while [ $# != 0 ]; do
+ case $1 in
+ -l)
+ createlist=YES
+ shift
+ ;;
+ -t)
+ shift
+ type=$1
+ shift
+ ;;
+ *)
+ args="$args $1"
+ shift
+ ;;
+ esac
+done
+
+if [ X"$args" != X ]; then
+ set - $args
+fi
+
+case $# in
+3)
+ PRE=$1
+ shift
+ ;;
+2)
+ PRE=X
+ ;;
+*)
+ Usage
+ ;;
+esac
+
+FROMDIR=$1
+TODIR=$2
+
+if [ ! -d $FROMDIR ]; then
+ echo No such dir $FROMDIR
+ exit 2
+fi
+
+if [ ! -d $TODIR ]; then
+ echo No such dir $TODIR
+ exit 2
+fi
+
+cd $TODIR
+SUBDIRS="`find . -type d ! -name bindist -print`"
+
+DIRFILE=dir
+BINDIR=bindist
+EXTRASFILE=extras
+TAR="gnu-tar"
+TAROPTS="-c -v -z"
+TARLOPTS="-t -v -z -i"
+CKSUM=md5
+SUMFILE=SUMS.md5
+LISTFILE=FILES
+
+GenList()
+{
+ (cd $TODIR/$BINDIR
+ rm -f $SUMFILE $LISTFILE
+ for i in *.tgz; do
+ echo $i
+ $CKSUM $i >> $SUMFILE
+ echo $i >> $LISTFILE
+ echo "------------" >> $LISTFILE
+ $TAR $TARLOPTS -f $i >> $LISTFILE
+ echo "" >> $LISTFILE
+ done
+ if [ -f $TODIR/$EXTRASFILE ]; then
+ for i in `cat $TODIR/$EXTRASFILE`; do
+ $CKSUM `basename $i` >> $SUMFILE
+ done
+ fi
+ )
+}
+
+if [ ! -d $TODIR/$BINDIR ]; then
+ mkdir $TODIR/$BINDIR
+fi
+
+if [ $createlist = YES ]; then
+ GenList
+ exit 0;
+fi
+
+for d in $SUBDIRS; do
+ if [ ! -d $TODIR/$d ]; then
+ echo No such dir $TODIR/$d
+ exit 2
+ fi
+ (cd $TODIR/$d;
+ if [ ! -f $DIRFILE ]; then
+ echo No file $DIRFILE in $TODIR/$d
+# exit 3
+ else
+ DEFPREFIX=`cat $DIRFILE`
+ for i in *-$type; do
+ name=`basename $i -$type`
+ tarball=$PRE$name.tgz
+ echo creating $tarball
+ lfile="`cat $TODIR/$d/$i`"
+ if [ -f $name-excl ]; then
+ xfile="-X $TODIR/$d/$name-excl"
+ else
+ xfile=""
+ fi
+ if [ -f $name-dir ]; then
+ PREFIX=`cat $name-dir`
+ else
+ PREFIX=$DEFPREFIX
+ fi
+ (cd $FROMDIR/$PREFIX
+ $TAR $TAROPTS -f $TODIR/$BINDIR/$tarball $xfile $lfile
+ )
+ done
+ fi
+ if [ -f $EXTRASFILE ]; then
+ for i in `cat $EXTRASFILE`; do
+ rm -f $TODIR/$BINDIR/`basename $i`
+ cp $FROMDIR/$PREFIX/$i $TODIR/$BINDIR
+ done
+ fi
+ )
+done
+
+# GenList
+
+exit 0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/dir b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/dir
new file mode 100644
index 000000000..11c5b9da7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/dir
@@ -0,0 +1 @@
+usr/X11R6
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/etc-dir b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/etc-dir
new file mode 100644
index 000000000..412cec0c3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/etc-dir
@@ -0,0 +1 @@
+etc/X11
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/etc-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/etc-list
new file mode 100644
index 000000000..9c558e357
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/etc-list
@@ -0,0 +1 @@
+.
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/fsrv-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/fsrv-list
new file mode 100644
index 000000000..2f578c539
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/fsrv-list
@@ -0,0 +1,2 @@
+bin/xfs.exe
+man/man1/xfs.1
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/host.def b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/host.def
new file mode 100644
index 000000000..4650f8824
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/host.def
@@ -0,0 +1,3 @@
+#define InstallEmptyHostDef
+#define BuildBindist
+
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/lib-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/lib-excl
new file mode 100644
index 000000000..d7fb5cb03
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/lib-excl
@@ -0,0 +1,14 @@
+lib/X11/XF86Setup
+lib/X11/app-defaults
+lib/X11/config
+lib/X11/doc
+lib/X11/fonts
+lib/X11/fs
+lib/X11/lbxproxy
+lib/X11/proxymngr
+lib/X11/rstart
+lib/X11/twm
+lib/X11/xdm
+lib/X11/xinit
+lib/X11/xsm
+lib/X11/xserver
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/lib-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/lib-list
new file mode 100644
index 000000000..9673fea05
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/lib-list
@@ -0,0 +1,2 @@
+lib/X11
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/man-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/man-excl
new file mode 100644
index 000000000..e5b2fd2e7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/man-excl
@@ -0,0 +1,2 @@
+man/man1/xfs.1
+man/cat1/xmseconfig.0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/man-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/man-list
new file mode 100644
index 000000000..2a3700c15
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/man-list
@@ -0,0 +1 @@
+man
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/nest-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/nest-list
new file mode 100644
index 000000000..ca3ea83df
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/nest-list
@@ -0,0 +1 @@
+bin/Xnest.exe
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/prog-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/prog-excl
new file mode 100644
index 000000000..3204ca88f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/prog-excl
@@ -0,0 +1,5 @@
+lib/Server
+lib/X11
+lib/lib*.a
+lib/modules
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/prog-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/prog-list
new file mode 100644
index 000000000..059b71061
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/prog-list
@@ -0,0 +1,3 @@
+lib
+include
+lib/X11/config
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/prt-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/prt-list
new file mode 100644
index 000000000..88e46fd6f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/prt-list
@@ -0,0 +1 @@
+bin/Xprt.exe
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/update-upd b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/update-upd
new file mode 100644
index 000000000..050fcfe7a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/update-upd
@@ -0,0 +1,32 @@
+bin/XWin.exe
+bin/gccmakedep.exe
+bin/mkhtmlindex.exe
+bin/rman.exe
+bin/pswrap.exe
+bin/twm.exe
+bin/xedit.exe
+bin/xfs.exe
+bin/xman.exe
+bin/xterm.exe
+include/X11/Xos.h
+include/X11/Xosdefs.h
+include/X11/Xos_r.h
+lib/X11/config/FreeBSD.cf
+lib/X11/config/Imake.rules
+lib/X11/config/Imake.tmpl
+lib/X11/config/NetBSD.cf
+lib/X11/config/OpenBSD.cf
+lib/X11/config/X11.tmpl
+lib/X11/config/cygwin.cf
+lib/X11/config/gnu.cf
+lib/X11/config/linux.cf
+lib/X11/config/osf1.cf
+lib/X11/config/xfree86.cf
+lib/X11/xkb/rules/xfree86.lst
+lib/X11/xkb/symbols/us
+lib/libX11.a
+lib/libXaw.a
+lib/libXfont.a
+lib/libXft.a
+lib/libfreetype.a
+man/man1/XWin.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/vfb-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/vfb-list
new file mode 100644
index 000000000..350e4775c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/vfb-list
@@ -0,0 +1 @@
+bin/Xvfb.exe
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/xserv-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/xserv-list
new file mode 100644
index 000000000..f09db6963
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Cygwin/xserv-list
@@ -0,0 +1,2 @@
+bin/XWin.exe
+bin/X
diff --git a/xc/programs/Xserver/hw/xfree86/input/acecad/acecad.c b/xc/programs/Xserver/hw/xfree86/input/acecad/acecad.c
new file mode 100644
index 000000000..0081ff8d7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/acecad/acecad.c
@@ -0,0 +1,916 @@
+/*
+ * Copyright (c) 2001 Edouard TISSERANT <tissered@esstin.u-nancy.fr>
+ * Parts inspired from Shane Watts <shane@bofh.asn.au> XFree86 3 Acecad Driver
+ * Thanks to Emily, from AceCad, For giving me documents.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/acecad/acecad.c,v 1.1 2001/08/13 19:35:00 dawes Exp $ */
+
+#define _ACECAD_C_
+/*****************************************************************************
+ * Standard Headers
+ ****************************************************************************/
+
+#ifdef LINUX_INPUT
+#include <asm/types.h>
+#include <linux/input.h>
+#ifdef BUS_PCI
+#undef BUS_PCI
+#endif
+#ifdef BUS_ISA
+#undef BUS_ISA
+#endif
+#endif
+
+#include <misc.h>
+#include <xf86.h>
+#define NEED_XF86_TYPES
+#include <xf86_ansic.h>
+#include <xf86_OSproc.h>
+#include <xisb.h>
+#include <xf86Xinput.h>
+#include <exevents.h>
+#include <xf86Module.h>
+
+/*****************************************************************************
+ * Local Headers
+ ****************************************************************************/
+#include "acecad.h"
+
+/*****************************************************************************
+ * Variables without includable headers
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Local Variables
+ ****************************************************************************/
+
+#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
+#undef read
+#define read(a,b,c) xf86ReadSerial((a),(b),(c))
+
+/* max number of input events to read in one read call */
+#define MAX_EVENTS 50
+
+
+static InputDriverRec ACECAD =
+{
+ 1,
+ "acecad",
+ NULL,
+ AceCadPreInit,
+ NULL,
+ NULL,
+ 0
+};
+
+
+static XF86ModuleVersionInfo VersionRec =
+{
+ "acecad",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_XINPUT,
+ ABI_XINPUT_VERSION,
+ MOD_CLASS_XINPUT,
+ {0, 0, 0, 0}
+};
+
+
+static const char *default_options[] =
+{
+ "BaudRate", "9600",
+ "StopBits", "1",
+ "DataBits", "8",
+ "Parity", "Odd",
+ "Vmin", "1",
+ "Vtime", "10",
+ "FlowControl", "Xoff",
+ NULL
+};
+
+XF86ModuleData acecadModuleData = { &VersionRec, SetupProc, TearDownProc};
+
+/*****************************************************************************
+ * Function Definitions
+ ****************************************************************************/
+
+static pointer
+SetupProc( pointer module,
+ pointer options,
+ int *errmaj,
+ int *errmin )
+{
+ xf86AddInputDriver(&ACECAD, module, 0);
+ return module;
+}
+
+static void
+TearDownProc( pointer p )
+{
+ LocalDevicePtr local = (LocalDevicePtr) p;
+ AceCadPrivatePtr priv = (AceCadPrivatePtr) local->private;
+
+ DeviceOff (local->dev);
+
+ xf86RemoveLocalDevice (local);
+
+ xf86CloseSerial (local->fd);
+ XisbFree (priv->buffer);
+ xfree (priv);
+ xfree (local->name);
+ xfree (local);
+}
+
+static int
+IsUSBLine(int fd)
+{
+ int version;
+ int err;
+
+ SYSCALL(err = ioctl(fd, EVIOCGVERSION, &version));
+
+ if (!err) {
+ xf86Msg(X_CONFIG,"Kernel Input driver version is %d.%d.%d\n",
+ version >> 16, (version >> 8) & 0xff, version & 0xff);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+static InputInfoPtr
+AceCadPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
+{
+ LocalDevicePtr local = xf86AllocateInput(drv, 0);
+ AceCadPrivatePtr priv = xcalloc (1, sizeof (AceCadPrivateRec));
+ int speed;
+ char *s;
+
+ if ((!local) || (!priv))
+ goto SetupProc_fail;
+
+ memset(priv,0,sizeof (AceCadPrivateRec));
+
+ local->name = dev->identifier;
+ local->type_name = "AceCad Tablet";
+ local->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
+ local->motion_history_proc = xf86GetMotionEvents;
+ local->control_proc = NULL;
+ local->close_proc = CloseProc;
+ local->switch_mode = NULL;
+ local->conversion_proc = ConvertProc;
+ local->reverse_conversion_proc = ReverseConvertProc;
+ local->dev = NULL;
+ local->private = priv;
+ local->private_flags = 0;
+ local->conf_idev = dev;
+ local->device_control = DeviceControl;
+ /*local->always_core_feedback = 0;*/
+
+ xf86CollectInputOptions(local, default_options, NULL);
+
+ xf86OptionListReport(local->options);
+
+ priv->acecadInc = xf86SetIntOption(local->options, "Increment", 0 );
+
+ local->fd = xf86OpenSerial (local->options);
+ if (local->fd == -1)
+ {
+ xf86Msg(X_ERROR,"AceCad driver unable to open device\n");
+ goto SetupProc_fail;
+ }
+ xf86ErrorFVerb( 6, "tty port opened successfully\n" );
+
+ if(IsUSBLine(local->fd)){
+ priv->acecadUSB=1;
+
+ local->read_input = USBReadInput;
+
+ if (USBQueryHardware(local) != Success)
+ {
+ ErrorF ("Unable to query/initialize AceCad hardware.\n");
+ goto SetupProc_fail;
+ }
+ }
+ else{
+ priv->acecadUSB=0;
+
+ local->read_input = ReadInput;
+
+ speed = xf86SetIntOption(local->options, "ReportSpeed", 85 );
+
+ switch (speed)
+ {
+ case 120:
+ priv->acecadReportSpeed = 'Q';
+ break;
+ case 85:
+ priv->acecadReportSpeed = 'R';
+ break;
+ case 10:
+ priv->acecadReportSpeed = 'S';
+ break;
+ case 2:
+ priv->acecadReportSpeed = 'T';
+ break;
+ default:
+ priv->acecadReportSpeed = 'R';
+ speed = 85;
+ xf86Msg(X_CONFIG, "Acecad Tablet: ReportSpeed possible values:\n 120, 85, 10, 2 \n");
+ }
+
+ xf86Msg(X_CONFIG, "Acecad Tablet report %d points/s\n", speed);
+
+ priv->buffer = XisbNew (local->fd, 200);
+
+ /*
+ * Verify that hardware is attached and fuctional
+ */
+ if (QueryHardware(priv) != Success)
+ {
+ xf86Msg(X_ERROR,"Unable to query/initialize AceCad hardware.\n");
+ goto SetupProc_fail;
+ }
+ }
+
+ s = xf86FindOptionValue(local->options, "Mode");
+ if (s && (xf86NameCmp(s, "Relative") == 0))
+ {
+ priv->flags = priv->flags & ~ABSOLUTE_FLAG;
+ }
+ else
+ {
+ priv->flags = priv->flags | ABSOLUTE_FLAG;
+ }
+
+ xf86Msg(X_CONFIG, "Acecad Tablet is in %s mode\n",(priv->flags & ABSOLUTE_FLAG) ? "absolute" : "relative");
+ DBG (9, XisbTrace (priv->buffer, 1));
+
+ local->history_size = xf86SetIntOption(local->options , "HistorySize", 0);
+
+ xf86ProcessCommonOptions(local, local->options);
+
+ local->flags |= XI86_CONFIGURED;
+
+ if (local->fd != -1)
+ {
+ RemoveEnabledDevice (local->fd);
+ if (priv->buffer)
+ {
+ XisbFree(priv->buffer);
+ priv->buffer = NULL;
+ }
+ xf86CloseSerial(local->fd);
+ }
+ RemoveEnabledDevice (local->fd);
+ local->fd = -1;
+ return (local);
+
+ /*
+ * If something went wrong, cleanup and return NULL
+ */
+ SetupProc_fail:
+ if ((local) && (local->fd))
+ xf86CloseSerial (local->fd);
+ if (local)
+ xfree (local);
+
+ if ((priv) && (priv->buffer))
+ XisbFree (priv->buffer);
+ if (priv)
+ xfree (priv);
+ return (NULL);
+}
+
+static Bool
+DeviceControl (DeviceIntPtr dev, int mode)
+{
+ Bool RetValue;
+
+ switch (mode)
+ {
+ case DEVICE_INIT:
+ DeviceInit (dev);
+ RetValue = Success;
+ break;
+ case DEVICE_ON:
+ RetValue = DeviceOn( dev );
+ break;
+ case DEVICE_OFF:
+ RetValue = DeviceOff( dev );
+ break;
+ case DEVICE_CLOSE:
+ RetValue = DeviceClose( dev );
+ break;
+ default:
+ RetValue = BadValue;
+ }
+
+ return( RetValue );
+}
+
+static Bool
+DeviceOn (DeviceIntPtr dev)
+{
+ char buffer[256];
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ AceCadPrivatePtr priv = (AceCadPrivatePtr) (local->private);
+
+ xf86Msg(X_CONFIG, "Acecad Tablet Device On\n");
+
+ local->fd = xf86OpenSerial(local->options);
+ if (local->fd == -1)
+ {
+ xf86Msg(X_WARNING, "%s: cannot open input device\n", local->name);
+ return (!Success);
+ }
+
+
+ if (priv->acecadUSB==0){
+ priv->buffer = XisbNew(local->fd, 200);
+ if (!priv->buffer)
+ {
+ xf86CloseSerial(local->fd);
+ local->fd = -1;
+ return (!Success);
+ }
+
+ /*Rets qu'a l'envoyer a la tablette */
+ sprintf(buffer, "%s%c%c%c%c", acecad_initstr, priv->acecadReportSpeed ,ACECAD_INCREMENT, 32 + priv->acecadInc, (priv->flags & ABSOLUTE_FLAG)? ACECAD_ABSOLUTE: ACECAD_RELATIVE);
+ XisbWrite (priv->buffer, (unsigned char *)buffer, strlen(buffer));
+ }
+
+ xf86FlushInput(local->fd);
+ xf86AddEnabledDevice (local);
+ dev->public.on = TRUE;
+ return (Success);
+}
+
+static Bool
+DeviceOff (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ AceCadPrivatePtr priv = (AceCadPrivatePtr) (local->private);
+
+
+ if (local->fd != -1)
+ {
+ RemoveEnabledDevice (local->fd);
+ if (priv->buffer)
+ {
+ XisbFree(priv->buffer);
+ priv->buffer = NULL;
+ }
+ xf86CloseSerial(local->fd);
+ }
+
+
+ xf86RemoveEnabledDevice (local);
+ dev->public.on = FALSE;
+ return (Success);
+}
+
+static Bool
+DeviceClose (DeviceIntPtr dev)
+{
+ xf86Msg(X_CONFIG, "Acecad Tablet Device Close\n");
+ return (Success);
+}
+
+static void
+ControlProc(DeviceIntPtr device,
+ PtrCtrl *ctrl)
+{
+ xf86Msg(X_CONFIG, "Acecad Tablet Control Proc\n");
+}
+
+static Bool
+DeviceInit (DeviceIntPtr dev)
+{
+ int rx, ry;
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ AceCadPrivatePtr priv = (AceCadPrivatePtr) (local->private);
+ unsigned char map[] =
+ {0, 1, 2, 3};
+
+ xf86Msg(X_CONFIG, "Acecad Tablet Device Init\n");
+
+ /* 3 boutons */
+ if (InitButtonClassDeviceStruct (dev, 3, map) == FALSE)
+ {
+ ErrorF ("Unable to allocate AceCad ButtonClassDeviceStruct\n");
+ return !Success;
+ }
+
+ if (InitFocusClassDeviceStruct (dev) == FALSE)
+ {
+ ErrorF("Unable to allocate AceCad FocusClassDeviceStruct\n");
+ return !Success;
+ }
+
+ if (InitPtrFeedbackClassDeviceStruct(dev,
+ ControlProc) == FALSE) {
+ ErrorF("unable to init ptr feedback\n");
+ return !Success;
+ }
+
+
+ /* 3 axes */
+ if (InitValuatorClassDeviceStruct (dev, 3, xf86GetMotionEvents,
+ local->history_size,
+ ((priv->flags & ABSOLUTE_FLAG)? Absolute: Relative)|OutOfProximity)
+ == FALSE)
+ {
+ ErrorF ("Unable to allocate AceCad ValuatorClassDeviceStruct\n");
+ return !Success;
+ }
+ else
+ {
+
+ InitValuatorAxisStruct(dev,
+ 0,
+ 0, /* min val */
+ priv->acecadMaxX, /* max val */
+ 1000, /* resolution */
+ 0, /* min_res */
+ 1000); /* max_res */
+ InitValuatorAxisStruct(dev,
+ 1,
+ 0, /* min val */
+ priv->acecadMaxY, /* max val */
+ 1000, /* resolution */
+ 0, /* min_res */
+ 1000); /* max_res */
+ InitValuatorAxisStruct(dev,
+ 2,
+ 0, /* min val */
+ priv->acecadMaxZ, /* max val */
+ 1000, /* resolution */
+ 0, /* min_res */
+ 1000); /* max_res */
+
+ }
+
+ if (InitProximityClassDeviceStruct (dev) == FALSE)
+ {
+ ErrorF ("Unable to allocate ProximityClassDeviceStruct\n");
+ return !Success;
+ }
+
+ xf86MotionHistoryAllocate (local);
+
+
+ /* On ne peut pas calculer l'increment avant, faute d'ecran pour
+ connaitre la taille... */
+
+ if (priv->acecadInc > 95)
+ priv->acecadInc = 95;
+ if (priv->acecadInc < 1)
+ {
+ /* guess the best increment value given video mode */
+ rx=priv->acecadMaxX / screenInfo.screens[0]->width;
+ ry=priv->acecadMaxY / screenInfo.screens[0]->height;
+ if (rx < ry)
+ priv->acecadInc = rx;
+ else
+ priv->acecadInc = ry;
+ if (priv->acecadInc < 1)
+ priv->acecadInc = 1;
+ }
+
+ xf86Msg(X_CONFIG, "Acecad Tablet Increment: %d\n",priv->acecadInc);
+
+ return (Success);
+}
+
+static void
+ReadInput (LocalDevicePtr local)
+{
+ int x, y, z;
+ int prox, buttons;
+ int is_core_pointer, is_absolute;
+ AceCadPrivatePtr priv = (AceCadPrivatePtr) (local->private);
+
+ /*xf86Msg(X_CONFIG, "Acecad Tablet Read Input\n");*/
+
+ is_absolute = (priv->flags & ABSOLUTE_FLAG);
+ is_core_pointer = xf86IsCorePointer(local->dev);
+
+ /*
+ * set blocking to -1 on the first call because we know there is data to
+ * read. Xisb automatically clears it after one successful read so that
+ * succeeding reads are preceeded buy a select with a 0 timeout to prevent
+ * read from blocking indefinately.
+ */
+ XisbBlockDuration (priv->buffer, -1);
+
+ while (AceCadGetPacket (priv) == Success)
+ {
+ x = (int)priv->packet[1] | ((int)priv->packet[2] << 7);
+ y = (int)priv->packet[3] | ((int)priv->packet[4] << 7);
+
+ if (!(priv->flags & ABSOLUTE_FLAG))
+ {
+ x = priv->packet[0] & XSIGN_BIT? x:-x;
+ y = priv->packet[0] & YSIGN_BIT? y:-y;
+ }
+ else
+ {
+ y = priv->acecadMaxY - y ;
+ }
+
+
+ z = ((int)priv->packet[5] << 2) |
+ (((int)priv->packet[6] & 0x01) << 1) |
+ (((int)priv->packet[6] & 0x10) >> 4);
+
+ buttons = ((int)priv->packet[0] & 0x07) |
+ ((int)priv->packet[6] & 0x02 << 2);
+
+ prox = (priv->packet[0] & PROXIMITY_BIT)? 0: 1;
+
+ if (prox)
+ {
+ if (!(priv->acecadOldProximity))
+ if (!is_core_pointer)
+ {
+ /*xf86Msg(X_CONFIG, "Acecad Tablet ProxIN %d %d %d\n",x, y, z);*/
+ xf86PostProximityEvent(local->dev, 1, 0, 3 , x, y, z);
+ }
+
+ if ((is_absolute && ((priv->acecadOldX != x) || (priv->acecadOldY != y) || (priv->acecadOldZ != z)))
+ || (!is_absolute && (x || y)))
+ {
+ if (is_absolute || priv->acecadOldProximity)
+ {
+ /*xf86Msg(X_CONFIG, "Acecad Tablet Motion %d %d %d\n", x, y, z);*/
+ xf86PostMotionEvent(local->dev, is_absolute, 0, 3, x, y, z);
+ }
+ }
+
+ if (priv->acecadOldButtons != buttons)
+ {
+ int delta;
+
+ delta = buttons ^ priv->acecadOldButtons;
+ while(delta)
+ {
+ int id;
+
+ id=ffs(delta);
+ delta &= ~(1 << (id-1));
+
+ /*xf86Msg(X_CONFIG, "Acecad Tablet Button %d 0x%x\n",id,(buttons&(1<<(id-1))));*/
+ xf86PostButtonEvent(local->dev, is_absolute, id, (buttons&(1<<(id-1))), 0, 3, x, y,z);
+ }
+ }
+
+ priv->acecadOldButtons = buttons;
+ priv->acecadOldX = x;
+ priv->acecadOldY = y;
+ priv->acecadOldZ = z;
+ priv->acecadOldProximity = prox;
+ }
+ else
+ {
+ if (!is_core_pointer)
+ if (priv->acecadOldProximity)
+ {
+ /*xf86Msg(X_CONFIG, "Acecad Tablet ProxOUT %d %d %d\n",x, y, z);*/
+ xf86PostProximityEvent(local->dev, 0, 0, 3, x,y,z);
+ }
+ priv->acecadOldProximity = 0;
+ }
+ }
+ /*xf86Msg(X_CONFIG, "Acecad Tablet Sortie Read Input\n");*/
+}
+
+#define set_bit(byte,nb,bit) (bit ? byte | (1<<nb) : byte & (~(1<<nb)))
+static void
+USBReadInput (LocalDevicePtr local)
+{
+ int len;
+ struct input_event * event;
+ char eventbuf[sizeof(struct input_event) * MAX_EVENTS];
+ AceCadPrivatePtr priv = (AceCadPrivatePtr) (local->private);
+ int x = priv->acecadOldX;
+ int y = priv->acecadOldY;
+ int z = priv->acecadOldZ;
+ int prox = priv->acecadOldProximity;
+ int buttons = priv->acecadOldButtons;
+ int is_core_pointer;
+
+ is_core_pointer = xf86IsCorePointer(local->dev);
+
+ SYSCALL(len = read(local->fd, eventbuf, sizeof(eventbuf)));
+
+ if (len <= 0) {
+ ErrorF("Error reading wacom device : %s\n", strerror(errno));
+ return;
+ }
+
+ for (event=(struct input_event *)eventbuf;
+ event<(struct input_event *)(eventbuf+len); event++) {
+
+ switch (event->type) {
+ case EV_ABS:
+ switch (event->code) {
+ case ABS_X:
+ x = event->value;
+ break;
+
+ case ABS_Y:
+ y = event->value;
+ break;
+
+ case ABS_PRESSURE:
+ z = event->value;
+ break;
+
+ case ABS_MISC:
+ break;
+
+ }
+ break; /* EV_ABS */
+
+ case EV_KEY:
+ switch (event->code) {
+ case BTN_TOOL_PEN:
+ prox = event->value;
+ break;
+
+ case BTN_TOUCH:
+ buttons=set_bit(buttons,0,event->value);
+ break;
+
+ case BTN_STYLUS:
+ buttons=set_bit(buttons,1,event->value);
+ break;
+
+ case BTN_STYLUS2:
+ buttons=set_bit(buttons,2,event->value);
+ break;
+ }
+ break; /* EV_KEY */
+ default:
+ xf86Msg(X_ERROR, "UNKNOWN event->code=%d\n", event->code);
+ } /* switch event->type */
+
+ /* ABS_MISC is the event terminator */
+ if (event->type != EV_ABS || event->code != ABS_MISC) {
+ continue;
+ }
+
+ if (prox)
+ {
+ if (!(priv->acecadOldProximity))
+ if (!is_core_pointer)
+ {
+ xf86PostProximityEvent(local->dev, 1, 0, 3 , x, y, z);
+ }
+
+
+ xf86PostMotionEvent(local->dev, 1, 0, 3, x, y, z);
+
+ if (priv->acecadOldButtons != buttons)
+ {
+ int delta;
+
+ delta = buttons ^ priv->acecadOldButtons;
+ while(delta)
+ {
+ int id;
+
+ id=ffs(delta);
+ delta &= ~(1 << (id-1));
+
+ xf86PostButtonEvent(local->dev, 1, id, (buttons&(1<<(id-1))), 0, 3, x, y,z);
+ }
+ }
+ }
+ else
+ {
+ if (!is_core_pointer)
+ if (priv->acecadOldProximity)
+ {
+ xf86PostProximityEvent(local->dev, 0, 0, 3, x,y,z);
+ }
+ priv->acecadOldProximity = 0;
+ }
+
+ priv->acecadOldButtons = buttons;
+ priv->acecadOldX = x;
+ priv->acecadOldY = y;
+ priv->acecadOldZ = z;
+ priv->acecadOldProximity = prox;
+ }
+ /*xf86Msg(X_CONFIG, "Acecad Tablet Sortie Read Input\n");*/
+}
+
+static void
+CloseProc (LocalDevicePtr local)
+{
+}
+
+/*
+ * The ConvertProc function may need to be tailored for your device.
+ * This function converts the device's valuator outputs to x and y coordinates
+ * to simulate mouse events.
+ */
+static Bool
+ConvertProc (LocalDevicePtr local,
+ int first,
+ int num,
+ int v0,
+ int v1,
+ int v2,
+ int v3,
+ int v4,
+ int v5,
+ int *x,
+ int *y)
+{
+ AceCadPrivatePtr priv = (AceCadPrivatePtr)(local->private);
+
+ *x = v0 * screenInfo.screens[0]->width / priv->acecadMaxX;
+ *y = v1 * screenInfo.screens[0]->height / priv->acecadMaxY;
+ return TRUE;
+}
+
+
+static Bool
+ReverseConvertProc( LocalDevicePtr local,
+ int x,
+ int y,
+ int *valuators)
+{
+ AceCadPrivatePtr priv = (AceCadPrivatePtr)(local->private);
+
+ valuators[0] = x * priv->acecadMaxX / screenInfo.screens[0]->width;
+ valuators[1] = y * priv->acecadMaxY / screenInfo.screens[0]->height;
+
+ return TRUE;
+}
+
+
+#define WriteString(str)\
+XisbWrite (priv->buffer, (unsigned char *)(str), strlen(str))
+
+
+static Bool
+QueryHardware (AceCadPrivatePtr priv)
+{
+
+ /* Reset */
+ WriteString("z0");
+
+ /* Wait */
+ milisleep (250);
+
+ /* Prompt Mode in order to not be disturbed */
+ WriteString(ACECAD_PROMPT_MODE);
+
+ /* Flush */
+ while(XisbRead(priv->buffer)>=0);
+
+ /* Ask for Config packet*/
+ WriteString(ACECAD_CONFIG);
+
+ /* Read the packet */
+ XisbBlockDuration (priv->buffer, 1000000);
+ NewPacket (priv);
+
+ /*xf86Msg(X_CONFIG, "Acecad Tablet init envoyé \n");*/
+
+ if ((AceCadGetPacket (priv) == Success))
+ {
+ priv->acecadMaxX = (int)priv->packet[1] + ((int)priv->packet[2] << 7);
+ priv->acecadMaxY = (int)priv->packet[3] + ((int)priv->packet[4] << 7);
+ priv->acecadMaxZ = 512;
+ xf86Msg(X_CONFIG, "Acecad Tablet MaxX:%d MaxY:%d\n",priv->acecadMaxX,priv->acecadMaxY);
+ }
+ else
+ return (!Success);
+
+ /*xf86Msg(X_CONFIG, "Acecad Tablet query hardware fini \n");*/
+ return (Success);
+}
+
+#define BITS_PER_LONG (sizeof(long) * 8)
+#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
+#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
+#define OFF(x) ((x)%BITS_PER_LONG)
+#define LONG(x) ((x)/BITS_PER_LONG)
+
+static Bool
+USBQueryHardware (LocalDevicePtr local)
+{
+ AceCadPrivatePtr priv = (AceCadPrivatePtr) local->private;
+ unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
+ int i, j;
+ int abs[5];
+ char name[256] = "Unknown";
+
+ ioctl(local->fd, EVIOCGNAME(sizeof(name)), name);
+ xf86Msg(X_CONFIG, "Kernel Input device name: \"%s\"\n", name);
+
+ memset(bit, 0, sizeof(bit));
+ ioctl(local->fd, EVIOCGBIT(0, EV_MAX), bit[0]);
+
+ for (i = 0; i < EV_MAX; i++)
+ if (test_bit(i, bit[0])) {
+ ioctl(local->fd, EVIOCGBIT(i, KEY_MAX), bit[i]);
+ for (j = 0; j < KEY_MAX; j++)
+ if (test_bit(j, bit[i])) {
+ if (i == EV_ABS) {
+ ioctl(local->fd, EVIOCGABS(j), abs);
+ switch (j) {
+ case ABS_X:
+ priv->acecadMaxX = abs[2];
+ break;
+
+ case ABS_Y:
+ priv->acecadMaxY = abs[2];
+ break;
+
+ case ABS_PRESSURE:
+ priv->acecadMaxZ = abs[2];
+ break;
+ }
+ }
+ }
+ }
+
+ xf86Msg(X_CONFIG, "Acecad Tablet MaxX:%d MaxY:%d MaxZ:%d\n",priv->acecadMaxX,priv->acecadMaxY,priv->acecadMaxZ);
+ return (Success);
+}
+
+static void
+NewPacket (AceCadPrivatePtr priv)
+{
+ priv->packeti = 0;
+}
+
+static Bool
+AceCadGetPacket (AceCadPrivatePtr priv)
+{
+ int count = 0;
+ int c = 0;
+
+ while((c = XisbRead(priv->buffer))>=0 )
+ {
+
+ /*
+ * fail after 500 bytes so the server doesn't hang forever if a
+ * device sends bad data.
+ */
+ if (count++ > 500)
+ {
+ NewPacket (priv);
+ return (!Success);
+ }
+
+ if (c & PHASING_BIT)
+ {
+ NewPacket(priv);
+
+ /*xf86Msg(X_CONFIG, "Push %2.2x\n",(char) c);*/
+ XisbBlockDuration (priv->buffer, 10000);
+ priv->packet[priv->packeti++] = c;
+ count=ACECAD_PACKET_SIZE-1;
+ while(count-- && (c = XisbRead(priv->buffer))>=0)
+ {
+ /*xf86Msg(X_CONFIG, "Push %2.2x\n",(char) c);*/
+ priv->packet[priv->packeti++] = c;
+ }
+ XisbBlockDuration (priv->buffer, 0);
+ if(c > 0)
+ return (Success);
+ }
+ }
+ return (!Success);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/input/acecad/acecad.h b/xc/programs/Xserver/hw/xfree86/input/acecad/acecad.h
new file mode 100644
index 000000000..d1ec95030
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/acecad/acecad.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2001 Edouard TISSERANT <tissered@esstin.u-nancy.fr>
+ * Parts inspired from Shane Watts <shane@bofh.asn.au> Xfree 3 Acecad Driver
+ * Thanks to Emily, from AceCad, For giving me documents.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/acecad/acecad.h,v 1.1 2001/08/13 19:35:00 dawes Exp $ */
+
+#ifndef _ACECAD_H_
+#define _ACECAD_H_
+
+/******************************************************************************
+ * Definitions
+ * structs, typedefs, #defines, enums
+ *****************************************************************************/
+#define ACECAD_PACKET_SIZE 7
+
+#define ACECAD_CONFIG "a" /* Send configuration (max coords) */
+
+#define ACECAD_ABSOLUTE 'F' /* Absolute mode */
+#define ACECAD_RELATIVE 'E' /* Relative mode */
+
+#define ACECAD_UPPER_ORIGIN "b" /* Origin upper left */
+
+#define ACECAD_PROMPT_MODE "B" /* Prompt mode */
+#define ACECAD_STREAM_MODE "@" /* Stream mode */
+#define ACECAD_INCREMENT 'I' /* Set increment */
+#define ACECAD_BINARY_FMT "zb" /* Binary reporting */
+
+#define ACECAD_PROMPT "P" /* Prompt for current position */
+
+#define PHASING_BIT 0x80
+#define PROXIMITY_BIT 0x40
+#define TABID_BIT 0x20
+#define XSIGN_BIT 0x10
+#define YSIGN_BIT 0x08
+#define BUTTON_BITS 0x07
+#define COORD_BITS 0x7f
+
+#define ABSOLUTE_FLAG 1
+
+#define milisleep(ms) xf86usleep (ms * 1000)
+
+#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
+
+static const char * acecad_initstr = ACECAD_BINARY_FMT ACECAD_STREAM_MODE;
+
+typedef struct
+{
+ XISBuffer *buffer;
+ int acecadInc; /* increment between transmits */
+ int acecadOldX; /* previous X position */
+ int acecadOldY; /* previous Y position */
+ int acecadOldZ; /* previous Z position */
+ int acecadOldProximity; /* previous proximity */
+ int acecadOldButtons; /* previous buttons state */
+ int acecadMaxX; /* max X value */
+ int acecadMaxY; /* max Y value */
+ int acecadMaxZ; /* max Y value */
+ char acecadReportSpeed; /* report speed */
+ int acecadUSB; /*USB flag*/
+ int flags; /* various flags */
+ int packeti; /* number of bytes read */
+ int PacketSize; /* number of bytes read */
+ unsigned char packet[ACECAD_PACKET_SIZE]; /* data read on the device */
+} AceCadPrivateRec, *AceCadPrivatePtr;
+
+
+/******************************************************************************
+ * Declarations
+ *****************************************************************************/
+static MODULESETUPPROTO( SetupProc );
+static void TearDownProc (void *);
+static Bool DeviceControl (DeviceIntPtr, int);
+static Bool DeviceOn (DeviceIntPtr);
+static Bool DeviceOff (DeviceIntPtr);
+static Bool DeviceClose (DeviceIntPtr);
+static Bool DeviceInit (DeviceIntPtr);
+static void ReadInput (LocalDevicePtr);
+static void USBReadInput (LocalDevicePtr);
+static void CloseProc (LocalDevicePtr);
+static Bool ConvertProc (LocalDevicePtr, int, int, int, int, int, int, int, int, int *, int *);
+static Bool ReverseConvertProc(LocalDevicePtr , int , int , int*);
+static Bool QueryHardware (AceCadPrivatePtr);
+static Bool USBQueryHardware (LocalDevicePtr);
+static void NewPacket (AceCadPrivatePtr priv);
+static Bool AceCadGetPacket (AceCadPrivatePtr);
+static InputInfoPtr AceCadPreInit(InputDriverPtr, IDevPtr , int);
+static int IsUSBLine(int);
+
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/input/acecad/acecad.man b/xc/programs/Xserver/hw/xfree86/input/acecad/acecad.man
new file mode 100644
index 000000000..0f8996707
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/acecad/acecad.man
@@ -0,0 +1,40 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/input/acecad/acecad.man,v 1.1 2001/08/13 19:35:00 dawes Exp $
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH ACECAD __drivermansuffix__ __vendorversion__
+.SH NAME
+acecad \- Acecad Flair input driver
+.SH SYNOPSIS
+.B "Section \*qInputDevice\*q"
+.br
+.BI " Identifier \*q" idevname \*q
+.br
+.B " Driver \*qacecad\*q"
+.br
+.BI " Option \*qDevice\*q \*q" devpath \*q
+.br
+\ \ ...
+.br
+.B EndSection
+.SH DESCRIPTION
+.B acecad
+is an XFree86 input driver for Acecad Flair devices...
+.PP
+The
+.B acecad
+driver functions as a pointer input device, and may be used as the
+X server's core pointer.
+THIS MAN PAGE NEEDS TO BE FILLED IN.
+.SH SUPPORTED HARDWARE
+What is supported...
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details and for options that can be used with all input drivers. This
+section only covers configuration details specific to this driver.
+.PP
+Config details...
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__).
+.SH AUTHORS
+Authors include...
+Edouard TISSERANT
diff --git a/xc/programs/Xserver/hw/xfree86/input/calcomp/Imakefile b/xc/programs/Xserver/hw/xfree86/input/calcomp/Imakefile
new file mode 100644
index 000000000..f5eec8d8e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/calcomp/Imakefile
@@ -0,0 +1,26 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/calcomp/Imakefile,v 1.1 2001/08/12 22:48:43 alanh Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = xf86Calcomp.c
+OBJS = xf86Calcomp.o
+
+DRIVER = calcomp
+
+INCLUDES = -I. -I$(XF86COMSRC) -I../../loader -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget($(DRIVER),$(OBJS))
+
+InstallObjectModule($(DRIVER),$(MODULEDIR),input)
+
+DependTarget()
+
+InstallDriverSDKObjectModule($(DRIVER),$(DRIVERSDKMODULEDIR),input)
diff --git a/xc/programs/Xserver/hw/xfree86/input/calcomp/calcomp.man b/xc/programs/Xserver/hw/xfree86/input/calcomp/calcomp.man
new file mode 100644
index 000000000..2b025c012
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/calcomp/calcomp.man
@@ -0,0 +1,82 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/input/calcomp/calcomp.man,v 1.2 2001/08/12 22:51:29 alanh Exp $
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH CALCOMP __drivermansuffix__ __vendorversion__
+.SH NAME
+calcomp \- Calcomp input driver
+.SH SYNOPSIS
+.nf
+.B "Section \*qInputDevice\*q"
+.BI " Identifier \*q" idevname \*q
+.B " Driver \*qcalcomp\*q"
+.BI " Option \*qDevice\*q \*q" devpath \*q
+\ \ ...
+.B EndSection
+.fi
+.SH DESCRIPTION
+.B calcomp
+is an XFree86 input driver for Calcomp devices.
+.PP
+The
+.B calcomp
+driver functions as a pointer input device, and may be used as the
+X server's core pointer.
+.SH SUPPORTED HARDWARE
+This driver supports the Calcomp binary format used by the Drawing Board II
+and III series.
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details and for options that can be used with all input drivers. This
+section only covers configuration details specific to this driver.
+.PP
+Both the 3 button stylus and the 4- or 16 button lens cursors can be used
+without changing the configuration file. Support for pressure sensitivity
+has not been tested, so the solid-tip stylus will probably not work.
+.PP
+This device supports the following entries:
+.RS 8
+.TP 4
+.B Option \fI"Device"\fP \fI"path"\fP
+sets the path to the special file which represents the serial line where
+the tablet is plugged. This option is mandatory.
+.TP 4
+.B Option \fI"Cursor"\fP \fI"Stylus"|"Puck"\fP
+this option is supported for backward compatibility only, but it should
+not be necessary.
+.TP 4
+.B Option \fI"DeviceName"\fP \fI"name"\fP
+sets the name of the X device. Some user-space programs may require a fixed
+name, e.g. TABLET, to recognize the digitizer.
+.TP 4
+.B Option \fI"Mode"\fP \fI"Relative"|"Absolute"\fP
+sets the mode of the device. Currently only Absolute mode is supported.
+.TP 4
+.B Option \fI"Pressure"\fP \fI"on"\fP
+enables pressure reporting if your tablet supports it. This option is
+untested and may not work.
+.TP 4
+.B Option \fI"AlwaysCore"\fP \fI"on"\fP
+enables the sharing of the core pointer. When this feature is enabled, the
+device will take control of the core pointer (and thus will emit core events)
+and at the same time will be able, when asked so, to report extended events.
+.TP 4
+.B Option \fI"MinX"\fP \fI"number"\fP
+X coordinate of the bottom left corner of the active zone.
+.TP 4
+.B Option \fI"MinY"\fP \fI"number"\fP
+Y coordinate of the bottom left corner of the active zone.
+.TP 4
+.B Option \fI"MaxX"\fP \fI"Inumber"\fP
+X coordinate of the top right corner of the active zone.
+.TP 4
+.B Option \fI"MaxY"\fP \fI"number"\fP
+Y coordinate of the top right corner of the active zone.
+.TP 4
+.B Option \fI"DebugLevel"\fP \fInumber \fP
+sets the level of debugging info reported.
+.TP 4
+.RE
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__).
+.SH AUTHORS
+Martin Kroeker <mk@daveg.com>
diff --git a/xc/programs/Xserver/hw/xfree86/input/calcomp/xf86Calcomp.c b/xc/programs/Xserver/hw/xfree86/input/calcomp/xf86Calcomp.c
new file mode 100644
index 000000000..9d4f95bc2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/calcomp/xf86Calcomp.c
@@ -0,0 +1,834 @@
+/*
+ * Copyright (c) 2000,2001 Martin Kroeker (mk@daveg.com)
+ * sample driver used :
+ * Copyright (c) 1998 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ * Except as contained in this notice, the names of Martin Kroeker and/or
+ * Daveg GmbH shall not be used in advertising or otherwise to promote the
+ * sale, use or other dealings in this Software without prior written
+ * authorization from Martin Kroeker or Daveg GmbH.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/calcomp/xf86Calcomp.c,v 1.2 2001/08/15 11:54:27 tsi Exp $ */
+
+#define _CALCOMP_C_
+/*****************************************************************************
+ * Standard Headers
+ ****************************************************************************/
+
+#include <misc.h>
+#include <xf86.h>
+#define NEED_XF86_TYPES
+#include <xf86_ansic.h>
+#include <xf86_OSproc.h>
+#include <xf86Xinput.h>
+#include <xisb.h>
+#include <exevents.h> /* Needed for InitValuator/Proximity stuff */
+
+/*****************************************************************************
+ * Local Headers
+ ****************************************************************************/
+#include "xf86Calcomp.h"
+
+/*****************************************************************************
+ * Variables without includable headers
+ ****************************************************************************/
+ #define DEBUG 1
+/*****************************************************************************
+ * Local Variables
+ ****************************************************************************/
+
+InputDriverRec CALCOMP = {
+ 1,
+ "calcomp",
+ NULL,
+ CalcompPreInit, /*preinit ?*/
+ NULL,
+ NULL,
+ 0
+ };
+
+/*
+ * Be sure to set vmin appropriately for your device's protocol. You want to
+ * read a full packet before returning
+ */
+static const char *default_options[] =
+{
+ "Device", "/dev/ttyS1",
+ "BaudRate", "9600",
+ "StopBits", "1",
+ "DataBits", "8",
+ "Parity", "None",
+ "Vmin", "1",
+ "Vtime", "1",
+ "FlowControl", "None"
+};
+
+
+#ifdef XFree86LOADER
+
+static XF86ModuleVersionInfo VersionRec =
+{
+ "calcomp",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_XINPUT,
+ ABI_XINPUT_VERSION,
+ MOD_CLASS_XINPUT,
+ {0, 0, 0, 0} /* signature, to be patched into the file by
+ * a tool */
+};
+
+static const char *reqSymbols[] = {
+ "AddEnabledDevice",
+ "ErrorF",
+ "InitButtonClassDeviceStruct",
+ "InitProximityClassDeviceStruct",
+ "InitValuatorAxisStruct",
+ "InitValuatorClassDeviceStruct",
+ "InitPtrFeedbackClassDeviceStruct",
+ "RemoveEnabledDevice",
+ "Xcalloc",
+ "Xfree",
+ "XisbBlockDuration",
+ "XisbFree",
+ "XisbNew",
+ "XisbRead",
+ "XisbTrace",
+ "screenInfo",
+ "xf86AddInputDriver",
+ "xf86AllocateInput",
+ "xf86CloseSerial",
+ "xf86CollectInputOptions",
+ "xf86ErrorFVerb",
+ "xf86FindOptionValue",
+ "xf86GetMotionEvents",
+ "xf86GetVerbosity",
+ "xf86MotionHistoryAllocate",
+ "xf86NameCmp",
+ "xf86OpenSerial",
+ "xf86CloseSerial",
+ "xf86OptionListCreate",
+ "xf86OptionListMerge",
+ "xf86OptionListReport",
+ "xf86PostButtonEvent",
+ "xf86PostMotionEvent",
+ "xf86PostProximityEvent",
+ "xf86ProcessCommonOptions",
+ "xf86ScaleAxis",
+ "xf86SetIntOption",
+ "xf86SetStrOption",
+ "xf86XInputSetScreen",
+ "xf86XInputSetSendCoreEvents",
+ NULL
+ };
+
+
+static pointer
+CalcompSetupProc( pointer module,
+ pointer options,
+ int *errmaj,
+ int *errmin )
+ {
+ xf86LoaderReqSymLists(reqSymbols, NULL);
+ xf86AddInputDriver(&CALCOMP, module, 0);
+ return (pointer) 1;
+ }
+
+
+
+XF86ModuleData calcompModuleData = { &VersionRec, CalcompSetupProc, NULL };
+
+
+#endif /* XFree86LOADER */
+
+
+
+
+/*****************************************************************************
+ * Function Definitions
+ ****************************************************************************/
+
+
+/*
+ * The TearDownProc may have to be tailored to your device
+ */
+/******************************************************
+static void
+TearDownProc( pointer p )
+{
+ LocalDevicePtr local = (LocalDevicePtr) p;
+ CALCOMPPrivatePtr priv = (CALCOMPPrivatePtr) local->private;
+
+ ErrorF ("Calcomp TearDownProc Called\n");
+
+ DeviceOff (local->dev);
+
+
+ xf86CloseSerial (local->fd);
+ XisbFree (priv->buffer);
+ xfree (priv);
+ xfree (local->name);
+ xfree (local);
+}
+**********************************************************/
+
+
+
+/*
+ * The DeviceControl function should not need to be changed
+ * except to remove ErrorFs
+ */
+static Bool
+DeviceControl (DeviceIntPtr dev, int mode)
+{
+ Bool RetValue;
+
+/* ErrorF ("DeviceControl called mode = %d\n", mode);*/
+ switch (mode)
+ {
+ case DEVICE_INIT:
+/* ErrorF ("\tINIT\n");*/
+ DeviceInit (dev);
+ RetValue = Success;
+ break;
+ case DEVICE_ON:
+/* ErrorF ("\tON\n");*/
+ RetValue = DeviceOn( dev );
+ break;
+ case DEVICE_OFF:
+/* ErrorF ("\tOFF\n");*/
+ RetValue = DeviceOff( dev );
+ break;
+ case DEVICE_CLOSE:
+/* ErrorF ("\tCLOSE\n");*/
+ RetValue = DeviceClose( dev );
+ break;
+ default:
+ ErrorF ("\tBAD MODE\n");
+ RetValue = BadValue;
+ }
+
+ return( RetValue );
+}
+
+/*
+ * The DeviceOn function should not need to be changed
+ */
+static Bool
+DeviceOn (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+
+ AddEnabledDevice (local->fd);
+ dev->public.on = TRUE;
+ return (Success);
+}
+
+/*
+ * The DeviceOff function should not need to be changed
+ */
+static Bool
+DeviceOff (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+
+ RemoveEnabledDevice (local->fd);
+ dev->public.on = FALSE;
+ return (Success);
+}
+
+/*
+ * The DeviceClose function should not need to be changed
+ */
+static Bool
+DeviceClose (DeviceIntPtr dev)
+{
+ return (Success);
+}
+
+/*
+ * The DeviceInit function will need to be tailored to your device
+ */
+static Bool
+DeviceInit (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ CALCOMPPrivatePtr priv = (CALCOMPPrivatePtr) (local->private);
+ unsigned char map[] =
+ {0, 1};
+
+ /*
+ * Set up buttons, valuators etc for your device
+ */
+ if (InitButtonClassDeviceStruct (dev, 1, map) == FALSE)
+ {
+ ErrorF ("Unable to allocate CALCOMP ButtonClassDeviceStruct\n");
+ return !Success;
+ }
+ if (InitFocusClassDeviceStruct (dev) == FALSE) { /* is this necessary? */
+ ErrorF ("Unable to allocate CALCOMP focus class device\n");
+ return !Success;
+ }
+
+ /*
+ * this example device reports motions on 2 axes in absolute coordinates.
+ * Device may reports touch pressure on the 3rd axis.
+ */
+ if (InitValuatorClassDeviceStruct (dev, 3, xf86GetMotionEvents,
+ local->history_size, Absolute) == FALSE)
+ {
+ ErrorF ("Unable to allocate CALCOMP ValuatorClassDeviceStruct\n");
+ return !Success;
+ }
+ else
+ {
+ InitValuatorAxisStruct (dev, 0, priv->min_x, priv->max_x,
+ 39400,
+ 0 /* min_res */ ,
+ 12000 /* max_res */ );
+ InitValuatorAxisStruct (dev, 1, priv->min_y, priv->max_y,
+ 39400,
+ 0 /* min_res */ ,
+ 39400 /* max_res */ );
+
+ InitValuatorAxisStruct (dev, 2, priv->min_z, priv->max_z,
+ 32,
+ 0 /* min_res */ ,
+ 32 /* max_res */ );
+ }
+
+ if (InitProximityClassDeviceStruct (dev) == FALSE)
+ {
+ ErrorF ("unable to allocate CALCOMP ProximityClassDeviceStruct\n");
+ return !Success;
+ }
+
+
+ if (InitPtrFeedbackClassDeviceStruct(dev,
+ ControlProc) == FALSE) {
+ ErrorF("unable to init ptr feedback\n");
+ return !Success;
+ }
+
+ /*
+ * Allocate the motion events buffer.
+ */
+ xf86MotionHistoryAllocate (local);
+ return (Success);
+}
+
+/*
+ * The ReadInput function will have to be tailored to your device
+ */
+static void
+ReadInput (LocalDevicePtr local)
+{
+ int x=0, y=0 , z=0;
+ /*int state;*/
+ int prox,buttons;
+ Bool is_absolute = TRUE; /* FIXME */
+ CALCOMPPrivatePtr priv = (CALCOMPPrivatePtr) (local->private);
+
+ /*
+ * set blocking to -1 on the first call because we know there is data to
+ * read. Xisb automatically clears it after one successful read so that
+ * succeeding reads are preceeded by a select with a 0 timeout to prevent
+ * read from blocking indefinitely.
+ */
+ XisbBlockDuration (priv->buffer, -1);
+ while (CALCOMPGetPacket (priv) == Success)
+ {
+ /*
+ * Examine priv->packet and call these functions as appropriate:
+ *
+ xf86PostProximityEvent
+ xf86PostMotionEvent
+ xf86PostButtonEvent
+ */
+ /* Format of 6 bytes data packet in Calcomp Binary Encoding
+
+ Byte 1
+ bit 7 Phasing bit, always 1
+ bit 6 Buttons on a 16bit cursor
+ bit 5 Button 3
+ bit 4 Button 2
+ bit 3 Button 1
+ bit 2 Button 0 (Stylus tip)
+ bit 1 X15
+ bit 0 X14
+ Byte 2
+ bit 7 Always 0
+ bits 6-0 = X13 - X7
+ Byte 3
+ bit 7 Always 0
+ bits 6-0 = X6 - X0
+ Byte 4
+ bit 7 Always 0
+ bit 6 Proximity
+ bits 3-0 = Y17 - Y14
+ Byte 5
+ bit 7 Always 0
+ bits 6-0 = Y13 - Y7
+ Byte 6
+ bit 7 Always 0
+ bits 6-0 = Y6 - Y0
+ */
+ x = priv->packet[2] + priv->packet[1] * 128
+ +(priv->packet[0] & 0x03) *128*128;
+ y = priv->packet[5] + priv->packet[4]*128 +priv->packet[3]*128*128;
+ y = priv->max_y -y;
+ prox = ((int)priv->packet[3] & PROXIMITY_BIT)? 0: 1;
+
+ buttons = (((int)priv->packet[0] & BUTTON_BITS) >>2);
+ if (buttons && ! priv->pressure ) {
+ if (buttons >15) {
+ buttons = buttons -15;
+ }else{
+ buttons = buttons /2;
+ if (buttons <4 ) buttons = buttons +1;
+ }
+ }else{
+ z = buttons; /* button bits convey pressure data*/
+ if (z >= priv->button_threshold) buttons = 1;
+xf86Msg(X_INFO,"Tablett pressurebutton = %d >= %d\n",z,priv->button_threshold);
+ }
+/*xf86Msg(X_INFO,"Tablett x y prox buttons = %d %d %d %d\n",x,y,prox,buttons);*/
+ if (prox) {
+ if (!(priv->prox)) {
+ xf86PostProximityEvent(local->dev, 1, 0, 2, x, y);
+ }
+
+ if ((is_absolute && ((priv->x != x) || (priv->y != y)))
+ || (!is_absolute && (x || y))) {
+ priv->x = x;
+ priv->y = y;
+
+ if (is_absolute || priv->prox) {
+ xf86PostMotionEvent(local->dev, is_absolute, 0, 3, x, y, z);
+
+ }
+ }
+ if (priv->buttons != buttons) {
+ int delta;
+ int button;
+ delta = buttons - priv->buttons;
+ button = (delta > 0)? delta: ((delta == 0)? priv->buttons : -delta);
+ if (priv->buttons != buttons) {
+ xf86PostButtonEvent(local->dev, is_absolute, button,
+ (delta > 0), 0, 2, x, y);
+ }
+ }
+ priv->buttons = buttons;
+ priv->x = x;
+ priv->y = y;
+ priv->prox = prox;
+ } else { /* !PROXIMITY */
+ /* Any changes in buttons are ignored when !proximity */
+ if (priv->prox) xf86PostProximityEvent(local->dev, 0, 0, 2, x, y);
+ priv->prox = 0;
+ }
+
+ } /* while packets come in */
+}
+
+/*
+ * The ControlProc function may need to be tailored for your device
+ */
+static void
+ControlProc (DeviceIntPtr device, PtrCtrl * control)
+{
+}
+static int
+ChangeControlProc(LocalDevicePtr local, xDeviceCtl *control)
+{
+return(Success);
+}
+/*
+ * the CloseProc should not need to be tailored to your device
+ */
+static void
+CloseProc (LocalDevicePtr local)
+{
+}
+
+/*
+ * The SwitchMode function may need to be tailored for your device
+ */
+static int
+SwitchMode (ClientPtr client, DeviceIntPtr dev, int mode)
+{
+ return (Success);
+}
+
+/*
+ * The ConvertProc function may need to be tailored for your device.
+ * This function converts the device's valuator outputs to x and y coordinates
+ * to simulate mouse events.
+ */
+static Bool
+ConvertProc (LocalDevicePtr local,
+ int first,
+ int num,
+ int v0,
+ int v1,
+ int v2,
+ int v3,
+ int v4,
+ int v5,
+ int *x,
+ int *y)
+{
+CALCOMPPrivatePtr priv=(CALCOMPPrivatePtr) local->private;
+double factorX,factorY;
+
+xf86Msg(X_INFO,"Calcomp ConvertProc called\n");
+if (first !=0 || num == 1) return FALSE;
+
+factorX= ((double) priv->screen_width)
+ /(priv->max_x - priv->min_x);
+factorY= ((double) priv->screen_height)
+ /(priv->max_y - priv->min_y);
+
+ *x = v0*factorX;
+ *y = v1*factorY;
+ return (Success);
+}
+
+/*
+ * the QueryHardware fuction should be tailored to your device to
+ * verify the device is attached and functional and perform any
+ * needed initialization.
+ */
+static Bool
+QueryHardware (int fd, CALCOMPPrivatePtr priv)
+{
+char buffer[255];
+int err;
+
+ SYSCALL(err = write(fd, DB_COMM_SETUP, strlen(DB_COMM_SETUP)));
+ if (err<0) return !Success;
+
+ xf86WaitForInput(-1,500);
+
+ SYSCALL(err = write(fd, DB_UPPER_ORIGIN, strlen(DB_UPPER_ORIGIN)));
+ if (err<0) return !Success;
+
+ xf86WaitForInput(-1,500);
+
+ SYSCALL(err = write(fd, DB_BINARY_FMT, strlen(DB_BINARY_FMT)));
+ if (err<0) return !Success;
+
+ xf86WaitForInput(-1,500);
+
+ SYSCALL(err = write(fd, DB_XINCREMENT, strlen(DB_XINCREMENT)));
+ if (err<0) return !Success;
+
+ xf86WaitForInput(-1,500);
+
+ SYSCALL(err = write(fd, DB_YINCREMENT, strlen(DB_YINCREMENT)));
+ if (err<0) return !Success;
+
+ xf86WaitForInput(-1,500);
+
+ SYSCALL(err = write(fd, DB_1000LPI, strlen(DB_1000LPI)));
+ if (err<0) return !Success;
+
+ xf86WaitForInput(-1,500);
+
+ SYSCALL(err = write(fd, DB_STREAM_MODE, strlen(DB_STREAM_MODE)));
+ if (err<0) return !Success;
+
+ xf86WaitForInput(-1,500);
+ if (priv->pressure)
+ SYSCALL(err = write(fd, DB_PRESSURE_ON, strlen(DB_PRESSURE_ON)));
+ else
+ SYSCALL(err = write(fd, DB_PRESSURE_OFF, strlen(DB_PRESSURE_OFF)));
+ if (err<0) return !Success;
+
+ xf86WaitForInput(-1,500);
+
+ if (!xf86CalWriteAndRead(fd, DB_FIRMID, buffer, 35, 1))
+ return !Success;
+
+ xf86Msg(X_INFO,"Calcomp firmware ID : %s\n", buffer);
+ memset(buffer,32,35);
+
+ xf86WaitForInput(-1,500);
+
+ if (!xf86CalWriteAndRead(fd, DB_PRODID, buffer, 20, 1))
+ return !Success;
+ xf86Msg(X_INFO,"Product ID : %s\n", buffer);
+
+ memset(buffer,32,20);
+
+ xf86WaitForInput(-1,500);
+
+ if (!xf86CalWriteAndRead(fd, DB_CONFIG, buffer, 6, 1))
+ return !Success;
+ priv->max_x = (int)buffer[2] + ((int)buffer[1] << 7)
+ + (((int)buffer[0]&0x03)<<14);
+ priv->max_y = (int)buffer[5] + ((int)buffer[4] << 7);
+
+ xf86Msg(X_INFO,"Tablet size : %d x %d \n", priv->max_x,priv->max_y);
+
+
+ xf86WaitForInput(-1,500);
+
+
+ SYSCALL(err = write(fd, DB_ABSOLUTE, strlen(DB_ABSOLUTE)));
+ if (err<0) return !Success;
+
+
+
+/*
+*/
+ return (Success);
+
+}
+
+static InputInfoPtr
+CalcompPreInit( InputDriverPtr drv,
+ IDevPtr dev, int flags)
+ {
+
+ InputInfoPtr local;
+ CALCOMPPrivatePtr priv = xcalloc (1, sizeof (CALCOMPPrivateRec));
+ char *s;
+
+ if (!(local = xf86AllocateInput(drv, 0)))
+ return NULL;
+
+ xf86Msg (X_INFO,"Calcomp SetupProc called\n");
+ if ((!local) || (!priv))
+ goto SetupProc_fail;
+
+
+ xf86CollectInputOptions(local, default_options, NULL);
+
+ xf86OptionListReport( local->options );
+ local->fd = xf86OpenSerial (local->options);
+
+
+
+
+
+
+
+ if (local->fd == -1)
+ {
+ xf86Msg (X_ERROR,"CALCOMP driver unable to open device\n");
+ goto SetupProc_fail;
+ } else {
+ xf86Msg( X_INFO,"CALCOMP driver: Serial device opened\n");
+ }
+
+ priv->min_x = xf86SetIntOption( local->options, "MinX", 0 );
+ priv->max_x = xf86SetIntOption( local->options, "MaxX", 1000 );
+ priv->min_y = xf86SetIntOption( local->options, "MinY", 0 );
+ priv->max_y = xf86SetIntOption( local->options, "MaxY", 1000 );
+ priv->min_z = xf86SetIntOption( local->options, "MinZ", 0 );
+ priv->max_z = xf86SetIntOption( local->options, "MaxZ", 32 );
+ priv->button_threshold = xf86SetIntOption (local->options, "ButtonThreshold", 16 );
+ priv->pressure = xf86SetIntOption (local->options, "Pressure", 0);
+ priv->untouch_delay = xf86SetIntOption( local->options, "UntouchDelay", 10 );
+ priv->report_delay = xf86SetIntOption( local->options, "ReportDelay", 40 );
+ priv->screen_num = xf86SetIntOption( local->options, "ScreenNumber", 0 );
+ priv->button_number = xf86SetIntOption( local->options, "ButtonNumber", 1 );
+
+ xf86Msg(X_INFO,"options read MaxX=%d, MaxY=%d\n",priv->max_x,priv->max_y);
+
+ s = xf86FindOptionValue (local->options, "ReportingMode");
+ if ((s) && (xf86NameCmp (s, "raw") == 0))
+
+ priv->reporting_mode = TS_Raw;
+ else
+ priv->reporting_mode = TS_Scaled;
+
+ priv->checksum = 0;
+ priv->buffer = XisbNew (local->fd, 200);
+
+ DBG (9, XisbTrace (priv->buffer, 1));
+
+ /*
+ * Verify that your hardware is attached and fuctional if you can
+ */
+ if (QueryHardware (local->fd, priv) != Success)
+ {
+ xf86Msg (X_ERROR,"Unable to query/initialize CALCOMP hardware.\n");
+ goto SetupProc_fail;
+ }else
+ xf86Msg (X_INFO,"Calcomp tablet queried OK\n");
+
+ local->name = xf86SetStrOption( local->options, "DeviceName", "CALCOMP XInput Device");
+ xf86Msg(X_CONFIG," Calcomp device name is %s\n",local->name);
+ /* Set the type that's appropriate for your device
+ * XI_KEYBOARD
+ * XI_MOUSE
+ * XI_TABLET
+ * XI_TOUCHSCREEN
+ * XI_TOUCHPAD
+ * XI_BARCODE
+ * XI_BUTTONBOX
+ * XI_KNOB_BOX
+ * XI_ONE_KNOB
+ * XI_NINE_KNOB
+ * XI_TRACKBALL
+ * XI_QUADRATURE
+ * XI_ID_MODULE
+ * XI_SPACEBALL
+ * XI_DATAGLOVE
+ * XI_EYETRACKER
+ * XI_CURSORKEYS
+ * XI_FOOTMOUSE
+ */
+ local->type_name = XI_TABLET;
+ /*
+ * Standard setup for the local device record
+ */
+ local->device_control = DeviceControl;
+ local->read_input = ReadInput;
+ local->control_proc = ChangeControlProc;
+ local->close_proc = CloseProc;
+ local->switch_mode = SwitchMode;
+ local->conversion_proc = ConvertProc;
+ local->dev = NULL;
+ local->private = priv;
+ local->private_flags = 0;
+ local->history_size = xf86SetIntOption( local->options, "HistorySize", 0 );
+ local->flags |= XI86_CONFIGURED;
+
+ xf86Msg(X_INFO,"Calcomp base setup finished\n");
+ return (local);
+SetupProc_fail:
+ xf86Msg (X_ERROR,"Calcomp setup failed, unloading tablet driver\n");
+/* taken from xf86Wacom*/
+ xfree (priv);
+ xf86DeleteInput(local, 0);
+/* * */
+ return (NULL);
+
+
+ }
+
+/*
+ * This function should be renamed for your device and tailored to handle
+ * your device's protocol.
+ */
+static Bool
+CALCOMPGetPacket (CALCOMPPrivatePtr priv)
+{
+ int count = 0;
+ int c;
+
+ while ((c = XisbRead (priv->buffer)) >= 0)
+ {
+ /*
+ * fail after 500 bytes so the server doesn't hang forever if a
+ * device sends bad data.
+ */
+ if (count++ > 500)
+ return (!Success);
+
+
+ if (c > 127) /* phasing bit set, start of packet */
+ {
+ priv->packeti=0;
+ priv->packet[priv->packeti++] = (unsigned char) c;
+ }
+ else {
+ if (priv->packeti >0 && priv->packeti < CALCOMP_BODY_LEN)
+ priv->packet[priv->packeti++] = (unsigned char) c;
+ if (priv->packeti == CALCOMP_BODY_LEN)
+ {
+ priv->packeti=0;
+ return (Success);
+ }
+ }
+ }
+ return (!Success);
+}
+
+/*
+** xf86CalWriteAndRead
+** Write data, and get the response.
+*/
+static char *
+xf86CalWriteAndRead(int fd, char *data, char *buffer, int len, int cr_term)
+{
+ int err, numread = 0;
+ int retries = 5;
+
+
+
+ xf86FlushInput(fd);
+
+ SYSCALL(err = write(fd, data, strlen(data)));
+ if (err == -1) {
+ xf86Msg(X_ERROR,"Calcomp write");
+ return NULL;
+ }
+do {
+ err=xf86WaitForInput(fd, 2000);
+ if (err < 0 ) {
+ xf86Msg(X_ERROR,"Calcomp select failed\n");
+ return NULL;
+ }
+ retries--;
+ }
+ while (err<1 && retries >0);
+
+if (retries<=0) {
+ xf86Msg(X_WARNING,"Timeout while reading Calcomp tablet. No tablet connected ???\n");
+ return NULL;
+ }
+
+ while (numread < len) {
+ if (err == -1) {
+ xf86Msg(X_ERROR,"Calcomp select");
+ return NULL;
+ }
+
+ SYSCALL(err = read(fd, buffer + numread++, 1));
+ if (err == -1) {
+ xf86Msg(X_ERROR,"Calcomp read");
+ return NULL;
+ }
+ if (!err) {
+ --numread;
+ break;
+ }
+ if (cr_term && buffer[numread - 1] == '\r') {
+ buffer[numread - 1] = 0;
+ break;
+ }
+ }
+ buffer[numread] = 0;
+ return buffer;
+ }
+
diff --git a/xc/programs/Xserver/hw/xfree86/input/calcomp/xf86Calcomp.h b/xc/programs/Xserver/hw/xfree86/input/calcomp/xf86Calcomp.h
new file mode 100644
index 000000000..6a1ed031d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/calcomp/xf86Calcomp.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2000-2001 Martin Kroeker (mk@daveg.com)
+ * code derived from sample driver
+ * Copyright (c) 1998 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/calcomp/xf86Calcomp.h,v 1.1 2001/08/12 22:48:43 alanh Exp $ */
+
+#ifndef _CALCOMP_H_
+#define _CALCOMP_H_
+
+/******************************************************************************
+ * Definitions
+ * structs, typedefs, #defines, enums
+ *****************************************************************************/
+#define CALCOMP_PACKET_SIZE 5
+#define CALCOMP_INIT_CHECKSUM 0
+#define CALCOMP_BODY_LEN 6
+
+
+
+/*************************************************************************/
+#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
+
+#define DB_COMM_SETUP "\033%C1N81\r" /* Serial communication setup */
+#define DB_FIRMID "\033%__V\r" /* Request firmware ID string */
+#define DB_PRODID "\033%__p\r" /* Request product ID string */
+#define DB_CONFIG "\033%VS\r" /* Send configuration (max coords) */
+
+#define DB_ABSOLUTE "\033%IR\r" /* Absolute mode */
+#define DB_RELATIVE "\033%IT\r" /* Relative mode */
+
+#define DB_UPPER_ORIGIN "\033%L1\r" /* Origin upper left */
+#define DB_1000LPI "\033%JR1000,0\r" /* 1000 lines per inch */
+
+#define DB_PROMPT_MODE "\033%Q?\r" /* Prompt mode (untested!) */
+#define DB_STREAM_MODE "\033%IR\r" /* Stream mode */
+#define DB_XINCREMENT "\033%X1\r"
+#define DB_YINCREMENT "\033%Y1\r" /* Set increment to 1 */
+#define DB_BINARY_FMT "\033%^23\r" /* Calcomp binary mode */
+#define DB_PRESSURE_OFF "\033%VA0\r" /* Select button or pressure */
+#define DB_PRESSURE_ON "\033%VA1\r" /* reporting */
+#define DB_PROMPT "?" /* Prompt for current position */
+
+#define PHASING_BIT 0x80
+#define PROXIMITY_BIT 0x20
+#define BUTTON_BITS 0x7c
+#define COORD_BITS 0x7f
+#define tcflush(fd, n) xf86FlushInput((fd))
+#undef read
+#define read(a,b,c) xf86ReadSerial((a),(b),(c))
+#undef write
+#define write(a,b,c) xf86WriteSerial((a),(char*)(b),(c))
+#undef close
+#define close(a) xf86CloseSerial((a))
+
+/*************************************************************************/
+typedef enum
+{
+ CALCOMP_normal, /*CALCOMP_type,*/ CALCOMP_body, CALCOMP_checksum
+}
+CALCOMPState;
+
+#define WORD_ASSEMBLY(byte1, byte2) (((byte2) << 8) | (byte1))
+
+typedef struct _CALCOMPPrivateRec
+{
+ int min_x; /* Minimum x reported by calibration */
+ int max_x; /* Maximum x */
+ int min_y; /* Minimum y reported by calibration */
+ int max_y; /* Maximum y */
+ int min_z;
+ int max_z;
+ int button_threshold; /* Z > button threshold = button click */
+ int pressure; /* 0 or 1, do we need pressure info */
+ int axes;
+ int prox; /* Proximity */
+ int x,y; /* x,y values */
+ int buttons; /* button state */
+ Bool button_down; /* is the "button" currently down */
+ int button_number; /* which button to report */
+ int reporting_mode; /* TS_Raw or TS_Scaled */
+
+ int untouch_delay; /* Delay before reporting an untouch (in ms) */
+ int report_delay; /* Delay between touch report packets */
+
+ int screen_num; /* Screen associated with the device */
+ int screen_width; /* Width of the associated X screen */
+ int screen_height; /* Height of the screen */
+ XISBuffer *buffer;
+ unsigned char packet[CALCOMP_PACKET_SIZE]; /* packet being/just read */
+ int packeti; /* index into packet */
+ unsigned char checksum; /* Current checksum of data in assembly *
+ * buffer */
+ CALCOMPState lex_mode;
+}
+CALCOMPPrivateRec, *CALCOMPPrivatePtr;
+
+/******************************************************************************
+ * Declarations
+ *****************************************************************************/
+static MODULESETUPPROTO( CalcompSetupProc );
+/*static void TearDownProc (pointer p);*/
+static Bool DeviceControl (DeviceIntPtr, int);
+static Bool DeviceOn (DeviceIntPtr);
+static Bool DeviceOff (DeviceIntPtr);
+static Bool DeviceClose (DeviceIntPtr);
+static Bool DeviceInit (DeviceIntPtr);
+static void ReadInput (LocalDevicePtr);
+static void ControlProc (DeviceIntPtr, PtrCtrl *);
+static int ChangeControlProc (LocalDevicePtr, xDeviceCtl *);
+static void CloseProc (LocalDevicePtr);
+static int SwitchMode (ClientPtr, DeviceIntPtr, int);
+static Bool ConvertProc (LocalDevicePtr, int, int, int, int, int, int, int, int, int *, int *);
+static Bool QueryHardware (int , CALCOMPPrivatePtr);
+static Bool CALCOMPGetPacket (CALCOMPPrivatePtr priv);
+static char * xf86CalWriteAndRead(int, char *, char *, int , int );
+static InputInfoPtr CalcompPreInit(InputDriverPtr, IDevPtr, int) ;
+/*
+ * DO NOT PUT ANYTHING AFTER THIS ENDIF
+ */
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/input/dmc/Imakefile b/xc/programs/Xserver/hw/xfree86/input/dmc/Imakefile
new file mode 100644
index 000000000..e61fe57a3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/dmc/Imakefile
@@ -0,0 +1,30 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/dmc/Imakefile,v 1.1 2001/08/17 13:27:55 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = xf86DMC.c
+OBJS = xf86DMC.o
+
+DRIVER = dmc
+
+INCLUDES = -I. -I$(XF86COMSRC) -I../../loader -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget($(DRIVER),$(OBJS))
+
+InstallObjectModule($(DRIVER),$(MODULEDIR),input)
+
+#if !defined(XF86DriverSDK)
+InstallModuleManPage($(DRIVER))
+#endif
+
+DependTarget()
+
+InstallDriverSDKObjectModule($(DRIVER),$(DRIVERSDKMODULEDIR),input)
diff --git a/xc/programs/Xserver/hw/xfree86/input/dmc/dmc.man b/xc/programs/Xserver/hw/xfree86/input/dmc/dmc.man
new file mode 100644
index 000000000..f1e3bf1f9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/dmc/dmc.man
@@ -0,0 +1,39 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/input/dmc/dmc.man,v 1.1 2001/08/17 13:27:55 dawes Exp $
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH DMC __drivermansuffix__ __vendorversion__
+.SH NAME
+dmc \- DMC input driver
+.SH SYNOPSIS
+.B "Section \*qInputDevice\*q"
+.br
+.BI " Identifier \*q" idevname \*q
+.br
+.B " Driver \*qdmc\*q"
+.br
+.BI " Option \*qDevice\*q \*q" devpath \*q
+.br
+\ \ ...
+.br
+.B EndSection
+.SH DESCRIPTION
+.B dmc
+is an XFree86 input driver for DMC FIT10-controller...
+.PP
+The
+.B dmc
+driver functions as a pointer input device, and may be used as the
+X server's core pointer.
+THIS MAN PAGE NEEDS TO BE FILLED IN.
+.SH SUPPORTED HARDWARE
+What is supported...
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details and for options that can be used with all input drivers. This
+section only covers configuration details specific to this driver.
+.PP
+Config details...
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__).
+.SH AUTHORS
+Authors include...
diff --git a/xc/programs/Xserver/hw/xfree86/input/dmc/xf86DMC.c b/xc/programs/Xserver/hw/xfree86/input/dmc/xf86DMC.c
new file mode 100644
index 000000000..b28941787
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/dmc/xf86DMC.c
@@ -0,0 +1,692 @@
+/*
+ * Copyright (c) 1999 Machine Vision Holdings Incorporated
+ * Author: Mayk Langer <langer@vsys.de>
+ *
+ * Template driver used: Copyright (c) 1998 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, cpy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/dmc/xf86DMC.c,v 1.1 2001/08/17 13:27:55 dawes Exp $ */
+
+#define _DMC_C_
+
+#include <misc.h>
+#include <xf86.h>
+#define NEED_XF86_TYPES
+#include <xf86_ansic.h>
+#include <xf86_OSproc.h>
+#include <xf86Xinput.h>
+#include <xisb.h>
+#include <exevents.h>
+
+#include "xf86DMC.h"
+
+InputDriverRec DMC = {
+ 1,
+ "dmc",
+ NULL,
+ DMCPreInit,
+ /*DMCUnInit*/NULL,
+ NULL,
+ 0
+};
+
+
+
+#ifdef XFree86LOADER
+
+static XF86ModuleVersionInfo VersionRec =
+{
+ "dmc",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_XINPUT,
+ ABI_XINPUT_VERSION,
+ MOD_CLASS_XINPUT,
+ {0, 0, 0, 0} /* signature, to be patched into the file by
+ * a tool */
+};
+
+
+static const char *reqSymbols[] = {
+ "AddEnabledDevice",
+ "ErrorF",
+ "InitButtonClassDeviceStruct",
+ "InitProximityClassDeviceStruct",
+ "InitValuatorAxisStruct",
+ "InitValuatorClassDeviceStruct",
+ "InitPtrFeedbackClassDeviceStruct",
+ "RemoveEnabledDevice",
+ "Xcalloc",
+ "Xfree",
+ "XisbBlockDuration",
+ "XisbFree",
+ "XisbNew",
+ "XisbRead",
+ "XisbTrace",
+ "screenInfo",
+ "xf86AddInputDriver",
+ "xf86AllocateInput",
+ "xf86CloseSerial", /* first one */
+ "xf86CollectInputOptions",
+ "xf86ErrorFVerb",
+ "xf86FindOptionValue",
+ "xf86GetMotionEvents",
+ "xf86GetVerbosity",
+ "xf86MotionHistoryAllocate",
+ "xf86NameCmp",
+ "xf86OpenSerial",
+ "xf86CloseSerial", /* second one ? */
+ "xf86OptionListCreate",
+ "xf86OptionListMerge",
+ "xf86OptionListReport",
+ "xf86PostButtonEvent",
+ "xf86PostMotionEvent",
+ "xf86PostProximityEvent",
+ "xf86ProcessCommonOptions",
+ "xf86RemoveLocalDevice",
+ "xf86ScaleAxis",
+ "xf86SetIntOption",
+ "xf86SetStrOption",
+ "xf86XInputSetScreen",
+ "xf86XInputSetSendCoreEvents",
+ NULL
+};
+
+
+static pointer
+DMCSetupProc( pointer module,
+ pointer options,
+ int *errmaj,
+ int *errmin )
+{
+ xf86LoaderReqSymLists(reqSymbols, NULL);
+ xf86AddInputDriver(&DMC, module, 0);
+ return (pointer) 1;
+}
+
+XF86ModuleData dmcModuleData = { &VersionRec, DMCSetupProc, NULL };
+
+
+#endif /* XFree86LOADER */
+
+
+/*
+ * Be sure to set vmin appropriately for your device's protocol. You want to
+ * read a full packet before returning
+ */
+static const char *default_options[] =
+{
+ /* "Device", "/dev/ttyS1",*/
+ "BaudRate", "9600",
+ "StopBits", "1",
+ "DataBits", "8",
+ "Parity", "None",
+ "Vmin", "3",
+ "Vtime", "1",
+ "FlowControl", "None",
+ NULL,
+};
+
+
+/*****************************************************************************
+ * Function Definitions
+ ****************************************************************************/
+
+
+
+static InputInfoPtr
+DMCPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
+{
+ InputInfoPtr pInfo;
+ DMCPrivatePtr priv = xcalloc (1, sizeof (DMCPrivateRec));
+ char *s;
+
+ if (!priv)
+ return NULL;
+
+ if (!(pInfo = xf86AllocateInput(drv, 0))) {
+ xfree(priv);
+ return NULL;
+ }
+
+ priv->min_x = 0;
+ priv->max_x = 1024;
+ priv->min_y = 768;
+ priv->max_y = 0;
+ priv->screen_num = 0;
+ priv->screen_width = -1;
+ priv->screen_height = -1;
+ priv->lex_mode = DMC_byte0;
+ priv->swap_xy = 0;
+ priv->button_down = FALSE;
+ priv->button_number = 1;
+ priv->proximity = FALSE;
+ priv->pen_down = 0;
+
+ pInfo->type_name = XI_TOUCHSCREEN;
+ pInfo->device_control = DeviceControl;
+ pInfo->read_input = ReadInput;
+ pInfo->control_proc = ControlProc;
+ pInfo->close_proc = CloseProc;
+ pInfo->switch_mode = SwitchMode;
+ pInfo->conversion_proc = ConvertProc;
+ pInfo->dev = NULL;
+ pInfo->private = priv;
+ pInfo->private_flags = 0;
+ pInfo->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
+ pInfo->conf_idev = dev;
+
+ xf86CollectInputOptions(pInfo, default_options, NULL);
+
+ xf86OptionListReport( pInfo->options );
+
+ pInfo->fd = xf86OpenSerial (pInfo->options);
+ if (pInfo->fd == -1)
+ {
+ ErrorF ("DMC driver unable to open device\n");
+ goto SetupProc_fail;
+ }
+ xf86CloseSerial(pInfo->fd);
+ /*
+ * Process the options for your device like this
+ */
+ priv->min_x = xf86SetIntOption( pInfo->options, "MinX", 0 );
+ priv->max_x = xf86SetIntOption( pInfo->options, "MaxX", 1024 );
+ priv->min_y = xf86SetIntOption( pInfo->options, "MinY", 768 );
+ priv->max_y = xf86SetIntOption( pInfo->options, "MaxY", 0 );
+ priv->screen_num = xf86SetIntOption( pInfo->options, "ScreenNumber", 0 );
+ priv->button_number = xf86SetIntOption( pInfo->options, "ButtonNumber", 1 );
+ priv->swap_xy = xf86SetIntOption( pInfo->options, "SwapXY", 0 );
+ priv->buffer = NULL;
+ s = xf86FindOptionValue (pInfo->options, "ReportingMode");
+ if ((s) && (xf86NameCmp (s, "raw") == 0))
+ priv->reporting_mode = TS_Raw;
+ else
+ priv->reporting_mode = TS_Scaled;
+
+ priv->proximity = FALSE;
+ priv->button_down = FALSE;
+ priv->lex_mode = DMC_byte0;
+
+ if (QueryHardware (priv) != Success)
+ {
+ ErrorF ("Unable to query/initialize DMC hardware.\n");
+ goto SetupProc_fail;
+ }
+
+ /* this results in an xstrdup that must be freed later */
+ pInfo->name = xf86SetStrOption( pInfo->options, "DeviceName", "DMC");
+ xf86ProcessCommonOptions(pInfo, pInfo->options);
+
+ pInfo->flags |= XI86_CONFIGURED;
+ return (pInfo);
+
+ SetupProc_fail:
+ if ((pInfo) && (pInfo->fd))
+ xf86CloseSerial (pInfo->fd);
+ if ((pInfo) && (pInfo->name))
+ xfree (pInfo->name);
+
+ if ((priv) && (priv->buffer))
+ XisbFree (priv->buffer);
+ if (priv)
+ xfree (priv);
+ return (pInfo);
+}
+
+static Bool
+DeviceControl (DeviceIntPtr dev, int mode)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ DMCPrivatePtr priv = (DMCPrivatePtr) (pInfo->private);
+ unsigned char map[] =
+ {0, 1};
+
+ switch (mode)
+ {
+ case DEVICE_INIT:
+ /*
+ * these have to be here instead of in the SetupProc, because when the
+ * SetupProc is run at server startup, screenInfo is not setup yet
+ */
+ priv->screen_width = screenInfo.screens[priv->screen_num]->width;
+ priv->screen_height = screenInfo.screens[priv->screen_num]->height;
+
+ /*
+ * Device reports button press for 1 button.
+ */
+ if (InitButtonClassDeviceStruct (dev, 1, map) == FALSE)
+ {
+ ErrorF ("Unable to allocate DMC ButtonClassDeviceStruct\n");
+ return !Success;
+ }
+
+ /*
+ * Device reports motions on 2 axes in absolute coordinates.
+ * Axes min and max values are reported in raw coordinates.
+ */
+ if (InitValuatorClassDeviceStruct (dev, 2, xf86GetMotionEvents,
+ pInfo->history_size, Absolute) == FALSE)
+ {
+ ErrorF ("Unable to allocate DMC ValuatorClassDeviceStruct\n");
+ return !Success;
+ }
+ else
+ {
+ InitValuatorAxisStruct (dev, 0, priv->min_x, priv->max_x,
+ 9500,
+ 0 /* min_res */ ,
+ 9500 /* max_res */ );
+ InitValuatorAxisStruct (dev, 1, priv->min_y, priv->max_y,
+ 10500,
+ 0 /* min_res */ ,
+ 10500 /* max_res */ );
+ }
+
+ if (InitProximityClassDeviceStruct (dev) == FALSE)
+ {
+ ErrorF ("unable to allocate DMC ProximityClassDeviceStruct\n");
+ return !Success;
+ }
+
+ if (InitPtrFeedbackClassDeviceStruct(dev, DMCPtrCtrl) == FALSE)
+ {
+ ErrorF ("unable to allocate DMC PtrFeedbackClassDeviceStruct\n");
+ return !Success;
+ }
+
+ /*
+ * Allocate the motion events buffer.
+ */
+ xf86MotionHistoryAllocate (pInfo);
+ return (Success);
+
+ case DEVICE_ON:
+ pInfo->fd = xf86OpenSerial(pInfo->options);
+ if (pInfo->fd == -1)
+ {
+ xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
+ return (!Success);
+ }
+ else
+ {
+ priv->buffer = XisbNew(pInfo->fd, 64);
+ if (!priv->buffer)
+ {
+ xf86CloseSerial(pInfo->fd);
+ pInfo->fd = -1;
+ return (!Success);
+ }
+ else
+ {
+ unsigned char buf[2] = { 0x05, 0x40 };
+
+ sleep(1); /* touch need ca. 500ms delay !!! */
+ XisbBlockDuration (priv->buffer, 500000);
+ if ( DMCSendPacket(priv, buf, 2) == Success )
+ {
+ /* wait for right response */
+ priv->lex_mode = DMC_Response0;
+ if (DMCGetPacket (priv) == Success )
+ {
+ if ( priv->packet[0] == 0x06 )
+ {
+ buf[0] = 0x31;
+ DMCSendPacket(priv,buf,1);
+ priv->lex_mode = DMC_Response0;
+ xf86Msg(X_ERROR, "DMC-Touch found\n");
+ }
+ else
+ {
+ xf86Msg(X_ERROR, "DMC-Touch found\n");
+ return (!Success);
+ }
+ }
+ else
+ {
+ xf86Msg(X_ERROR, "DMC-Touch found\n");
+ return (!Success);
+ }
+ }
+ else
+ {
+ xf86Msg(X_ERROR, "DMC-Touch found\n");
+ return (!Success);
+ }
+ }
+ }
+
+ XisbBlockDuration (priv->buffer, -1);
+ priv->lex_mode = DMC_byte0;
+
+ xf86FlushInput(pInfo->fd);
+ AddEnabledDevice (pInfo->fd);
+ dev->public.on = TRUE;
+ return (Success);
+
+ case DEVICE_OFF:
+ case DEVICE_CLOSE:
+ if (pInfo->fd != -1)
+ {
+ RemoveEnabledDevice (pInfo->fd);
+ if (priv->buffer)
+ {
+ XisbFree(priv->buffer);
+ priv->buffer = NULL;
+ }
+ xf86CloseSerial(pInfo->fd);
+ }
+ dev->public.on = FALSE;
+ return (Success);
+ default:
+ return (BadValue);
+ }
+
+}
+
+
+/*
+ * The ReadInput function will have to be tailored to your device
+ */
+static void
+ReadInput (InputInfoPtr pInfo)
+{
+ DMCPrivatePtr priv = (DMCPrivatePtr) (pInfo->private);
+ int x,y;
+ unsigned char opck[ DMC_PACKET_SIZE ];
+
+ /*
+ * set blocking to -1 on the first call because we know there is data to
+ * read. Xisb automatically clears it after one successful read so that
+ * succeeding reads are preceeded buy a select with a 0 timeout to prevent
+ * read from blocking indefinately.
+ */
+ XisbBlockDuration (priv->buffer, -1);
+ while (1)
+ {
+ memcpy(opck,priv->packet,5);
+
+ if ( DMCGetPacket (priv) != Success)
+ break;
+ if ( priv->packet[0] == 0x11 )
+ priv->pen_down=1;
+ else
+ priv->pen_down=0;
+
+ if ( priv->swap_xy)
+ {
+ y = priv->packet[1]*256+priv->packet[2];
+ x = priv->packet[3]*256+priv->packet[4];
+ }
+ else
+ {
+ x = priv->packet[1]*256+priv->packet[2];
+ y = priv->packet[3]*256+priv->packet[4];
+ }
+ priv->packet[0] = priv->pen_down ? 0x01 : 0x00;
+
+ if (priv->reporting_mode == TS_Scaled)
+ {
+ x = xf86ScaleAxis (x, 0, priv->screen_width, priv->min_x,
+ priv->max_x);
+ y = xf86ScaleAxis (y, 0, priv->screen_height, priv->min_y,
+ priv->max_y);
+ }
+
+ xf86XInputSetScreen (pInfo, priv->screen_num, x, y);
+
+ if ((priv->proximity == FALSE) && (priv->packet[0] & 0x01))
+ {
+ priv->proximity = TRUE;
+ xf86PostProximityEvent (pInfo->dev, 1, 0, 2, x, y);
+ }
+
+ /*
+ * Send events.
+ *
+ * We *must* generate a motion before a button change if pointer
+ * location has changed as DIX assumes this. This is why we always
+ * emit a motion, regardless of the kind of packet processed.
+ */
+
+ xf86PostMotionEvent (pInfo->dev, TRUE, 0, 2, x, y);
+
+ /*
+ * Emit a button press or release.
+ */
+ if ((priv->button_down == FALSE) && (priv->packet[0] & 0x01))
+
+ {
+ xf86PostButtonEvent (pInfo->dev, TRUE,
+ priv->button_number, 1, 0, 2, x, y);
+ priv->button_down = TRUE;
+ }
+ if ((priv->button_down == TRUE) && !(priv->packet[0] & 0x01))
+ {
+ xf86PostButtonEvent (pInfo->dev, TRUE,
+ priv->button_number, 0, 0, 2, x, y);
+ priv->button_down = FALSE;
+ }
+ /*
+ * the untouch should always come after the button release
+ */
+ if ((priv->proximity == TRUE) && !(priv->packet[0] & 0x01))
+ {
+ priv->proximity = FALSE;
+ xf86PostProximityEvent (pInfo->dev, 0, 0, 2, x, y);
+ }
+ }
+}
+
+/*
+ * The ControlProc function may need to be tailored for your device
+ */
+static int
+ControlProc (InputInfoPtr pInfo, xDeviceCtl * control)
+{
+ xDeviceTSCalibrationCtl *c = (xDeviceTSCalibrationCtl *) control;
+ DMCPrivatePtr priv = (DMCPrivatePtr) (pInfo->private);
+
+ priv->min_x = c->min_x;
+ priv->max_x = c->max_x;
+ priv->min_y = c->min_y;
+ priv->max_y = c->max_y;
+
+ return (Success);
+}
+
+/*
+ * the CloseProc should not need to be tailored to your device
+ */
+static void
+CloseProc (InputInfoPtr pInfo)
+{
+
+}
+
+/*
+ * The SwitchMode function may need to be tailored for your device
+ */
+static int
+SwitchMode (ClientPtr client, DeviceIntPtr dev, int mode)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ DMCPrivatePtr priv = (DMCPrivatePtr) (pInfo->private);
+
+
+ if ((mode == TS_Raw) || (mode == TS_Scaled))
+ {
+ priv->reporting_mode = mode;
+ return (Success);
+ }
+ else if ((mode == SendCoreEvents) || (mode == DontSendCoreEvents))
+ {
+ xf86XInputSetSendCoreEvents (pInfo, (mode == SendCoreEvents));
+ return (Success);
+ }
+ else
+ return (!Success);
+}
+
+/*
+ * The ConvertProc function may need to be tailored for your device.
+ * This function converts the device's valuator outputs to x and y coordinates
+ * to simulate mouse events.
+ */
+static Bool
+ConvertProc (InputInfoPtr pInfo,
+ int first,
+ int num,
+ int v0,
+ int v1,
+ int v2,
+ int v3,
+ int v4,
+ int v5,
+ int *x,
+ int *y)
+{
+ DMCPrivatePtr priv = (DMCPrivatePtr) (pInfo->private);
+
+ if (priv->reporting_mode == TS_Raw)
+ {
+ *x = xf86ScaleAxis (v0, 0, priv->screen_width, priv->min_x,
+ priv->max_x);
+ *y = xf86ScaleAxis (v1, 0, priv->screen_height, priv->min_y,
+ priv->max_y);
+ }
+ else
+ {
+ *x = v0;
+ *y = v1;
+ }
+ return (TRUE);
+}
+
+/*
+ * the QueryHardware fuction should be tailored to your device to
+ * verify the device is attached and functional and perform any
+ * needed initialization.
+ */
+static Bool
+QueryHardware (DMCPrivatePtr priv)
+{
+ /* Maybe once we get the hardware to actually respond correctly to its
+ configuration 'packets' */
+
+ return (Success);
+}
+
+/*
+ * This function should be renamed for your device and tailored to handle
+ * your device's protocol.
+ */
+static Bool
+DMCGetPacket (DMCPrivatePtr priv)
+{
+ int count = 0;
+ int c;
+
+ while ((c = XisbRead (priv->buffer)) >= 0)
+ {
+ /*
+ * fail after 500 bytes so the server doesn't hang forever if a
+ * device sends bad data.
+ */
+ if (count++ > 500)
+ return (!Success);
+
+ switch (priv->lex_mode)
+ {
+ case DMC_byte0:
+ if ((( c & 0x3f ) != 0x11 ) &&
+ (( c & 0x3f ) != 0x10 ))
+ return (!Success);
+
+ priv->packet[0] = (unsigned char) c & 0x3f;
+ priv->lex_mode = DMC_byte1;
+ break;
+
+ case DMC_byte1:
+ priv->packet[1] = (unsigned char) c;
+ priv->lex_mode = DMC_byte2;
+ break;
+
+ case DMC_byte2:
+ priv->packet[2] = (unsigned char) c;
+ priv->lex_mode = DMC_byte3;
+ break;
+
+ case DMC_byte3:
+ priv->packet[3] = (unsigned char) c;
+ priv->lex_mode = DMC_byte4;
+ break;
+
+ case DMC_byte4:
+ priv->packet[4] = (unsigned char) c;
+ priv->lex_mode = DMC_byte0;
+ return (Success);
+ break;
+
+ case DMC_Response0:
+ priv->packet[0] = (unsigned char) c;
+ return (Success);
+ break;
+
+ }
+ }
+ return (!Success);
+}
+
+static Bool
+DMCSendPacket (DMCPrivatePtr priv, unsigned char *buf, int len)
+{
+ int count = 0;
+
+ while ( len > 0 )
+ {
+ if ( XisbWrite(priv->buffer, buf, 1) == 1 )
+ {
+ buf++;
+ len--;
+ continue;
+ }
+ if ( count++ > 500 )
+ break;
+ }
+ return (len ? !Success : Success);
+}
+
+static void
+DMCPtrCtrl(DeviceIntPtr device, PtrCtrl *ctrl)
+{
+ /* I have no clue what this does, except that registering it stops the
+ X server segfaulting in ProcGetPointerMapping()
+ Ho Hum.
+ */
+}
diff --git a/xc/programs/Xserver/hw/xfree86/input/dmc/xf86DMC.h b/xc/programs/Xserver/hw/xfree86/input/dmc/xf86DMC.h
new file mode 100644
index 000000000..588e970ad
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/dmc/xf86DMC.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1999 Machine Vision Holdings Incorporated
+ * Author: Mayk Langer <langer@vsys.de>
+ *
+ * Template driver used: Copyright (c) 1998 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/dmc/xf86DMC.h,v 1.1 2001/08/17 13:27:55 dawes Exp $ */
+
+#ifndef _DMC_H_
+#define _DMC_H_
+
+/******************************************************************************
+ * Definitions
+ * structs, typedefs, #defines, enums
+ *****************************************************************************/
+
+#define DMC_PACKET_SIZE 5
+
+typedef enum
+{
+ DMC_byte0, DMC_byte1, DMC_byte2, DMC_byte3, DMC_byte4,
+ DMC_Response0
+}
+DMCState;
+
+
+typedef struct _DMCPrivateRec
+{
+ int min_x; /* Minimum x reported by calibration */
+ int max_x; /* Maximum x */
+ int min_y; /* Minimum y reported by calibration */
+ int max_y; /* Maximum y */
+ Bool button_down; /* is the "button" currently down */
+ int button_number; /* which button to report */
+ int reporting_mode; /* TS_Raw or TS_Scaled */
+
+ int screen_num; /* Screen associated with the device */
+ int screen_width; /* Width of the associated X screen */
+ int screen_height; /* Height of the screen */
+ int proximity;
+ int swap_xy;
+ XISBuffer *buffer;
+ unsigned char packet[DMC_PACKET_SIZE]; /* packet being/just read */
+ DMCState lex_mode;
+ char pen_down;
+}
+DMCPrivateRec, *DMCPrivatePtr;
+
+/******************************************************************************
+ * Declarations
+ *****************************************************************************/
+
+static Bool DeviceControl (DeviceIntPtr, int);
+static void ReadInput (InputInfoPtr);
+static int ControlProc (InputInfoPtr, xDeviceCtl *);
+static void CloseProc (InputInfoPtr);
+static int SwitchMode (ClientPtr, DeviceIntPtr, int);
+static Bool ConvertProc (InputInfoPtr, int, int, int, int, int, int, int, int, int *, int *);
+static Bool QueryHardware (DMCPrivatePtr);
+static Bool DMCGetPacket (DMCPrivatePtr priv);
+static Bool DMCSendPacket (DMCPrivatePtr priv, unsigned char *buf, int len );
+
+static InputInfoPtr
+DMCPreInit(InputDriverPtr drv, IDevPtr dev, int flags);
+
+static void
+DMCPtrCtrl(DeviceIntPtr device, PtrCtrl *ctrl);
+
+
+#endif /* _DMC_H_ */
diff --git a/xc/programs/Xserver/hw/xfree86/input/magictouch/Imakefile b/xc/programs/Xserver/hw/xfree86/input/magictouch/Imakefile
new file mode 100644
index 000000000..81d048c23
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/magictouch/Imakefile
@@ -0,0 +1,30 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/magictouch/Imakefile,v 1.1 2001/07/03 15:13:57 paulo Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = xf86MagicTouch.c
+OBJS = xf86MagicTouch.o
+
+DRIVER = magictouch
+
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86SRC)/loader -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(SERVERSRC)/mi -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget($(DRIVER),$(OBJS))
+
+InstallObjectModule($(DRIVER),$(MODULEDIR),input)
+
+#if !defined(XF86DriverSDK)
+InstallModuleManPage($(DRIVER))
+#endif
+
+DependTarget()
+
+InstallDriverSDKObjectModule($(DRIVER),$(DRIVERSDKMODULEDIR),input)
diff --git a/xc/programs/Xserver/hw/xfree86/input/magictouch/magictouch.man b/xc/programs/Xserver/hw/xfree86/input/magictouch/magictouch.man
new file mode 100644
index 000000000..29a78a47f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/magictouch/magictouch.man
@@ -0,0 +1,25 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/input/magictouch/magictouch.man,v 1.1 2001/07/03 15:13:57 paulo Exp $
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH VOID __drivermansuffix__ __vendorversion__
+.SH NAME
+void \- null input driver
+.SH SYNOPSIS
+.nf
+.B "Section \*qInputDevice\*q"
+.BI " Identifier \*q" idevname \*q
+.B " Driver \*qmagictouch\*q"
+\ \ ...
+.B EndSection
+.fi
+.SH DESCRIPTION
+.B magictouch
+is an XFree86 input driver.
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details and for options that can be used with all input drivers. This
+driver doesn't have any configuration options in addition to those.
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86cfg(1), xf86config(1), Xserver(1), X(__miscmansuffix__).
+.SH AUTHORS
+Authors include...
diff --git a/xc/programs/Xserver/hw/xfree86/input/magictouch/xf86MagicTouch.c b/xc/programs/Xserver/hw/xfree86/input/magictouch/xf86MagicTouch.c
new file mode 100644
index 000000000..4154512c3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/magictouch/xf86MagicTouch.c
@@ -0,0 +1,1107 @@
+/*
+ * $XFree86: xc/programs/Xserver/hw/xfree86/input/magictouch/xf86MagicTouch.c,v 1.2 2001/07/04 13:38:09 tsi Exp $
+ */
+
+#include <xf86Version.h>
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(3,9,0,0,0)
+#define XFREE86_V4
+#endif
+
+#ifdef XFREE86_V4
+
+#ifndef XFree86LOADER
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#endif
+
+#include <misc.h>
+#include <xf86.h>
+#if !defined(DGUX)
+#include <xf86_ansic.h>
+#endif
+#include <xf86_OSproc.h>
+#include <xf86Xinput.h>
+#include <exevents.h>
+
+#ifdef XFree86LOADER
+#include <xf86Module.h>
+#endif
+
+#else /* XFREE86_V4 */
+
+#include "Xos.h"
+#include <signal.h>
+#include <stdio.h>
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+
+#include "XI.h"
+#include "XIproto.h"
+
+#if defined(sun) && !defined(i386)
+#include <errno.h>
+#include <termio.h>
+#include <fcntl.h>
+#include <ctype.h>
+
+#include "extio.h"
+#else /* defined(sun) && !defined(i386) */
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Procs.h"
+#include "xf86_OSlib.h"
+#include "xf86_Config.h"
+#include "xf86Xinput.h"
+#include "xf86Version.h"
+#endif /* defined(sun) && !defined(i386) */
+
+#if !defined(sun) || defined(i386)
+#include "os.h"
+#include "osdep.h"
+#include "exevents.h"
+
+#include "extnsionst.h"
+#include "extinit.h"
+#endif /* !defined(sun) || defined(i386) */
+
+#endif /* XFREE86_V4 */
+
+
+#ifndef XFREE86_V4
+#if !defined(sun) || defined(i386)
+/*
+ ***************************************************************************
+ *
+ * Configuration descriptor.
+ *
+ ***************************************************************************
+ */
+
+#define PORT 1
+#define MAGIC_DEVICE_NAME 2
+#define SCREEN_NO 3
+#define MAXX 4
+#define MAXY 5
+#define MINX 6
+#define MINY 7
+#define DEBUG_LEVEL 8
+#define HISTORY_SIZE 9
+#define LINK_SPEED 10
+#define ALWAYS_CORE 11
+#define SWAP_AXES 12
+#define N_SAMPLE_X 13
+#define N_SAMPLE_Y 14
+
+static SymTabRec MagicTab[] = {
+ { ENDSUBSECTION, "endsubsection" },
+ { PORT, "port" },
+ { MAGIC_DEVICE_NAME, "devicename" },
+ { SCREEN_NO, "screenno" },
+ { MAXX, "maximumxposition" },
+ { MAXY, "maximumyposition" },
+ { MINX, "minimumxposition" },
+ { MINY, "minimumyposition" },
+ { DEBUG_LEVEL, "debuglevel" },
+ { HISTORY_SIZE, "historysize" },
+ { LINK_SPEED, "linkspeed" },
+ { ALWAYS_CORE, "alwayscore" },
+ { SWAP_AXES, "swapxy" },
+ { N_SAMPLE_X, "numsamplex" },
+ { N_SAMPLE_Y, "numsampley" },
+ { -1, "" },
+};
+
+
+#define LS1200 1
+#define LS2400 2
+#define LS4800 3
+#define LS9600 4
+
+static SymTabRec LinkSpeedTab[] = {
+ { LS1200, "b1200" },
+ { LS2400, "b2400" },
+ { LS4800, "b4800" },
+ { LS9600, "b9600" }
+};
+#endif /* !defined(sun) || defined(i386) */
+
+/*
+ * This struct connects a line speed with
+ * a compatible motion packet delay. The
+ * driver will attempt to enforce a correct
+ * delay (according to this table) in order to
+ * avoid losing data in the touchscreen controller.
+ * LinkSpeedValues should be kept in sync with
+ * LinkSpeedTab.
+ */
+typedef struct {
+ int speed;
+ int delay;
+} LinkParameterStruct;
+
+static LinkParameterStruct LinkSpeedValues[] = {
+ { B1200, 8 },
+ { B2400, 4 },
+ { B4800, 2 },
+ { B9600, 1 }
+};
+#endif /* XFREE86_V4 */
+
+
+/*
+ ***************************************************************************
+ *
+ * Default constants.
+ *
+ ***************************************************************************
+ */
+#define MAGIC_PACKET_SIZE 5
+#define MAGIC_PORT "/dev/magictouch"
+#define MAGIC_LINK_SPEED B9600
+
+/* First byte of the packet */
+#define MGCT_TOUCH 0x01
+#define MGCT_RKEY 0x02
+#define MGCT_LKEY 0x04
+#define MGCT_MKEY 0x08
+#define MGCT_CLICK_STATUS 0x10
+
+#define MEDIE_X 20
+#define MEDIE_Y 20
+
+
+/*
+ ***************************************************************************
+ *
+ * Usefull macros.
+ *
+ ***************************************************************************
+ */
+#define WORD_ASSEMBLY(byte1, byte2) (((byte2) << 8) | (byte1))
+#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
+
+/* This one is handy, thanx Fred ! */
+#ifdef DBG
+#undef DBG
+#endif
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+static int debug_level = 0;
+#define DEBUG 1
+#if DEBUG
+#define DBG(lvl, f) {if ((lvl) == debug_level) { f; } }
+#else
+#define DBG(lvl, f)
+#endif
+
+
+#ifdef XFREE86_V4
+#undef SYSCALL
+#undef read
+#undef write
+#undef close
+#undef strdup
+#define SYSCALL(call) call
+#define read(fd, ptr, num) xf86ReadSerial(fd, ptr, num)
+#define write(fd, ptr, num) xf86WriteSerial(fd, ptr, num)
+#define close(fd) xf86CloseSerial(fd)
+#define strdup(str) xf86strdup(str)
+#endif
+
+
+
+
+
+
+/*
+ ***************************************************************************
+ *
+ * Device private records.
+ *
+ ***************************************************************************
+ */
+typedef struct _MagicPrivateRec {
+ char *input_dev; /* The touchscreen input tty */
+ int min_x; /* Minimum x reported by calibration */
+ int max_x; /* Maximum x */
+ int min_y; /* Minimum y reported by calibration */
+ int max_y; /* Maximum y */
+#ifndef XFREE86_V4
+ int link_speed; /* Speed of the RS232 link connecting the ts. */
+#endif
+ int screen_no; /* Screen associated with the device */
+ int screen_width; /* Width of the associated X screen */
+ int screen_height; /* Height of the screen */
+ int swap_axes; /* Swap X an Y axes if != 0 */
+ unsigned char packet_buf[MAGIC_PACKET_SIZE]; /* Assembly buffer */
+ int packet_pos;
+ int buf_x[MEDIE_X], i_x, num_medie_x;
+ int buf_y[MEDIE_Y], i_y, num_medie_y;
+ Bool first_x, first_y;
+ Bool first_entry;
+ Bool e_presente;
+ Bool click_on;
+} MagicPrivateRec, *MagicPrivatePtr;
+
+
+#ifndef XFREE86_V4
+#if !defined(sun) || defined(i386)
+/*
+ ****************************************************************************
+ * xf86MagicConfig --
+ * Configure the device driver from configuration data
+ ****************************************************************************
+ */
+static Bool
+xf86MagicConfig(LocalDevicePtr *array,
+ int inx,
+ int max,
+ LexPtr val)
+{
+ LocalDevicePtr local = array[inx];
+ MagicPrivatePtr priv = (MagicPrivatePtr)(local->private);
+ int token;
+
+ while ((token = xf86GetToken(MagicTab)) != ENDSUBSECTION) {
+ switch(token) {
+
+ case PORT:
+ if (xf86GetToken(NULL) != STRING) {
+ xf86ConfigError("MagicTouch input port expected");
+ }
+ priv->input_dev = strdup(val->str);
+ if (xf86Verbose) {
+ ErrorF("%s MagicTouch input port: %s\n",
+ XCONFIG_GIVEN, priv->input_dev);
+ }
+ break;
+
+ case MAGIC_DEVICE_NAME:
+ if (xf86GetToken(NULL) != STRING) {
+ xf86ConfigError("Magictouch device name expected");
+ }
+ local->name = strdup(val->str);
+ if (xf86Verbose) {
+ ErrorF("%s MagicTouch X device name: %s\n",
+ XCONFIG_GIVEN, local->name);
+ }
+ break;
+
+ case SCREEN_NO:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("MagicTouch screen number expected");
+ }
+ priv->screen_no = val->num;
+ if (xf86Verbose) {
+ ErrorF("%s MagicTouch associated screen: %d\n",
+ XCONFIG_GIVEN, priv->screen_no);
+ }
+ break;
+
+ case LINK_SPEED:
+ {
+ int ltoken = xf86GetToken(LinkSpeedTab);
+ if (ltoken == EOF ||
+ ltoken == STRING ||
+ ltoken == NUMBER) {
+ xf86ConfigError("MagicTouch link speed expected");
+ }
+ priv->link_speed = LinkSpeedValues[ltoken-1].speed;
+ if (xf86Verbose) {
+ ErrorF("%s MagicTouch link speed: %s bps\n",
+ XCONFIG_GIVEN, (LinkSpeedTab[ltoken-1].name)+1);
+ }
+ }
+ break;
+
+ case MAXX:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("MagicTouch maximum x position expected");
+ }
+ priv->max_x = val->num;
+ if (xf86Verbose) {
+ ErrorF("%s MagicTouch maximum x position: %d\n",
+ XCONFIG_GIVEN, priv->max_x);
+ }
+ break;
+
+ case MAXY:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("MagicTouch maximum y position expected");
+ }
+ priv->max_y = val->num;
+ if (xf86Verbose) {
+ ErrorF("%s MagicTouch maximum y position: %d\n",
+ XCONFIG_GIVEN, priv->max_y);
+ }
+ break;
+
+ case MINX:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("MagicTouch minimum x position expected");
+ }
+ priv->min_x = val->num;
+ if (xf86Verbose) {
+ ErrorF("%s MagicTouch minimum x position: %d\n",
+ XCONFIG_GIVEN, priv->min_x);
+ }
+ break;
+
+ case MINY:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("MagicTouch minimum y position expected");
+ }
+ priv->min_y = val->num;
+ if (xf86Verbose) {
+ ErrorF("%s MagicTouch minimum y position: %d\n",
+ XCONFIG_GIVEN, priv->min_y);
+ }
+ break;
+
+ case DEBUG_LEVEL:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("MagicTouch driver debug level expected");
+ }
+ debug_level = val->num;
+ if (xf86Verbose) {
+#if DEBUG
+ ErrorF("%s MagicTouch debug level sets to %d\n", XCONFIG_GIVEN,
+ debug_level);
+#else
+ ErrorF("%s MagicTouch debug not available\n",
+ XCONFIG_GIVEN, debug_level);
+#endif
+ }
+ break;
+
+ case HISTORY_SIZE:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("MagicTouch motion history size expected");
+ }
+ local->history_size = val->num;
+ if (xf86Verbose) {
+ ErrorF("%s MagicTouch motion history size is %d\n", XCONFIG_GIVEN,
+ local->history_size);
+ }
+ break;
+
+ case ALWAYS_CORE:
+ xf86AlwaysCore(local, TRUE);
+ if (xf86Verbose) {
+ ErrorF("%s MagicTouch device will always stays core pointer\n",
+ XCONFIG_GIVEN);
+ }
+ break;
+
+ case SWAP_AXES:
+ priv->swap_axes = 1;
+ if (xf86Verbose) {
+ ErrorF("%s MagicTouch device will work with X and Y axes swapped\n",
+ XCONFIG_GIVEN);
+ }
+ break;
+
+ case N_SAMPLE_X:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("MagicTouch driver NumSamplesX expected");
+ }
+ priv->num_medie_x = val->num;
+
+
+ if (priv->num_medie_x>MEDIE_X)
+ priv->num_medie_x=MEDIE_X;
+
+ DBG(4,
+ ErrorF("NumSampleX = %d\n", priv->num_medie_x)
+ );
+
+ break;
+
+ case N_SAMPLE_Y:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("MagicTouch driver NumSamplesY expected");
+ }
+ priv->num_medie_y = val->num;
+
+ if (priv->num_medie_y>MEDIE_Y)
+ priv->num_medie_y=MEDIE_Y;
+
+ DBG(4,
+ ErrorF("NumSampleY = %d\n", priv->num_medie_y)
+ );
+ break;
+
+ case EOF:
+ FatalError("Unexpected EOF (missing EndSubSection)");
+ break;
+
+ default:
+ xf86ConfigError("MagicTouch subsection keyword expected");
+ break;
+ }
+ }
+
+ if (priv->max_x - priv->min_x <= 0) {
+ ErrorF("%s MagicTouch: reverse x mode (minimum x position >= maximum x position)\n",
+ XCONFIG_GIVEN);
+ }
+ if (priv->max_y - priv->min_y <= 0) {
+ ErrorF("%s MagicTouch: reverse y mode (minimum y position >= maximum y position)\n",
+ XCONFIG_GIVEN);
+ }
+
+ DBG(2, ErrorF("xf86MagicConfig port name=%s\n", priv->input_dev))
+
+ return Success;
+}
+
+#endif /* !defined(sun) || defined(i386) */
+#endif /* XFREE86_V4 */
+
+/****************************************************************************
+ *
+ * xf86MagicQueryOK --
+ * Testa la presenza del touch controller.
+ * Si osserva che al primo accesso al touch dopo l'accensione e'
+ * presente nel buffer di ricezione il codice 0xF che identifica la
+ * vera presenza del touch controller.
+ * Dal secondo accesso in poi bisogna interrogare il touch controller
+ * per verificarne l'esistenza.
+ ****************************************************************************
+ */
+static Bool
+xf86MagicQueryOK(int fd)
+{
+ Bool ok;
+ int result;
+ char buf;
+
+ ok = Success;
+
+ /* Provo a leggere un byte dal buffer di ricezione */
+ SYSCALL( result = read(fd, &buf, 1) );
+
+ DBG(4, ErrorF("<<%s[%d]>> QueryOK: read --> %d\n", __FILE__, __LINE__, result) );
+
+ /* Se result e' -1 vuol dire che non c'e' nessun carattere nel
+ buffer. Allora X/Window e' stato avviato almeno una volta */
+ if (result<0) {
+ DBG(4,
+ ErrorF("Avvio n-esimo di X/Windows\n");
+ ErrorF("Controllo presenza Touch Controller\n")
+ );
+
+ /* Cerco il touch controller. Invio il carattere 0x00. */
+ buf = 0;
+ SYSCALL( result = write(fd, &buf, 1) );
+
+ /* Attendo 20 ms per dare il tempo al touch controller di
+ capire il comando */
+ usleep(20000);
+
+ /* Leggo la risposta */
+ SYSCALL( result = read(fd, &buf, 1) );
+
+ DBG(4,
+ ErrorF("QueryOK: buf==%X, result==%d\n", buf, result)
+ );
+ }
+
+ /* Se result<0 allora il touch controller non e' presente sul
+ disposito. Non posso proseguire */
+ if (result<0) {
+ DBG(4,
+ ErrorF("<<%s[%d]>> result<0\n", __FILE__, __LINE__)
+ );
+ ok = !Success;
+ }
+ /* Se il touch controller ha risposto allora controllo cosa ha
+ risposto */
+ else {
+ ok = (buf==0xF ? Success : !Success);
+ DBG(4,
+ ErrorF("<<%s[%d]>> QueryOK buf==%x\n", __FILE__, __LINE__, buf)
+ );
+ }
+
+ return ok;
+}
+
+/*
+ ***********************************************************************
+ *
+ * xf86MagicControl
+ *
+ ***********************************************************************
+ */
+static Bool
+xf86MagicControl(DeviceIntPtr dev,
+ int mode)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ MagicPrivatePtr priv = (MagicPrivatePtr)(local->private);
+ unsigned char map[] = { 0, 1 };
+ unsigned char req[MAGIC_PACKET_SIZE], replay[MAGIC_PACKET_SIZE];
+ int status_line;
+
+ switch (mode) {
+ case DEVICE_INIT:
+ DBG(2, ErrorF("MagicTouch init...\n") );
+
+ /* Controlla il numero di schermo selezionato */
+ if (priv->screen_no >= screenInfo.numScreens || priv->screen_no<0)
+ priv->screen_no = 0;
+ /* Legge le dimensioni dello schermo */
+ priv->screen_width = screenInfo.screens[priv->screen_no]->width;
+ priv->screen_height = screenInfo.screens[priv->screen_no]->height;
+
+ if (InitButtonClassDeviceStruct(dev, 1, map)==FALSE) {
+ ErrorF("Impossibile allocare ButtonClassDeviceStruct per MagicTouch\n");
+ return !Success;
+ }
+
+ if (InitFocusClassDeviceStruct(dev)==FALSE) {
+ ErrorF("Impossibile allocare FocusClassDeviceStruct per MagicTouch\n");
+ return !Success;
+ }
+
+ /*
+ * Il movimento viene eseguito su due assi in coordinate assolute.
+ */
+ if (InitValuatorClassDeviceStruct(dev, 2, xf86GetMotionEvents, local->history_size, Absolute) == FALSE )
+ {
+ ErrorF("MagicTouch ValuatorClassDeviceStruct: ERRORE\n");
+ return !Success;
+ }
+ else {
+ InitValuatorAxisStruct(dev, 0, priv->min_x, priv->max_x,
+ 9500,
+ 0, /* min res */
+ 9500 /* max res */);
+
+ InitValuatorAxisStruct(dev, 1, priv->min_y, priv->max_y,
+ 10500,
+ 0,
+ 10500);
+ }
+
+ if (InitFocusClassDeviceStruct(dev)==FALSE) {
+ ErrorF("Impossibile allocare FocusClassDeviceStruct per MagicTouch\n");
+ }
+
+ /*
+ * Alloca il buffer degli eventi spostamento
+ */
+ xf86MotionHistoryAllocate(local);
+
+ #ifndef XFREE86_V4
+ AssignTypeAndName(dev, local->atom, local->name);
+ #endif /* XFREE86_V4 */
+
+ DBG(2, ErrorF("MagicTouch INIT OK\n") );
+
+ break; /* DEVICE_INIT*/
+
+ case DEVICE_ON:
+ DBG(2, ErrorF("MagicTouch ON\n") );
+ if (local->fd<0) {
+ #ifndef XFREE86_V4
+ struct termios termios_tty;
+ int i,result;
+ #endif
+
+ DBG(2, ErrorF("Opening device...\n") );
+
+ #ifdef XFREE86_V4
+ local->fd = xf86OpenSerial(local->options);
+ if (local->fd<0) {
+ ErrorF("Impossibile aprire MagicTouch\n");
+ return !Success;
+ }
+ #else
+ SYSCALL( local->fd = open(priv->input_dev, O_RDWR | O_NDELAY, 0) );
+ if (local->fd<0) {
+ Error("Impossibile aprire MagicTouch\n");
+ return !Success;
+ }
+
+ DBG(3, ErrorF("Provo a configurare il MagicTouch\n") );
+
+
+ memset(&termios_tty, 0, sizeof(termios_tty) );
+ termios_tty.c_iflag = 0;
+ termios_tty.c_cflag = priv->link_speed | CS8 | CREAD | CLOCAL;
+ termios_tty.c_oflag = 0;
+ termios_tty.c_lflag = 0;
+ termios_tty.c_cc[VTIME]=0;
+ termios_tty.c_cc[VMIN]=1;
+
+ /*
+ * Attivo l'RTS per abilitare il touch controller
+ */
+ #if 0
+ SYSCALL( result = ioctl(local->fd, TIOCMGET, &status_line) );
+ if (result<0)
+ {
+ Error("Impossibile leggere stato linee seriale\n");
+ close(local->fd);
+ return !Success;
+ }
+ status_line |= TIOCM_RTS;
+ SYSCALL( result = ioctl(local->fd, TIOCMSET, &status_line) );
+ if (result<0)
+ {
+ Error("Impossibile settare stato linee seriale\n");
+ close(local->fd);
+ return !Success;
+ }
+ #endif
+
+ SYSCALL( result = tcsetattr(local->fd, TCSANOW, &termios_tty) );
+ if (result<0)
+ {
+ Error("Impossibile configurare MagicTouch\n");
+ close(local->fd);
+ return !Success;
+ }
+ #endif
+
+
+ /* Controlla se e' presente il touch controller.*/
+ req[0] = 0x00;
+ if (xf86MagicQueryOK(local->fd)!=Success) {
+ ErrorF("MagicTouch not present\n");
+ close(local->fd);
+ return !Success;
+ }
+
+ priv->e_presente = TRUE;
+
+ AddEnabledDevice(local->fd);
+ dev->public.on = TRUE;
+ } /* if (local->fd<0) */
+ break; /* DEVICE_ON */
+
+ case DEVICE_CLOSE:
+ case DEVICE_OFF:
+ DBG(2, ErrorF("MagicTouch OFF\n") );
+ dev->public.on = FALSE;
+ if (local->fd>=0)
+ emoveEnabledDevice(local->fd);
+
+ SYSCALL( close(local->fd) );
+ local->fd = -1;
+ DBG(2, ErrorF("OK\n") );
+ break; /* DEVICE_OFF*/
+
+ default:
+ ErrorF("unsupported mode %d\n", mode);
+ return !Success;
+ } /* switch (mode) */
+
+ return Success;
+}
+
+
+
+/*
+ ***************************************************************************
+ *
+ * GetPacket --
+ *
+ ***************************************************************************
+ */
+static Bool
+GetPacket(LocalDevicePtr local, unsigned char *buffer, int *n_rx, int fd)
+{
+ int num_bytes;
+ int i;
+ Bool ok;
+ MagicPrivatePtr priv=(MagicPrivatePtr) local->private;
+
+ DBG(6, ErrorF("Entering GetPacket with packet_pos == %d\n", *n_rx) );
+
+ SYSCALL(
+ num_bytes=read(fd, buffer+*n_rx, MAGIC_PACKET_SIZE-*n_rx)
+ );
+
+ /* Se e' il primo ingresso nella procedura e ho letto un solo byte,
+ allora e' arrivato lo 0x0F di risposta all-inizializzazione del
+ touch controlloer */
+ /* Sto gia' leggendo un pacchetto normale */
+ *n_rx += num_bytes;
+
+ DBG(8,
+ for (i=0; i<*n_rx; i++)
+ ErrorF("%3X", buffer[i]);
+ ErrorF("\n")
+ );
+
+ ok = (*n_rx==MAGIC_PACKET_SIZE ? Success : !Success );
+
+ if (ok==Success)
+ *n_rx = 0;
+
+ DBG(6,
+ if(ok==Success)
+ ErrorF("GetPacket OK\n");
+ else
+ ErrorF("GetPacket FAIL\n")
+ );
+
+ return ok;
+}
+
+/*
+ ************************************************************************
+ *
+ * xf86MagicReadInput
+ *
+ ************************************************************************
+ */
+static
+int medie_x(LocalDevicePtr local, int x)
+{
+ int i,res;
+ float medie;
+ MagicPrivatePtr priv = (MagicPrivatePtr)(local->private);
+
+ DBG(6,
+ ErrorF("Medie in X = %d\n", priv->num_medie_x)
+ );
+
+ if (priv->first_x) {
+ priv->first_x = FALSE;
+ for (i=0; i<priv->num_medie_x; i++)
+ priv->buf_x[i] = x;
+
+ res = x;
+ }
+ else {
+ priv->buf_x[priv->i_x] = x;
+ priv->i_x++;
+ if (priv->i_x>=priv->num_medie_x)
+ priv->i_x = 0;
+
+ medie = 0.0;
+ for (i=0; i<priv->num_medie_x; i++)
+ medie += priv->buf_x[i];
+
+ res = (int)(medie/priv->num_medie_x);
+ }
+
+ return res;
+}
+
+static
+int medie_y(LocalDevicePtr local, int y)
+{
+ int i,res;
+ float medie;
+ MagicPrivatePtr priv = (MagicPrivatePtr)(local->private);
+
+ DBG(6,
+ ErrorF("Medie in Y = %d\n", priv->num_medie_y)
+ );
+
+ if (priv->first_y) {
+ priv->first_y = FALSE;
+ for (i=0; i<priv->num_medie_y; i++)
+ priv->buf_y[i] = y;
+
+ res = y;
+ }
+ else {
+ priv->buf_y[priv->i_y] = y;
+ priv->i_y++;
+ if (priv->i_y>=priv->num_medie_y)
+ priv->i_y = 0;
+
+ medie = 0.0;
+ for (i=0; i<priv->num_medie_y; i++)
+ medie += priv->buf_y[i];
+
+ res = (int)(medie/priv->num_medie_y);
+ }
+
+ return res;
+}
+
+/*
+static
+int MAX(int x, int y)
+{
+ return (x>=y ? x : y);
+}
+*/
+
+#define MAX(x,y) (x>=y ? x : y)
+
+static void
+xf86MagicReadInput(LocalDevicePtr local)
+{
+ MagicPrivatePtr priv = (MagicPrivatePtr)(local->private);
+ int cur_x, cur_y;
+ Bool touch_now;
+ static int n_coms = 0;
+
+ if (!priv->e_presente) {
+ DBG(4,
+ ErrorF("<<%s[%d]>> ReadInput: Touch Controller non inizializzato\n")
+ );
+ return;
+ }
+
+ DBG(4, ErrorF("Entering ReadInput\n"));
+ /*
+ * Try to get a packet.
+ */
+ if (GetPacket(local, priv->packet_buf, &priv->packet_pos, local->fd)==Success)
+ {
+ /* Calculate the (x,y) coord of pointer */
+ cur_x = priv->packet_buf[1];
+ cur_x <<= 6;
+ cur_x |= priv->packet_buf[2];
+
+ cur_y = priv->packet_buf[3];
+ cur_y <<= 6;
+ cur_y |= priv->packet_buf[4];
+
+ touch_now = priv->packet_buf[0] & MGCT_TOUCH == MGCT_TOUCH;
+
+ /* Se c'e' pressione sul touch inizio a calcolare la posizione
+ e a spostare il cursore grafico */
+ if (touch_now) {
+ DBG(6,
+ ErrorF("Touch premuto: medio i valori di posizione\n")
+ );
+ cur_x = medie_x(local, cur_x);
+ cur_y = medie_y(local, cur_y);
+ }
+ else {
+ DBG(6,
+ ErrorF("Touch rilasciato:\n"
+ "\tazzeramento buffer memoria\n"
+ "\tposizionamento immediato\n")
+ );
+
+ /* Se non ho pressione allora comando lo spostamento
+ del cursore senza mediare. Svuoto il buffer delle medie */
+ priv->first_x = TRUE;
+ priv->first_y = TRUE;
+ }
+ /* Comando lo spostamento */
+ xf86PostMotionEvent(local->dev, TRUE, 0, 2, cur_x, cur_y);
+ /* comanda la pressione del tasto */
+
+ DBG(9,
+ ErrorF("touch_now==%s\n", (touch_now==TRUE ? "TRUE" : "FALSE") )
+ );
+ if (touch_now!=priv->click_on) {
+ DBG(9,
+ ErrorF("Bottone == %s\n", (touch_now==TRUE ? "PREMUTO" : "RILASCAITO") )
+ );
+ priv->click_on = touch_now;
+ xf86PostButtonEvent(local->dev, TRUE, 1, touch_now, 0, 2, cur_x, cur_y);
+ }
+ } /* GetPacket */
+}
+
+
+/*
+ ************************************************************************
+ *
+ * xf86MagicConvert
+ *
+ ************************************************************************
+ */
+static Bool
+xf86MagicConvert(LocalDevicePtr local,
+ int first,
+ int num,
+ int v0,
+ int v1,
+ int v2,
+ int v3,
+ int v4,
+ int v5,
+ int *x,
+ int *y)
+{
+ MagicPrivatePtr priv = (MagicPrivatePtr) local->private;
+ int width = priv->max_x - priv->min_x;
+ int height = priv->max_y - priv->min_y;
+ int input_x, input_y;
+
+ if (first != 0 || num != 2) {
+ return FALSE;
+ }
+
+ DBG(3, ErrorF("MagicConvert: v0(%d), v1(%d)\n", v0, v1));
+
+ if (priv->swap_axes) {
+ input_x = v1;
+ input_y = v0;
+ }
+ else {
+ input_x = v0;
+ input_y = v1;
+ }
+ *x = (priv->screen_width * (input_x - priv->min_x)) / width;
+ *y = (priv->screen_height - (priv->screen_height * (input_y - priv->min_y)) / height);
+
+#ifdef XFREE86_V4
+ /*
+ * Need to check if still on the correct screen.
+ * This call is here so that this work can be done after
+ * calib and before posting the event.
+ */
+ xf86XInputSetScreen(local, priv->screen_no, *x, *y);
+#endif
+
+ DBG(3, ErrorF("MagicConvert: x(%d), y(%d)\n", *x, *y));
+
+ return TRUE;
+}
+
+
+
+/*
+ ************************************************************************
+ *
+ * xf86MagicAllocate
+ *
+ ************************************************************************
+ */
+static LocalDevicePtr
+#ifndef XFREE86_V4
+xf86MagicAllocate(void)
+#else
+xf86MagicAllocate(InputDriverPtr drv)
+#endif
+{
+ #ifndef XFREE86_V4
+ LocalDevicePtr local = (LocalDevicePtr) xalloc( sizeof(LocalDeviceRec) );
+ #else
+ LocalDevicePtr local = xf86AllocateInput(drv, 0);
+ #endif
+
+ MagicPrivatePtr priv = (MagicPrivatePtr) xalloc( sizeof(MagicPrivateRec) );
+
+ /* Controlla la corretta allocazione di buffers. Se uno dei buffers non
+ e' stato allocato correttamente termina l'inizializzazione
+ */
+ if (!local) {
+ if (priv)
+ xfree(priv);
+ return NULL;
+ }
+
+ if (!priv) {
+ if (local)
+ xfree(local);
+ return NULL;
+ }
+
+ /* I buffers sono allocati correttamente */
+ #ifdef XFREE86_V4
+ priv->input_dev = strdup(MAGIC_PORT);
+ #else
+ priv->input_dev = MAGIC_PORT;
+ priv->link_speed = MAGIC_LINK_SPEED;
+ #endif
+
+ priv->min_x = 60;
+ priv->max_x = 960;
+ priv->min_y = 60;
+ priv->max_y = 960;
+ priv->screen_no = 0;
+ priv->screen_width = -1;
+ priv->screen_height = -1;
+ priv->swap_axes = 0;
+ priv->first_x =
+ priv->first_y = TRUE;
+ priv->first_entry = TRUE;
+ priv->e_presente = FALSE;
+ priv->click_on = FALSE;
+ priv->i_x =
+ priv->i_y = 0;
+ priv->packet_pos = 0;
+ bzero(priv->buf_x, MEDIE_X);
+ bzero(priv->buf_y, MEDIE_Y);
+ priv->num_medie_x = MEDIE_X;
+ priv->num_medie_y = MEDIE_Y;
+
+ local->name = XI_TOUCHSCREEN;
+ local->flags = 0;
+
+ #ifndef XFREE86_V4
+ #if !defined(sun) || defined(i386)
+ local->device_config = xf86MagicConfig;
+ #endif /* !defined(sun) || defined(i386) */
+ #endif /* XFREE86_V4*/
+
+ local->device_control = xf86MagicControl;
+ local->read_input = xf86MagicReadInput;
+ local->control_proc = NULL;
+ local->close_proc = NULL;
+ local->switch_mode = NULL;
+ local->conversion_proc = xf86MagicConvert;
+ local->reverse_conversion_proc = NULL;
+ local->fd = -1;
+ local->atom = 0;
+ local->dev = NULL;
+ local->private = priv;
+ local->type_name = "MagicTouch";
+ local->history_size = 0;
+
+ return local;
+
+} /* xf86MagicAllocae */
+
+
+
+#ifndef XFREE86_V4
+
+/*
+ * Sezione relativa a X < 4.0.0
+ */
+
+DeviceAssocRec magictouch_assoc = {
+ "magictouch",
+ xf86MagicAllocate
+};
+
+#ifdef DYNAMIC_MODULE
+
+#ifndef DLSYM_BUG
+int init_module(unsigned long server_version)
+#else
+int init_xf86Magic(unsigned long server_version)
+#endif
+{
+ /* Aggiunge l'assiocazione per il touchscreen */
+ xf86AddDeviceAssoc(&magictouch_assoc);
+
+ /* Controlla la versione */
+ if (server_version != XF86_VERSION_CURRENT) {
+ ErrorF("Warining: MagicTouch module compiled for version %s\n", XF86_VERSION);
+ return 0;
+ }
+ return 1;
+}
+#endif /* DYNAMIC_MODULE */
+
+#else
+/*
+ * Sezione relativa a X >= 4.0.0
+ */
+
+#endif /* XFREE86_V4 */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sunos/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/sunos/Imakefile
new file mode 100644
index 000000000..eb79cf471
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sunos/Imakefile
@@ -0,0 +1,85 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/Imakefile,v 1.2 2001/08/17 22:08:15 tsi Exp $
+XCOMM
+XCOMM Copyright 2001 The XFree86 Project, Inc. All Rights Reserved.
+XCOMM
+XCOMM Permission is hereby granted, free of charge, to any person obtaining a
+XCOMM copy of this software and associated documentation files (the
+XCOMM "Software"), to deal in the Software without restriction, including
+XCOMM without limitation the rights to use, copy, modify, merge, publish,
+XCOMM distribute, sublicense, and/or sell copies of the Software, and to permit
+XCOMM persons to whom the Software is furnished to do so, subject to the
+XCOMM following conditions:
+XCOMM
+XCOMM The above copyright notice and this permission notice shall be included
+XCOMM in all copies or substantial portions of the Software.
+XCOMM
+XCOMM THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+XCOMM OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+XCOMM MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+XCOMM IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR
+XCOMM OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+XCOMM ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+XCOMM OTHER DEALINGS IN THE SOFTWARE.
+XCOMM
+XCOMM Except as contained in this notice, the name of the XFree86 Project shall
+XCOMM not be used in advertising or otherwise to promote the sale, use or other
+XCOMM dealings in this Software without prior written authorization from the
+XCOMM XFree86 Project.
+XCOMM
+
+/* This is a combined Imakefile intended for all SunOS variants */
+
+#include <Server.tmpl>
+
+#if !HasGcc && defined(i386Architecture)
+PROWORKS_INOUT_SRC = sun_inout.s
+PROWORKS_INOUT_OBJ = sun_inout.s
+#endif
+
+#if defined(i386Architecture) && (OSMinorVersion < 8)
+IO_SRC = sysv_io.c
+IO_OBJ = sysv_io.o
+KBD_SRCS = sysv_kbd.c std_kbdEv.c
+KBD_OBJS = sysv_kbd.o std_kbdEv.o
+VTSW_SRC = VTsw_usl.c
+VTSW_OBJ = VTsw_usl.o
+#else
+IO_SRC = sun_io.c
+IO_OBJ = sun_io.o
+KBD_SRCS = sun_kbd.c sun_kbdEv.c
+KBD_OBJS = sun_kbd.o sun_kbdEv.o
+VTSW_SRC = VTsw_noop.c
+VTSW_OBJ = VTsw_noop.o
+#endif
+
+SRCS = sun_bios.c sun_init.c $(IO_SRC) $(KBD_SRCS) $(PROWORKS_INOUT_SRC) \
+ sun_mouse.c sun_vid.c agp_noop.c libc_wrapper.c kmod_noop.c pm_noop.c \
+ posix_tty.c sigiostubs.c stdPci.c stdResource.c $(VTSW_SRC)
+OBJS = sun_bios.o sun_init.o $(IO_OBJ) $(KBD_OBJS) $(PROWORKS_INOUT_OBJ) \
+ sun_mouse.o sun_vid.o agp_noop.o libc_wrapper.o kmod_noop.o pm_noop.o \
+ posix_tty.o sigiostubs.o stdPci.o stdResource.o $(VTSW_OBJ)
+
+INCLUDES = -I. -I$(XF86OSSRC) -I$(XF86COMSRC) \
+ -I$(SERVERSRC)/mi -I$(SERVERSRC)/include -I$(SERVERSRC)/Xext \
+ -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+DEFINES = -DUSESTDRES
+
+SubdirLibraryRule($(OBJS))
+NormalLibraryObjectRule()
+NormalAsmObjectRule()
+
+LinkSourceFile($(VTSW_SRC),../shared)
+LinkSourceFile(agp_noop.c,../shared)
+LinkSourceFile(libc_wrapper.c,../shared)
+LinkSourceFile(kmod_noop.c,../shared)
+LinkSourceFile(pm_noop.c,../shared)
+LinkSourceFile(posix_tty.c,../shared)
+LinkSourceFile(sigiostubs.c,../shared)
+LinkSourceFile(stdPci.c,../shared)
+LinkSourceFile(stdResource.c,../shared)
+LinkSourceFile(std_kbdEv.c,../shared)
+LinkSourceFile(sysv_io.c,../sysv)
+LinkSourceFile(sysv_kbd.c,../shared)
+
+DependTarget()
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_bios.c b/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_bios.c
new file mode 100644
index 000000000..c42c7b9c7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_bios.c
@@ -0,0 +1,104 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_bios.c,v 1.1 2001/05/28 02:42:31 tsi Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ * Copyright 1999 by David Holland <davidh@iquest.net>
+ *
+ * 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 names of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS 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.
+ */
+
+#ifdef i386
+#define _NEED_SYSI86
+#endif
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+extern char *apertureDevName;
+
+/*
+ * Read BIOS via mmap()ing physical memory.
+ */
+int
+xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf,
+ int Len)
+{
+#ifdef i386
+ int fd;
+ unsigned char *ptr;
+ char solx86_vtname[20];
+ int psize;
+ int mlen;
+
+ /*
+ * Solaris 2.1 x86 SVR4 (10/27/93)
+ * The server must treat the virtual terminal device file
+ * as the standard SVR4 /dev/pmem. By default, then used VT
+ * is considered the "default" file to open.
+ *
+ * Solaris 2.8 x86 (7/26/99) - DWH
+ *
+ * Use /dev/xsvc for everything.
+ */
+ psize = xf86getpagesize();
+ Offset += Base & (psize - 1);
+ Base &= ~(psize - 1);
+ mlen = (Offset + Len + psize - 1) & ~(psize - 1);
+#ifndef __SOL8__
+ if (Base >= 0xA0000 && Base + mlen < 0xFFFFF && xf86Info.vtno >= 0)
+ sprintf(solx86_vtname,"/dev/vt%02d",xf86Info.vtno);
+ else
+#endif
+ {
+ if (!apertureDevName)
+ if (!xf86LinearVidMem())
+ FatalError("xf86ReadBIOS: Could not mmap "
+ "BIOS [a=%x]\n", Base);
+ sprintf(solx86_vtname, apertureDevName);
+ }
+
+ if ((fd = open(solx86_vtname, O_RDONLY)) < 0)
+ {
+ xf86Msg(X_WARNING, "xf86ReadBIOS: Failed to open %s (%s)\n",
+ solx86_vtname, strerror(errno));
+ return(-1);
+ }
+ ptr = (unsigned char *)mmap((caddr_t)0, mlen, PROT_READ,
+ MAP_SHARED, fd, (off_t)Base);
+ if (ptr == MAP_FAILED)
+ {
+ xf86Msg(X_WARNING, "xf86ReadBIOS: %s mmap failed "
+ "[0x%05x, 0x%04x]\n",
+ solx86_vtname, Base, mlen);
+ close(fd);
+ return(-1);
+ }
+ (void)memcpy(Buf, (void *)(ptr + Offset), Len);
+ (void)munmap((caddr_t)ptr, mlen);
+ (void)close(fd);
+ return(Len);
+#else
+ FatalError("xf86ReadBIOS() called\n");
+
+ return -1; /* G'd'ole gcc */
+#endif
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_init.c b/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_init.c
new file mode 100644
index 000000000..63de850b7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_init.c
@@ -0,0 +1,330 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_init.c,v 1.2 2001/08/17 22:08:15 tsi Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ * Copyright 1999 by David Holland <davidh@iquest.net>
+ *
+ * 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 names of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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 "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+static Bool KeepTty = FALSE;
+static Bool Protect0 = FALSE;
+#ifdef HAS_USL_VTS
+static int VTnum = -1;
+static int xf86StartVT = -1;
+#endif
+
+static char fb_dev[PATH_MAX] = "/dev/console";
+
+void
+xf86OpenConsole(void)
+{
+ int fd, i;
+#ifdef HAS_USL_VTS
+ struct vt_mode VT;
+ struct vt_stat vtinfo;
+ int FreeVTslot;
+ MessageType from = X_PROBED;
+#endif
+
+ if (serverGeneration == 1)
+ {
+ /* Check if we're run with euid==0 */
+ if (geteuid() != 0)
+ FatalError("xf86OpenConsole: Server must be suid root\n");
+
+ /* Protect page 0 to help find NULL dereferencing */
+ /* mprotect() doesn't seem to work */
+ if (Protect0)
+ {
+ int fd = -1;
+
+ if ((fd = open("/dev/zero", O_RDONLY, 0)) < 0)
+ {
+ xf86Msg(X_WARNING,
+ "xf86OpenConsole: cannot open /dev/zero (%s)\n",
+ strerror(errno));
+ }
+ else
+ {
+ if ((int)mmap(0, 0x1000, PROT_NONE,
+ MAP_FIXED | MAP_SHARED, fd, 0) == -1)
+ xf86Msg(X_WARNING,
+ "xf86OpenConsole: failed to protect page 0 (%s)\n",
+ strerror(errno));
+
+ close(fd);
+ }
+ }
+
+#ifdef HAS_USL_VTS
+
+ /*
+ * Setup the virtual terminal manager
+ */
+ if (VTnum != -1)
+ {
+ xf86Info.vtno = VTnum;
+ from = X_CMDLINE;
+ }
+ else
+ {
+ if ((fd = open("/dev/vt00",O_RDWR,0)) < 0)
+ FatalError("xf86OpenConsole: Cannot open /dev/vt00 (%s)\n",
+ strerror(errno));
+
+ if (ioctl(fd, VT_GETSTATE, &vtinfo) < 0)
+ FatalError("xf86OpenConsole: Cannot determine current VT\n");
+
+ xf86StartVT = vtinfo.v_active;
+
+ /*
+ * There is a SEVERE problem with x86's VT's. The VT_OPENQRY
+ * ioctl() will panic the entire system if all 8 (7 VT's+Console)
+ * terminals are used. The only other way I've found to determine
+ * if there is a free VT is to try activating all the the available
+ * VT's and see if they all succeed - if they do, there there is no
+ * free VT, and the Xserver cannot continue without panic'ing the
+ * system. (It's ugly, but it seems to work.) Note there is a
+ * possible race condition here.
+ *
+ * David Holland 2/23/94
+ */
+
+ FreeVTslot = 0;
+ for (i = 7; (i >= 0) && !FreeVTslot; i--)
+ if (ioctl(fd, VT_ACTIVATE, i) != 0)
+ FreeVTslot = 1;
+
+ if (!FreeVTslot) ||
+ (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
+ (xf86Info.vtno == -1))
+ FatalError("xf86OpenConsole: Cannot find a free VT\n");
+
+ close(fd);
+ }
+
+ xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
+
+ sprintf(fb_dev, "/dev/vt%02d", xf86Info.vtno); /* Solaris 2.1 x86 */
+
+#endif /* HAS_USL_VTS */
+
+ if (!KeepTty)
+ setpgrp();
+
+ if (((xf86Info.consoleFd = open(fb_dev, O_RDWR | O_NDELAY, 0)) < 0))
+ FatalError("xf86OpenConsole: Cannot open %s (%s)\n",
+ fb_dev, strerror(errno));
+
+#ifdef HAS_USL_VTS
+
+ /* Change ownership of the vt */
+ chown(fb_dev, getuid(), getgid());
+
+ /*
+ * Now get the VT
+ */
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
+
+ if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
+
+ if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
+ FatalError("xf86OpenConsole: VT_GETMODE failed\n");
+
+ signal(SIGUSR1, xf86VTRequest);
+
+ VT.mode = VT_PROCESS;
+ VT.relsig = SIGUSR1;
+ VT.acqsig = SIGUSR1;
+
+ if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
+ FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n");
+
+ if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0)
+ FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed\n");
+ }
+ else /* serverGeneration != 1 */
+ {
+ /*
+ * Now re-get the VT
+ */
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
+
+ if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
+
+ /*
+ * If the server doesn't have the VT when the reset occurs,
+ * this is to make sure we don't continue until the activate
+ * signal is received.
+ */
+ if (!xf86Screens[0]->vtSema)
+ sleep(5);
+
+#endif /* HAS_USL_VTS */
+
+ }
+}
+
+void
+xf86CloseConsole(void)
+{
+#ifdef HAS_USL_VTS
+ struct vt_mode VT;
+#endif
+#if defined(__SOL8__) || !defined(i386)
+ int tmp;
+#endif
+
+#ifdef HAS_USL_VTS
+
+ /*
+ * Solaris 2.1 x86 doesn't seem to "switch" back to the console when the VT
+ * is relinquished and its mode is reset to auto. Also, Solaris 2.1 seems
+ * to associate vt00 with the console so I've opened the "console" back up
+ * and made it the active vt again in text mode and then closed it. There
+ * must be a better hack for this but I'm not aware of one at this time.
+ *
+ * Doug Anson 11/6/93
+ * danson@lgc.com
+ *
+ * Fixed - 12/5/93 - David Holland - davidh@dorite.use.com
+ * Did the whole thing similarly to the way linux does it
+ */
+
+ /* Reset the display back to text mode */
+ ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT);
+ if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1)
+ {
+ VT.mode = VT_AUTO; /* Set default vt handling */
+ ioctl(xf86Info.consoleFd, VT_SETMODE, &VT);
+ }
+
+ /* Activate the VT that X was started on */
+ ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86StartVT);
+
+#endif /* HAS_USL_VTS */
+
+ close(xf86Info.consoleFd);
+
+#if defined(__SOL8__) || !defined(i386)
+
+ /*
+ * This probably shouldn't be here. However, there is no corresponding
+ * xf86CloseKbd() routine - DWH
+ */
+
+ /* Set the keyboard into "indirect" mode and turn off even translation */
+ tmp = 0;
+ (void) ioctl(xf86Info.kbdFd, KIOCSDIRECT, &tmp);
+ tmp = TR_ASCII;
+ (void) ioctl(xf86Info.kbdFd, KIOCTRANS, &tmp);
+
+ close(xf86Info.kbdFd);
+
+#endif
+}
+
+int
+xf86ProcessArgument(int argc, char **argv, int i)
+{
+ /*
+ * Keep server from detaching from controlling tty. This is useful when
+ * debugging, so the server can receive keyboard signals.
+ */
+ if (!strcmp(argv[i], "-keeptty"))
+ {
+ KeepTty = TRUE;
+ return 1;
+ }
+
+ /*
+ * Undocumented flag to protect page 0 from read/write to help catch NULL
+ * pointer dereferences. This is purely a debugging flag.
+ */
+ if (!strcmp(argv[i], "-protect0"))
+ {
+ Protect0 = TRUE;
+ return 1;
+ }
+
+#ifdef HAS_USL_VTS
+
+ if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
+ {
+ if (sscanf(argv[i], "vt%2d", &VTnum) == 0)
+ {
+ UseMsg();
+ VTnum = -1;
+ return 0;
+ }
+
+ return 1;
+ }
+
+#endif /* HAS_USL_VTS */
+
+#if defined(__SOL8__) || !defined(i386)
+
+ if ((i + 1) < argc) {
+ if (!strcmp(argv[i], "-dev")) {
+ strncpy(fb_dev, argv[i+1], PATH_MAX);
+ fb_dev[PATH_MAX - 1] = '\0';
+ return 2;
+ }
+
+ if (!strcmp(argv[i], "-ar1")) {
+ xf86Info.kbdDelay = atoi(argv[i + 1]) * 1000;
+ return 2;
+ }
+
+ if (!strcmp(argv[i], "-ar2")) {
+ xf86Info.kbdRate = atoi(argv[i + 1]) * 1000;
+ return 2;
+ }
+ }
+
+#endif
+
+ return 0;
+}
+
+void xf86UseMsg()
+{
+#ifdef HAS_USL_VTS
+ ErrorF("vtXX Use the specified VT number\n");
+#endif
+#if defined(__SOL8__) || !defined(i386)
+ ErrorF("-dev <fb> Framebuffer device\n");
+ ErrorF("-ar1 <float> Set autorepeat initiate time (sec)\n");
+ ErrorF(" (if not using XKB)\n");
+ ErrorF("-ar2 <float> Set autorepeat interval time (sec)\n");
+ ErrorF(" (if not using XKB)\n");
+#endif
+ ErrorF("-keeptty Don't detach controlling tty\n");
+ ErrorF(" (for debugging only)\n");
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_inout.s b/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_inout.s
new file mode 100644
index 000000000..e8f03d0e8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_inout.s
@@ -0,0 +1,124 @@
+/ $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_inout.s,v 1.1 2001/05/28 02:42:31 tsi Exp $
+/
+/ Copyright 1994-2001 The XFree86 Project, Inc. All Rights Reserved.
+/
+/ Permission is hereby granted, free of charge, to any person obtaining a copy
+/ of this software and associated documentation files (the "Software"), to deal
+/ in the Software without restriction, including without limitation the rights
+/ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+/ copies of the Software, and to permit persons to whom the Software is
+/ furnished to do so, subject to the following conditions:
+/
+/ The above copyright notice and this permission notice shall be included in
+/ all copies or substantial portions of the Software.
+/
+/ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+/ XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+/ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+/ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+/
+/ Except as contained in this notice, the name of the XFree86 Project shall not
+/ be used in advertising or otherwise to promote the sale, use or other
+/ dealings in this Software without prior written authorization from the
+/ XFree86 Project.
+/
+/
+/ File: sun_inout.s
+/
+/ Purpose: Provide inb(), inw(), inl(), outb(), outw(), outl() functions
+/ for Solaris x86 using the ProWorks compiler by SunPro
+/
+/ Author: Installed into XFree86 SuperProbe by Doug Anson (danson@lgc.com)
+/ Portions donated to XFree86 by Steve Dever (Steve.Dever@Eng.Sun.Com)
+/
+/ Synopsis: (c callable external declarations)
+/ extern unsigned char inb(int port);
+/ extern unsigned short inw(int port);
+/ extern unsigned long inl(int port);
+/ extern void outb(int port, unsigned char value);
+/ extern void outw(int port, unsigned short value);
+/ extern void outl(int port, unsigned long value);
+/
+
+.file "sunos_inout.s"
+.text
+
+.globl inb
+.globl inw
+.globl inl
+.globl outb
+.globl outw
+.globl outl
+
+/
+/ unsigned char inb(int port);
+/
+.align 4
+inb:
+ movl 4(%esp),%edx
+ subl %eax,%eax
+ inb (%dx)
+ ret
+.type inb,@function
+.size inb,.-inb
+
+/
+/ unsigned short inw(int port);
+/
+.align 4
+inw:
+ movl 4(%esp),%edx
+ subl %eax,%eax
+ inw (%dx)
+ ret
+.type inw,@function
+.size inw,.-inw
+
+/
+/ unsigned long inl(int port);
+/
+.align 4
+inl:
+ movl 4(%esp),%edx
+ inl (%dx)
+ ret
+.type inl,@function
+.size inl,.-inl
+
+/
+/ void outb(int port, unsigned char value);
+/
+.align 4
+outb:
+ movl 4(%esp),%edx
+ movl 8(%esp),%eax
+ outb (%dx)
+ ret
+.type outb,@function
+.size outb,.-outb
+
+/
+/ void outw(int port, unsigned short value);
+/
+.align 4
+outw:
+ movl 4(%esp),%edx
+ movl 8(%esp),%eax
+ outw (%dx)
+ ret
+.type outw,@function
+.size outw,.-outw
+
+/
+/ void outl(int port, unsigned long value);
+/
+.align 4
+outl:
+ movl 4(%esp),%edx
+ movl 8(%esp),%eax
+ outl (%dx)
+ ret
+.type outl,@function
+.size outl,.-outl
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_io.c b/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_io.c
new file mode 100644
index 000000000..e2140b2b8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_io.c
@@ -0,0 +1,56 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_io.c,v 1.1 2001/05/28 02:42:31 tsi Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ *
+ * 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 names of Thomas Roell and David Dawes
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Thomas Roell and
+ * David Dawes makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THOMAS ROELL AND DAVID DAWES DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL THOMAS ROELL OR DAVID DAWES 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 "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+void
+xf86SoundKbdBell(int loudness, int pitch, int duration)
+{
+ int kbdCmd;
+
+ if (loudness && pitch)
+ {
+ kbdCmd = KBD_CMD_BELL;
+ if (ioctl (xf86Info.kbdFd, KIOCCMD, &kbdCmd) == -1) {
+ ErrorF("Failed to activate bell\n");
+ return;
+ }
+
+ usleep(xf86Info.bell_duration * loudness * 20);
+
+ kbdCmd = KBD_CMD_NOBELL;
+ if (ioctl (xf86Info.kbdFd, KIOCCMD, &kbdCmd) == -1)
+ ErrorF ("Failed to deactivate bell\n");
+ }
+}
+
+void
+xf86SetKbdLeds(int leds)
+{
+ if( ioctl(xf86Info.kbdFd, KIOCSLED, &leds) < 0 )
+ ErrorF("Failed to set Keyboard LED's\n");
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_kbd.c b/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_kbd.c
new file mode 100644
index 000000000..7e4998817
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_kbd.c
@@ -0,0 +1,112 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_kbd.c,v 1.1 2001/05/28 02:42:31 tsi Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Dawes <dawes@XFree86.org>
+ * Copyright 1999 by David Holland <davidh@iquest.net)
+ *
+ * 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 names of Thomas Roell, David Dawes, and David Holland not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Thomas Roell, David Dawes, and
+ * David Holland make no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THOMAS ROELL, DAVID DAWES, AND DAVID HOLLAND DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THOMAS ROELL, DAVID DAWES, OR DAVID HOLLAND
+ * 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 "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+static int sun_otranslation = -1;
+static int sun_odirect = -1;
+
+int
+xf86GetKbdLeds()
+{
+ int leds;
+
+ ioctl(xf86Info.kbdFd, KIOCGLED, &leds);
+ return leds;
+}
+
+void
+xf86SetKbdRepeat(char rad)
+{
+ /* Nothing to do */
+}
+
+/*
+ * Save initial keyboard state. This is called at the start of each server
+ * generation.
+ */
+
+void
+xf86KbdInit()
+{
+ int ktype, klayout;
+
+ if (xf86Info.kbdFd < 0) {
+ xf86Info.kbdFd = open("/dev/kbd", O_RDWR|O_NONBLOCK);
+ if(xf86Info.kbdFd < 0)
+ FatalError("Unable to open keyboard: /dev/kbd\n");
+ }
+
+ /*
+ * None of the followin should ever fail. If it does, something is
+ * broken (IMO) - DWH 8/21/99
+ */
+
+ if (ioctl(xf86Info.kbdFd, KIOCTYPE, &ktype) < 0)
+ FatalError("Unable to determine keyboard type: %d\n", errno);
+
+ if (ioctl(xf86Info.kbdFd, KIOCLAYOUT, &klayout) < 0)
+ FatalError("Unable to determine keyboard layout: %d\n", errno);
+
+ if (ioctl(xf86Info.kbdFd, KIOCGTRANS, &sun_otranslation) < 0)
+ FatalError("Unable to determine keyboard translation mode\n");
+
+ if (ioctl(xf86Info.kbdFd, KIOCGDIRECT, &sun_odirect) < 0)
+ FatalError("Unable to determine keyboard direct setting\n");
+}
+
+int
+xf86KbdOn(void)
+{
+ int tmp = 1;
+
+ if (ioctl(xf86Info.kbdFd, KIOCSDIRECT, &tmp) == -1)
+ FatalError("Setting keyboard direct mode on\n");
+
+ /* Setup translation */
+
+ tmp = TR_UNTRANS_EVENT;
+
+ if (ioctl(xf86Info.kbdFd, KIOCTRANS, &tmp) == -1)
+ FatalError("Setting keyboard translation\n");
+
+ return xf86Info.kbdFd;
+}
+
+int
+xf86KbdOff()
+{
+ if ((sun_otranslation != -1) &&
+ (ioctl(xf86Info.kbdFd, KIOCTRANS, &sun_otranslation) < 0))
+ FatalError("Unable to restore keyboard translation mode\n");
+
+ if ((sun_odirect != 0) &&
+ (ioctl(xf86Info.kbdFd, KIOCSDIRECT, &sun_odirect) < 0 ))
+ FatalError("Unable to restore keyboard direct setting\n");
+
+ return xf86Info.kbdFd;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_kbdEv.c b/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_kbdEv.c
new file mode 100644
index 000000000..1c95b5b77
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_kbdEv.c
@@ -0,0 +1,497 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_kbdEv.c,v 1.2 2001/08/17 22:08:15 tsi Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ *
+ * 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 names of Thomas Roell and David Dawes not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Thomas Roell and David Dawes make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL AND DAVID DAWES DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+ * IN NO EVENT SHALL THOMAS ROELL OR DAVID DAWES 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.
+ */
+
+/* [JCH-96/01/21] Extended std reverse map to four buttons. */
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#ifdef XINPUT
+#include "XI.h"
+#include "XIproto.h"
+#include "xf86Xinput.h"
+#else
+#include "inputstr.h"
+#endif
+
+#ifdef XFreeXDGA
+#include "dgaproc.h"
+#endif
+
+#include <sys/vuid_event.h>
+#include "atKeynames.h"
+
+#ifdef XKB
+extern Bool noXkbExtension;
+#endif
+
+#define XE_POINTER 1
+#define XE_KEYBOARD 2
+
+#ifdef XTESTEXT1
+
+#define XTestSERVER_SIDE
+#include "xtestext1.h"
+extern short xtest_mousex;
+extern short xtest_mousey;
+extern int on_steal_input;
+extern Bool XTestStealKeyData();
+extern void XTestStealMotionData();
+
+#ifdef XINPUT
+#define ENQUEUE(ev, code, direction, dev_type) \
+ (ev)->u.u.detail = (code); \
+ (ev)->u.u.type = (direction); \
+ if (!on_steal_input || \
+ XTestStealKeyData((ev)->u.u.detail, (ev)->u.u.type, dev_type, \
+ xtest_mousex, xtest_mousey)) \
+ xf86eqEnqueue((ev))
+#else
+#define ENQUEUE(ev, code, direction, dev_type) \
+ (ev)->u.u.detail = (code); \
+ (ev)->u.u.type = (direction); \
+ if (!on_steal_input || \
+ XTestStealKeyData((ev)->u.u.detail, (ev)->u.u.type, dev_type, \
+ xtest_mousex, xtest_mousey)) \
+ mieqEnqueue((ev))
+#endif
+
+#else /* ! XTESTEXT1 */
+
+#ifdef XINPUT
+#define ENQUEUE(ev, code, direction, dev_type) \
+ (ev)->u.u.detail = (code); \
+ (ev)->u.u.type = (direction); \
+ xf86eqEnqueue((ev))
+#else
+#define ENQUEUE(ev, code, direction, dev_type) \
+ (ev)->u.u.detail = (code); \
+ (ev)->u.u.type = (direction); \
+ mieqEnqueue((ev))
+#endif
+
+#endif
+
+static void startautorepeat(long keycode);
+static CARD32 processautorepeat(OsTimerPtr timer, CARD32 now, pointer arg);
+
+static OsTimerPtr sunTimer = NULL;
+
+/* Map the Solaris keycodes to the "XFree86" keycodes. */
+static unsigned char map[256] = {
+ KEY_NOTUSED, /* 0 */
+ KEY_Tilde, /* 1 */
+ KEY_1, /* 2 */
+ KEY_2, /* 3 */
+ KEY_3, /* 4 */
+ KEY_4, /* 5 */
+ KEY_5, /* 6 */
+ KEY_6, /* 7 */
+ KEY_7, /* 8 */
+ KEY_8, /* 9 */
+ KEY_9, /* 10 */
+ KEY_0, /* 11 */
+ KEY_Minus, /* 12 */
+ KEY_Equal, /* 13 */
+ 0x7D, /*KEY_P_YEN*/ /* 14 */
+ KEY_BackSpace, /* 15 */
+ KEY_Tab, /* 16 */
+ KEY_Q, /* 17 */
+ KEY_W, /* 18 */
+ KEY_E, /* 19 */
+ KEY_R, /* 20 */
+ KEY_T, /* 21 */
+ KEY_Y, /* 22 */
+ KEY_U, /* 23 */
+ KEY_I, /* 24 */
+ KEY_O, /* 25 */
+ KEY_P, /* 26 */
+ KEY_LBrace, /* 27 */
+ KEY_RBrace, /* 28 */
+ KEY_BSlash, /* 29 */
+ KEY_CapsLock, /* 30 */
+ KEY_A, /* 31 */
+ KEY_S, /* 32 */
+ KEY_D, /* 33 */
+ KEY_F, /* 34 */
+ KEY_G, /* 35 */
+ KEY_H, /* 36 */
+ KEY_J, /* 37 */
+ KEY_K, /* 38 */
+ KEY_L, /* 39 */
+ KEY_SemiColon, /* 40 */
+ KEY_Quote, /* 41 */
+ KEY_UNKNOWN, /* 42 */
+ KEY_Enter, /* 43 */
+ KEY_ShiftL, /* 44 */
+ KEY_Less, /* 45 */
+ KEY_Z, /* 46 */
+ KEY_X, /* 47 */
+ KEY_C, /* 48 */
+ KEY_V, /* 49 */
+ KEY_B, /* 50 */
+ KEY_N, /* 51 */
+ KEY_M, /* 52 */
+ KEY_Comma, /* 53 */
+ KEY_Period, /* 54 */
+ KEY_Slash, /* 55 */
+ KEY_BSlash2, /* 56 */
+ KEY_ShiftR, /* 57 */
+ KEY_LCtrl, /* 58 */
+ KEY_LMeta, /* 59 */
+ KEY_Alt, /* 60 */
+ KEY_Space, /* 61 */
+ KEY_AltLang, /* 62 */
+ KEY_RMeta, /* 63 */
+ KEY_RCtrl, /* 64 */
+ KEY_Menu, /* 65 */
+ KEY_UNKNOWN, /* 66 */
+ KEY_UNKNOWN, /* 67 */
+ KEY_UNKNOWN, /* 68 */
+ KEY_UNKNOWN, /* 69 */
+ KEY_UNKNOWN, /* 70 */
+ KEY_UNKNOWN, /* 71 */
+ KEY_UNKNOWN, /* 72 */
+ KEY_UNKNOWN, /* 73 */
+ KEY_UNKNOWN, /* 74 */
+ KEY_Insert, /* 75 */
+ KEY_Delete, /* 76 */
+ KEY_UNKNOWN, /* 77 */
+ KEY_UNKNOWN, /* 78 */
+ KEY_Left, /* 79 */
+ KEY_Home, /* 80 */
+ KEY_End, /* 81 */
+ KEY_UNKNOWN, /* 82 */
+ KEY_Up, /* 83 */
+ KEY_Down, /* 84 */
+ KEY_PgUp, /* 85 */
+ KEY_PgDown, /* 86 */
+ KEY_UNKNOWN, /* 87 */
+ KEY_UNKNOWN, /* 88 */
+ KEY_Right, /* 89 */
+ KEY_NumLock, /* 90 */
+ KEY_KP_7, /* 91 */
+ KEY_KP_4, /* 92 */
+ KEY_KP_1, /* 93 */
+ KEY_UNKNOWN, /* 94 */
+ KEY_KP_Divide, /* 95 */
+ KEY_KP_8, /* 96 */
+ KEY_KP_5, /* 97 */
+ KEY_KP_2, /* 98 */
+ KEY_KP_0, /* 99 */
+ KEY_KP_Multiply, /* 100 */
+ KEY_KP_9, /* 101 */
+ KEY_KP_6, /* 102 */
+ KEY_KP_3, /* 103 */
+ KEY_KP_Decimal, /* 104 */
+ KEY_KP_Minus, /* 105 */
+ KEY_KP_Plus, /* 106 */
+ KEY_UNKNOWN, /* 107 */
+ KEY_KP_Enter, /* 108 */
+ KEY_UNKNOWN, /* 109 */
+ KEY_Escape, /* 110 */
+ KEY_UNKNOWN, /* 111 */
+ KEY_F1, /* 112 */
+ KEY_F2, /* 113 */
+ KEY_F3, /* 114 */
+ KEY_F4, /* 115 */
+ KEY_F5, /* 116 */
+ KEY_F6, /* 117 */
+ KEY_F7, /* 118 */
+ KEY_F8, /* 119 */
+ KEY_F9, /* 120 */
+ KEY_F10, /* 121 */
+ KEY_F11, /* 122 */
+ KEY_F12, /* 123 */
+ KEY_Print, /* 124 */
+ KEY_ScrollLock, /* 125 */
+ KEY_Pause, /* 126 */
+ KEY_UNKNOWN, /* 127 */
+ KEY_UNKNOWN, /* 128 */
+ KEY_UNKNOWN, /* 129 */
+ KEY_UNKNOWN, /* 130 */
+ KEY_NFER, /* 131 */
+ KEY_XFER, /* 132 */
+ KEY_HKTG, /* 133 */
+ KEY_UNKNOWN, /* 134 */
+ /* The rest default to KEY_UNKNOWN */
+};
+
+/*
+ * sunPostKbdEvent --
+ * Translate the raw hardware Firm_event into an XEvent, and tell DIX
+ * about it. KeyCode preprocessing and so on is done ...
+ *
+ * Most of the Solaris stuff has whacked Panix/PC98 support in the
+ * interests of simplicity - DWH 8/30/99
+ */
+
+static void
+sunPostKbdEvent(Firm_event *event)
+{
+ int specialkey;
+ Bool down;
+ KeyClassRec *keyc = ((DeviceIntPtr)xf86Info.pKeyboard)->key;
+ Bool updateLeds = FALSE;
+ Bool UsePrefix = FALSE;
+ Bool Direction = FALSE;
+ xEvent kevent;
+ KeySym *keysym;
+ int keycode;
+ static int lockkeys = 0;
+
+ /* Give down a value */
+ if (event->value == VKEY_DOWN)
+ down = TRUE;
+ else
+ down = FALSE;
+
+ /*
+ * and now get some special keysequences
+ */
+
+ specialkey = map[event->id];
+
+ if ((ModifierDown(ControlMask | AltMask)) ||
+ (ModifierDown(ControlMask | AltLangMask)))
+ {
+ switch (specialkey) {
+
+ case KEY_BackSpace:
+ if (!xf86Info.dontZap) {
+ DGAShutdown();
+ GiveUp(0);
+ }
+ break;
+
+ /*
+ * The idea here is to pass the scancode down to a list of registered
+ * routines. There should be some standard conventions for processing
+ * certain keys.
+ */
+ case KEY_KP_Minus: /* Keypad - */
+ if (!xf86Info.dontZoom) {
+ if (down)
+ xf86ZoomViewport(xf86Info.currentScreen, -1);
+ return;
+ }
+ break;
+
+ case KEY_KP_Plus: /* Keypad + */
+ if (!xf86Info.dontZoom) {
+ if (down)
+ xf86ZoomViewport(xf86Info.currentScreen, 1);
+ return;
+ }
+ break;
+ }
+ }
+
+ /*
+ * Now map the scancodes to real X-keycodes ...
+ */
+ keycode = map[event->id];
+ if (keycode == KEY_NOTUSED) {
+ xf86MsgVerb(X_INFO, 0,
+ "raw code %d mapped to KEY_NOTUSED -- please report\n", event->id);
+ return;
+ }
+ if (keycode == KEY_UNKNOWN) {
+ xf86MsgVerb(X_INFO, 0,
+ "raw code %d mapped to KEY_UNKNOWN -- please report\n", event->id);
+ return;
+ }
+ keycode += MIN_KEYCODE;
+ keysym = keyc->curKeySyms.map +
+ (keyc->curKeySyms.mapWidth *
+ (keycode - keyc->curKeySyms.minKeyCode));
+
+#ifdef XKB
+ if (noXkbExtension)
+#endif
+ {
+ /*
+ * Toggle lock keys.
+ */
+#define CAPSFLAG 0x01
+#define NUMFLAG 0x02
+#define SCROLLFLAG 0x04
+#define MODEFLAG 0x08
+
+ if (down) {
+ /*
+ * Handle the KeyPresses of the lock keys.
+ */
+
+ switch (keysym[0]) {
+
+ case XK_Caps_Lock:
+ if (lockkeys & CAPSFLAG) {
+ lockkeys &= ~CAPSFLAG;
+ return;
+ }
+ lockkeys |= CAPSFLAG;
+ updateLeds = TRUE;
+ xf86Info.capsLock = down;
+ break;
+
+ case XK_Num_Lock:
+ if (lockkeys & NUMFLAG) {
+ lockkeys &= ~NUMFLAG;
+ return;
+ }
+ lockkeys |= NUMFLAG;
+ updateLeds = TRUE;
+ xf86Info.numLock = down;
+ break;
+
+ case XK_Scroll_Lock:
+ if (lockkeys & SCROLLFLAG) {
+ lockkeys &= ~SCROLLFLAG;
+ return;
+ }
+ lockkeys |= SCROLLFLAG;
+ updateLeds = TRUE;
+ xf86Info.scrollLock = down;
+ break;
+ }
+ } else {
+ /*
+ * Handle the releases of the lock keys.
+ */
+
+ switch (keysym[0]) {
+
+ case XK_Caps_Lock:
+ if (lockkeys & CAPSFLAG)
+ return;
+ updateLeds = TRUE;
+ xf86Info.capsLock = down;
+ break;
+
+ case XK_Num_Lock:
+ if (lockkeys & NUMFLAG)
+ return;
+ updateLeds = TRUE;
+ xf86Info.numLock = down;
+ break;
+
+ case XK_Scroll_Lock:
+ if (lockkeys & SCROLLFLAG)
+ return;
+ updateLeds = TRUE;
+ xf86Info.scrollLock = down;
+ break;
+ }
+ }
+
+ if (updateLeds)
+ xf86KbdLeds();
+
+ /*
+ * If this keycode is not a modifier key, and its down initiate the
+ * autorepeate sequence. (Only necessary if not using XKB).
+ *
+ * If its not down, then reset the timer.
+ */
+ if (!keyc->modifierMap[keycode]) {
+ if (down) {
+ startautorepeat(keycode);
+ } else {
+ TimerFree(sunTimer);
+ sunTimer = NULL;
+ }
+ }
+ }
+
+ xf86Info.lastEventTime =
+ kevent.u.keyButtonPointer.time =
+ GetTimeInMillis();
+
+ /*
+ * And now send these prefixes ...
+ * NOTE: There cannot be multiple Mode_Switch keys !!!!
+ */
+
+ ENQUEUE(&kevent, keycode, (down ? KeyPress : KeyRelease), XE_KEYBOARD);
+}
+
+/*
+ * Lets try reading more than one keyboard event at a time in the hopes that
+ * this will be slightly more efficient. Or we could just try the MicroSoft
+ * method, and forget about efficiency. :-)
+ */
+void
+xf86KbdEvents()
+{
+ Firm_event event[64];
+ int nBytes, i;
+
+ /* I certainly hope its not possible to read partial events */
+
+ if ((nBytes = read(xf86Info.kbdFd, (char *)event, sizeof(event))) > 0)
+ {
+ for (i = 0; i < (nBytes / sizeof(Firm_event)); i++)
+ sunPostKbdEvent(&event[i]);
+ }
+}
+
+/*
+ * Autorepeat stuff
+ */
+
+void
+startautorepeat(long keycode)
+{
+ sunTimer = TimerSet(sunTimer, /* Timer */
+ 0, /* Flags */
+ xf86Info.kbdDelay, /* millis */
+ processautorepeat, /* callback */
+ (pointer) keycode); /* arg for timer */
+}
+
+CARD32
+processautorepeat(OsTimerPtr timer, CARD32 now, pointer arg)
+{
+ xEvent kevent;
+ int keycode;
+
+ keycode = (long)arg;
+
+ xf86Info.lastEventTime =
+ kevent.u.keyButtonPointer.time =
+ GetTimeInMillis();
+
+ /*
+ * Repeat a key by faking a KeyRelease, and a KeyPress event in rapid
+ * succession
+ */
+
+ ENQUEUE(&kevent, keycode, KeyRelease, XE_KEYBOARD);
+ ENQUEUE(&kevent, keycode, KeyPress, XE_KEYBOARD);
+
+ /* And return the appropriate value so we get rescheduled */
+ return xf86Info.kbdRate;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_mouse.c b/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_mouse.c
new file mode 100644
index 000000000..cc3b7ec6b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_mouse.c
@@ -0,0 +1,316 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_mouse.c,v 1.2 2001/08/17 22:08:15 tsi Exp $ */
+/*
+ * Copyright 1999-2001 The XFree86 Project, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the XFree86 Project shall
+ * not be used in advertising or otherwise to promote the sale, use or other
+ * dealings in this Software without prior written authorization from the
+ * XFree86 Project.
+ */
+
+#include "xf86.h"
+#include "xf86_OSlib.h"
+#include "xf86OSmouse.h"
+
+#if defined(__SOL8__) || !defined(i386)
+
+#include "xisb.h"
+#include "mipointer.h"
+#include <sys/vuid_event.h>
+
+/* Names of protocols that are handled internally here. */
+
+static const char *internalNames[] = {
+ "VUID",
+ NULL
+};
+
+typedef struct _VuidMseRec {
+ Firm_event event;
+ unsigned char *buffer;
+} VuidMseRec, *VuidMsePtr;
+
+
+static int vuidMouseProc(DeviceIntPtr pPointer, int what);
+static void vuidReadInput(InputInfoPtr pInfo);
+
+/* This function is called when the protocol is "VUID". */
+static Bool
+vuidPreInit(InputInfoPtr pInfo, const char *protocol, int flags)
+{
+ MouseDevPtr pMse = pInfo->private;
+ VuidMsePtr pVuidMse;
+ int i;
+
+ pVuidMse = xalloc(sizeof(VuidMseRec));
+ if (pVuidMse == NULL) {
+ xf86Msg(X_ERROR, "%s: cannot allocate VuidMouseRec\n", pInfo->name);
+ xfree(pMse);
+ return FALSE;
+ }
+
+ pMse->protocol = protocol;
+ xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol);
+
+ /* Collect the options, and process the common options. */
+ xf86CollectInputOptions(pInfo, NULL, NULL);
+ xf86ProcessCommonOptions(pInfo, pInfo->options);
+
+ /* Check if the device can be opened. */
+ pInfo->fd = xf86OpenSerial(pInfo->options);
+ if (pInfo->fd == -1) {
+ if (xf86GetAllowMouseOpenFail())
+ xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
+ else {
+ xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name);
+ xfree(pVuidMse);
+ xfree(pMse);
+ return FALSE;
+ }
+ }
+ pVuidMse->buffer = (unsigned char *)&pVuidMse->event;
+ xf86CloseSerial(pInfo->fd);
+ pInfo->fd = -1;
+
+ /* Private structure */
+ pMse->mousePriv = pVuidMse;
+
+ /* Process common mouse options (like Emulate3Buttons, etc). */
+ pMse->CommonOptions(pInfo);
+
+ /* Setup the local procs. */
+ pInfo->device_control = vuidMouseProc;
+ pInfo->read_input = vuidReadInput;
+
+ pInfo->flags |= XI86_CONFIGURED;
+ return TRUE;
+}
+
+static void
+vuidReadInput(InputInfoPtr pInfo)
+{
+ MouseDevPtr pMse;
+ VuidMsePtr pVuidMse;
+ int buttons;
+ int dx = 0, dy = 0, dz = 0, dw = 0;
+ unsigned int n;
+ int c;
+ unsigned char *pBuf;
+
+ pMse = pInfo->private;
+ pVuidMse = pMse->mousePriv;
+ buttons = pMse->lastButtons;
+ XisbBlockDuration(pMse->buffer, -1);
+ pBuf = pVuidMse->buffer;
+ n = 0;
+
+ do {
+ while (n < sizeof(Firm_event) && (c = XisbRead(pMse->buffer)) >= 0) {
+ pBuf[n++] = (unsigned char)c;
+ }
+
+ if (n == 0)
+ return;
+
+ if (n != sizeof(Firm_event)) {
+ xf86Msg(X_WARNING, "%s: incomplete packet, size %d\n",
+ pInfo->name, n);
+ }
+
+ if (pVuidMse->event.id >= BUT_FIRST && pVuidMse->event.id <= BUT_LAST) {
+ /* button */
+ int butnum = pVuidMse->event.id - BUT_FIRST;
+ if (butnum < 3)
+ butnum = 2 - butnum;
+ if (!pVuidMse->event.value)
+ buttons &= ~(1 << butnum);
+ else
+ buttons |= (1 << butnum);
+ } else if (pVuidMse->event.id >= VLOC_FIRST &&
+ pVuidMse->event.id <= VLOC_LAST) {
+ /* axis */
+ int delta = pVuidMse->event.value;
+ switch(pVuidMse->event.id) {
+ case LOC_X_DELTA:
+ dx += delta;
+ break;
+ case LOC_Y_DELTA:
+ dy -= delta;
+ break;
+ }
+ }
+
+ n = 0;
+ if ((c = XisbRead(pMse->buffer)) >= 0) {
+ /* Another packet. Handle it right away. */
+ pBuf[n++] = c;
+ }
+ } while (n != 0);
+
+ pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw);
+ return;
+}
+
+#define NUMEVENTS 64
+
+static int
+vuidMouseProc(DeviceIntPtr pPointer, int what)
+{
+ InputInfoPtr pInfo;
+ MouseDevPtr pMse;
+ VuidMsePtr pVuidMse;
+ unsigned char map[MSE_MAXBUTTONS + 1];
+ int nbuttons;
+
+ pInfo = pPointer->public.devicePrivate;
+ pMse = pInfo->private;
+ pMse->device = pPointer;
+ pVuidMse = pMse->mousePriv;
+
+ switch (what) {
+ case DEVICE_INIT:
+ pPointer->public.on = FALSE;
+
+ for (nbuttons = 0; nbuttons < MSE_MAXBUTTONS; ++nbuttons)
+ map[nbuttons + 1] = nbuttons + 1;
+
+ InitPointerDeviceStruct((DevicePtr)pPointer,
+ map,
+ min(pMse->buttons, MSE_MAXBUTTONS),
+ miPointerGetMotionEvents,
+ pMse->Ctrl,
+ miPointerGetMotionBufferSize());
+
+ /* X valuator */
+ xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1);
+ xf86InitValuatorDefaults(pPointer, 0);
+ /* Y valuator */
+ xf86InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1);
+ xf86InitValuatorDefaults(pPointer, 1);
+ xf86MotionHistoryAllocate(pInfo);
+ break;
+
+ case DEVICE_ON:
+ pInfo->fd = xf86OpenSerial(pInfo->options);
+ if (pInfo->fd == -1)
+ xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
+ else {
+ pMse->buffer = XisbNew(pInfo->fd,
+ NUMEVENTS * sizeof(Firm_event));
+ if (!pMse->buffer) {
+ xfree(pMse);
+ xf86CloseSerial(pInfo->fd);
+ pInfo->fd = -1;
+ } else {
+ int fmt = VUID_FIRM_EVENT;
+ ioctl(pInfo->fd, VUIDSFORMAT, &fmt);
+ xf86FlushInput(pInfo->fd);
+ AddEnabledDevice(pInfo->fd);
+ }
+ }
+ pMse->lastButtons = 0;
+ pMse->emulateState = 0;
+ pPointer->public.on = TRUE;
+ break;
+
+ case DEVICE_OFF:
+ case DEVICE_CLOSE:
+ if (pInfo->fd != -1) {
+ RemoveEnabledDevice(pInfo->fd);
+ if (pMse->buffer) {
+ XisbFree(pMse->buffer);
+ pMse->buffer = NULL;
+ }
+ xf86CloseSerial(pInfo->fd);
+ pInfo->fd = -1;
+ }
+ pPointer->public.on = FALSE;
+ usleep(300000);
+ break;
+ }
+ return Success;
+}
+
+static Bool
+sunMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags)
+{
+ /* The protocol is guaranteed to be one of the internalNames[] */
+ if (xf86NameCmp(protocol, "VUID") == 0) {
+ return vuidPreInit(pInfo, protocol, flags);
+ }
+ return TRUE;
+}
+
+static const char **
+BuiltinNames(void)
+{
+ return internalNames;
+}
+
+static Bool
+CheckProtocol(const char *protocol)
+{
+ int i;
+
+ for (i = 0; internalNames[i]; i++)
+ if (xf86NameCmp(protocol, internalNames[i]) == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+static const char *
+DefaultProtocol(void)
+{
+ return "VUID";
+}
+
+#else /* __SOL8__ || !i386 */
+
+#undef MSE_MISC
+#define MSE_MISC 0
+
+#endif /* !__SOL8__ && i386 */
+
+static int
+SupportedInterfaces(void)
+{
+ /* XXX This needs to be checked. */
+ return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO | MSE_XPS2 | MSE_MISC;
+}
+
+OSMouseInfoPtr
+xf86OSMouseInit(int flags)
+{
+ OSMouseInfoPtr p;
+
+ p = xcalloc(sizeof(OSMouseInfoRec), 1);
+ if (!p)
+ return NULL;
+ p->SupportedInterfaces = SupportedInterfaces;
+#if defined(__SOL8__) || !defined(i386)
+ p->BuiltinNames = BuiltinNames;
+ p->DefaultProtocol = DefaultProtocol;
+ p->CheckProtocol = CheckProtocol;
+ p->PreInit = sunMousePreInit;
+#endif
+ return p;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_vid.c b/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_vid.c
new file mode 100644
index 000000000..15bf69b11
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_vid.c
@@ -0,0 +1,239 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_vid.c,v 1.1 2001/05/28 02:42:31 tsi Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * 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 names of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS 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.
+ *
+ */
+
+#ifdef i386
+#define _NEED_SYSI86
+#endif
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+/***************************************************************************/
+/* Video Memory Mapping section */
+/***************************************************************************/
+
+char *apertureDevName = NULL;
+
+Bool
+xf86LinearVidMem()
+{
+#ifdef i386
+ int mmapFd;
+
+ apertureDevName = "/dev/xsvc";
+ if ((mmapFd = open(apertureDevName, O_RDWR)) < 0)
+ {
+#ifndef __SOL8__
+ apertureDevName = "/dev/fbs/aperture";
+ if((mmapFd = open(apertureDevName, O_RDWR)) < 0)
+#endif
+ {
+ xf86Msg(X_WARNING,
+ "xf86LinearVidMem: failed to open %s (%s)\n",
+ apertureDevName, strerror(errno));
+ xf86Msg(X_WARNING, "xf86LinearVidMem:"
+#ifndef __SOL8__
+ " either /dev/fbs/aperture or"
+#endif
+ " /dev/xsvc device driver"
+ " required\n");
+ xf86Msg(X_WARNING,
+ "xf86LinearVidMem: linear memory access disabled\n");
+ return FALSE;
+ }
+ }
+ close(mmapFd);
+ return TRUE;
+#else /* i386 */
+ FatalError("xf86LinearVidMem() called\n");
+
+ return FALSE; /* Gd'ole gcc */
+#endif /* i386 */
+}
+
+pointer
+xf86MapVidMem(int ScreenNum, int Flags, unsigned long Base, unsigned long Size)
+{
+#ifdef i386
+ pointer base;
+ int fd;
+ char solx86_vtname[20];
+
+ /*
+ * Solaris 2.1 x86 SVR4 (10/27/93)
+ * The server must treat the virtual terminal device file as the
+ * standard SVR4 /dev/pmem.
+ *
+ * Using the /dev/vtXX device as /dev/pmem only works for the
+ * A0000-FFFFF region - If we wish you mmap the linear aperture
+ * it requires a device driver.
+ *
+ * So what we'll do is use /dev/vtXX for the A0000-FFFFF stuff, and
+ * try to use the /dev/fbs/aperture or /dev/xsvc driver if the server
+ * tries to mmap anything > FFFFF. Its very very unlikely that the
+ * server will try to mmap anything below FFFFF that can't be handled
+ * by /dev/vtXX.
+ *
+ * DWH - 2/23/94
+ * DWH - 1/31/99 (Gee has it really been 5 years?)
+ *
+ * Solaris 2.8 7/26/99
+ * Use /dev/xsvc for everything
+ *
+ * DWH - 7/26/99 - Solaris8/dev/xsvc changes
+ */
+
+#ifndef __SOL8__
+ if(Base < 0xFFFFF)
+ sprintf(solx86_vtname,"/dev/vt%02d",xf86Info.vtno);
+ else
+#endif
+ {
+ if (!apertureDevName)
+ if (!xf86LinearVidMem())
+ FatalError("xf86MapVidMem: Could not mmap "
+ "linear framebuffer [s=%x,a=%x]\n",
+ Size, Base);
+
+ sprintf(solx86_vtname, apertureDevName);
+ }
+
+ if ((fd = open(solx86_vtname, O_RDWR,0)) < 0)
+ {
+ FatalError("xf86MapVidMem: failed to open %s (%s)\n",
+ solx86_vtname, strerror(errno));
+ }
+ base = mmap((caddr_t)0, Size, PROT_READ|PROT_WRITE,
+ MAP_SHARED, fd, (off_t)Base);
+ close(fd);
+ if (base == MAP_FAILED)
+ {
+ FatalError("%s: Could not mmap framebuffer [s=%x,a=%x] (%s)\n",
+ "xf86MapVidMem", Size, Base, strerror(errno));
+ }
+ return(base);
+#else /* i386 */
+ FatalError("xf86MapVidMem() called\n");
+
+ return NULL; /* Gd'ole gcc */
+#endif
+}
+
+/* ARGSUSED */
+void
+xf86UnMapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+{
+ munmap(Base, Size);
+}
+
+/***************************************************************************/
+/* I/O Permissions section */
+/***************************************************************************/
+
+static Bool ExtendedEnabled = FALSE;
+
+void
+xf86EnableIO()
+{
+#ifdef i386
+ if (ExtendedEnabled)
+ return;
+
+ if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0)
+ FatalError("xf86EnableIOPorts: Failed to set IOPL for I/O\n");
+#endif /* i386 */
+
+ ExtendedEnabled = TRUE;
+}
+
+void
+xf86DisableIO()
+{
+#ifdef i386
+ if(!ExtendedEnabled)
+ return;
+
+ sysi86(SI86V86, V86SC_IOPL, 0);
+#endif /* i386 */
+
+ ExtendedEnabled = FALSE;
+}
+
+
+/***************************************************************************/
+/* Interrupt Handling section */
+/***************************************************************************/
+
+Bool xf86DisableInterrupts()
+{
+#ifdef i386
+ if (!ExtendedEnabled && (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0))
+ return FALSE;
+
+#ifdef __GNUC__
+ __asm__ __volatile__("cli");
+#else
+ asm("cli");
+#endif /* __GNUC__ */
+
+ if (!ExtendedEnabled)
+ sysi86(SI86V86, V86SC_IOPL, 0);
+#endif /* i386 */
+
+ return TRUE;
+}
+
+void xf86EnableInterrupts()
+{
+#ifdef i386
+ if (!ExtendedEnabled && (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0))
+ return;
+
+#ifdef __GNUC__
+ __asm__ __volatile__("sti");
+#else
+ asm("sti");
+#endif /* __GNUC__ */
+
+ if (!ExtendedEnabled)
+ sysi86(SI86V86, V86SC_IOPL, 0);
+#endif /* i386 */
+}
+
+void
+xf86MapReadSideEffects(int ScreenNum, int Flags, pointer Base,
+ unsigned long Size)
+{
+}
+
+Bool
+xf86CheckMTRR(int ScreenNum)
+{
+ return FALSE;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/xf86cfg/TODO b/xc/programs/Xserver/hw/xfree86/xf86cfg/TODO
new file mode 100644
index 000000000..75fe91b95
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf86cfg/TODO
@@ -0,0 +1,33 @@
+$XFree86: xc/programs/Xserver/hw/xfree86/xf86cfg/TODO,v 1.1 2001/07/04 16:09:14 paulo Exp $
+
+o Have code to fetch the SymTabRec chipset list from a video driver.
+ This is mostly useful for the testing tool/interface, so that the
+ Cards file "uptodate" state can also be verified.
+ Probably it is better to forgot about the Cards file, and
+ either parse the output of scanpci, or link libscanpci.a
+ (and whatever else be required) in xf86cfg.
+
+o Check if a module is "certified", there was some talk about a
+ certification process in the past.
+
+o Rewrite mouse driver to use the same code as video drivers, so that
+ it is possible to store all available options in a single place.
+ This would also require rewriting all existing input device modules.
+ (Probably most of this can be made with cpp macros).
+
+o Create a protocol to allow 3rd part xf86cfg modules.
+
+o Write an interface for testing extensions/accel, maybe a frontend to
+ xdpyinfo, x11perf, glxinfo, etc.
+
+o Write a "wizard" mode, as several users find the graphical interface
+ too complicated, but find the text one easier to user.
+
+o Write code to use a Monitors database, either update the old Monitors
+ file or use RedHat MonitorsDB.
+ Chris Morgan is writting code to use MonitorsDB.
+ If xf86cfg could be changed to ddcprobe (in all supported platforms),
+ it would be even be a better solution than using a database.
+
+o Add interface to allow changing comments without the need of editing
+ XF86Config with a text editor.
diff --git a/xc/programs/Xserver/hw/xfree86/xf86cfg/loadmod.c b/xc/programs/Xserver/hw/xfree86/xf86cfg/loadmod.c
new file mode 100644
index 000000000..d1f78a64c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf86cfg/loadmod.c
@@ -0,0 +1,595 @@
+/*
+ * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * CONECTIVA LINUX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Conectiva Linux shall
+ * not be used in advertising or otherwise to promote the sale, use or other
+ * dealings in this Software without prior written authorization from
+ * Conectiva Linux.
+ *
+ * Author: Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
+ *
+ * $XFree86: xc/programs/Xserver/hw/xfree86/xf86cfg/loadmod.c,v 1.7 2001/08/01 00:44:57 tsi Exp $
+ */
+
+#ifdef USE_MODULES
+#define LOADER_PRIVATE
+#include "loader.h"
+
+#define True 1
+#define False 0
+#define XtPointer char*
+#define XtMalloc malloc
+#define XtCalloc calloc
+#define XtRealloc realloc
+#define XtFree free
+#define XtNew(t) malloc(sizeof(t))
+#define XtNewString(s) ((s) ? strdup(s) : NULL)
+
+#define pointer void*
+
+/* XXX beware (or fix it) libc functions called here are the xf86 ones */
+
+static void AddModuleOptions(char*, const OptionInfoRec*);
+#if 0
+void xf86AddDriver(DriverPtr, void*, int);
+Bool xf86ServerIsOnlyDetecting(void);
+void xf86AddInputDriver(InputDriverPtr, pointer, int);
+void xf86AddModuleInfo(ModuleInfoPtr, void*);
+Bool xf86LoaderCheckSymbol(const char*);
+void xf86LoaderReqSymLists(const char **, ...);
+void xf86Msg(int, const char*, ...);
+void xf86PrintChipsets(const char*, const char*, SymTabPtr);
+void xf86ErrorFVerb(int verb, const char *format, ...);
+pciVideoPtr *xf86GetPciVideoInfo(void);
+int xf86MatchDevice(const char*, GDevPtr**);
+int xf86MatchPciInstances(const char*, int, SymTabPtr, PciChipsets*, GDevPtr*, int, DriverPtr,int**);
+int xf86MatchIsaInstances(const char*, SymTabPtr, pointer*, DriverPtr, pointer, GDevPtr*, int, int**);
+void *xf86LoadDrvSubModule(DriverPtr drv, const char*);
+void xf86DrvMsg(int, int, const char*, ...);
+#endif
+void *xf86GetPciConfigInfo(void);
+
+extern char *loaderPath, **loaderList, **ploaderList;
+xf86cfgModuleOptions *module_options;
+FontModule *font_module;
+int numFontModules;
+
+extern int noverify, error_level;
+
+int xf86ShowUnresolved = 1;
+
+LOOKUP miLookupTab[] = {{0,0}};
+LOOKUP dixLookupTab[] = {{0,0}};
+LOOKUP fontLookupTab[] = {{0,0}};
+LOOKUP extLookupTab[] = {{0,0}};
+LOOKUP xfree86LookupTab[] = {
+ /* Loader functions */
+ SYMFUNC(LoaderDefaultFunc)
+ SYMFUNC(LoadSubModule)
+ SYMFUNC(DuplicateModule)
+ SYMFUNC(LoaderErrorMsg)
+ SYMFUNC(LoaderCheckUnresolved)
+ SYMFUNC(LoadExtension)
+ SYMFUNC(LoadFont)
+ SYMFUNC(LoaderReqSymbols)
+ SYMFUNC(LoaderReqSymLists)
+ SYMFUNC(LoaderRefSymbols)
+ SYMFUNC(LoaderRefSymLists)
+ SYMFUNC(UnloadSubModule)
+ SYMFUNC(LoaderSymbol)
+ SYMFUNC(LoaderListDirs)
+ SYMFUNC(LoaderFreeDirList)
+ SYMFUNC(LoaderGetOS)
+
+ /*
+ * these here are our own interfaces to libc functions
+ */
+ SYMFUNC(xf86abort)
+ SYMFUNC(xf86abs)
+ SYMFUNC(xf86acos)
+ SYMFUNC(xf86asin)
+ SYMFUNC(xf86atan)
+ SYMFUNC(xf86atan2)
+ SYMFUNC(xf86atof)
+ SYMFUNC(xf86atoi)
+ SYMFUNC(xf86atol)
+ SYMFUNC(xf86bsearch)
+ SYMFUNC(xf86ceil)
+ SYMFUNC(xf86calloc)
+ SYMFUNC(xf86clearerr)
+ SYMFUNC(xf86close)
+ SYMFUNC(xf86cos)
+ SYMFUNC(xf86exit)
+ SYMFUNC(xf86exp)
+ SYMFUNC(xf86fabs)
+ SYMFUNC(xf86fclose)
+ SYMFUNC(xf86feof)
+ SYMFUNC(xf86ferror)
+ SYMFUNC(xf86fflush)
+ SYMFUNC(xf86fgetc)
+ SYMFUNC(xf86fgetpos)
+ SYMFUNC(xf86fgets)
+ SYMFUNC(xf86floor)
+ SYMFUNC(xf86fmod)
+ SYMFUNC(xf86fopen)
+ SYMFUNC(xf86fprintf)
+ SYMFUNC(xf86fputc)
+ SYMFUNC(xf86fputs)
+ SYMFUNC(xf86fread)
+ SYMFUNC(xf86free)
+ SYMFUNC(xf86freopen)
+ SYMFUNC(xf86frexp)
+ SYMFUNC(xf86fscanf)
+ SYMFUNC(xf86fseek)
+ SYMFUNC(xf86fsetpos)
+ SYMFUNC(xf86ftell)
+ SYMFUNC(xf86fwrite)
+ SYMFUNC(xf86getc)
+ SYMFUNC(xf86getenv)
+ SYMFUNC(xf86getpagesize)
+ SYMFUNC(xf86hypot)
+ SYMFUNC(xf86ioctl)
+ SYMFUNC(xf86isalnum)
+ SYMFUNC(xf86isalpha)
+ SYMFUNC(xf86iscntrl)
+ SYMFUNC(xf86isdigit)
+ SYMFUNC(xf86isgraph)
+ SYMFUNC(xf86islower)
+ SYMFUNC(xf86isprint)
+ SYMFUNC(xf86ispunct)
+ SYMFUNC(xf86isspace)
+ SYMFUNC(xf86isupper)
+ SYMFUNC(xf86isxdigit)
+ SYMFUNC(xf86labs)
+ SYMFUNC(xf86ldexp)
+ SYMFUNC(xf86log)
+ SYMFUNC(xf86log10)
+ SYMFUNC(xf86lseek)
+ SYMFUNC(xf86malloc)
+ SYMFUNC(xf86memchr)
+ SYMFUNC(xf86memcmp)
+ SYMFUNC(xf86memcpy)
+#if (defined(__powerpc__) && (defined(Lynx) || defined(linux))) || defined(__sparc__) || defined(__ia64__)
+ /*
+ * Some PPC, SPARC, and IA64 compilers generate calls to memcpy to handle
+ * structure copies. This causes a problem both here and in shared
+ * libraries as there is no way to map the name of the call to the
+ * correct function.
+ */
+ SYMFUNC(memcpy)
+ /*
+ * Some PPC, SPARC, and IA64 compilers generate calls to memset to handle
+ * aggregate initializations.
+ */
+ SYMFUNC(memset)
+#endif
+ SYMFUNC(xf86memmove)
+ SYMFUNC(xf86memset)
+ SYMFUNC(xf86mmap)
+ SYMFUNC(xf86modf)
+ SYMFUNC(xf86munmap)
+ SYMFUNC(xf86open)
+ SYMFUNC(xf86perror)
+ SYMFUNC(xf86pow)
+ SYMFUNC(xf86printf)
+ SYMFUNC(xf86qsort)
+ SYMFUNC(xf86read)
+ SYMFUNC(xf86realloc)
+ SYMFUNC(xf86remove)
+ SYMFUNC(xf86rename)
+ SYMFUNC(xf86rewind)
+ SYMFUNC(xf86setbuf)
+ SYMFUNC(xf86setvbuf)
+ SYMFUNC(xf86sin)
+ SYMFUNC(xf86snprintf)
+ SYMFUNC(xf86sprintf)
+ SYMFUNC(xf86sqrt)
+ SYMFUNC(xf86sscanf)
+ SYMFUNC(xf86strcat)
+ SYMFUNC(xf86strcmp)
+ SYMFUNC(xf86strcasecmp)
+ SYMFUNC(xf86strcpy)
+ SYMFUNC(xf86strcspn)
+ SYMFUNC(xf86strerror)
+ SYMFUNC(xf86strlen)
+ SYMFUNC(xf86strncmp)
+ SYMFUNC(xf86strncasecmp)
+ SYMFUNC(xf86strncpy)
+ SYMFUNC(xf86strpbrk)
+ SYMFUNC(xf86strchr)
+ SYMFUNC(xf86strrchr)
+ SYMFUNC(xf86strspn)
+ SYMFUNC(xf86strstr)
+ SYMFUNC(xf86strtod)
+ SYMFUNC(xf86strtok)
+ SYMFUNC(xf86strtol)
+ SYMFUNC(xf86strtoul)
+ SYMFUNC(xf86tan)
+ SYMFUNC(xf86tmpfile)
+ SYMFUNC(xf86tolower)
+ SYMFUNC(xf86toupper)
+ SYMFUNC(xf86ungetc)
+ SYMFUNC(xf86vfprintf)
+ SYMFUNC(xf86vsnprintf)
+ SYMFUNC(xf86vsprintf)
+ SYMFUNC(xf86write)
+
+/* non-ANSI C functions */
+ SYMFUNC(xf86opendir)
+ SYMFUNC(xf86closedir)
+ SYMFUNC(xf86readdir)
+ SYMFUNC(xf86rewinddir)
+ SYMFUNC(xf86ffs)
+ SYMFUNC(xf86strdup)
+ SYMFUNC(xf86bzero)
+ SYMFUNC(xf86usleep)
+ SYMFUNC(xf86execl)
+
+ SYMFUNC(xf86getsecs)
+ SYMFUNC(xf86fpossize) /* for returning sizeof(fpos_t) */
+
+ SYMFUNC(xf86stat)
+ SYMFUNC(xf86fstat)
+ SYMFUNC(xf86access)
+ SYMFUNC(xf86geteuid)
+ SYMFUNC(xf86getegid)
+ SYMFUNC(xf86getpid)
+ SYMFUNC(xf86mknod)
+ SYMFUNC(xf86chmod)
+ SYMFUNC(xf86chown)
+ SYMFUNC(xf86sleep)
+ SYMFUNC(xf86mkdir)
+ SYMFUNC(xf86shmget)
+ SYMFUNC(xf86shmat)
+ SYMFUNC(xf86shmdt)
+ SYMFUNC(xf86shmctl)
+ SYMFUNC(xf86setjmp)
+ SYMFUNC(xf86longjmp)
+
+ SYMFUNC(xf86AddDriver)
+ SYMFUNC(xf86ServerIsOnlyDetecting)
+ SYMFUNC(xf86AddInputDriver)
+ SYMFUNC(xf86AddModuleInfo)
+ SYMFUNC(xf86LoaderCheckSymbol)
+
+ SYMFUNC(xf86LoaderReqSymLists)
+ SYMFUNC(xf86Msg)
+ SYMFUNC(ErrorF)
+ SYMFUNC(xf86PrintChipsets)
+ SYMFUNC(xf86ErrorFVerb)
+ SYMFUNC(xf86GetPciVideoInfo)
+ SYMFUNC(xf86MatchDevice)
+ SYMFUNC(xf86MatchPciInstances)
+ SYMFUNC(xf86MatchIsaInstances)
+ SYMFUNC(Xfree)
+ SYMFUNC(xf86LoadDrvSubModule)
+ SYMFUNC(xf86DrvMsg)
+ SYMFUNC(xf86GetPciConfigInfo)
+ {0,0}
+};
+
+static DriverPtr driver;
+static ModuleInfoPtr info;
+static SymTabPtr chips;
+static int vendor;
+ModuleType module_type = GenericModule;
+
+static void
+AddModuleOptions(char *name, const OptionInfoRec *option)
+{
+ xf86cfgModuleOptions *ptr;
+ const OptionInfoRec *tmp;
+ SymTabPtr ctmp;
+ int count;
+
+ ptr = XtNew(xf86cfgModuleOptions);
+ ptr->name = XtNewString(name);
+ ptr->type = module_type;
+ if (option) {
+ for (count = 0, tmp = option; tmp->name != NULL; tmp++, count++)
+ ;
+ ++count;
+ ptr->option = XtCalloc(1, count * sizeof(OptionInfoRec));
+ for (count = 0, tmp = option; tmp->name != NULL; count++, tmp++) {
+ memcpy(&ptr->option[count], tmp, sizeof(OptionInfoRec));
+ ptr->option[count].name = XtNewString(tmp->name);
+ if (tmp->type == OPTV_STRING || tmp->type == OPTV_ANYSTR)
+ ptr->option[count].value.str = XtNewString(tmp->value.str);
+ }
+ }
+ else
+ ptr->option = NULL;
+ if (vendor != -1 && chips) {
+ ptr->vendor = vendor;
+ for (count = 0, ctmp = chips; ctmp->name; ctmp++, count++)
+ ;
+ ++count;
+ ptr->chipsets = XtCalloc(1, count * sizeof(SymTabRec));
+ for (count = 0, ctmp = chips; ctmp->name != NULL; count++, ctmp++) {
+ memcpy(&ptr->chipsets[count], ctmp, sizeof(SymTabRec));
+ ptr->chipsets[count].name = XtNewString(ctmp->name);
+ }
+ }
+ else
+ ptr->chipsets = NULL;
+
+ ptr->next = module_options;
+ module_options = ptr;
+}
+
+extern void xf86WrapperInit(void);
+
+void
+xf86cfgLoaderInit(void)
+{
+ LoaderInit();
+ xf86WrapperInit();
+}
+
+void
+xf86cfgLoaderInitList(int type)
+{
+ static const char *generic[] = {
+ ".",
+ NULL
+ };
+ static const char *video[] = {
+ "drivers",
+ NULL
+ };
+ static const char *input[] = {
+ "input",
+ NULL
+ };
+ static const char *font[] = {
+ "fonts",
+ NULL
+ };
+ const char **subdirs;
+
+ switch (type) {
+ case GenericModule:
+ subdirs = generic;
+ break;
+ case VideoModule:
+ subdirs = video;
+ break;
+ case InputModule:
+ subdirs = input;
+ break;
+ case FontRendererModule:
+ subdirs = font;
+ break;
+ default:
+ fprintf(stderr, "Invalid value passed to xf86cfgLoaderInitList.\n");
+ subdirs = generic;
+ break;
+ }
+ LoaderSetPath(loaderPath);
+ loaderList = LoaderListDirs(subdirs, NULL);
+}
+
+void
+xf86cfgLoaderFreeList(void)
+{
+ LoaderFreeDirList(loaderList);
+}
+
+int
+xf86cfgCheckModule(void)
+{
+ int errmaj, errmin;
+ ModuleDescPtr module;
+ int nfonts;
+ FontModule *fonts, *pfont_module;
+
+ driver = NULL;
+ chips = NULL;
+ info = NULL;
+ pfont_module = NULL;
+ vendor = -1;
+ module_type = GenericModule;
+
+ if ((module = LoadModule(*ploaderList, NULL, NULL, NULL, NULL,
+ NULL, &errmaj, &errmin)) == NULL) {
+ LoaderErrorMsg(NULL, *ploaderList, errmaj, errmin);
+ return (0);
+ }
+ else if (driver && driver->AvailableOptions) {
+ /* at least fbdev does not call xf86MatchPciInstances in Probe */
+ if (driver->Identify)
+ (*driver->Identify)(-1);
+ if (driver->Probe)
+ (*driver->Probe)(driver, PROBE_DETECT);
+ AddModuleOptions(*ploaderList, (*driver->AvailableOptions)(-1, -1));
+ }
+ else if (info && info->AvailableOptions)
+ AddModuleOptions(*ploaderList, (*info->AvailableOptions)(NULL));
+
+ if (!noverify) {
+ XF86ModuleData *initdata = NULL;
+ char *p;
+
+ p = XtMalloc(strlen(*ploaderList) + strlen("ModuleData") + 1);
+ strcpy(p, *ploaderList);
+ strcat(p, "ModuleData");
+ initdata = LoaderSymbol(p);
+ if (initdata) {
+ XF86ModuleVersionInfo *vers;
+
+ vers = initdata->vers;
+ if (vers && strcmp(*ploaderList, vers->modname)) {
+ /* This was a problem at some time for some video drivers */
+ CheckMsg(CHECKER_FILE_MODULE_NAME_MISMATCH,
+ "WARNING file/module name mismatch: \"%s\" \"%s\"\n",
+ *ploaderList, vers->modname);
+ ++error_level;
+ }
+ }
+ XtFree(p);
+ }
+
+ nfonts = numFontModules;
+ numFontModules = 0;
+ fonts = FontModuleList;
+ if (fonts) {
+ while (fonts->name) {
+ if (strcmp(fonts->name, *ploaderList) == 0)
+ pfont_module = fonts;
+ ++numFontModules;
+ ++fonts;
+ }
+ }
+ if (pfont_module)
+ module_type = FontRendererModule;
+ else if (nfonts + 1 <= numFontModules) {
+ /* loader.c will flag a warning if -noverify is not set */
+ pfont_module = &FontModuleList[nfonts];
+ module_type = FontRendererModule;
+ }
+
+ if (font_module) {
+ XtFree((XtPointer)font_module->name);
+ XtFree((XtPointer)font_module);
+ font_module = NULL;
+ }
+ if (pfont_module) {
+ font_module = XtNew(FontModule);
+ memcpy(font_module, pfont_module, sizeof(FontModule));
+ font_module->name = XtNewString(pfont_module->name);
+ }
+
+ UnloadModule(module);
+
+ return (1);
+}
+
+void
+xf86AddDriver(DriverPtr drv, void *module, int flags)
+{
+ driver = drv;
+ if (driver)
+ driver->module = module;
+ module_type = VideoModule;
+}
+
+Bool
+xf86ServerIsOnlyDetecting(void)
+{
+ return (True);
+}
+
+void
+xf86AddInputDriver(InputDriverPtr inp, void *module, int flags)
+{
+ module_type = InputModule;
+}
+
+void
+xf86AddModuleInfo(ModuleInfoPtr inf, void *module)
+{
+ info = inf;
+}
+
+Bool
+xf86LoaderCheckSymbol(const char *symbol)
+{
+ return LoaderSymbol(symbol) != NULL;
+}
+
+void
+xf86LoaderReqSymLists(const char **list0, ...)
+{
+}
+
+#if 0
+void xf86Msg(int type, const char *format, ...)
+{
+}
+#endif
+
+/*ARGSUSED*/
+void
+xf86PrintChipsets(const char *name, const char *msg, SymTabPtr chipsets)
+{
+ vendor = 0;
+ chips = chipsets;
+}
+
+pciVideoPtr *
+xf86GetPciVideoInfo(void)
+{
+ static pciVideoRec pci_video;
+ static pciVideoPtr pci_video_ptr[2] = { &pci_video };
+
+ memset(&pci_video, 0, sizeof(pciVideoRec));
+
+ return (pci_video_ptr);
+}
+
+int
+xf86MatchDevice(const char *name, GDevPtr **gdev)
+{
+ *gdev = NULL;
+
+ return (1);
+}
+
+int
+xf86MatchPciInstances(const char *name, int VendorID, SymTabPtr chipsets, PciChipsets *PCIchipsets,
+ GDevPtr *devList, int numDevs, DriverPtr drvp, int **foundEntities)
+{
+ vendor = VendorID;
+ chips = chipsets;
+ *foundEntities = NULL;
+
+ return (0);
+}
+
+int
+xf86MatchIsaInstances(const char *name, SymTabPtr chipsets, IsaChipsets *ISAchipsets, DriverPtr drvp,
+ FindIsaDevProc FindIsaDevice, GDevPtr *devList, int numDevs, int **foundEntities)
+{
+ *foundEntities = NULL;
+
+ return (0);
+}
+
+/*ARGSUSED*/
+void *
+xf86LoadDrvSubModule(DriverPtr drv, const char *name)
+{
+ pointer ret;
+ int errmaj = 0, errmin = 0;
+
+ ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL,
+ &errmaj, &errmin);
+ if (!ret)
+ LoaderErrorMsg(NULL, name, errmaj, errmin);
+ return (ret);
+}
+
+void *
+xf86GetPciConfigInfo(void)
+{
+ return (NULL);
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xwin/XWin.man b/xc/programs/Xserver/hw/xwin/XWin.man
new file mode 100644
index 000000000..b48ae6ddc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xwin/XWin.man
@@ -0,0 +1,86 @@
+.\" $XFree86: xc/programs/Xserver/hw/xwin/XWin.man,v 1.2 2001/07/29 22:08:15 tsi Exp $
+.TH XWIN 1 __vendorversion__
+.SH NAME
+XWin \- X Server for the Cygwin environment on Microsoft Windows
+.SH SYNOPSIS
+.B XWin
+[ options ] ...
+.SH DESCRIPTION
+.I XWin
+is an X Server for the X Window System on the Cygwin environment
+running on Microsoft Windows.
+.SH OPTIONS
+.PP
+In addition to the normal server options described in the \fIXserver(1)\fP
+manual page, \fIXWin\fP accepts the following command line switches:
+.TP 8
+.B "\-depth \fIdepth\fP"
+Specify the color depth, in bits per pixel, to use when running in
+fullscreen with a DirectDraw engine. This parameter is ignored if
+\fB\-fullscreen\fP is not specified.
+.TP 8
+.B "\-emulate3buttons \fItimeout\fP"
+Emulate a three button mouse; pressing both buttons within
+.I timeout
+milliseconds causes an emulated middle button press. The default
+.I timeout
+is 50 milliseconds.
+.TP 8
+.B "\-engine \fIengine_type_id\fP"
+Override the server's automatically supported engine type. This
+parameter will be ignored if the specified engine type is not
+supported on the current system. The supported engine type ids are 1
+- Windows GDI, 2 - DirectDraw, and 4 - DirectDraw4.
+.TP 8
+.B \-fullscreen
+Run the server in fullscreen mode, as opposed to the default windowed
+mode.
+.TP 8
+.B "\-screen \fIscreen_number\fP \fIwidth\fP \fIheight\fP"
+Sets the display resolution for the X server to use on screen
+.I screen_number.
+.SH "SEE ALSO"
+.PP
+X(__miscmansuffix__), Xserver(1), xdm(1), xinit(1)
+.SH BUGS
+.I XWin
+and this man page still have many limitations. Some of the more obvious
+ones are:
+.br
+- The display mode can not be changed once the X server has started.
+.br
+- Locking your Windows NT Workstation with Ctrl-Alt-Del while
+.I XWin has the keyboard focus causes the keyboard to misbehave in
+.I XWin until you press and release the Ctrl key and Alt key once.
+.PP
+.SH AUTHORS
+XFree86 was originally ported to Cygwin by Dakshinamurthy Karra,
+Dr. Peter Busch, John Fortin, and Suhaib Siddiqi.
+.I XWin
+is maintained by the Cygwin/XFree86 project, with hosting services
+provided by RedHat.
+.PP
+The following members, in alphabetical order by last name, of the
+Cygwin/XFree86 Team contributed to the XFree86 4.1.0 release:
+.PP
+Robert Collins - Lead website maintainer
+.br
+Christopher Faylor - Management of hosting services, general
+programming guru
+.br
+Alexander Gottwald - AltGr handling for non-U.S. keyboards
+.br
+Alan Hourihane - Developer, patch reviewer, general programming guru
+.br
+Pierre A Humblet - Debugging of socket-related crashes, developer
+.br
+Harold L Hunt II - Lead developer, documentation, and minor website updates
+.br
+Suhaib Siddiqi - Project lead
+
+
+
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xwin/wincutpaste.c b/xc/programs/Xserver/hw/xwin/wincutpaste.c
new file mode 100644
index 000000000..3897dfa48
--- /dev/null
+++ b/xc/programs/Xserver/hw/xwin/wincutpaste.c
@@ -0,0 +1,53 @@
+/* $XFree86: xc/programs/Xserver/hw/xwin/wincutpaste.c,v 1.1 2001/06/25 08:12:33 alanh Exp $ */
+#include "win.h"
+#define NEED_EVENTS
+#include <X.h>
+#include <Xproto.h>
+#include "selection.h"
+#include "input.h"
+#include <Xatom.h>
+
+extern WindowPtr *WindowTable; /* Why isn't this in a header file? */
+extern Selection *CurrentSelections;
+extern int NumCurrentSelections;
+
+
+static Bool inSetXCutText = FALSE;
+
+void
+winSetXCutText (char *str, int len)
+{
+ int i = 0;
+
+ inSetXCutText = TRUE;
+ ChangeWindowProperty (WindowTable[0], XA_CUT_BUFFER0, XA_STRING,
+ 8, PropModeReplace, len,
+ (pointer)str, TRUE);
+
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != XA_PRIMARY)
+ i++;
+
+ if (i < NumCurrentSelections) {
+ xEvent event;
+
+ if (CurrentSelections[i].client) {
+ event.u.u.type = SelectionClear;
+ event.u.selectionClear.time = GetTimeInMillis();
+ event.u.selectionClear.window = CurrentSelections[i].window;
+ event.u.selectionClear.atom = CurrentSelections[i].selection;
+ (void) TryClientEvents (CurrentSelections[i].client,
+ &event,
+ 1,
+ NoEventMask,
+ NoEventMask,
+ NullGrab);
+ }
+
+ CurrentSelections[i].window = None;
+ CurrentSelections[i].pWin = NULL;
+ CurrentSelections[i].client = NullClient;
+ }
+
+ inSetXCutText = FALSE;
+}
diff --git a/xc/programs/Xserver/hw/xwin/winlayer.c b/xc/programs/Xserver/hw/xwin/winlayer.c
new file mode 100644
index 000000000..ab15dcf6f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xwin/winlayer.c
@@ -0,0 +1,236 @@
+/*
+ *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
+ *
+ *Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ *"Software"), to deal in the Software without restriction, including
+ *without limitation the rights to use, copy, modify, merge, publish,
+ *distribute, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
+ *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *Except as contained in this notice, the name of the XFree86 Project
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from the XFree86 Project.
+ *
+ * Authors: Harold L Hunt II
+ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winlayer.c,v 1.6 2001/08/16 08:23:36 alanh Exp $ */
+
+#include "win.h"
+
+
+/*
+ * Create initial layer. Cygwin only needs one initial layer.
+ */
+
+LayerPtr
+winLayerCreate (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ PixmapPtr pPixmap = NULL;
+ DWORD dwLayerKind;
+
+ ErrorF ("winLayerCreate () - dwDepth %d\n",
+ pScreenInfo->dwDepth);
+
+ /* We only need a single layer kind: shadow */
+ dwLayerKind = LAYER_SHADOW;
+ pPixmap = LAYER_SCREEN_PIXMAP;
+
+ return LayerCreate (pScreen,
+ dwLayerKind,
+ pScreenInfo->dwDepth,
+ pPixmap,
+ pScreenPriv->pwinShadowUpdate,
+ NULL, /* No ShadowWindowProc */
+ 0, /* Rotate */
+ 0);
+}
+
+#ifdef RANDR
+/*
+ * Used as a function parameter to WalkTree.
+ */
+
+int
+winLayerAdd (WindowPtr pWindow, pointer value)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ LayerPtr pLayer = (LayerPtr) value;
+
+ ErrorF ("winLayerAdd ()\n");
+
+ if (!LayerWindowAdd (pScreen, pLayer, pWindow))
+ return WT_STOPWALKING;
+
+ return WT_WALKCHILDREN;
+}
+
+
+/*
+ * Used as a function parameter to WalkTree.
+ */
+
+int
+winLayerRemove (WindowPtr pWindow, pointer value)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ LayerPtr pLayer = (LayerPtr) value;
+
+ ErrorF ("winLayerRemove ()\n");
+
+ LayerWindowRemove (pScreen, pLayer, pWindow);
+
+ return WT_WALKCHILDREN;
+}
+
+
+/*
+ * Answer queries about the RandR features supported.
+ */
+
+Bool
+winRandRGetInfo (ScreenPtr pScreen, Rotation *pRotations)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ int n;
+ RRVisualGroupPtr pVisualGroup;
+ RRGroupOfVisualGroupPtr pGroupOfVisualGroup = NULL;
+ Rotation rotateKind;
+ RRScreenSizePtr pSize;
+
+ ErrorF ("winRandRGetInfo ()\n");
+
+ /* Don't support rotations, yet */
+ *pRotations = RR_Rotate_0; /* | RR_Rotate_90 | RR_Rotate_180 | ... */
+
+ /* Check for something naughty. Don't know what exactly... */
+ for (n = 0; n < pScreen->numDepths; n++)
+ if (pScreen->allowedDepths[n].numVids)
+ break;
+ if (n == pScreen->numDepths)
+ return FALSE;
+
+ /* Create an RandR visual group */
+ pVisualGroup = RRCreateVisualGroup (pScreen);
+ if (!pVisualGroup)
+ return FALSE;
+
+
+ /* Not sure what this does */
+ if (!RRAddDepthToVisualGroup (pScreen,
+ pVisualGroup,
+ &pScreen->allowedDepths[n]))
+ {
+ RRDestroyVisualGroup (pScreen, pVisualGroup);
+ return FALSE;
+ }
+
+ /* Register the RandR visual group */
+ pVisualGroup = RRRegisterVisualGroup (pScreen, pVisualGroup);
+ if (!pVisualGroup)
+ return FALSE;
+
+ pGroupOfVisualGroup = RRRegisterGroupOfVisualGroup (pScreen,
+ pGroupOfVisualGroup);
+
+ /* You have to be kidding */
+ if (!RRAddVisualGroupToGroupOfVisualGroup (pScreen,
+ pGroupOfVisualGroup,
+ pVisualGroup))
+ {
+ RRDestroyGroupOfVisualGroup (pScreen, pGroupOfVisualGroup);
+ /* pVisualGroup left until screen closed */
+ return FALSE;
+ }
+
+ /* I can't afford a clue */
+ pGroupOfVisualGroup = RRRegisterGroupOfVisualGroup (pScreen,
+ pGroupOfVisualGroup);
+ if (!pGroupOfVisualGroup)
+ return FALSE;
+
+ /*
+ * Register supported sizes. This can be called many times, but
+ * we only support one size for now.
+ */
+ pSize = RRRegisterSize (pScreen,
+ pScreenInfo->dwWidth,
+ pScreenInfo->dwHeight,
+ pScreenInfo->dwWidth_mm,
+ pScreenInfo->dwHeight_mm,
+ pGroupOfVisualGroup);
+
+ /* Only one allowed rotation for now */
+ rotateKind = RR_Rotate_0;
+
+ /* Tell RandR what the current config is */
+ RRSetCurrentConfig (pScreen, rotateKind, pSize, pVisualGroup);
+
+ return TRUE;
+}
+
+
+/*
+ * Configure which RandR features are supported.
+ */
+
+Bool
+winRandRSetConfig (ScreenPtr pScreen,
+ Rotation rotateKind,
+ RRScreenSizePtr pSize,
+ RRVisualGroupPtr pVisualGroup)
+{
+ ErrorF ("winRandRSetConfig ()\n");
+
+ /*
+ * Apparently the only thing that can change is rotation.
+ * We don't support rotation, so that means nothing can change, right?
+ */
+
+ assert (rotateKind == RR_Rotate_0);
+
+ return TRUE;
+}
+
+
+/*
+ * Initialize the RandR layer.
+ */
+
+Bool
+winRandRInit (ScreenPtr pScreen)
+{
+ rrScrPrivPtr pRRScrPriv;
+
+ ErrorF ("winRandRInit ()\n");
+
+ if (!RRScreenInit (pScreen))
+ {
+ ErrorF ("winRandRInit () - RRScreenInit () failed\n");
+ return FALSE;
+ }
+
+ /* Set some RandR function pointers */
+ pRRScrPriv = rrGetScrPriv (pScreen);
+ pRRScrPriv->rrGetInfo = winRandRGetInfo;
+ pRRScrPriv->rrSetConfig = winRandRSetConfig;
+
+ return TRUE;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xwin/winnativegdi.c b/xc/programs/Xserver/hw/xwin/winnativegdi.c
new file mode 100644
index 000000000..19ef4fbcf
--- /dev/null
+++ b/xc/programs/Xserver/hw/xwin/winnativegdi.c
@@ -0,0 +1,387 @@
+/*
+ *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
+ *
+ *Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ *"Software"), to deal in the Software without restriction, including
+ *without limitation the rights to use, copy, modify, merge, publish,
+ *distribute, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
+ *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *Except as contained in this notice, the name of the XFree86 Project
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from the XFree86 Project.
+ *
+ * Authors: Harold L Hunt II
+ */
+/* $XFree86: xc/programs/Xserver/hw/xwin/winnativegdi.c,v 1.4 2001/07/31 18:45:25 tsi Exp $ */
+
+#include "win.h"
+
+/*
+ * We wrap whatever CloseScreen procedure was specified by fb;
+ * a pointer to said procedure is stored in our privates.
+ */
+Bool
+winCloseScreenNativeGDI (int nIndex, ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+#if 0
+ Bool fReturn;
+#endif
+
+ ErrorF ("winCloseScreenNativeGDI () - Freeing screen resources\n");
+
+ /* Flag that the screen is closed */
+ pScreenPriv->fClosed = TRUE;
+ pScreenPriv->fActive = FALSE;
+
+#if 0
+ /* Call the wrapped CloseScreen procedure */
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+
+ ErrorF ("winCloseScreenNativeGDI () - Calling miCloseScreen ()\n");
+
+ fReturn = (*pScreen->CloseScreen) (nIndex, pScreen);
+
+ ErrorF ("winCloseScreenNativeGDI () - miCloseScreen () returned\n");
+#endif
+
+ /* Delete the window property */
+ RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);
+
+ /* Redisplay the Windows cursor */
+ if (!pScreenPriv->fCursor)
+ ShowCursor (TRUE);
+
+ /* Kill our window */
+ if (pScreenPriv->hwndScreen)
+ {
+ DestroyWindow (pScreenPriv->hwndScreen);
+ pScreenPriv->hwndScreen = NULL;
+ }
+
+ /* Delete our garbage bitmap */
+ if (g_hbmpGarbage != NULL)
+ {
+ DeleteObject (g_hbmpGarbage);
+ g_hbmpGarbage = NULL;
+ }
+
+ /* Invalidate our screeninfo's pointer to the screen */
+ pScreenInfo->pScreen = NULL;
+
+ /* Free the screen privates for this screen */
+ xfree (pScreenPriv);
+
+ ErrorF ("winCloseScreenNativeGDI () - Returning\n");
+
+ return TRUE;
+}
+
+Bool
+winInitVisualsNativeGDI (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+
+ /* Set the bitsPerRGB and bit masks */
+ switch (pScreenInfo->dwDepth)
+ {
+ case 32:
+ case 24:
+ pScreenPriv->dwBitsPerRGB = 8;
+ pScreenPriv->dwRedMask = 0x00FF0000;
+ pScreenPriv->dwGreenMask = 0x0000FF00;
+ pScreenPriv->dwBlueMask = 0x000000FF;
+ break;
+
+ case 16:
+ pScreenPriv->dwBitsPerRGB = 6;
+ pScreenPriv->dwRedMask = 0xF800;
+ pScreenPriv->dwGreenMask = 0x07E0;
+ pScreenPriv->dwBlueMask = 0x001F;
+ break;
+
+ case 15:
+ pScreenPriv->dwBitsPerRGB = 5;
+ pScreenPriv->dwRedMask = 0x7C00;
+ pScreenPriv->dwGreenMask = 0x07E0;
+ pScreenPriv->dwBlueMask = 0x001F;
+ break;
+
+ case 8:
+ pScreenPriv->dwBitsPerRGB = 8;
+ pScreenPriv->dwRedMask = 0;
+ pScreenPriv->dwGreenMask = 0;
+ pScreenPriv->dwBlueMask = 0;
+ break;
+
+ default:
+ ErrorF ("winInitVisualsNativeGDI () - Unknown screen depth\n");
+ return FALSE;
+ break;
+ }
+
+ /* Tell the user how many bits per RGB we are using */
+ ErrorF ("winInitVisualsNativeGDI () - Using dwBitsPerRGB: %d\n",
+ pScreenPriv->dwBitsPerRGB);
+
+ /* Create a single visual according to the Windows screen depth */
+ switch (pScreenInfo->dwDepth)
+ {
+ case 32:
+ case 24:
+ case 16:
+ case 15:
+ if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
+ TrueColorMask,
+ pScreenPriv->dwBitsPerRGB,
+ TrueColor,
+ pScreenPriv->dwRedMask,
+ pScreenPriv->dwGreenMask,
+ pScreenPriv->dwBlueMask))
+ {
+ ErrorF ("winInitVisuals () - miSetVisualTypesAndMasks failed\n");
+ return FALSE;
+ }
+ break;
+
+ case 8:
+ ErrorF ("winInitVisuals () - Calling miSetVisualTypesAndMasks\n");
+ if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth,
+ StaticColorMask,
+ pScreenPriv->dwBitsPerRGB,
+ StaticColor,
+ pScreenPriv->dwRedMask,
+ pScreenPriv->dwGreenMask,
+ pScreenPriv->dwBlueMask))
+ {
+ ErrorF ("winInitVisuals () - miSetVisualTypesAndMasks failed\n");
+ return FALSE;
+ }
+ break;
+
+ default:
+ ErrorF ("winInitVisualsNativeGDI () - Unknown screen depth\n");
+ return FALSE;
+ }
+
+#if 1
+ ErrorF ("winInitVisualsNativeGDI () - Returning\n");
+#endif
+
+ return TRUE;
+}
+
+/* Adjust the video mode */
+Bool
+winAdjustVideoModeNativeGDI (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ HDC hdc = NULL;
+ HDC hdcMem = NULL;
+ HBITMAP hbmp = NULL;
+ DWORD dwDepth;
+
+ hdc = GetDC (NULL);
+
+ /* We're in serious trouble if we can't get a DC */
+ if (hdc == NULL)
+ {
+ ErrorF ("winAdjustVideoModeNativeGDI () - GetDC () failed\n");
+ return FALSE;
+ }
+
+ /* Set the garbage bitmap handle */
+ if (g_hbmpGarbage == NULL)
+ {
+ g_hbmpGarbage = CreateCompatibleBitmap (hdc, 0, 0);
+ }
+
+ /* Query GDI for current display depth */
+ dwDepth = GetDeviceCaps (hdc, BITSPIXEL);
+
+ /* GDI cannot change the screen depth */
+ if (pScreenInfo->dwDepth == WIN_DEFAULT_DEPTH)
+ {
+ /* No -depth parameter passed, let the user know the depth being used */
+ ErrorF ("winAdjustVideoModeNativeGDI () - Using Windows display "
+ "depth of %d bits per pixel\n", dwDepth);
+
+ /* Use GDI's depth */
+ pScreenInfo->dwDepth = dwDepth;
+ }
+ else if (dwDepth != pScreenInfo->dwDepth)
+ {
+ /* Warn user if GDI depth is different than -depth parameter */
+ ErrorF ("winAdjustVideoModeNativeGDI () - Command line depth: %d, "\
+ "using depth: %d\n", pScreenInfo->dwDepth, dwDepth);
+
+ /* We'll use GDI's depth */
+ pScreenInfo->dwDepth = dwDepth;
+ }
+
+ /* Release our DC */
+ ReleaseDC (NULL, hdc);
+
+ return TRUE;
+}
+
+Bool
+winActivateAppNativeGDI (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+
+ /*
+ * Are we active?
+ * Are we fullscreen?
+ */
+ if (pScreenPriv != NULL
+ && pScreenPriv->fActive
+ && pScreenInfo->fFullScreen)
+ {
+ /*
+ * Activating, attempt to bring our window
+ * to the top of the display
+ */
+ ShowWindow (pScreenPriv->hwndScreen, SW_RESTORE);
+ }
+
+ /*
+ * Are we inactive?
+ * Are we fullscreen?
+ */
+ if (pScreenPriv != NULL
+ && !pScreenPriv->fActive
+ && pScreenInfo->fFullScreen)
+ {
+ /*
+ * Deactivating, stuff our window onto the
+ * task bar.
+ */
+ ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE);
+ }
+
+ return TRUE;
+}
+
+HBITMAP
+winCreateDIBNativeGDI (int iWidth, int iHeight, int iDepth,
+ void **ppvBits)
+{
+ BITMAPINFOHEADER *pbmih = NULL;
+ HDC hdcMem = NULL;
+ HBITMAP hBitmap = NULL;
+
+ /* Don't create an invalid bitmap */
+ if (iWidth == 0
+ || iHeight == 0
+ || iDepth == 0)
+ {
+ ErrorF ("\nwinCreateDIBNativeGDI () - Invalid specs w %d h %d d %d\n\n",
+ iWidth, iHeight, iDepth);
+ return NULL;
+ }
+
+ /* Create a scratch DC */
+ hdcMem = CreateCompatibleDC (NULL);
+ if (hdcMem == NULL)
+ {
+ ErrorF ("winCreateDIBNativeGDI () - CreateCompatibleDC () failed\n");
+ return NULL;
+ }
+
+ /* Allocate bitmap info header */
+ pbmih = (BITMAPINFOHEADER*) xalloc (sizeof (BITMAPINFOHEADER)
+ + 256 * sizeof (RGBQUAD));
+ if (pbmih == NULL)
+ {
+ ErrorF ("winCreateDIBNativeGDI () - xalloc () failed\n");
+ return FALSE;
+ }
+ ZeroMemory (pbmih, sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD));
+
+ /* Describe bitmap to be created */
+ pbmih->biSize = sizeof (BITMAPINFOHEADER);
+ pbmih->biWidth = iWidth;
+ pbmih->biHeight = -iHeight;
+ pbmih->biPlanes = 1;
+ pbmih->biBitCount = iDepth;
+ pbmih->biCompression = BI_RGB;
+ pbmih->biSizeImage = 0;
+ pbmih->biXPelsPerMeter = 0;
+ pbmih->biYPelsPerMeter = 0;
+ pbmih->biClrUsed = 0;
+ pbmih->biClrImportant = 0;
+
+ /* Create a DIB with a bit pointer */
+ hBitmap = CreateDIBSection (hdcMem,
+ (BITMAPINFO *) pbmih,
+ DIB_RGB_COLORS,
+ ppvBits,
+ NULL,
+ 0);
+ if (hBitmap == NULL)
+ {
+ ErrorF ("winCreateDIBNativeGDI () - CreateDIBSection () failed\n");
+ return NULL;
+ }
+
+ /* Free the bitmap info header memory */
+ xfree (pbmih);
+ pbmih = NULL;
+
+#if CYGDEBUG
+ ErrorF ("winCreateDIBNativeGDI () - CreateDIBSection () returned\n");
+#endif
+
+ /* Free the scratch DC */
+ DeleteDC (hdcMem);
+ hdcMem = NULL;
+
+ return hBitmap;
+}
+
+/* Set engine specific funtions */
+Bool
+winSetEngineFunctionsNativeGDI (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+
+ /* Set our pointers */
+ pScreenPriv->pwinAllocateFB
+ = (winAllocateFBProcPtr) (void (*)())NoopDDA;
+ pScreenPriv->pwinShadowUpdate
+ = (winShadowUpdateProcPtr) (void (*)())NoopDDA;
+ pScreenPriv->pwinCloseScreen = winCloseScreenNativeGDI;
+ pScreenPriv->pwinInitVisuals = winInitVisualsNativeGDI;
+ pScreenPriv->pwinAdjustVideoMode = winAdjustVideoModeNativeGDI;
+ if (pScreenInfo->fFullScreen)
+ pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowFullScreen;
+ else
+ pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
+ pScreenPriv->pwinFinishScreenInit = winFinishScreenInitNativeGDI;
+ pScreenPriv->pwinBltExposedRegions
+ = (winBltExposedRegionsProcPtr) (void (*)())NoopDDA;
+ pScreenPriv->pwinActivateApp = winActivateAppNativeGDI;
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/miext/layer/Imakefile b/xc/programs/Xserver/miext/layer/Imakefile
new file mode 100644
index 000000000..673f8fefc
--- /dev/null
+++ b/xc/programs/Xserver/miext/layer/Imakefile
@@ -0,0 +1,44 @@
+XCOMM $XFree86: xc/programs/Xserver/miext/layer/Imakefile,v 1.1 2001/05/29 04:54:13 keithp Exp $
+XCOMM
+XCOMM
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#ifdef XFree86Version
+#if DoLoadableServer
+XFMODSRC = shmodule.c
+XFMODOBJ = shmodule.o
+#endif
+#endif
+
+SRCS = layergc.c \
+ layerinit.c \
+ layerpict.c \
+ layerwin.c
+
+OBJS = layergc.o \
+ layerinit.o \
+ layerpict.o \
+ layerwin.o
+
+ INCLUDES = -I. -I../shadow -I../../mi -I../../fb -I../../include -I$(XINCLUDESRC) \
+ -I$(FONTINCSRC) -I$(XF86SRC)/common $(EXTRAINCLUDES) \
+ -I../../render -I$(EXTINCSRC)
+ LINTLIBS = ../../dix/llib-ldix.ln ../../os/llib-los.ln \
+ ../../mi/llib-lmi.ln
+
+NormalLibraryObjectRule()
+LibraryModuleTarget(layer,$(OBJS))
+LintLibraryTarget(layer,$(SRCS))
+
+NormalLintTarget($(SRCS))
+
+InstallLibraryModule(layer,$(MODULEDIR),.)
+
+#ifndef OS2Architecture
+DependTarget()
+#endif
+
+InstallDriverSDKLibraryModule(layer,$(DRIVERSDKMODULEDIR),.)
+InstallDriverSDKNonExecFile(layer.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/xc/programs/Xserver/miext/layer/layer.h b/xc/programs/Xserver/miext/layer/layer.h
new file mode 100644
index 000000000..e8cfe442f
--- /dev/null
+++ b/xc/programs/Xserver/miext/layer/layer.h
@@ -0,0 +1,145 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/layer/layer.h,v 1.4 2001/08/01 00:44:58 tsi Exp $
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, 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 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.
+ */
+
+#ifndef _LAYER_H_
+#define _LAYER_H_
+
+#include <shadow.h>
+
+#define LAYER_FB 0
+#define LAYER_SHADOW 1
+
+typedef struct _LayerKind *LayerKindPtr;
+typedef struct _LayerWin *LayerWinPtr;
+typedef struct _LayerList *LayerListPtr;
+typedef struct _LayerGC *LayerGCPtr;
+typedef struct _Layer *LayerPtr;
+typedef struct _LayerScreen *LayerScreenPtr;
+
+/*
+ * We'll try to work without a list of windows in each layer
+ * for now, this will make computing bounding boxes for each
+ * layer rather expensive, so that may need to change at some point.
+ */
+
+#define LAYER_SCREEN_PIXMAP ((PixmapPtr) 1)
+
+typedef struct _Layer {
+ LayerPtr pNext; /* a list of all layers for this screen */
+ LayerKindPtr pKind; /* characteristics of this layer */
+ int refcnt; /* reference count, layer is freed when zero */
+ int windows; /* number of windows, free pixmap when zero */
+ int depth; /* window depth in this layer */
+ PixmapPtr pPixmap; /* pixmap for this layer (may be frame buffer) */
+ Bool freePixmap; /* whether to free this pixmap when done */
+ RegionRec region; /* valid set of pPixmap for drawing */
+ ShadowUpdateProc update; /* for shadow layers, update/window/closure values */
+ ShadowWindowProc window;
+ int rotate;
+ void *closure;
+} LayerRec;
+
+/*
+ * Call this before wrapping stuff for acceleration, it
+ * gives layer pointers to the raw frame buffer functions
+ */
+
+Bool
+LayerStartInit (ScreenPtr pScreen);
+
+/*
+ * Initialize wrappers for each acceleration type and
+ * call this function, it will move the needed functions
+ * into a new LayerKind and replace them with the generic
+ * functions.
+ */
+
+int
+LayerNewKind (ScreenPtr pScreen);
+
+/*
+ * Finally, call this function and layer
+ * will wrap the screen functions and prepare for execution
+ */
+
+Bool
+LayerFinishInit (ScreenPtr pScreen);
+
+/*
+ * At any point after LayerStartInit, a new layer can be created.
+ */
+LayerPtr
+LayerCreate (ScreenPtr pScreen,
+ int kind,
+ int depth,
+ PixmapPtr pPixmap,
+ ShadowUpdateProc update,
+ ShadowWindowProc window,
+ int rotate,
+ void *closure);
+
+/*
+ * Create a layer pixmap
+ */
+Bool
+LayerCreatePixmap (ScreenPtr pScreen, LayerPtr pLayer);
+
+/*
+ * Change a layer pixmap
+ */
+void
+LayerSetPixmap (ScreenPtr pScreen, LayerPtr pLayer, PixmapPtr pPixmap);
+
+/*
+ * Destroy a layer pixmap
+ */
+void
+LayerDestroyPixmap (ScreenPtr pScreen, LayerPtr pLayer);
+
+/*
+ * Change a layer kind
+ */
+void
+LayerSetKind (ScreenPtr pScreen, LayerPtr pLayer, int kind);
+
+/*
+ * Destroy a layer. The layer must not contain any windows.
+ */
+void
+LayerDestroy (ScreenPtr pScreen, LayerPtr layer);
+
+/*
+ * Add a window to a layer
+ */
+Bool
+LayerWindowAdd (ScreenPtr pScreen, LayerPtr pLayer, WindowPtr pWin);
+
+/*
+ * Remove a window from a layer
+ */
+
+void
+LayerWindowRemove (ScreenPtr pScreen, LayerPtr pLayer, WindowPtr pWin);
+
+#endif /* _LAYER_H_ */
diff --git a/xc/programs/Xserver/miext/layer/layergc.c b/xc/programs/Xserver/miext/layer/layergc.c
new file mode 100644
index 000000000..64ceda1ad
--- /dev/null
+++ b/xc/programs/Xserver/miext/layer/layergc.c
@@ -0,0 +1,192 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/layer/layergc.c,v 1.3 2001/06/05 01:11:07 keithp Exp $
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, 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 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 "layerstr.h"
+
+GCFuncs layerGCFuncs = {
+ layerValidateGC, layerChangeGC, layerCopyGC, layerDestroyGC,
+ layerChangeClip, layerDestroyClip, layerCopyClip
+};
+
+#if 0
+/*
+ * XXX dont need this until this supports
+ * separate clipping and multiple layers
+ */
+GCOps layerGCOps = {
+ layerFillSpans, layerSetSpans,
+ layerPutImage, layerCopyArea,
+ layerCopyPlane, layerPolyPoint,
+ layerPolylines, layerPolySegment,
+ layerPolyRectangle, layerPolyArc,
+ layerFillPolygon, layerPolyFillRect,
+ layerPolyFillArc, layerPolyText8,
+ layerPolyText16, layerImageText8,
+ layerImageText16, layerImageGlyphBlt,
+ layerPolyGlyphBlt, layerPushPixels,
+#ifdef NEED_LINEHELPER
+ NULL,
+#endif
+ {NULL} /* devPrivate */
+};
+#endif
+
+Bool
+layerCreateGC (GCPtr pGC)
+{
+ Bool ret = TRUE;
+ int kind;
+ LayerKindPtr pLayKind;
+ LayerPtr pLayer;
+ ScreenPtr pScreen = pGC->pScreen;
+ layerScrPriv(pScreen);
+ layerGCPriv(pGC);
+
+ /*
+ * XXX assume the first layer can handle all GCs
+ */
+ pLayKind = &pLayScr->kinds[0];
+ if (pLayScr->pLayers)
+ pLayKind = pLayScr->pLayers->pKind;
+ pLayGC->pKind = pLayKind;
+ LayerUnwrap (pScreen,pLayGC->pKind,CreateGC);
+
+ if (!(*pScreen->CreateGC) (pGC))
+ ret = FALSE;
+ LayerWrap (pScreen,pLayKind,CreateGC,layerCreateGC);
+
+ LayerWrap (pGC,pLayGC,funcs,&layerGCFuncs);
+
+ return ret;
+}
+
+void
+layerValidateGC(GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw)
+{
+ layerGCPriv(pGC);
+ LayerKindPtr pKind;
+
+ if (pDraw->type == DRAWABLE_WINDOW)
+ {
+ layerWinPriv ((WindowPtr) pDraw);
+ pKind = layerWinLayer (pLayWin)->pKind;
+ }
+ else
+ {
+ /* XXX assume the first layer can handle all pixmaps */
+ layerScrPriv (pDraw->pScreen);
+ pKind = &pLayScr->kinds[0];
+ if (pLayScr->pLayers)
+ pKind = pLayScr->pLayers->pKind;
+ }
+
+ LayerUnwrap (pGC,pLayGC,funcs);
+ if (pKind != pLayGC->pKind)
+ {
+ /*
+ * Clean up the previous user
+ */
+ CreateGCProcPtr CreateGC;
+ (*pGC->funcs->DestroyGC) (pGC);
+
+ pGC->serialNumber = GC_CHANGE_SERIAL_BIT;
+
+ pLayGC->pKind = pKind;
+
+ /*
+ * Temporarily unwrap Create GC and let
+ * the new code setup the GC
+ */
+ CreateGC = pGC->pScreen->CreateGC;
+ LayerUnwrap (pGC->pScreen, pLayGC->pKind, CreateGC);
+ (*pGC->pScreen->CreateGC) (pGC);
+ LayerWrap (pGC->pScreen, pLayGC->pKind, CreateGC, CreateGC);
+ }
+
+ (*pGC->funcs->ValidateGC) (pGC, changes, pDraw);
+ LayerWrap(pGC,pLayGC,funcs,&layerGCFuncs);
+}
+
+void
+layerDestroyGC(GCPtr pGC)
+{
+ layerGCPriv(pGC);
+ LayerUnwrap (pGC,pLayGC,funcs);
+ (*pGC->funcs->DestroyGC)(pGC);
+ LayerWrap(pGC,pLayGC,funcs,&layerGCFuncs);
+}
+
+void
+layerChangeGC (GCPtr pGC,
+ unsigned long mask)
+{
+ layerGCPriv(pGC);
+ LayerUnwrap (pGC,pLayGC,funcs);
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ LayerWrap(pGC,pLayGC,funcs,&layerGCFuncs);
+}
+
+void
+layerCopyGC (GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst)
+{
+ layerGCPriv(pGCDst);
+ LayerUnwrap (pGCDst,pLayGC,funcs);
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ LayerWrap(pGCDst,pLayGC,funcs,&layerGCFuncs);
+}
+
+void
+layerChangeClip (GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects)
+{
+ layerGCPriv(pGC);
+ LayerUnwrap (pGC,pLayGC,funcs);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ LayerWrap(pGC,pLayGC,funcs,&layerGCFuncs);
+}
+
+void
+layerCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
+{
+ layerGCPriv(pGCDst);
+ LayerUnwrap (pGCDst,pLayGC,funcs);
+ (*pGCDst->funcs->CopyClip) (pGCSrc, pGCDst);
+ LayerWrap(pGCDst,pLayGC,funcs,&layerGCFuncs);
+}
+
+void
+layerDestroyClip(GCPtr pGC)
+{
+ layerGCPriv(pGC);
+ LayerUnwrap (pGC,pLayGC,funcs);
+ (*pGC->funcs->DestroyClip) (pGC);
+ LayerWrap(pGC,pLayGC,funcs,&layerGCFuncs);
+}
+
diff --git a/xc/programs/Xserver/miext/layer/layerinit.c b/xc/programs/Xserver/miext/layer/layerinit.c
new file mode 100644
index 000000000..a4e12a285
--- /dev/null
+++ b/xc/programs/Xserver/miext/layer/layerinit.c
@@ -0,0 +1,351 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/layer/layerinit.c,v 1.3 2001/07/20 19:25:01 keithp Exp $
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, 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 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 "layerstr.h"
+
+int layerScrPrivateIndex;
+int layerGCPrivateIndex;
+int layerWinPrivateIndex;
+int layerGeneration;
+
+/*
+ * Call this before wrapping stuff for acceleration, it
+ * gives layer pointers to the raw frame buffer functions
+ */
+
+extern const GCFuncs fbGCFuncs;
+extern GCFuncs shadowGCFuncs;
+
+Bool
+LayerStartInit (ScreenPtr pScreen)
+{
+ LayerScreenPtr pScrPriv;
+
+ if (layerGeneration != serverGeneration)
+ {
+ layerScrPrivateIndex = AllocateScreenPrivateIndex ();
+ if (layerScrPrivateIndex == -1)
+ return FALSE;
+ layerGCPrivateIndex = AllocateGCPrivateIndex ();
+ if (layerGCPrivateIndex == -1)
+ return FALSE;
+ layerWinPrivateIndex = AllocateWindowPrivateIndex ();
+ if (layerWinPrivateIndex == -1)
+ return FALSE;
+ layerGeneration = serverGeneration;
+ }
+ if (!AllocateGCPrivate (pScreen, layerGCPrivateIndex, sizeof (LayerGCRec)))
+ return FALSE;
+ if (!AllocateWindowPrivate (pScreen, layerWinPrivateIndex, sizeof (LayerWinRec)))
+ return FALSE;
+ pScrPriv = (LayerScreenPtr) xalloc (sizeof (LayerScreenRec));
+ if (!pScrPriv)
+ return FALSE;
+ pScrPriv->nkinds = 0;
+ pScrPriv->kinds = 0;
+ pScrPriv->pLayers = 0;
+ pScreen->devPrivates[layerScrPrivateIndex].ptr = (pointer) pScrPriv;
+ /*
+ * Add fb kind -- always 0
+ */
+ if (LayerNewKind (pScreen) < 0)
+ {
+ pScreen->devPrivates[layerScrPrivateIndex].ptr = 0;
+ xfree (pScrPriv);
+ return FALSE;
+ }
+ /*
+ * Add shadow kind -- always 1
+ */
+ if (!shadowSetup (pScreen))
+ return FALSE;
+ if (LayerNewKind (pScreen) < 0)
+ {
+ pScreen->devPrivates[layerScrPrivateIndex].ptr = 0;
+ xfree (pScrPriv->kinds);
+ xfree (pScrPriv);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Initialize wrappers for each acceleration type and
+ * call this function, it will move the needed functions
+ * into a new LayerKind and replace them with the generic
+ * functions.
+ */
+
+int
+LayerNewKind (ScreenPtr pScreen)
+{
+ layerScrPriv(pScreen);
+ LayerKindPtr pLayKind, pLayKinds;
+#ifdef RENDER
+ PictureScreenPtr ps = GetPictureScreen (pScreen);
+#endif
+ LayerPtr pLayer;
+
+ /*
+ * Allocate a new kind structure
+ */
+ if (pLayScr->kinds)
+ pLayKinds = (LayerKindPtr) xrealloc ((pointer) pLayScr->kinds,
+ (pLayScr->nkinds + 1) * sizeof (LayerKindRec));
+ else
+ pLayKinds = (LayerKindPtr) xalloc (sizeof (LayerKindRec));
+ if (!pLayKinds)
+ return -1;
+
+ /*
+ * Fix up existing layers to point at the new kind
+ */
+ for (pLayer = pLayScr->pLayers; pLayer; pLayer = pLayer->pNext)
+ {
+ int kind = pLayer->pKind - pLayScr->kinds;
+
+ pLayer->pKind = &pLayKinds[kind];
+ }
+
+ pLayScr->kinds = pLayKinds;
+ pLayKind = &pLayScr->kinds[pLayScr->nkinds];
+ pLayKind->kind = pLayScr->nkinds;
+
+ /*
+ * Extract wrapped functions from screen and stick in kind
+ */
+ pLayKind->CloseScreen = pScreen->CloseScreen;
+
+ pLayKind->CreateWindow = pScreen->CreateWindow;
+ pLayKind->DestroyWindow = pScreen->DestroyWindow;
+ pLayKind->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
+ pLayKind->PaintWindowBackground = pScreen->PaintWindowBackground;
+ pLayKind->PaintWindowBorder = pScreen->PaintWindowBorder;
+ pLayKind->CopyWindow = pScreen->CopyWindow;
+
+ pLayKind->CreateGC = pScreen->CreateGC;
+
+#ifdef RENDER
+ if (ps)
+ {
+ pLayKind->Composite = ps->Composite;
+ pLayKind->Glyphs = ps->Glyphs;
+ pLayKind->CompositeRects = ps->CompositeRects;
+ }
+#endif
+ /*
+ * If not underlying frame buffer kind,
+ * replace screen functions with those
+ */
+ if (pLayKind->kind != 0)
+ {
+ pScreen->CloseScreen = pLayKinds->CloseScreen;
+
+ pScreen->CreateWindow = pLayKinds->CreateWindow;
+ pScreen->DestroyWindow = pLayKinds->DestroyWindow;
+ pScreen->ChangeWindowAttributes = pLayKinds->ChangeWindowAttributes;
+ pScreen->PaintWindowBackground = pLayKinds->PaintWindowBackground;
+ pScreen->PaintWindowBorder = pLayKinds->PaintWindowBorder;
+ pScreen->CopyWindow = pLayKinds->CopyWindow;
+
+ pScreen->CreateGC = pLayKinds->CreateGC;
+
+#ifdef RENDER
+ if (ps)
+ {
+ ps->Composite = pLayKinds->Composite;
+ ps->Glyphs = pLayKinds->Glyphs;
+ ps->CompositeRects = pLayKinds->CompositeRects;
+ }
+#endif
+ }
+
+ pLayScr->nkinds++;
+ return pLayKind->kind;
+}
+
+/*
+ * Finally, call this function and layer
+ * will wrap the screen functions and prepare for execution
+ */
+
+Bool
+LayerFinishInit (ScreenPtr pScreen)
+{
+ layerScrPriv(pScreen);
+#ifdef RENDER
+ PictureScreenPtr ps = GetPictureScreen (pScreen);
+#endif
+
+ pScreen->CloseScreen = layerCloseScreen;
+
+ pScreen->CreateWindow = layerCreateWindow;
+ pScreen->DestroyWindow = layerDestroyWindow;
+ pScreen->ChangeWindowAttributes = layerChangeWindowAttributes;
+ pScreen->PaintWindowBackground = layerPaintWindowBackground;
+ pScreen->PaintWindowBorder = layerPaintWindowBorder;
+ pScreen->CopyWindow = layerCopyWindow;
+
+ pScreen->CreateGC = layerCreateGC;
+
+#ifdef RENDER
+ if (ps)
+ {
+ ps->Composite = layerComposite;
+ ps->Glyphs = layerGlyphs;
+ ps->CompositeRects = layerCompositeRects;
+ }
+#endif
+
+ return TRUE;
+}
+
+/*
+ * At any point after LayerStartInit, a new layer can be created.
+ */
+LayerPtr
+LayerCreate (ScreenPtr pScreen,
+ int kind,
+ int depth,
+ PixmapPtr pPixmap,
+ ShadowUpdateProc update,
+ ShadowWindowProc window,
+ int rotate,
+ void *closure)
+{
+ layerScrPriv(pScreen);
+ LayerPtr pLay, *pPrev;
+ LayerKindPtr pLayKind;
+
+ if (kind < 0 || pLayScr->nkinds <= kind)
+ return 0;
+ pLayKind = &pLayScr->kinds[kind];
+ pLay = (LayerPtr) xalloc (sizeof (LayerRec));
+ if (!pLay)
+ return 0;
+ /*
+ * Initialize the layer
+ */
+ pLay->pNext = 0;
+ pLay->pKind = pLayKind;
+ pLay->refcnt = 1;
+ pLay->windows = 0;
+ pLay->depth = depth;
+ pLay->pPixmap = pPixmap;
+ pLay->update = update;
+ pLay->window = window;
+ pLay->rotate = rotate;
+ pLay->closure = closure;
+ if (pPixmap == LAYER_SCREEN_PIXMAP)
+ pLay->freePixmap = FALSE;
+ else
+ {
+ pLay->freePixmap = TRUE;
+ if (pPixmap)
+ pPixmap->refcnt++;
+ }
+ REGION_INIT (pScreen, &pLay->region, NullBox, 0);
+ /*
+ * Hook the layer at the end of the list
+ */
+ for (pPrev = &pLayScr->pLayers; *pPrev; pPrev = &(*pPrev)->pNext)
+ ;
+ *pPrev = pLay;
+ return pLay;
+}
+
+/*
+ * Change a layer pixmap
+ */
+void
+LayerSetPixmap (ScreenPtr pScreen, LayerPtr pLayer, PixmapPtr pPixmap)
+{
+ LayerDestroyPixmap (pScreen, pLayer);
+ pLayer->pPixmap = pPixmap;
+ if (pPixmap == LAYER_SCREEN_PIXMAP)
+ pLayer->freePixmap = FALSE;
+ else
+ {
+ if (pPixmap)
+ pPixmap->refcnt++;
+ pLayer->freePixmap = TRUE;
+ }
+}
+
+/*
+ * Destroy a layer. The layer must not contain any windows.
+ */
+void
+LayerDestroy (ScreenPtr pScreen, LayerPtr pLay)
+{
+ layerScrPriv(pScreen);
+ LayerPtr *pPrev;
+
+ --pLay->refcnt;
+ if (pLay->refcnt > 0)
+ return;
+ /*
+ * Unhook the layer from the list
+ */
+ for (pPrev = &pLayScr->pLayers; *pPrev; pPrev = &(*pPrev)->pNext)
+ if (*pPrev == pLay)
+ {
+ *pPrev = pLay->pNext;
+ break;
+ }
+ /*
+ * Free associated storage
+ */
+ LayerDestroyPixmap (pScreen, pLay);
+ REGION_UNINIT (pScreen, &pLay->region);
+ xfree (pLay);
+}
+
+/*
+ * CloseScreen wrapper
+ */
+Bool
+layerCloseScreen (int index, ScreenPtr pScreen)
+{
+ layerScrPriv(pScreen);
+ int kind;
+
+ /* XXX this is a mess -- fbCloseScreen can only be called once,
+ * and yet the intervening layers need to be called as well.
+ */
+ kind = pLayScr->nkinds - 1;
+ pScreen->CloseScreen = pLayScr->kinds[kind].CloseScreen;
+ (*pScreen->CloseScreen) (index, pScreen);
+
+ /*
+ * make sure the shadow layer is cleaned up as well
+ */
+ if (kind != LAYER_SHADOW)
+ xfree (shadowGetScrPriv (pScreen));
+
+ xfree (pLayScr->kinds);
+ xfree (pLayScr);
+ pScreen->devPrivates[layerScrPrivateIndex].ptr = 0;
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/miext/layer/layerpict.c b/xc/programs/Xserver/miext/layer/layerpict.c
new file mode 100644
index 000000000..e233d0271
--- /dev/null
+++ b/xc/programs/Xserver/miext/layer/layerpict.c
@@ -0,0 +1,145 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/layer/layerpict.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, 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 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 "layerstr.h"
+
+void
+layerComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ LayerPtr pLayer;
+ LayerWinLoopRec loop;
+ DrawablePtr pDstDrawable = pDst->pDrawable;
+ ScreenPtr pScreen = pDstDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen (pScreen);
+
+ if (pDstDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWin = (WindowPtr) pDstDrawable;
+ for (pLayer = LayerWindowFirst (pWin, &loop);
+ pLayer;
+ pLayer = LayerWindowNext (pWin, &loop))
+ {
+ LayerUnwrap (ps, pLayer->pKind, Composite);
+ (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc,
+ xMask, yMask, xDst, yDst, width, height);
+ LayerWrap (ps, pLayer->pKind, Composite, layerComposite);
+ }
+ LayerWindowDone (pWin, &loop);
+ }
+ else
+ {
+ layerScrPriv (pScreen);
+ LayerUnwrap (ps, &pLayScr->kinds[LAYER_FB], Composite);
+ (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc,
+ xMask, yMask, xDst, yDst, width, height);
+ LayerWrap (ps, &pLayScr->kinds[LAYER_FB], Composite, layerComposite);
+ }
+}
+
+void
+layerGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ LayerPtr pLayer;
+ LayerWinLoopRec loop;
+ DrawablePtr pDstDrawable = pDst->pDrawable;
+ ScreenPtr pScreen = pDstDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen (pScreen);
+
+ if (pDstDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWin = (WindowPtr) pDstDrawable;
+ for (pLayer = LayerWindowFirst (pWin, &loop);
+ pLayer;
+ pLayer = LayerWindowNext (pWin, &loop))
+ {
+ LayerUnwrap (ps, pLayer->pKind, Glyphs);
+ (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc,
+ nlist, list, glyphs);
+ LayerWrap (ps, pLayer->pKind, Glyphs, layerGlyphs);
+ }
+ LayerWindowDone (pWin, &loop);
+ }
+ else
+ {
+ layerScrPriv (pScreen);
+ LayerUnwrap (ps, &pLayScr->kinds[LAYER_FB], Glyphs);
+ (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc,
+ nlist, list, glyphs);
+ LayerWrap (ps, &pLayScr->kinds[LAYER_FB], Glyphs, layerGlyphs);
+ }
+}
+
+void
+layerCompositeRects (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects)
+{
+ LayerPtr pLayer;
+ LayerWinLoopRec loop;
+ DrawablePtr pDstDrawable = pDst->pDrawable;
+ ScreenPtr pScreen = pDstDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen (pScreen);
+
+ if (pDstDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWin = (WindowPtr) pDstDrawable;
+ for (pLayer = LayerWindowFirst (pWin, &loop);
+ pLayer;
+ pLayer = LayerWindowNext (pWin, &loop))
+ {
+ LayerUnwrap (ps, pLayer->pKind, CompositeRects);
+ (*ps->CompositeRects) (op, pDst, color, nRect, rects);
+ LayerWrap (ps, pLayer->pKind, CompositeRects, layerCompositeRects);
+ }
+ LayerWindowDone (pWin, &loop);
+ }
+ else
+ {
+ layerScrPriv (pScreen);
+ LayerUnwrap (ps, &pLayScr->kinds[LAYER_FB], CompositeRects);
+ (*ps->CompositeRects) (op, pDst, color, nRect, rects);
+ LayerWrap (ps, &pLayScr->kinds[LAYER_FB], CompositeRects, layerCompositeRects);
+ }
+}
diff --git a/xc/programs/Xserver/miext/layer/layerstr.h b/xc/programs/Xserver/miext/layer/layerstr.h
new file mode 100644
index 000000000..81b8d9035
--- /dev/null
+++ b/xc/programs/Xserver/miext/layer/layerstr.h
@@ -0,0 +1,411 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/layer/layerstr.h,v 1.2 2001/06/04 09:45:41 keithp Exp $
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, 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 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.
+ */
+
+#ifndef _LAYERSTR_H_
+#define _LAYERSTR_H_
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "font.h"
+#include "dixfontstr.h"
+#include "fontstruct.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "globals.h"
+#include "gcstruct.h"
+#include "layer.h"
+#ifdef RENDER
+#include "picturestr.h"
+#endif
+
+extern int layerScrPrivateIndex;
+extern int layerGCPrivateIndex;
+extern int layerWinPrivateIndex;
+
+/*
+ * One of these for each possible set of underlying
+ * rendering code. The first kind always points at the
+ * underlying frame buffer code and is created in LayerStartInit
+ * so that LayerNewKind can unwrap the screen and prepare it
+ * for another wrapping sequence.
+ *
+ * The set of functions wrapped here must be at least the union
+ * of all functions wrapped by any rendering layer in use; they're
+ * easy to add, so don't be shy
+ */
+
+typedef struct _LayerKind {
+ int kind; /* kind index */
+
+ CloseScreenProcPtr CloseScreen;
+
+ CreateWindowProcPtr CreateWindow;
+ DestroyWindowProcPtr DestroyWindow;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ CopyWindowProcPtr CopyWindow;
+
+ CreateGCProcPtr CreateGC;
+
+ CompositeProcPtr Composite;
+ GlyphsProcPtr Glyphs;
+ CompositeRectsProcPtr CompositeRects;
+
+} LayerKindRec;
+
+#define LayerWrap(orig,lay,member,func) \
+ (((lay)->member = (orig)->member),\
+ ((orig)->member = (func)))
+#define LayerUnwrap(orig,lay,member) \
+ ((orig)->member = (lay)->member)
+
+/*
+ * This is the window private structure allocated for
+ * all windows. There are two possible alternatives here,
+ * either the window belongs to a single layer and uses its
+ * internal clip/borderClip lists or the window belongs to one
+ * or more layers and uses a separate clip/borderclip for each
+ * layer. When this is integrated into the core window struct,
+ * the LayerWinKind can become a single bit saving 8 bytes per
+ * window.
+ */
+
+typedef struct _LayerWin {
+ Bool isList;
+ union {
+ LayerPtr pLayer;
+ LayerListPtr pLayList;
+ } u;
+} LayerWinRec;
+
+typedef struct _LayerList {
+ LayerListPtr pNext; /* list of layers for this window */
+ LayerPtr pLayer; /* the layer */
+ Bool inheritClip; /* use the window clipList/borderClip */
+ RegionRec clipList; /* per-layer clip/border clip lists */
+ RegionRec borderClip;
+} LayerListRec;
+
+#define layerGetWinPriv(pWin) ((LayerWinPtr) (pWin)->devPrivates[layerWinPrivateIndex].ptr)
+#define layerWinPriv(pWin) LayerWinPtr pLayWin = layerGetWinPriv(pWin)
+
+#define layerWinLayer(pLayWin) ((pLayWin)->isList ? (pLayWin)->u.pLayList->pLayer : (pLayWin)->u.pLayer)
+
+typedef struct _LayerWinLoop {
+ LayerWinPtr pLayWin;
+ LayerListPtr pLayList;
+ PixmapPtr pPixmap; /* original window pixmap */
+ RegionRec clipList; /* saved original clipList contents */
+ RegionRec borderClip; /* saved original borderClip contents */
+} LayerWinLoopRec, *LayerWinLoopPtr;
+
+#define layerWinFirstLayer(pLayWin,pLayList) ((pLayWin)->isList ? ((pLayList) = (pLayWin)->u.pLayList)->pLayer : pLayWin->u.pLayer)
+#define layerWinNextLayer(pLayWin,pLayList) ((pLayWin)->isList ? ((pLayList) = (pLayList)->pNext)->pLayer : 0)
+
+LayerPtr
+LayerWindowFirst (WindowPtr pWin, LayerWinLoopPtr pLoop);
+
+LayerPtr
+LayerWindowNext (WindowPtr pWin, LayerWinLoopPtr pLoop);
+
+void
+LayerWindowDone (WindowPtr pWin, LayerWinLoopPtr pLoop);
+
+
+/*
+ * This is the GC private structure allocated for all GCs.
+ * XXX this is really messed up; I'm not sure how to fix it yet
+ */
+
+typedef struct _LayerGC {
+ GCFuncs *funcs;
+ LayerKindPtr pKind;
+} LayerGCRec;
+
+#define layerGetGCPriv(pGC) ((LayerGCPtr) (pGC)->devPrivates[layerGCPrivateIndex].ptr)
+#define layerGCPriv(pGC) LayerGCPtr pLayGC = layerGetGCPriv(pGC)
+
+/*
+ * This is the screen private, it contains
+ * the layer kinds and the layers themselves
+ */
+typedef struct _LayerScreen {
+ int nkinds; /* number of elements in kinds array */
+ LayerKindPtr kinds; /* created kinds; reallocated when new ones added */
+ LayerPtr pLayers; /* list of layers for this screen */
+} LayerScreenRec;
+
+#define layerGetScrPriv(pScreen) ((LayerScreenPtr) (pScreen)->devPrivates[layerScrPrivateIndex].ptr)
+#define layerScrPriv(pScreen) LayerScreenPtr pLayScr = layerGetScrPriv(pScreen)
+
+Bool
+layerCloseScreen (int index, ScreenPtr pScreen);
+
+Bool
+layerCreateWindow (WindowPtr pWin);
+
+Bool
+layerDestroyWindow (WindowPtr pWin);
+
+Bool
+layerChangeWindowAttributes (WindowPtr pWin, unsigned long mask);
+
+void
+layerPaintWindowBackground (WindowPtr pWin, RegionPtr pRegion, int what);
+
+void
+layerPaintWindowBorder (WindowPtr pWin, RegionPtr pRegion, int what);
+
+void
+layerCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+
+Bool
+layerCreateGC (GCPtr pGC);
+
+void
+layerComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+void
+layerGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs);
+
+void
+layerCompositeRects (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects);
+
+void layerValidateGC(GCPtr, unsigned long, DrawablePtr);
+void layerChangeGC(GCPtr, unsigned long);
+void layerCopyGC(GCPtr, unsigned long, GCPtr);
+void layerDestroyGC(GCPtr);
+void layerChangeClip(GCPtr, int, pointer, int);
+void layerDestroyClip(GCPtr);
+void layerCopyClip(GCPtr, GCPtr);
+
+void
+layerFillSpans(DrawablePtr pDraw,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted);
+
+void
+layerSetSpans(DrawablePtr pDraw,
+ GCPtr pGC,
+ char *pcharsrc,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int nspans,
+ int fSorted);
+
+void
+layerPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage
+);
+
+RegionPtr
+layerCopyArea(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+);
+
+RegionPtr
+layerCopyPlane(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+);
+
+void
+layerPolyPoint(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit
+);
+void
+layerPolylines(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit
+);
+
+void
+layerPolySegment(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+);
+
+void
+layerPolyRectangle(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects
+);
+
+void
+layerPolyArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+);
+
+void
+layerFillPolygon(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr pptInit
+);
+
+void
+layerPolyFillRect(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+);
+
+void
+layerPolyFillArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+);
+
+int
+layerPolyText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+);
+
+int
+layerPolyText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+);
+
+void
+layerImageText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+);
+
+void
+layerImageText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+);
+
+void
+layerImageGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+);
+
+void
+layerPolyGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+);
+
+void
+layerPushPixels(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy, int xOrg, int yOrg
+);
+
+#endif /* _LAYERSTR_H_ */
diff --git a/xc/programs/Xserver/miext/layer/layerwin.c b/xc/programs/Xserver/miext/layer/layerwin.c
new file mode 100644
index 000000000..1b19ba99a
--- /dev/null
+++ b/xc/programs/Xserver/miext/layer/layerwin.c
@@ -0,0 +1,443 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/layer/layerwin.c,v 1.4 2001/07/20 19:25:01 keithp Exp $
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, 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 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 "layerstr.h"
+
+static LayerListPtr
+NewLayerList (ScreenPtr pScreen, LayerPtr pLayer)
+{
+ LayerListPtr pLayList;
+
+ pLayList = (LayerListPtr) xalloc (sizeof (LayerListRec));
+ if (!pLayList)
+ return 0;
+ pLayList->pNext = 0;
+ pLayList->pLayer = pLayer;
+ pLayList->inheritClip = TRUE;
+ REGION_INIT (pScreen, &pLayList->clipList, NullBox, 0);
+ REGION_INIT (pScreen, &pLayList->borderClip, NullBox, 0);
+ return pLayList;
+}
+
+static void
+FreeLayerList (ScreenPtr pScreen, LayerListPtr pLayList)
+{
+ REGION_UNINIT (&pScreen, &pLayList->clipList);
+ REGION_UNINIT (&pScreen, &pLayList->borderClip);
+ xfree (pLayList);
+}
+
+/*
+ * Create pixmap for a layer
+ */
+
+Bool
+LayerCreatePixmap (ScreenPtr pScreen, LayerPtr pLayer)
+{
+ /* XXX create full-screen sized layers all around */
+ pLayer->pPixmap = (*pScreen->CreatePixmap) (pScreen, pScreen->width,
+ pScreen->height, pLayer->depth);
+ if (!pLayer->pPixmap)
+ return FALSE;
+ if (pLayer->pKind->kind == LAYER_SHADOW)
+ {
+ if (!shadowAdd (pScreen, pLayer->pPixmap, pLayer->update,
+ pLayer->window, pLayer->rotate, pLayer->closure))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Destroy pixmap for a layer
+ */
+
+void
+LayerDestroyPixmap (ScreenPtr pScreen, LayerPtr pLayer)
+{
+ if (pLayer->pPixmap)
+ {
+ if (pLayer->pKind->kind == LAYER_SHADOW)
+ shadowRemove (pScreen, pLayer->pPixmap);
+ if (pLayer->freePixmap)
+ (*pScreen->DestroyPixmap) (pLayer->pPixmap);
+ }
+ pLayer->pPixmap = 0;
+}
+
+/*
+ * Add a window to a layer
+ */
+Bool
+LayerWindowAdd (ScreenPtr pScreen, LayerPtr pLayer, WindowPtr pWin)
+{
+ layerWinPriv(pWin);
+
+ if (pLayer->pPixmap == LAYER_SCREEN_PIXMAP)
+ pLayer->pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
+ else if (!pLayer->pPixmap && !LayerCreatePixmap (pScreen, pLayer))
+ return FALSE;
+ /*
+ * Add a new layer list if needed
+ */
+ if (pLayWin->isList || pLayWin->u.pLayer)
+ {
+ LayerListPtr pPrev;
+ LayerListPtr pLayList;
+
+ if (!pLayWin->isList)
+ {
+ pPrev = NewLayerList (pScreen, pLayWin->u.pLayer);
+ if (!pPrev)
+ return FALSE;
+ }
+ else
+ {
+ for (pPrev = pLayWin->u.pLayList; pPrev->pNext; pPrev = pPrev->pNext)
+ ;
+ }
+ pLayList = NewLayerList (pScreen, pLayer);
+ if (!pLayList)
+ {
+ if (!pLayWin->isList)
+ FreeLayerList (pScreen, pPrev);
+ return FALSE;
+ }
+ pPrev->pNext = pLayList;
+ if (!pLayWin->isList)
+ {
+ pLayWin->isList = TRUE;
+ pLayWin->u.pLayList = pPrev;
+ }
+ }
+ else
+ pLayWin->u.pLayer = pLayer;
+ /*
+ * XXX only one layer supported for drawing, last one wins
+ */
+ (*pScreen->SetWindowPixmap) (pWin, pLayer->pPixmap);
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pLayer->refcnt++;
+ pLayer->windows++;
+ return TRUE;
+}
+
+/*
+ * Remove a window from a layer
+ */
+
+void
+LayerWindowRemove (ScreenPtr pScreen, LayerPtr pLayer, WindowPtr pWin)
+{
+ layerWinPriv(pWin);
+
+ if (pLayWin->isList)
+ {
+ LayerListPtr *pPrev;
+ LayerListPtr pLayList;
+
+ for (pPrev = &pLayWin->u.pLayList; pLayList = *pPrev; pPrev = &pLayList->pNext)
+ {
+ if (pLayList->pLayer == pLayer)
+ {
+ *pPrev = pLayList->pNext;
+ FreeLayerList (pScreen, pLayList);
+ --pLayer->windows;
+ if (pLayer->windows <= 0)
+ LayerDestroyPixmap (pScreen, pLayer);
+ LayerDestroy (pScreen, pLayer);
+ break;
+ }
+ }
+ pLayList = pLayWin->u.pLayList;
+ if (!pLayList)
+ {
+ /*
+ * List is empty, set isList back to false
+ */
+ pLayWin->isList = FALSE;
+ pLayWin->u.pLayer = 0;
+ }
+ else if (!pLayList->pNext && pLayList->inheritClip)
+ {
+ /*
+ * List contains a single element using the
+ * window clip, free the list structure and
+ * host the layer back to the window private
+ */
+ pLayer = pLayList->pLayer;
+ FreeLayerList (pScreen, pLayList);
+ pLayWin->isList = FALSE;
+ pLayWin->u.pLayer = pLayer;
+ }
+ }
+ else
+ {
+ if (pLayWin->u.pLayer == pLayer)
+ {
+ --pLayer->windows;
+ if (pLayer->windows <= 0)
+ LayerDestroyPixmap (pScreen, pLayer);
+ LayerDestroy (pScreen, pLayer);
+ pLayWin->u.pLayer = 0;
+ }
+ }
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+}
+
+/*
+ * Looping primitives for window layering. Usage:
+ *
+ * for (pLayer = LayerWindowFirst (pWin, &loop);
+ * pLayer;
+ * pLayer = LayerWindowNext (&loop))
+ * {
+ * ...
+ * }
+ * LayerWindowDone (pWin, &loop);
+ */
+
+LayerPtr
+LayerWindowFirst (WindowPtr pWin, LayerWinLoopPtr pLoop)
+{
+ layerWinPriv (pWin);
+ LayerListPtr pLayList;
+ LayerPtr pLayer;
+
+ pLoop->pLayWin = pLayWin;
+ if (!pLayWin->isList)
+ return pLayWin->u.pLayer;
+
+ /*
+ * Preserve original state
+ */
+ pLoop->clipList = pWin->clipList;
+ pLoop->borderClip = pWin->borderClip;
+ pLoop->pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
+
+ /*
+ * Set initial list element
+ */
+ pLoop->pLayList = pLayWin->u.pLayList;
+
+ /*
+ * Return first layer
+ */
+ return LayerWindowNext (pWin, pLoop);
+}
+
+LayerPtr
+LayerWindowNext (WindowPtr pWin, LayerWinLoopPtr pLoop)
+{
+ LayerPtr pLayer;
+ LayerWinPtr pLayWin = pLoop->pLayWin;
+ LayerListPtr pLayList;
+
+ if (!pLayWin->isList)
+ return 0;
+
+ pLayList = pLoop->pLayList;
+ pLayer = pLayList->pLayer;
+ /*
+ * Configure window for this layer
+ */
+ (*pWin->drawable.pScreen->SetWindowPixmap) (pWin, pLayer->pPixmap);
+ if (!pLayList->inheritClip)
+ {
+ pWin->clipList = pLayList->clipList;
+ pWin->borderClip = pLayList->borderClip;
+ }
+ /*
+ * Step to next layer list
+ */
+ pLoop->pLayList = pLayList->pNext;
+ /*
+ * Return layer
+ */
+ return pLayer;
+}
+
+void
+LayerWindowDone (WindowPtr pWin, LayerWinLoopPtr pLoop)
+{
+ LayerWinPtr pLayWin = pLoop->pLayWin;
+
+ if (!pLayWin->isList)
+ return;
+ /*
+ * clean up after the loop
+ */
+ pWin->clipList = pLoop->clipList;
+ pWin->borderClip = pLoop->clipList;
+ (*pWin->drawable.pScreen->SetWindowPixmap) (pWin, pLoop->pPixmap);
+}
+
+Bool
+layerCreateWindow (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ layerWinPriv(pWin);
+ layerScrPriv(pScreen);
+ LayerPtr pLayer;
+ Bool ret;
+
+ pLayWin->isList = FALSE;
+ pLayWin->u.pLayer = 0;
+
+ /*
+ * input only windows don't live in any layer
+ */
+ if (pWin->drawable.type == UNDRAWABLE_WINDOW)
+ return TRUE;
+ /*
+ * Use a reasonable default layer -- the first
+ * layer matching the windows depth. Subsystems needing
+ * alternative layering semantics can override this by
+ * replacing this function. Perhaps a new screen function
+ * could be used to select the correct initial window
+ * layer instead.
+ */
+ for (pLayer = pLayScr->pLayers; pLayer; pLayer = pLayer->pNext)
+ if (pLayer->depth == pWin->drawable.depth)
+ break;
+ ret = TRUE;
+ if (pLayer)
+ {
+ pScreen->CreateWindow = pLayer->pKind->CreateWindow;
+ ret = (*pScreen->CreateWindow) (pWin);
+ pLayer->pKind->CreateWindow = pScreen->CreateWindow;
+ pScreen->CreateWindow = layerCreateWindow;
+ LayerWindowAdd (pScreen, pLayer, pWin);
+ }
+ return ret;
+}
+
+Bool
+layerDestroyWindow (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ layerWinPriv(pWin);
+ LayerPtr pLayer;
+ Bool ret = TRUE;
+
+ while (pLayer = layerWinLayer (pLayWin))
+ {
+ LayerUnwrap (pScreen, pLayer->pKind, DestroyWindow);
+ ret = (*pScreen->DestroyWindow) (pWin);
+ LayerWrap (pScreen, pLayer->pKind, DestroyWindow, layerDestroyWindow);
+ LayerWindowRemove (pWin->drawable.pScreen, pLayer, pWin);
+ }
+ return ret;
+}
+
+Bool
+layerChangeWindowAttributes (WindowPtr pWin, unsigned long mask)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ layerWinPriv (pWin);
+ LayerPtr pLay;
+ LayerWinLoopRec loop;
+ Bool ret = TRUE;
+
+ for (pLay = LayerWindowFirst (pWin, &loop);
+ pLay;
+ pLay = LayerWindowNext (pWin, &loop))
+ {
+ LayerUnwrap(pScreen,pLay->pKind,ChangeWindowAttributes);
+ if (!(*pScreen->ChangeWindowAttributes) (pWin, mask))
+ ret = FALSE;
+ LayerWrap(pScreen,pLay->pKind,ChangeWindowAttributes,layerChangeWindowAttributes);
+ }
+ LayerWindowDone (pWin, &loop);
+ return ret;
+}
+
+void
+layerPaintWindowBackground (WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ layerWinPriv (pWin);
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ LayerPtr pLay;
+ LayerWinLoopRec loop;
+
+ for (pLay = LayerWindowFirst (pWin, &loop);
+ pLay;
+ pLay = LayerWindowNext (pWin, &loop))
+ {
+ LayerUnwrap(pScreen,pLay->pKind,PaintWindowBackground);
+ (*pScreen->PaintWindowBackground) (pWin, pRegion, what);
+ LayerWrap(pScreen,pLay->pKind,PaintWindowBackground,layerPaintWindowBackground);
+ }
+ LayerWindowDone (pWin, &loop);
+}
+
+void
+layerPaintWindowBorder (WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ layerWinPriv (pWin);
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ LayerPtr pLay;
+ LayerWinLoopRec loop;
+
+ for (pLay = LayerWindowFirst (pWin, &loop);
+ pLay;
+ pLay = LayerWindowNext (pWin, &loop))
+ {
+ LayerUnwrap(pScreen,pLay->pKind,PaintWindowBorder);
+ (*pScreen->PaintWindowBorder) (pWin, pRegion, what);
+ LayerWrap(pScreen,pLay->pKind,PaintWindowBorder,layerPaintWindowBorder);
+ }
+ LayerWindowDone (pWin, &loop);
+}
+
+void
+layerCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ layerWinPriv (pWin);
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ LayerPtr pLay;
+ LayerWinLoopRec loop;
+ int dx = 0, dy = 0;
+
+ for (pLay = LayerWindowFirst (pWin, &loop);
+ pLay;
+ pLay = LayerWindowNext (pWin, &loop))
+ {
+ LayerUnwrap(pScreen,pLay->pKind,CopyWindow);
+ /*
+ * Undo the translation done within the last CopyWindow proc (sigh)
+ */
+ if (dx || dy)
+ REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, dx, dy);
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
+ LayerWrap(pScreen,pLay->pKind,CopyWindow,layerCopyWindow);
+ /*
+ * Save offset to undo translation next time around
+ */
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ }
+ LayerWindowDone (pWin, &loop);
+}
+
diff --git a/xc/programs/Xserver/miext/shadow/shrot16pack_180.c b/xc/programs/Xserver/miext/shadow/shrot16pack_180.c
new file mode 100644
index 000000000..7ba41833e
--- /dev/null
+++ b/xc/programs/Xserver/miext/shadow/shrot16pack_180.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot16pack_180.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define FUNC shadowUpdateRotate16_180
+#define Data CARD16
+#define ROTATE 180
+
+#include "shrotpack.h"
diff --git a/xc/programs/Xserver/miext/shadow/shrot16pack_270.c b/xc/programs/Xserver/miext/shadow/shrot16pack_270.c
new file mode 100644
index 000000000..0b3c4e0ac
--- /dev/null
+++ b/xc/programs/Xserver/miext/shadow/shrot16pack_270.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot16pack_270.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define FUNC shadowUpdateRotate16_270
+#define Data CARD16
+#define ROTATE 270
+
+#include "shrotpack.h"
diff --git a/xc/programs/Xserver/miext/shadow/shrot16pack_90.c b/xc/programs/Xserver/miext/shadow/shrot16pack_90.c
new file mode 100644
index 000000000..574b3a157
--- /dev/null
+++ b/xc/programs/Xserver/miext/shadow/shrot16pack_90.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot16pack_90.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define FUNC shadowUpdateRotate16_90
+#define Data CARD16
+#define ROTATE 90
+
+#include "shrotpack.h"
diff --git a/xc/programs/Xserver/miext/shadow/shrot32pack_180.c b/xc/programs/Xserver/miext/shadow/shrot32pack_180.c
new file mode 100644
index 000000000..838622267
--- /dev/null
+++ b/xc/programs/Xserver/miext/shadow/shrot32pack_180.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot32pack_180.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define FUNC shadowUpdateRotate32_180
+#define Data CARD32
+#define ROTATE 180
+
+#include "shrotpack.h"
diff --git a/xc/programs/Xserver/miext/shadow/shrot32pack_270.c b/xc/programs/Xserver/miext/shadow/shrot32pack_270.c
new file mode 100644
index 000000000..b0dd28316
--- /dev/null
+++ b/xc/programs/Xserver/miext/shadow/shrot32pack_270.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot32pack_270.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define FUNC shadowUpdateRotate32_270
+#define Data CARD32
+#define ROTATE 270
+
+#include "shrotpack.h"
diff --git a/xc/programs/Xserver/miext/shadow/shrot32pack_90.c b/xc/programs/Xserver/miext/shadow/shrot32pack_90.c
new file mode 100644
index 000000000..9bdb18e25
--- /dev/null
+++ b/xc/programs/Xserver/miext/shadow/shrot32pack_90.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot32pack_90.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define FUNC shadowUpdateRotate32_90
+#define Data CARD32
+#define ROTATE 90
+
+#include "shrotpack.h"
diff --git a/xc/programs/Xserver/miext/shadow/shrot8pack_180.c b/xc/programs/Xserver/miext/shadow/shrot8pack_180.c
new file mode 100644
index 000000000..316c0c690
--- /dev/null
+++ b/xc/programs/Xserver/miext/shadow/shrot8pack_180.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot8pack_180.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define FUNC shadowUpdateRotate8_180
+#define Data CARD8
+#define ROTATE 180
+
+#include "shrotpack.h"
diff --git a/xc/programs/Xserver/miext/shadow/shrot8pack_270.c b/xc/programs/Xserver/miext/shadow/shrot8pack_270.c
new file mode 100644
index 000000000..bed542f6d
--- /dev/null
+++ b/xc/programs/Xserver/miext/shadow/shrot8pack_270.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot8pack_270.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define FUNC shadowUpdateRotate8_270
+#define Data CARD8
+#define ROTATE 270
+
+#include "shrotpack.h"
diff --git a/xc/programs/Xserver/miext/shadow/shrot8pack_90.c b/xc/programs/Xserver/miext/shadow/shrot8pack_90.c
new file mode 100644
index 000000000..f2618fc47
--- /dev/null
+++ b/xc/programs/Xserver/miext/shadow/shrot8pack_90.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot8pack_90.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define FUNC shadowUpdateRotate8_90
+#define Data CARD8
+#define ROTATE 90
+
+#include "shrotpack.h"
diff --git a/xc/programs/Xserver/miext/shadow/shrotate.c b/xc/programs/Xserver/miext/shadow/shrotate.c
new file mode 100644
index 000000000..9f631bd1d
--- /dev/null
+++ b/xc/programs/Xserver/miext/shadow/shrotate.c
@@ -0,0 +1,243 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrotate.c,v 1.3 2001/07/21 04:13:26 keithp Exp $
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, 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 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 "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "font.h"
+#include "dixfontstr.h"
+#include "fontstruct.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "globals.h"
+#include "gcstruct.h"
+#include "shadow.h"
+#include "fb.h"
+
+void
+shadowUpdateRotatePacked (ScreenPtr pScreen,
+ shadowBufPtr pBuf)
+{
+ RegionPtr damage = &pBuf->damage;
+ PixmapPtr pShadow = pBuf->pPixmap;
+ int nbox = REGION_NUM_RECTS (damage);
+ BoxPtr pbox = REGION_RECTS (damage);
+ FbBits *shaBits;
+ FbStride shaStride;
+ int shaBpp;
+ int shaXoff, shaYoff;
+ int box_x1, box_x2, box_y1, box_y2;
+ int sha_x1, sha_y1;
+ int scr_x1, scr_x2, scr_y1, scr_y2, scr_w, scr_h;
+ int scr_x, scr_y;
+ int w;
+ int pixelsPerBits;
+ int pixelsMask;
+ FbStride shaStepOverY, shaStepDownY, shaStepOverX, shaStepDownX;
+ FbBits *shaLine, *sha;
+ int shaHeight = pShadow->drawable.height;
+ int shaWidth = pShadow->drawable.width;
+ FbBits shaMask;
+ int shaFirstShift, shaShift;
+
+ fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, shaYoff);
+ pixelsPerBits = (sizeof (FbBits) * 8) / shaBpp;
+ pixelsMask = ~(pixelsPerBits - 1);
+ shaMask = FbBitsMask (FB_UNIT-shaBpp, shaBpp);
+ /*
+ * Compute rotation related constants to walk the shadow
+ */
+ switch (pBuf->rotate) {
+ case 0:
+ default:
+ shaStepOverX = shaBpp;
+ shaStepDownX = 0;
+ shaStepOverY = 0;
+ shaStepDownY = shaStride;
+ break;
+ case 90:
+ shaStepOverX = 0;
+ shaStepDownX = -shaBpp;
+ shaStepOverY = shaStride;
+ shaStepDownY = 0;
+ break;
+ case 180:
+ shaStepOverX = -shaBpp;
+ shaStepDownX = 0;
+ shaStepOverY = 0;
+ shaStepDownY = -shaStride;
+ break;
+ case 270:
+ shaStepOverX = 0;
+ shaStepDownX = shaBpp;
+ shaStepOverY = -shaStride;
+ shaStepDownY = 0;
+ break;
+ }
+ while (nbox--)
+ {
+ box_x1 = pbox->x1;
+ box_y1 = pbox->y1;
+ box_x2 = pbox->x2;
+ box_y2 = pbox->y2;
+ pbox++;
+
+ /*
+ * Compute screen and shadow locations for this box
+ */
+ switch (pBuf->rotate) {
+ case 0:
+ default:
+ scr_x1 = box_x1 & pixelsMask;
+ scr_x2 = (box_x2 + pixelsPerBits - 1) & pixelsMask;
+ scr_y1 = box_y1;
+ scr_y2 = box_y2;
+
+ sha_x1 = box_x1;
+ sha_y1 = box_y1;
+ break;
+ case 90:
+ scr_x1 = box_y1 & pixelsMask;
+ scr_x2 = (box_y2 + pixelsPerBits - 1) & pixelsMask;
+ scr_y1 = (shaWidth - box_x2);
+ scr_y2 = (shaWidth - box_x1);
+
+ sha_x1 = box_x2 - 1;
+ sha_y1 = scr_x1;
+ break;
+ case 180:
+ scr_x1 = (shaWidth - box_x2) & pixelsMask;
+ scr_x2 = (shaWidth - box_x1 + pixelsPerBits - 1) & pixelsMask;
+ scr_y1 = shaHeight - box_y2;
+ scr_y2 = shaHeight - box_y1;
+
+ sha_x1 = (shaWidth - scr_x1 - 1);
+ sha_y1 = box_y2 - 1;
+ break;
+ case 270:
+ scr_x1 = (shaHeight - box_y2) & pixelsMask;
+ scr_x2 = (shaHeight - box_y1 + pixelsPerBits - 1) & pixelsMask;
+ scr_y1 = box_x1;
+ scr_y2 = box_x2;
+
+ sha_x1 = box_x1;
+ sha_y1 = (shaHeight - scr_x1 - 1);
+ break;
+ }
+ scr_w = ((scr_x2 - scr_x1) * shaBpp) >> FB_SHIFT;
+ scr_h = scr_y2 - scr_y1;
+ scr_y = scr_y1;
+
+ /* shift amount for first pixel on screen */
+ shaFirstShift = FB_UNIT - ((sha_x1 * shaBpp) & FB_MASK) - shaBpp;
+
+ /* pointer to shadow data first placed on screen */
+ shaLine = (shaBits +
+ sha_y1 * shaStride +
+ ((sha_x1 * shaBpp) >> FB_SHIFT));
+
+ /*
+ * Copy the bits, always write across the physical frame buffer
+ * to take advantage of write combining.
+ */
+ while (scr_h--)
+ {
+ int p;
+ FbBits bits;
+ FbBits *win;
+ int i;
+ CARD32 winSize;
+
+ sha = shaLine;
+ shaShift = shaFirstShift;
+ w = scr_w;
+ scr_x = scr_x1 * shaBpp >> FB_SHIFT;
+
+ while (w)
+ {
+ /*
+ * Map some of this line
+ */
+ win = (FbBits *) (*pBuf->window) (pScreen,
+ scr_y,
+ scr_x << 2,
+ SHADOW_WINDOW_WRITE,
+ &winSize,
+ pBuf->closure);
+ i = (winSize >> 2);
+ if (i > w)
+ i = w;
+ w -= i;
+ scr_x += i;
+ /*
+ * Copy the portion of the line mapped
+ */
+ while (i--)
+ {
+ bits = 0;
+ p = pixelsPerBits;
+ /*
+ * Build one word of output from multiple inputs
+ *
+ * Note that for 90/270 rotations, this will walk
+ * down the shadow hitting each scanline once.
+ * This is probably not very efficient.
+ */
+ while (p--)
+ {
+ bits = FbScrLeft(bits, shaBpp);
+ bits |= FbScrRight (*sha, shaShift) & shaMask;
+
+ shaShift -= shaStepOverX;
+ if (shaShift >= FB_UNIT)
+ {
+ shaShift -= FB_UNIT;
+ sha--;
+ }
+ else if (shaShift < 0)
+ {
+ shaShift += FB_UNIT;
+ sha++;
+ }
+ sha += shaStepOverY;
+ }
+ *win++ = bits;
+ }
+ }
+ scr_y++;
+ shaFirstShift -= shaStepDownX;
+ if (shaFirstShift >= FB_UNIT)
+ {
+ shaFirstShift -= FB_UNIT;
+ shaLine--;
+ }
+ else if (shaFirstShift < 0)
+ {
+ shaFirstShift += FB_UNIT;
+ shaLine++;
+ }
+ shaLine += shaStepDownY;
+ }
+ }
+}
diff --git a/xc/programs/Xserver/render/miindex.c b/xc/programs/Xserver/render/miindex.c
new file mode 100644
index 000000000..eb52ac746
--- /dev/null
+++ b/xc/programs/Xserver/render/miindex.c
@@ -0,0 +1,252 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/miindex.c,v 1.4 2001/07/31 21:06:56 alanh Exp $
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, 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 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.
+ */
+
+#ifndef _MIINDEX_H_
+#define _MIINDEX_H_
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+#include "colormapst.h"
+
+Bool
+miBuildRenderColormap (ColormapPtr pColormap,
+ int num,
+ Pixel *first,
+ Pixel *last)
+{
+ int cube, ramp;
+ int r, g, b;
+ unsigned short red, green, blue;
+ Pixel pix;
+
+ cube = 0;
+ if ((pColormap->pVisual->class | DynamicClass) == PseudoColor)
+ {
+ for (cube = 0; cube * cube * cube < num; cube++)
+ ;
+ cube--;
+ }
+ if (cube == 1)
+ cube = 0;
+ ramp = num - (cube * cube * cube);
+ *first = MI_MAX_INDEXED;
+ *last = 0;
+ for (r = 0; r < cube; r++)
+ for (g = 0; g < cube; g++)
+ for (b = 0; b < cube; b++)
+ {
+ red = r * 65535 / (cube - 1);
+ green = g * 65535 / (cube - 1);
+ blue = b * 65535 / (cube - 1);
+ if (AllocColor (pColormap, &red, &green, &blue, &pix, 0) != Success)
+ return FALSE;
+ if (pix < *first)
+ *first = pix;
+ if (pix > *last)
+ *last = pix;
+ }
+ for (g = 0; g < ramp; g++)
+ {
+ red =
+ green =
+ blue = g * 65535 / (ramp - 1);
+ if (AllocColor (pColormap, &red, &green, &blue, &pix, 0) != Success)
+ return FALSE;
+ if (pix < *first)
+ *first = pix;
+ if (pix > *last)
+ *last = pix;
+ }
+
+ return TRUE;
+}
+
+/* 0 <= red, green, blue < 32 */
+static Pixel
+FindBestColor (miIndexedPtr pIndexed, int first, int num,
+ int red, int green, int blue)
+{
+ Pixel best = first;
+ int bestDist = 1 << 30;
+ int dist;
+ int dr, dg, db;
+ while (num--)
+ {
+ CARD32 v = pIndexed->rgba[first];
+
+ dr = ((v >> 19) & 0x1f);
+ dg = ((v >> 11) & 0x1f);
+ db = ((v >> 3) & 0x1f);
+ dr = dr - red;
+ dg = dg - green;
+ db = db - blue;
+ dist = dr * dr + dg * dg + db * db;
+ if (dist < bestDist)
+ {
+ bestDist = dist;
+ best = first;
+ }
+ first++;
+ }
+ return best;
+}
+
+/* 0 <= gray < 32768 */
+static Pixel
+FindBestGray (miIndexedPtr pIndexed, int first, int num, int gray)
+{
+ Pixel best = first;
+ int bestDist = 1 << 30;
+ int dist;
+ int dr;
+ int r;
+
+ while (num--)
+ {
+ CARD32 v = pIndexed->rgba[first];
+
+ r = v & 0xff;
+ r = r | (r << 8);
+ dr = gray - (r >> 1);
+ dist = dr * dr;
+ if (dist < bestDist)
+ {
+ bestDist = dist;
+ best = first;
+ }
+ first++;
+ }
+ return best;
+}
+
+Bool
+miInitIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat)
+{
+ miIndexedPtr pIndexed;
+ int num;
+ Pixel first, last;
+ Pixel pix[MI_MAX_INDEXED];
+ xrgb rgb[MI_MAX_INDEXED];
+ Pixel p, r, g, b;
+
+ if (pFormat->pVisual->ColormapEntries > MI_MAX_INDEXED)
+ return FALSE;
+ pIndexed = xalloc (sizeof (miIndexedRec));
+ if (!pIndexed)
+ return FALSE;
+ num = pFormat->pVisual->ColormapEntries;
+ first = 0;
+ last = num - 1;
+ if (pFormat->pVisual->class & DynamicClass)
+ {
+ if (pFormat->pVisual->vid == pScreen->rootVisual)
+ {
+ if (num > 100)
+ num = num - 10;
+ else
+ num = num / 2;
+ }
+ if (!miBuildRenderColormap (pFormat->pColormap, num, &first, &last))
+ {
+ xfree (pIndexed);
+ return FALSE;
+ }
+ }
+ /*
+ * Build mapping from pixel value to ARGB
+ */
+ for (p = 0; p < pFormat->pVisual->ColormapEntries; p++)
+ pix[p] = p;
+ QueryColors (pFormat->pColormap, pFormat->pVisual->ColormapEntries,
+ pix, rgb);
+ for (p = 0; p < pFormat->pVisual->ColormapEntries; p++)
+ pIndexed->rgba[p] = (0xff000000 |
+ ((rgb[p].red & 0xff00) << 8) |
+ ((rgb[p].green & 0xff00) ) |
+ ((rgb[p].blue & 0xff00) >> 8));
+ /*
+ * Build mapping from RGB to pixel value. This could probably be
+ * done a bit quicker...
+ */
+ switch (pFormat->pVisual->class | DynamicClass) {
+ case GrayScale:
+ pIndexed->color = FALSE;
+ for (r = 0; r < 32768; r++)
+ pIndexed->ent[r] = FindBestGray (pIndexed, first, last-first+1, r);
+ break;
+ case PseudoColor:
+ pIndexed->color = TRUE;
+ p = 0;
+ for (r = 0; r < 32; r++)
+ for (g = 0; g < 32; g++)
+ for (b = 0; b < 32; b++)
+ {
+ pIndexed->ent[p] = FindBestColor (pIndexed, first, last-first+1, r, g, b);
+ p++;
+ }
+ break;
+ }
+ pFormat->indexed = pIndexed;
+ return TRUE;
+}
+
+void
+miCloseIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat)
+{
+ if (pFormat->indexed)
+ {
+ xfree (pFormat->indexed);
+ pFormat->indexed = 0;
+ }
+}
+
+void
+miUpdateIndexed (ScreenPtr pScreen,
+ PictFormatPtr pFormat,
+ int ndef,
+ xColorItem *pdef)
+{
+ miIndexedPtr pIndexed = pFormat->indexed;
+
+ if (pIndexed)
+ {
+ while (ndef--)
+ {
+ pIndexed->rgba[pdef->pixel] = (0xff000000 |
+ ((pdef->red & 0xff00) << 8) |
+ ((pdef->green & 0xff00) ) |
+ ((pdef->blue & 0xff00) >> 8));
+ pdef++;
+ }
+ }
+}
+
+#endif /* _MIINDEX_H_ */