summaryrefslogtreecommitdiff
path: root/xc/programs
diff options
context:
space:
mode:
authordawes <dawes>2000-11-30 17:31:29 +0000
committerdawes <dawes>2000-11-30 17:31:29 +0000
commitd129f7fd02961869422c111dd8c3cf824bc54243 (patch)
treea8616855bbbfea89de0a0584e6d0daade1711bd2 /xc/programs
parentc6fd424b4371a3348ec8a34475cfacad1c8fddb9 (diff)
Initial revision
Diffstat (limited to 'xc/programs')
-rw-r--r--xc/programs/Xserver/hw/darwin/Imakefile28
-rw-r--r--xc/programs/Xserver/hw/darwin/Xdarwin.man63
-rw-r--r--xc/programs/Xserver/hw/darwin/darwin.c1071
-rw-r--r--xc/programs/Xserver/hw/darwin/darwin.h38
-rw-r--r--xc/programs/Xserver/hw/darwin/darwinCursor.c705
-rw-r--r--xc/programs/Xserver/hw/darwin/darwinKeyboard.c503
-rw-r--r--xc/programs/Xserver/hw/darwin/utils/Imakefile11
-rw-r--r--xc/programs/Xserver/hw/darwin/utils/dumpkeymap.c879
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ark/Imakefile49
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ark/ark.h71
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ark/ark_accel.c227
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ark/ark_driver.c1170
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ark/ark_reg.h88
13 files changed, 4903 insertions, 0 deletions
diff --git a/xc/programs/Xserver/hw/darwin/Imakefile b/xc/programs/Xserver/hw/darwin/Imakefile
new file mode 100644
index 000000000..2a1f2430a
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/Imakefile
@@ -0,0 +1,28 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/darwin/Imakefile,v 1.2 2000/11/16 03:22:18 dawes Exp $
+
+#include <Server.tmpl>
+#define IHaveSubdirs
+
+SUBDIRS = utils
+
+SRCS = darwin.c \
+ darwinCursor.c \
+ darwinKeyboard.c
+
+OBJS = darwin.o \
+ darwinCursor.o \
+ darwinKeyboard.o
+
+INCLUDES = -I. -I$(SERVERSRC)/mi -I$(SERVERSRC)/mfb -I$(SERVERSRC)/cfb \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(SERVERSRC)/os \
+ -I$(INCLUDESRC) -I$(FONTINCSRC)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(darwin,$(OBJS))
+
+InstallManPage(Xdarwin,$(MANDIR))
+
+DependTarget()
+
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
diff --git a/xc/programs/Xserver/hw/darwin/Xdarwin.man b/xc/programs/Xserver/hw/darwin/Xdarwin.man
new file mode 100644
index 000000000..aee06c433
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/Xdarwin.man
@@ -0,0 +1,63 @@
+.\" $XFree86: xc/programs/Xserver/hw/darwin/Xdarwin.man,v 1.1 2000/11/15 01:36:13 dawes Exp $
+.\"
+.TH XDARWIN 1 "Release 6.4" "X Version 11"
+.SH NAME
+Xdarwin \- X window system server for Darwin operating system
+.SH SYNOPSIS
+.B Xdarwin
+[ options ] ...
+.SH DESCRIPTION
+.I Xdarwin
+is the window server for Version 11 of the X window system on the Darwin
+operating system. It uses IOKit services to accesss the display framebuffer,
+mouse and keyboard and to provide a layer of hardware abstraction.
+.I Xdarwin
+will normally be started by the \fIxdm(1)\fP display manager or by a script
+that runs the program \fIxinit(1)\fP.
+.SH OPTIONS
+.PP
+In addition to the normal server options described in the \fIXserver(1)\fP
+manual page, \fIXdarwin\fP accepts the following command line switches:
+.TP 8
+.B \-fakebuttons
+Emulates a 3 button mouse using the Command and Option keys. Clicking the
+first mouse button while holding down Command will act like clicking
+button 2. Holding down Option will simulate button 3.
+.TP 8
+.B \-nofakebuttons
+Do not emulate a 3 button mouse. This is the default.
+.TP 8
+.B "\-size \fIwidth\fP \fIheight\fP"
+Sets the screeen resolution for the X server to use.
+.TP 8
+.B "\-depth \fIdepth\fP"
+Specifies the color bit depth to use. Currently only 8, 15, and 24 color bits
+per pixel are supported.
+.TP 8
+.B "\-refresh \fIrate\fP"
+Gives the refresh rate to use in Hz. For LCD displays this should be 0.
+.SH "SEE ALSO"
+.PP
+X(1), Xserver(1), xdm(1), xinit(1)
+.SH BUGS
+.I Xdarwin
+and this man page still have many limitations. Some of the more obvious
+ones are:
+.br
+- Only one display is supported.
+.br
+- The display mode can not be changed once the X server has started.
+.br
+- A screen saver is not supported.
+.br
+- The X server does not wake from sleep correctly.
+.br
+- The key repeat rate can not be changed.
+.PP
+.SH AUTHORS
+Original Port to Mac OS X Server - John Carmack
+.br
+Port to Darwin 1.0 - Dave Zarzycki
+.br
+Improvements and bug fixes - Torrey T. Lyons
+
diff --git a/xc/programs/Xserver/hw/darwin/darwin.c b/xc/programs/Xserver/hw/darwin/darwin.c
new file mode 100644
index 000000000..a28d07d70
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/darwin.c
@@ -0,0 +1,1071 @@
+/**************************************************************
+ *
+ * IOKit support for the Darwin X Server
+ *
+ * HISTORY:
+ * Original port to Mac OS X Server by John Carmack
+ * Port to Darwin 1.0 by Dave Zarzycki
+ * Significantly rewritten for XFree86 4.0.1 by Torrey Lyons
+ *
+ **************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/darwin/darwin.c,v 1.1 2000/11/15 01:36:13 dawes Exp $ */
+
+#define NDEBUG 1
+
+#include "X.h"
+#include "Xproto.h"
+#include "os.h"
+#include "servermd.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "mi.h"
+#include "mibstore.h"
+#include "mipointer.h"
+#include "micmap.h"
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <pthread.h>
+
+#include <mach/mach_interface.h>
+
+#define NO_CFPLUGIN
+#include <IOKit/IOKitLib.h>
+#include <IOKit/hidsystem/IOHIDShared.h>
+#include <IOKit/graphics/IOGraphicsLib.h>
+#include <drivers/event_status_driver.h>
+
+// Define this to work around bugs in the display drivers for
+// older PowerBook G3's. If the X server starts without this
+// #define, you don't need it.
+#undef OLD_POWERBOOK_G3
+
+#include "darwin.h"
+
+DarwinFramebufferRec dfb;
+unsigned char darwinKeyCommandL = 0, darwinKeyOptionL = 0;
+
+/* Fake button press/release for scroll wheel move. */
+#define SCROLLWHEELUPFAKE 4
+#define SCROLLWHEELDOWNFAKE 5
+
+static int darwinEventFD;
+static Bool fake3Buttons = FALSE;
+static DeviceIntPtr darwinPointer;
+static DeviceIntPtr darwinKeyboard;
+static UInt32 darwinDesiredWidth = 0, darwinDesiredHeight = 0;
+static IOIndex darwinDesiredDepth = -1;
+static SInt32 darwinDesiredRefresh = -1;
+
+// Common pixmap formats
+static PixmapFormatRec formats[] = {
+ { 1, 1, BITMAP_SCANLINE_PAD },
+ { 4, 8, BITMAP_SCANLINE_PAD },
+ { 8, 8, BITMAP_SCANLINE_PAD },
+ { 15, 16, BITMAP_SCANLINE_PAD },
+ { 16, 16, BITMAP_SCANLINE_PAD },
+ { 24, 32, BITMAP_SCANLINE_PAD }
+};
+const int NUMFORMATS = sizeof(formats)/sizeof(formats[0]);
+
+static Bool DarwinSaveScreen(ScreenPtr pScreen, int on)
+{ // FIXME
+ if (on == SCREEN_SAVER_FORCER) {
+ } else if (on == SCREEN_SAVER_ON) {
+ } else {
+ }
+ return TRUE;
+}
+
+/*
+ * DarwinStoreColors
+ * This is a callback from X to change the hardware colormap
+ * when using PsuedoColor
+ */
+static void DarwinStoreColors(
+ ColormapPtr pmap,
+ int numEntries,
+ xColorItem *pdefs)
+{
+ kern_return_t kr;
+ int i;
+ IOColorEntry *newColors;
+
+ assert( newColors = (IOColorEntry *)
+ xalloc( numEntries*sizeof(IOColorEntry) ));
+
+ // Convert xColorItem values to IOColorEntry
+ // assume the colormap is PsuedoColor
+ // as we do not support DirectColor
+ for (i = 0; i < numEntries; i++) {
+ newColors[i].index = pdefs[i].pixel;
+ newColors[i].red = pdefs[i].red;
+ newColors[i].green = pdefs[i].green;
+ newColors[i].blue = pdefs[i].blue;
+ }
+
+ kr = IOFBSetCLUT( dfb.fbService, 0, numEntries,
+ kSetCLUTByValue, newColors );
+ kern_assert( kr );
+
+ xfree( newColors );
+}
+
+/*
+ * DarwinAddScreen
+ * This is a callback from X during AddScreen() from InitOutput()
+ */
+static Bool DarwinAddScreen(
+ int index,
+ ScreenPtr pScreen,
+ int argc,
+ char **argv )
+{
+ int bitsPerRGB, i;
+ VisualPtr visual;
+
+ /* Communicate the information about our initialized screen back to X. */
+ bitsPerRGB = dfb.pixelInfo.bitsPerComponent;
+
+ // reset the visual list
+ miClearVisualTypes();
+
+ // setup a single visual appropriate for our pixel type
+ // Note: Darwin kIORGBDirectPixels = X window TrueColor, not DirectColor
+ if (dfb.pixelInfo.pixelType == kIORGBDirectPixels) {
+ if (!miSetVisualTypes( dfb.colorBitsPerPixel, TrueColorMask,
+ bitsPerRGB, TrueColor )) {
+ return FALSE;
+ }
+ } else if (dfb.pixelInfo.pixelType == kIOCLUTPixels) {
+ if (!miSetVisualTypes( dfb.colorBitsPerPixel, PseudoColorMask,
+ bitsPerRGB, PseudoColor )) {
+ return FALSE;
+ }
+ } else if (dfb.pixelInfo.pixelType == kIOFixedCLUTPixels) {
+ if (!miSetVisualTypes( dfb.colorBitsPerPixel, StaticColorMask,
+ bitsPerRGB, StaticColor )) {
+ return FALSE;
+ }
+ } else {
+ return FALSE;
+ }
+
+ // machine independent screen init
+ // setup _Screen structure in pScreen
+ if ( dfb.bitsPerPixel == 32 ) {
+ if (!cfb32ScreenInit(pScreen,
+ dfb.framebuffer,
+ dfb.width, dfb.height,
+ 75, 75, /* screen size in dpi, which we have no accurate knowledge of */
+ dfb.pitch / (dfb.bitsPerPixel/8))) {
+ return FALSE;
+ }
+ } else if ( dfb.bitsPerPixel == 16 ) {
+ if (!cfb16ScreenInit(pScreen,
+ dfb.framebuffer,
+ dfb.width, dfb.height,
+ 75, 75, /* screen size in dpi, which we have no accurate knowledge of */
+ dfb.pitch / (dfb.bitsPerPixel/8))) {
+ return FALSE;
+ }
+ } else if ( dfb.bitsPerPixel == 8 ) {
+ if (!cfbScreenInit(pScreen,
+ dfb.framebuffer,
+ dfb.width, dfb.height,
+ 75, 75, /* screen size in dpi, which we have no accurate knowledge of */
+ dfb.pitch / (dfb.bitsPerPixel/8))) {
+ return FALSE;
+ }
+ } else {
+ return FALSE;
+ }
+
+ // set the RGB order correctly for TrueColor, it is byte swapped by X
+ // FIXME: make work on x86 darwin if it ever gets buildable
+ if (dfb.bitsPerPixel > 8) {
+ for (i = 0, visual = pScreen->visuals; // someday we may have more than 1
+ i < pScreen->numVisuals; i++, visual++) {
+ if (visual->class == TrueColor) {
+ visual->offsetRed = bitsPerRGB * 2;
+ visual->offsetGreen = bitsPerRGB;
+ visual->offsetBlue = 0;
+#if FALSE
+ visual->redMask = ((1<<bitsPerRGB)-1) << visual->offsetRed;
+ visual->greenMask = ((1<<bitsPerRGB)-1) << visual->offsetGreen;
+ visual->blueMask = ((1<<bitsPerRGB)-1) << visual->offsetBlue;
+#else
+ visual->redMask = dfb.pixelInfo.componentMasks[0];
+ visual->greenMask = dfb.pixelInfo.componentMasks[1];
+ visual->blueMask = dfb.pixelInfo.componentMasks[2];
+#endif
+ }
+ }
+ }
+
+#ifdef MITSHM
+ ShmRegisterFbFuncs(pScreen);
+#endif
+
+ // setup cursor support, use hardware if possible
+ if (!DarwinInitCursor(pScreen)) {
+ return FALSE;
+ }
+
+ // this must be initialized (why doesn't X have a default?)
+ pScreen->SaveScreen = DarwinSaveScreen;
+
+ // initialize colormap handling as needed
+ if (dfb.pixelInfo.pixelType == kIOCLUTPixels) {
+ pScreen->StoreColors = DarwinStoreColors;
+ }
+
+ // create and install the default colormap and
+ // set pScreen->blackPixel / pScreen->white
+ if (!miCreateDefColormap( pScreen )) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * DarwinShutdownScreen
+ */
+void DarwinShutdownScreen( void )
+{
+#if 0
+ // we must close the HID System first
+ // because it is a client of the framebuffer
+ NXCloseEventStatus( dfb.hidParam );
+ IOServiceClose( dfb.hidService );
+ IOServiceClose( dfb.fbService );
+#endif
+}
+
+/*
+ =============================================================================
+
+ mouse callbacks
+
+ =============================================================================
+*/
+
+/*
+ * Set mouse acceleration and thresholding
+ * FIXME: We currently ignore the threshold in ctrl->threshold.
+ */
+static void DarwinChangePointerControl(
+ DeviceIntPtr device,
+ PtrCtrl *ctrl )
+{
+ kern_return_t kr;
+ double acceleration;
+
+ acceleration = ctrl->num / ctrl->den;
+ kr = IOHIDSetMouseAcceleration( dfb.hidParam, acceleration );
+ if (kr != KERN_SUCCESS)
+ ErrorF( "Could not set mouse acceleration with kernel return = 0x%x.\n", kr );
+}
+
+
+/*
+ * Motion history between events is not required to be supported.
+ */
+static int DarwinGetMotionEvents( DeviceIntPtr pDevice, xTimecoord *buff,
+ unsigned long start, unsigned long stop, ScreenPtr pScr)
+{
+ return 0;
+}
+
+
+/*
+ * DarwinMouseProc --
+ * Handle the initialization, etc. of a mouse
+ */
+
+static int DarwinMouseProc( DeviceIntPtr pPointer, int what ) {
+
+ char map[6];
+
+ switch (what) {
+
+ case DEVICE_INIT:
+ pPointer->public.on = FALSE;
+
+ map[1] = 1;
+ map[2] = 2;
+ map[3] = 3;
+ map[4] = 4;
+ map[5] = 5;
+ InitPointerDeviceStruct( (DevicePtr)pPointer,
+ map,
+ 5, // numbuttons (4 & 5 are scroll wheel)
+ DarwinGetMotionEvents, // miPointerGetMotionEvents ??
+ DarwinChangePointerControl,
+ 0 );
+ break;
+
+ case DEVICE_ON:
+ pPointer->public.on = TRUE;
+ AddEnabledDevice( darwinEventFD );
+ return Success;
+
+ case DEVICE_CLOSE:
+ case DEVICE_OFF:
+ pPointer->public.on = FALSE;
+ RemoveEnabledDevice( darwinEventFD );
+ return Success;
+ }
+
+ return Success;
+}
+
+/*
+ * DarwinKeybdProc
+ * callback from X
+ */
+static int DarwinKeybdProc( DeviceIntPtr pDev, int onoff )
+{
+ switch ( onoff ) {
+ case DEVICE_INIT:
+ DarwinKeyboardInit( pDev );
+ break;
+ case DEVICE_ON:
+ pDev->public.on = TRUE;
+ AddEnabledDevice( darwinEventFD );
+ break;
+ case DEVICE_OFF:
+ pDev->public.on = FALSE;
+ RemoveEnabledDevice( darwinEventFD );
+ break;
+ case DEVICE_CLOSE:
+ break;
+ }
+
+ return Success;
+}
+
+/*
+===========================================================================
+
+ Functions needed to link against device independent X
+
+===========================================================================
+*/
+
+/*
+ * ProcessInputEvents
+ * Read events from the event queue
+ */
+void ProcessInputEvents(void)
+{
+ xEvent xe;
+ NXEvent ev;
+ int r;
+ struct timeval tv;
+ struct timezone tz;
+
+ // try to read from our pipe
+ r = read( darwinEventFD, &ev, sizeof(ev));
+ if ((r == -1) && (errno != EAGAIN)) {
+ ErrorF("read(darwinEventFD) failed, errno=%d: %s\n", errno, strerror(errno));
+ return;
+ } else if ((r == -1) && (errno == EAGAIN)) {
+ return;
+ } else if ( r != sizeof( ev ) ) {
+ ErrorF( "Only read %i bytes from darwinPipe!", r );
+ return;
+ }
+
+ gettimeofday(&tv, &tz);
+
+ // translate it to an X event and post it
+ memset(&xe, 0, sizeof(xe));
+
+ xe.u.keyButtonPointer.rootX = ev.location.x;
+ xe.u.keyButtonPointer.rootY = ev.location.y;
+ //xe.u.keyButtonPointer.time = ev.time;
+ xe.u.keyButtonPointer.time = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+
+ /* A newer kernel generates multi-button events by NX_SYSDEFINED.
+ See iokit/Families/IOHIDSystem/IOHIDSystem.cpp version 1.1.1.7,
+ 2000/08/10 00:23:37 or later. */
+
+ switch( ev.type ) {
+ case NX_MOUSEMOVED:
+ xe.u.u.type = MotionNotify;
+ (darwinPointer->public.processInputProc)( &xe, darwinPointer, 1 );
+ break;
+
+ case NX_LMOUSEDOWN:
+ // Mimic multi-button mouse with Command and Option
+ if (fake3Buttons && ev.flags & (NX_COMMANDMASK | NX_ALTERNATEMASK)) {
+ if (ev.flags & NX_COMMANDMASK) {
+ // first fool X into forgetting about Command key
+ xe.u.u.type = KeyRelease;
+ xe.u.u.detail = darwinKeyCommandL;
+ (darwinKeyboard->public.processInputProc)
+ ( &xe, darwinKeyboard, 1 );
+ // push button 2
+ xe.u.u.type = ButtonPress;
+ xe.u.u.detail = 2; // de.key = button 2
+ (darwinPointer->public.processInputProc)
+ ( &xe, darwinPointer, 1 );
+ // reset Command key down
+ xe.u.u.type = KeyPress;
+ xe.u.u.detail = darwinKeyCommandL;
+ (darwinKeyboard->public.processInputProc)
+ ( &xe, darwinKeyboard, 1 );
+ } else {
+ // first fool X into forgetting about Option key
+ xe.u.u.type = KeyRelease;
+ xe.u.u.detail = darwinKeyOptionL;
+ (darwinKeyboard->public.processInputProc)
+ ( &xe, darwinKeyboard, 1 );
+ // push button 3
+ xe.u.u.type = ButtonPress;
+ xe.u.u.detail = 3; // de.key = button 3
+ (darwinPointer->public.processInputProc)
+ ( &xe, darwinPointer, 1 );
+ // reset Option key down
+ xe.u.u.type = KeyPress;
+ xe.u.u.detail = darwinKeyOptionL;
+ (darwinKeyboard->public.processInputProc)
+ ( &xe, darwinKeyboard, 1 );
+ }
+ } else {
+ xe.u.u.detail = 1; //de.key = button 1;
+ xe.u.u.type = ButtonPress;
+ (darwinPointer->public.processInputProc)
+ ( &xe, darwinPointer, 1 );
+ }
+ break;
+
+ case NX_LMOUSEUP:
+ // Mimic multi-button mouse with Command and Option
+ if (fake3Buttons && ev.flags & (NX_COMMANDMASK | NX_ALTERNATEMASK)) {
+ if (ev.flags & NX_COMMANDMASK) {
+ // first fool X into forgetting about Command key
+ xe.u.u.type = KeyRelease;
+ xe.u.u.detail = darwinKeyCommandL;
+ (darwinKeyboard->public.processInputProc)
+ ( &xe, darwinKeyboard, 1 );
+ // push button 2
+ xe.u.u.type = ButtonRelease;
+ xe.u.u.detail = 2; // de.key = button 2
+ (darwinPointer->public.processInputProc)
+ ( &xe, darwinPointer, 1 );
+ // reset Command key down
+ xe.u.u.type = KeyPress;
+ xe.u.u.detail = darwinKeyCommandL;
+ (darwinKeyboard->public.processInputProc)
+ ( &xe, darwinKeyboard, 1 );
+ } else {
+ // first fool X into forgetting about Option key
+ xe.u.u.type = KeyRelease;
+ xe.u.u.detail = darwinKeyOptionL;
+ (darwinKeyboard->public.processInputProc)
+ ( &xe, darwinKeyboard, 1 );
+ // push button 3
+ xe.u.u.type = ButtonRelease;
+ xe.u.u.detail = 3; // de.key = button 3
+ (darwinPointer->public.processInputProc)
+ ( &xe, darwinPointer, 1 );
+ // reset Option key down
+ xe.u.u.type = KeyPress;
+ xe.u.u.detail = darwinKeyOptionL;
+ (darwinKeyboard->public.processInputProc)
+ ( &xe, darwinKeyboard, 1 );
+ }
+ } else {
+ xe.u.u.detail = 1; //de.key = button 1;
+ xe.u.u.type = ButtonRelease;
+ (darwinPointer->public.processInputProc)
+ ( &xe, darwinPointer, 1 );
+ }
+ break;
+
+// Button 2 isn't handled correctly by older kernels anyway. Just let
+// NX_SYSDEFINED events handle these.
+ case NX_RMOUSEDOWN:
+#if 0
+ xe.u.u.detail = 2; //de.key;
+ xe.u.u.type = ButtonPress;
+ (darwinPointer->public.processInputProc)( &xe, darwinPointer, 1 );
+#endif
+ break;
+
+ case NX_RMOUSEUP:
+#if 0
+ xe.u.u.detail = 2; //de.key;
+ xe.u.u.type = ButtonRelease;
+ (darwinPointer->public.processInputProc)( &xe, darwinPointer, 1 );
+#endif
+ break;
+
+ case NX_KEYDOWN:
+ xe.u.u.type = KeyPress;
+ xe.u.u.detail = ev.data.key.keyCode + MIN_KEYCODE;
+ (darwinKeyboard->public.processInputProc)( &xe, darwinKeyboard, 1 );
+ break;
+
+ case NX_KEYUP:
+ xe.u.u.type = KeyRelease;
+ xe.u.u.detail = ev.data.key.keyCode + MIN_KEYCODE;
+ (darwinKeyboard->public.processInputProc)(&xe, darwinKeyboard, 1);
+ break;
+
+ case NX_FLAGSCHANGED:
+ {
+ static int old_state = 0;
+ int new_on_flags = ~old_state & ev.flags;
+ int new_off_flags = old_state & ~ev.flags;
+ old_state = ev.flags;
+ xe.u.u.detail = ev.data.key.keyCode + MIN_KEYCODE;
+
+ // alphalock is toggled rather than held on,
+ // so we have to handle it differently
+ if (new_on_flags & NX_ALPHASHIFTMASK ||
+ new_off_flags & NX_ALPHASHIFTMASK) {
+ xe.u.u.type = KeyPress;
+ (darwinKeyboard->public.processInputProc)
+ (&xe, darwinKeyboard, 1);
+ xe.u.u.type = KeyRelease;
+ (darwinKeyboard->public.processInputProc)
+ (&xe, darwinKeyboard, 1);
+ break;
+ }
+
+ if (new_on_flags) {
+ xe.u.u.type = KeyPress;
+ } else if (new_off_flags) {
+ xe.u.u.type = KeyRelease;
+ } else {
+ break;
+ }
+ (darwinKeyboard->public.processInputProc)(&xe, darwinKeyboard, 1);
+ break;
+ }
+
+ case NX_SYSDEFINED:
+ if (ev.data.compound.subType == 7) {
+ long hwDelta = ev.data.compound.misc.L[0];
+ long hwButtons = ev.data.compound.misc.L[1];
+ int i;
+
+ for (i = 1; i < 4; i++) {
+ if (hwDelta & (1 << i)) {
+ xe.u.u.detail = i + 1;
+ if (hwButtons & (1 << i)) {
+ xe.u.u.type = ButtonPress;
+ } else {
+ xe.u.u.type = ButtonRelease;
+ }
+ (darwinPointer->public.processInputProc)
+ ( &xe, darwinPointer, 1 );
+ }
+ }
+ }
+ break;
+
+ case NX_SCROLLWHEELMOVED:
+ {
+ short count = ev.data.scrollWheel.deltaAxis1;
+
+ if (count > 0) {
+ xe.u.u.detail = SCROLLWHEELUPFAKE;
+ } else {
+ xe.u.u.detail = SCROLLWHEELDOWNFAKE;
+ count = -count;
+ }
+
+ for (; count; --count) {
+ xe.u.u.type = ButtonPress;
+ (darwinPointer->public.processInputProc)
+ ( &xe, darwinPointer, 1 );
+ xe.u.u.type = ButtonRelease;
+ (darwinPointer->public.processInputProc)
+ ( &xe, darwinPointer, 1 );
+ }
+ break;
+ }
+
+ default:
+ ErrorF("unknown event caught: %d\n", ev.type);
+ ErrorF("\tev.type = %d\n", ev.type);
+ ErrorF("\tev.location.x,y = %d,%d\n", ev.location.x, ev.location.y);
+ ErrorF("\tev.time = %ld\n", ev.time);
+ ErrorF("\tev.flags = 0x%x\n", ev.flags);
+ ErrorF("\tev.window = %d\n", ev.window);
+ ErrorF("\tev.data.key.origCharSet = %d\n", ev.data.key.origCharSet);
+ ErrorF("\tev.data.key.charSet = %d\n", ev.data.key.charSet);
+ ErrorF("\tev.data.key.charCode = %d\n", ev.data.key.charCode);
+ ErrorF("\tev.data.key.keyCode = %d\n", ev.data.key.keyCode);
+ ErrorF("\tev.data.key.origCharCode = %d\n", ev.data.key.origCharCode);
+ break;
+ }
+
+ // why isn't this handled automatically by X???
+ //miPointerAbsoluteCursor( ev.location.x, ev.location.y, ev.time );
+ miPointerAbsoluteCursor( ev.location.x, ev.location.y,
+ tv.tv_sec * 1000 + tv.tv_usec / 1000 );
+ miPointerUpdate();
+
+}
+
+static void *DarwinHIDThread(void *arg);
+
+/*
+ * InitInput
+ * Register the keyboard and mouse devices
+ */
+void InitInput( int argc, char **argv )
+{ static int initialized = 0;
+ if (!initialized) {
+ int fd[2];
+
+ assert( pipe(fd) == 0 );
+ darwinEventFD = fd[0];
+ fcntl(darwinEventFD, F_SETFL, O_NONBLOCK);
+ pthread_create(&dfb.hidThread, NULL, DarwinHIDThread, (void *) fd[1]);
+
+ darwinPointer = AddInputDevice(DarwinMouseProc, TRUE);
+ RegisterPointerDevice( darwinPointer );
+
+ darwinKeyboard = AddInputDevice(DarwinKeybdProc, TRUE);
+ RegisterKeyboardDevice( darwinKeyboard );
+ }
+}
+
+EvGlobals * evg;
+mach_port_t masterPort;
+mach_port_t notificationPort;
+IONotificationPortRef NotificationPortRef;
+
+static void InitIOKit(void)
+{
+ kern_return_t kr;
+
+ kr = IOMasterPort(bootstrap_port, &masterPort);
+ kern_assert( kr );
+}
+
+static void ClearEvent(NXEvent * ep)
+{
+ static NXEvent nullEvent = {NX_NULLEVENT, {0, 0 }, 0, -1, 0 };
+
+ *ep = nullEvent;
+ ep->data.compound.subType = ep->data.compound.misc.L[0] =
+ ep->data.compound.misc.L[1] = 0;
+}
+
+static void *DarwinHIDThread(void *arg)
+{
+ int darwinEventWriteFD = (int)arg;
+
+ for (;;) {
+ IOReturn kr;
+ NXEvent ev;
+ NXEQElement *oldHead;
+ struct {
+ mach_msg_header_t header;
+ mach_msg_trailer_t trailer;
+ } msg;
+
+ kr = mach_msg((mach_msg_header_t*) &msg, MACH_RCV_MSG, 0,
+ sizeof(msg), notificationPort, 0, MACH_PORT_NULL);
+ assert(KERN_SUCCESS == kr);
+
+ while (evg->LLEHead != evg->LLETail) {
+ oldHead = (NXEQElement*)&evg->lleq[evg->LLEHead];
+ ev_lock(&oldHead->sema);
+ ev = oldHead->event;
+ ClearEvent(&oldHead->event);
+ evg->LLEHead = oldHead->next;
+ ev_unlock(&oldHead->sema);
+
+ write(darwinEventWriteFD, &ev, sizeof(ev));
+ }
+ }
+ return NULL;
+}
+
+void SetupFBandHID(void)
+{
+ kern_return_t kr;
+ io_service_t service;
+ io_iterator_t iter;
+ io_name_t name;
+ vm_address_t shmem, vram;
+ vm_size_t shmemSize;
+ int i;
+ UInt32 numModes;
+ IODisplayModeInformation modeInfo;
+ IODisplayModeID displayMode, *allModes;
+ IOIndex displayDepth;
+ IOFramebufferInformation fbInfo;
+ StdFBShmem_t *cshmem;
+
+ dfb.fbService = 0;
+ dfb.hidService = 0;
+
+ // find and open the IOFrameBuffer service
+ kr = IOServiceGetMatchingServices( masterPort,
+ IOServiceMatching( IOFRAMEBUFFER_CONFORMSTO ),
+ &iter );
+ kern_assert( kr );
+
+ assert(service = IOIteratorNext(iter));
+
+ kr = IOServiceOpen( service, mach_task_self(),
+ kIOFBServerConnectType, &dfb.fbService );
+ if (kr != KERN_SUCCESS)
+ FatalError("failed to connect as window server!\nMake sure you have quit the Mac OS X window server.\n");
+
+ IOObjectRelease( service );
+ IOObjectRelease( iter );
+
+ // create the slice of shared memory containing cursor state data
+ kr = IOFBCreateSharedCursor( dfb.fbService, kIOFBCurrentShmemVersion,
+ 32, 32 );
+ kern_assert( kr );
+
+ // SET THE SCREEN PARAMETERS
+ // get the current screen resolution, refresh rate and depth
+ kr = IOFBGetCurrentDisplayModeAndDepth( dfb.fbService, &displayMode,
+ &displayDepth );
+ kern_assert( kr );
+
+ // use the current screen resolution if the user
+ // only wants to change the refresh rate
+ if (darwinDesiredRefresh != -1 && darwinDesiredWidth == 0) {
+ kr = IOFBGetDisplayModeInformation( dfb.fbService, displayMode,
+ &modeInfo );
+ kern_assert( kr );
+ darwinDesiredWidth = modeInfo.nominalWidth;
+ darwinDesiredHeight = modeInfo.nominalHeight;
+ }
+
+ // use the current resolution and refresh rate
+ // if the user doesn't have a preference
+ if (darwinDesiredWidth == 0) {
+
+ // change the pixel depth if desired
+ if (darwinDesiredDepth != -1) {
+ kr = IOFBGetDisplayModeInformation( dfb.fbService, displayMode,
+ &modeInfo );
+ kern_assert( kr );
+ if (modeInfo.maxDepthIndex < darwinDesiredDepth)
+ FatalError("Current screen resolution does not support desired pixel depth!\n");
+
+ displayDepth = darwinDesiredDepth;
+ kr = IOFBSetDisplayModeAndDepth( dfb.fbService, displayMode,
+ displayDepth );
+ kern_assert( kr );
+ }
+
+ // look for display mode with correct resolution and refresh rate
+ } else {
+
+ // get an array of all supported display modes
+ kr = IOFBGetDisplayModeCount( dfb.fbService, &numModes );
+ kern_assert( kr );
+ assert(allModes = (IODisplayModeID *)
+ xalloc( numModes * sizeof(IODisplayModeID) ));
+ kr = IOFBGetDisplayModes( dfb.fbService, numModes, allModes );
+ kern_assert( kr );
+
+ for (i = 0; i < numModes; i++) {
+ kr = IOFBGetDisplayModeInformation( dfb.fbService, allModes[i],
+ &modeInfo );
+ kern_assert( kr );
+
+ if (modeInfo.flags & kDisplayModeValidFlag &&
+ modeInfo.nominalWidth == darwinDesiredWidth &&
+ modeInfo.nominalHeight == darwinDesiredHeight) {
+
+ if (darwinDesiredDepth == -1)
+ darwinDesiredDepth = modeInfo.maxDepthIndex;
+ if (modeInfo.maxDepthIndex < darwinDesiredDepth)
+ FatalError("Desired screen resolution does not support desired pixel depth!\n");
+ if ((darwinDesiredRefresh == -1 ||
+ (darwinDesiredRefresh << 16) == modeInfo.refreshRate)) {
+ displayMode = allModes[i];
+ displayDepth = darwinDesiredDepth;
+ kr = IOFBSetDisplayModeAndDepth( dfb.fbService, displayMode,
+ displayDepth );
+ kern_assert( kr );
+ break;
+ }
+ }
+ }
+
+ xfree( allModes );
+ if (i >= numModes)
+ FatalError("Desired screen resolution or refresh rate is not supported!\n");
+ }
+
+ kr = IOFBGetPixelInformation( dfb.fbService, displayMode, displayDepth,
+ kIOFBSystemAperture, &dfb.pixelInfo );
+ kern_assert( kr );
+
+#ifdef OLD_POWERBOOK_G3
+ if (dfb.pixelInfo.pixelType == kIOCLUTPixels)
+ dfb.pixelInfo.pixelType = kIOFixedCLUTPixels;
+#endif
+
+ kr = IOFBGetFramebufferInformationForAperture( dfb.fbService, kIOFBSystemAperture,
+ &fbInfo );
+ kern_assert( kr );
+
+ kr = IOConnectMapMemory( dfb.fbService, kIOFBCursorMemory,
+ mach_task_self(), (vm_address_t *) &cshmem,
+ &shmemSize, kIOMapAnywhere );
+ kern_assert( kr );
+ dfb.cursorShmem = cshmem;
+
+ kr = IOConnectMapMemory( dfb.fbService, kIOFBSystemAperture, mach_task_self(),
+ &vram, &shmemSize, kIOMapAnywhere );
+ kern_assert( kr );
+
+ dfb.framebuffer = (void*)vram;
+ dfb.width = fbInfo.activeWidth;
+ dfb.height = fbInfo.activeHeight;
+ dfb.pitch = fbInfo.bytesPerRow;
+ dfb.bitsPerPixel = fbInfo.bitsPerPixel;
+ dfb.colorBitsPerPixel = dfb.pixelInfo.componentCount *
+ dfb.pixelInfo.bitsPerComponent;
+
+ // find and open the HID System Service
+ kr = IOServiceGetMatchingServices( masterPort,
+ IOServiceMatching( kIOHIDSystemClass ),
+ &iter );
+ kern_assert( kr );
+
+ assert( service = IOIteratorNext( iter ) );
+
+ kr = IORegistryEntryGetName( service, name );
+ kern_assert( kr );
+
+ kr = IOServiceOpen( service, mach_task_self(), kIOHIDServerConnectType,
+ &dfb.hidService );
+ kern_assert( kr );
+
+ IOObjectRelease( service );
+ IOObjectRelease( iter );
+
+ kr = IOHIDCreateSharedMemory( dfb.hidService, kIOHIDCurrentShmemVersion );
+ kern_assert( kr );
+
+ kr = IOHIDSetEventsEnable(dfb.hidService, TRUE);
+ kern_assert( kr );
+
+ // Inform the HID system that the framebuffer is also connected to it
+ kr = IOConnectAddClient( dfb.hidService, dfb.fbService );
+ kern_assert( kr );
+
+ kr = IOHIDSetCursorEnable(dfb.hidService, TRUE);
+ kern_assert( kr );
+
+ kr = IOConnectMapMemory( dfb.hidService, kIOHIDGlobalMemory, mach_task_self(),
+ &shmem, &shmemSize, kIOMapAnywhere );
+ kern_assert( kr );
+
+ evg = (EvGlobals *)(shmem + ((EvOffsets *)shmem)->evGlobalsOffset);
+
+ assert(sizeof(EvGlobals) == evg->structSize);
+
+ NotificationPortRef = IONotificationPortCreate( masterPort );
+
+ notificationPort = IONotificationPortGetMachPort(NotificationPortRef);
+
+ kr = IOConnectSetNotificationPort( dfb.hidService, kIOHIDEventNotification,
+ notificationPort, 0 );
+ kern_assert( kr );
+
+ evg->movedMask |= NX_MOUSEMOVEDMASK;
+}
+
+
+/*
+ * InitOutput --
+ * Initialize screenInfo for all actually accessible framebuffers.
+ *
+ * FIXME: why does this get called multiple times when a session is starting?
+ */
+void InitOutput( ScreenInfo *pScreenInfo, int argc, char **argv )
+{ int i;
+ static int initialized = 0;
+// static PixmapFormatRec darwinFormat;
+
+ // perform one-time-only initialization
+ if ( !initialized ) {
+ initialized = 1;
+ // do our appkit or darwin device driver work to open and map a screen
+ InitIOKit();
+ SetupFBandHID();
+ }
+
+ pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
+ pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+ pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+ pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
+
+ // list how we want common pixmap formats to be padded
+ pScreenInfo->numPixmapFormats = NUMFORMATS;
+ for (i = 0; i < NUMFORMATS; i++)
+ pScreenInfo->formats[i] = formats[i];
+
+
+ AddScreen( DarwinAddScreen, argc, argv );
+}
+
+void OsVendorFatalError( void )
+{ ErrorF( " OsVendorFatalError\n" );
+}
+
+void OsVendorInit(void)
+{
+}
+
+/*
+ * ddxProcessArgument --
+ * Process device-dependent command line args. Returns 0 if argument is
+ * not device dependent, otherwise Count of number of elements of argv
+ * that are part of a device dependent commandline option.
+ */
+int ddxProcessArgument( int argc, char *argv[], int i )
+{
+#if 0
+ if ( !strcmp( argv[i], "-screen" ) ) {
+ if ( i == argc-1 ) {
+ FatalError( "-screen must be followed by a number" );
+ }
+ darwinScreenNumber = atoi( argv[i+1] );
+ ErrorF( "Attempting to use screen number %i\n", darwinScreenNumber );
+ return 2;
+ }
+#endif
+
+ if ( !strcmp( argv[i], "-fakebuttons" ) ) {
+ fake3Buttons = TRUE;
+ ErrorF( "Faking a three button mouse\n" );
+ return 1;
+ }
+
+ if ( !strcmp( argv[i], "-nofakebuttons" ) ) {
+ fake3Buttons = FALSE;
+ ErrorF( "Not faking a three button mouse\n" );
+ return 1;
+ }
+
+ if ( !strcmp( argv[i], "-size" ) ) {
+ if ( i >= argc-2 ) {
+ FatalError( "-size must be followed by two numbers" );
+ }
+#ifdef OLD_POWERBOOK_G3
+ ErrorF( "Ignoring unsupported -size option on old PowerBook G3\n");
+#else
+ darwinDesiredWidth = atoi( argv[i+1] );
+ darwinDesiredHeight = atoi( argv[i+2] );
+ ErrorF( "Attempting to use width x height = %i x %i\n",
+ darwinDesiredWidth, darwinDesiredHeight );
+#endif
+ return 3;
+ }
+
+ if ( !strcmp( argv[i], "-depth" ) ) {
+ int bitDepth;
+ if ( i == argc-1 ) {
+ FatalError( "-depth must be followed by a number" );
+ }
+#ifdef OLD_POWERBOOK_G3
+ ErrorF( "Ignoring unsupported -depth option on old PowerBook G3\n");
+#else
+ bitDepth = atoi( argv[i+1] );
+ if (bitDepth == 8)
+ darwinDesiredDepth = 0;
+ else if (bitDepth == 15)
+ darwinDesiredDepth = 1;
+ else if (bitDepth == 24)
+ darwinDesiredDepth = 2;
+ else
+ FatalError( "Unsupported pixel depth. Use 8, 15, or 24 bits" );
+ ErrorF( "Attempting to use pixel depth of %i\n", bitDepth );
+#endif
+ return 2;
+ }
+
+ if ( !strcmp( argv[i], "-refresh" ) ) {
+ if ( i == argc-1 ) {
+ FatalError( "-refresh must be followed by a number" );
+ }
+#ifdef OLD_POWERBOOK_G3
+ ErrorF( "Ignoring unsupported -refresh option on old PowerBook G3\n");
+#else
+ darwinDesiredRefresh = atoi( argv[i+1] );
+ ErrorF( "Attempting to use refresh rate of %i\n", darwinDesiredRefresh );
+#endif
+ return 2;
+ }
+
+ return 0;
+}
+
+/*
+ * ddxUseMsg --
+ * Print out correct use of device dependent commandline options.
+ * Maybe the user now knows what really to do ...
+ */
+void ddxUseMsg( void )
+{
+ ErrorF("\n");
+ ErrorF("\n");
+ ErrorF("Device Dependent Usage:\n");
+ ErrorF("\n");
+#if 0
+ ErrorF("-screen <0,1,...> : use this mac screen num.\n" );
+#endif
+ ErrorF("-fakebuttons : fake a three button mouse with Command and Option keys.\n");
+ ErrorF("-nofakebuttons : don't fake a three button mouse.\n");
+ ErrorF("-size <height> <width> : use a screen resolution of <height> x <width>.\n");
+ ErrorF("-depth <8,15,24> : use this bit depth.\n");
+ ErrorF("-refresh <rate> : use a monitor refresh rate of <rate> Hz.\n");
+ ErrorF("\n");
+}
+
+/*
+ * ddxGiveUp --
+ * Device dependent cleanup. Called by dix before normal server death.
+ */
+void ddxGiveUp( void ) {
+ ErrorF( " ddxGiveUp\n" );
+}
+
+/*
+ * AbortDDX --
+ * DDX - specific abort routine. Called by AbortServer(). The attempt is
+ * made to restore all original setting of the displays. Also all devices
+ * are closed.
+ */
+void AbortDDX( void ) {
+#if TRUE
+ ErrorF( " AbortDDX\n" );
+ /*
+ * This is needed for a abnormal server exit, since the normal exit stuff
+ * MUST also be performed (i.e. the vt must be left in a defined state)
+ */
+ ddxGiveUp();
+#endif
+}
+
+Bool DPMSSupported(void)
+{ return 0;
+}
+
+void DPMSSet(void)
+{ return;
+}
diff --git a/xc/programs/Xserver/hw/darwin/darwin.h b/xc/programs/Xserver/hw/darwin/darwin.h
new file mode 100644
index 000000000..a114167fa
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/darwin.h
@@ -0,0 +1,38 @@
+/* $XFree86: xc/programs/Xserver/hw/darwin/darwin.h,v 1.1 2000/11/15 01:36:13 dawes Exp $ */
+
+#ifndef _DARWIN_H
+#define _DARWIN_H
+
+#include <pthread.h>
+#include <IOKit/graphics/IOFramebufferShared.h>
+#include "inputstr.h"
+#include "screenint.h"
+#include "extensions/XKB.h"
+
+typedef struct {
+ pthread_t hidThread;
+ io_connect_t fbService;
+ io_connect_t hidService;
+ io_connect_t hidParam;
+ void *framebuffer;
+ int width;
+ int height;
+ int pitch;
+ int bitsPerPixel;
+ int colorBitsPerPixel;
+ IOPixelInformation pixelInfo;
+ StdFBShmem_t *cursorShmem;
+} DarwinFramebufferRec;
+
+void DarwinKeyboardInit(DeviceIntPtr pDev);
+Bool DarwinInitCursor(ScreenPtr pScreen);
+
+#define assert(x) { if ((x) == 0) \
+ FatalError("assert failed on line %d of %s!\n", __LINE__, __FILE__); }
+#define kern_assert(x) { if ((x) != KERN_SUCCESS) \
+ FatalError("assert failed on line %d of %s with kernel return 0x%x!\n", \
+ __LINE__, __FILE__, x); }
+
+#define MIN_KEYCODE XkbMinLegalKeyCode // unfortunately, this isn't 0...
+
+#endif /* _DARWIN_H */
diff --git a/xc/programs/Xserver/hw/darwin/darwinCursor.c b/xc/programs/Xserver/hw/darwin/darwinCursor.c
new file mode 100644
index 000000000..b6ff35f5b
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/darwinCursor.c
@@ -0,0 +1,705 @@
+/**************************************************************
+ *
+ * Cursor support for Darwin X Server
+ *
+ * Three different cursor modes are possible:
+ * X (0) - tracking via Darwin kernel,
+ * display via X machine independent
+ * Kernel (1) - tracking and display via Darwin kernel
+ * (not currently supported)
+ * Hardware (2) - tracking and display via hardware
+ *
+ * The X software cursor uses the Darwin software cursor
+ * routines in IOFramebuffer.cpp to track the cursor, but
+ * displays the cursor image using the X machine
+ * independent display cursor routines in midispcur.c.
+ *
+ * The kernel cursor uses IOFramebuffer.cpp routines to
+ * track and display the cursor. This gives better
+ * performance as the display calls don't have to cross
+ * the kernel boundary. Unfortunately, this mode has
+ * synchronization issues with the user land X server
+ * and isn't currently used.
+ *
+ * Hardware cursor support lets the hardware handle these
+ * details.
+ *
+ * Kernel and hardware cursor mode only work for cursors
+ * up to a certain size, currently 16x16 pixels. If a
+ * bigger cursor is set, we fallback to X cursor mode.
+ *
+ * HISTORY:
+ * 1.0 by Torrey T. Lyons, October 30, 2000
+ *
+ **************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/darwin/darwinCursor.c,v 1.1 2000/11/15 01:36:13 dawes Exp $ */
+
+#include "scrnintstr.h"
+#include "cursorstr.h"
+#include "micmap.h"
+#include <IOKit/graphics/IOGraphicsLib.h>
+#include <IOKit/hidsystem/IOHIDLib.h>
+#include "darwin.h"
+#include "mipointrst.h"
+
+#define DUMP_DARWIN_CURSOR FALSE
+
+// The cursors format are documented in IOFramebufferShared.h.
+#define RGBto34WithGamma(red, green, blue) \
+ ( 0x000F \
+ | (((red) & 0xF) << 12) \
+ | (((green) & 0xF) << 8) \
+ | (((blue) & 0xF) << 4) )
+#define RGBto38WithGamma(red, green, blue) \
+ ( 0xFF << 24 \
+ | (((red) & 0xFF) << 16) \
+ | (((green) & 0xFF) << 8) \
+ | (((blue) & 0xFF)) )
+#define HighBitOf32 0x80000000
+
+typedef struct {
+ Bool canHWCursor;
+ short cursorMode;
+ RecolorCursorProcPtr RecolorCursor;
+ InstallColormapProcPtr InstallColormap;
+ QueryBestSizeProcPtr QueryBestSize;
+ miPointerSpriteFuncPtr spriteFuncs;
+ ColormapPtr pInstalledMap;
+} DarwinCursorScreenRec, *DarwinCursorScreenPtr;
+
+extern DarwinFramebufferRec dfb;
+static int darwinCursorScreenIndex = -1;
+static unsigned long darwinCursorGeneration = 0;
+
+/*
+===========================================================================
+
+ Pointer sprite functions
+
+===========================================================================
+*/
+
+/*
+ Realizing the Darwin hardware cursor (ie. converting from the
+ X representation to the Darwin representation) is complicated
+ by the fact that we have three different potential cursor
+ formats to go to, one for each bit depth (8, 15, or 24).
+ The Darwin formats are documented in IOFramebufferShared.h.
+ X cursors are represented as two pieces, a source and a mask.
+ The mask is a bitmap indicating which parts of the cursor are
+ transparent and which parts are drawn. The source is a bitmap
+ indicating which parts of the non-transparent portion of the the
+ cursor should be painted in the foreground color and which should
+ be painted in the background color. The bitmaps are given in
+ 32-bit format with least significant byte and bit first.
+ (This is opposite PowerPC Darwin.)
+*/
+
+typedef struct {
+ unsigned char image[CURSORWIDTH*CURSORHEIGHT];
+ unsigned char mask[CURSORWIDTH*CURSORHEIGHT];
+} cursorPrivRec, *cursorPrivPtr;
+
+/*
+ * DarwinRealizeCursor8
+ * Convert the X cursor representation to an 8-bit depth
+ * format for Darwin. This function assumes the maximum cursor
+ * width is a multiple of 8.
+ */
+static Bool
+DarwinRealizeCursor8(
+ ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ cursorPrivPtr newCursor;
+ unsigned char *newSourceP, *newMaskP;
+ CARD32 *oldSourceP, *oldMaskP;
+ xColorItem fgColor, bgColor;
+ int index, x, y, rowPad;
+ int cursorWidth, cursorHeight;
+ ColormapPtr pmap;
+
+ // check cursor size just to be sure
+ cursorWidth = pCursor->bits->width;
+ cursorHeight = pCursor->bits->height;
+ if (cursorHeight > CURSORHEIGHT || cursorWidth > CURSORWIDTH)
+ return FALSE;
+
+ // get cursor colors in colormap
+ index = pScreen->myNum;
+ pmap = miInstalledMaps[index];
+ if (!pmap) return FALSE;
+
+ fgColor.red = pCursor->foreRed;
+ fgColor.green = pCursor->foreGreen;
+ fgColor.blue = pCursor->foreBlue;
+ FakeAllocColor(pmap, &fgColor);
+ bgColor.red = pCursor->backRed;
+ bgColor.green = pCursor->backGreen;
+ bgColor.blue = pCursor->backBlue;
+ FakeAllocColor(pmap, &bgColor);
+ FakeFreeColor(pmap, fgColor.pixel);
+ FakeFreeColor(pmap, bgColor.pixel);
+
+ // allocate memory for new cursor image
+ newCursor = xalloc( sizeof(cursorPrivRec) );
+ if (!newCursor)
+ return FALSE;
+ memset( newCursor->image, pScreen->blackPixel, CURSORWIDTH*CURSORHEIGHT );
+ memset( newCursor->mask, 0, CURSORWIDTH*CURSORHEIGHT );
+
+ // convert to 8-bit Darwin cursor format
+ oldSourceP = (CARD32 *) pCursor->bits->source;
+ oldMaskP = (CARD32 *) pCursor->bits->mask;
+ newSourceP = newCursor->image;
+ newMaskP = newCursor->mask;
+ rowPad = CURSORWIDTH - cursorWidth;
+
+ for (y = 0; y < cursorHeight; y++) {
+ for (x = 0; x < cursorWidth; x++) {
+ if (*oldSourceP & (HighBitOf32 >> x))
+ *newSourceP = fgColor.pixel;
+ else
+ *newSourceP = bgColor.pixel;
+ if (*oldMaskP & (HighBitOf32 >> x))
+ *newMaskP = 255;
+ else
+ *newSourceP = pScreen->blackPixel;
+ newSourceP++; newMaskP++;
+ }
+ oldSourceP++; oldMaskP++;
+ newSourceP += rowPad; newMaskP += rowPad;
+ }
+
+ // save the result
+ pCursor->devPriv[pScreen->myNum] = (pointer) newCursor;
+ return TRUE;
+}
+
+
+/*
+ * DarwinRealizeCursor15
+ * Convert the X cursor representation to an 15-bit depth
+ * format for Darwin.
+ */
+static Bool
+DarwinRealizeCursor15(
+ ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ unsigned short *newCursor;
+ unsigned short fgPixel, bgPixel;
+ unsigned short *newSourceP;
+ CARD32 *oldSourceP, *oldMaskP;
+ int x, y, rowPad;
+ int cursorWidth, cursorHeight;
+
+ // check cursor size just to be sure
+ cursorWidth = pCursor->bits->width;
+ cursorHeight = pCursor->bits->height;
+ if (cursorHeight > CURSORHEIGHT || cursorWidth > CURSORWIDTH)
+ return FALSE;
+
+ // allocate memory for new cursor image
+ newCursor = xalloc( CURSORWIDTH*CURSORHEIGHT*sizeof(short) );
+ if (!newCursor)
+ return FALSE;
+ memset( newCursor, 0, CURSORWIDTH*CURSORHEIGHT*sizeof(short) );
+
+ // calculate pixel values
+ fgPixel = RGBto34WithGamma( pCursor->foreRed, pCursor->foreGreen,
+ pCursor->foreBlue );
+ bgPixel = RGBto34WithGamma( pCursor->backRed, pCursor->backGreen,
+ pCursor->backBlue );
+
+ // convert to 15-bit Darwin cursor format
+ oldSourceP = (CARD32 *) pCursor->bits->source;
+ oldMaskP = (CARD32 *) pCursor->bits->mask;
+ newSourceP = newCursor;
+ rowPad = CURSORWIDTH - cursorWidth;
+
+ for (y = 0; y < cursorHeight; y++) {
+ for (x = 0; x < cursorWidth; x++) {
+ if (*oldMaskP & (HighBitOf32 >> x)) {
+ if (*oldSourceP & (HighBitOf32 >> x))
+ *newSourceP = fgPixel;
+ else
+ *newSourceP = bgPixel;
+ } else {
+ *newSourceP = 0;
+ }
+ newSourceP++;
+ }
+ oldSourceP++; oldMaskP++;
+ newSourceP += rowPad;
+ }
+
+#if DUMP_DARWIN_CURSOR
+ // Write out the cursor
+ ErrorF("Cursor: 0x%x\n", pCursor);
+ ErrorF("Width = %i, Height = %i, RowPad = %i\n", cursorWidth,
+ cursorHeight, rowPad);
+ for (y = 0; y < cursorHeight; y++) {
+ newSourceP = newCursor + y*CURSORWIDTH;
+ for (x = 0; x < cursorWidth; x++) {
+ if (*newSourceP == fgPixel)
+ ErrorF("x");
+ else if (*newSourceP == bgPixel)
+ ErrorF("o");
+ else
+ ErrorF(" ");
+ newSourceP++;
+ }
+ ErrorF("\n");
+ }
+#endif
+
+ // save the result
+ pCursor->devPriv[pScreen->myNum] = (pointer) newCursor;
+ return TRUE;
+}
+
+
+/*
+ * DarwinRealizeCursor24
+ * Convert the X cursor representation to an 24-bit depth
+ * format for Darwin. This function assumes the maximum cursor
+ * width is a multiple of 8.
+ */
+static Bool
+DarwinRealizeCursor24(
+ ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ unsigned int *newCursor;
+ unsigned int fgPixel, bgPixel;
+ unsigned int *newSourceP;
+ CARD32 *oldSourceP, *oldMaskP;
+ int x, y, rowPad;
+ int cursorWidth, cursorHeight;
+
+ // check cursor size just to be sure
+ cursorWidth = pCursor->bits->width;
+ cursorHeight = pCursor->bits->height;
+ if (cursorHeight > CURSORHEIGHT || cursorWidth > CURSORWIDTH)
+ return FALSE;
+
+ // allocate memory for new cursor image
+ newCursor = xalloc( CURSORWIDTH*CURSORHEIGHT*sizeof(int) );
+ if (!newCursor)
+ return FALSE;
+ memset( newCursor, 0, CURSORWIDTH*CURSORHEIGHT*sizeof(int) );
+
+ // calculate pixel values
+ fgPixel = RGBto38WithGamma( pCursor->foreRed, pCursor->foreGreen,
+ pCursor->foreBlue );
+ bgPixel = RGBto38WithGamma( pCursor->backRed, pCursor->backGreen,
+ pCursor->backBlue );
+
+ // convert to 24-bit Darwin cursor format
+ oldSourceP = (CARD32 *) pCursor->bits->source;
+ oldMaskP = (CARD32 *) pCursor->bits->mask;
+ newSourceP = newCursor;
+ rowPad = CURSORWIDTH - cursorWidth;
+
+ for (y = 0; y < cursorHeight; y++) {
+ for (x = 0; x < cursorWidth; x++) {
+ if (*oldMaskP & (HighBitOf32 >> x)) {
+ if (*oldSourceP & (HighBitOf32 >> x))
+ *newSourceP = fgPixel;
+ else
+ *newSourceP = bgPixel;
+ } else {
+ *newSourceP = 0;
+ }
+ newSourceP++;
+ }
+ oldSourceP++; oldMaskP++;
+ newSourceP += rowPad;
+ }
+
+#if DUMP_DARWIN_CURSOR
+ // Write out the cursor
+ ErrorF("Cursor: 0x%x\n", pCursor);
+ ErrorF("Width = %i, Height = %i, RowPad = %i\n", cursorWidth,
+ cursorHeight, rowPad);
+ for (y = 0; y < cursorHeight; y++) {
+ newSourceP = newCursor + y*CURSORWIDTH;
+ for (x = 0; x < cursorWidth; x++) {
+ if (*newSourceP == fgPixel)
+ ErrorF("x");
+ else if (*newSourceP == bgPixel)
+ ErrorF("o");
+ else
+ ErrorF(" ");
+ newSourceP++;
+ }
+ ErrorF("\n");
+ }
+#endif
+
+ // save the result
+ pCursor->devPriv[pScreen->myNum] = (pointer) newCursor;
+ return TRUE;
+}
+
+
+/*
+ * DarwinRealizeCursor
+ *
+ */
+static Bool
+DarwinRealizeCursor(
+ ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ Bool result;
+ DarwinCursorScreenPtr ScreenPriv = (DarwinCursorScreenPtr)
+ pScreen->devPrivates[darwinCursorScreenIndex].ptr;
+
+ if ((pCursor->bits->height > CURSORHEIGHT) ||
+ (pCursor->bits->width > CURSORWIDTH) ||
+ // FIXME: this condition is not needed after kernel cursor works
+ !ScreenPriv->canHWCursor) {
+ result = (*ScreenPriv->spriteFuncs->RealizeCursor)(pScreen, pCursor);
+ } else if (dfb.bitsPerPixel == 8) {
+ result = DarwinRealizeCursor8(pScreen, pCursor);
+ } else if (dfb.bitsPerPixel == 16) {
+ result = DarwinRealizeCursor15(pScreen, pCursor);
+ } else {
+ result = DarwinRealizeCursor24(pScreen, pCursor);
+ }
+
+ return result;
+}
+
+
+/*
+ * DarwinUnrealizeCursor
+ *
+ */
+static Bool
+DarwinUnrealizeCursor(
+ ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ Bool result;
+ DarwinCursorScreenPtr ScreenPriv = (DarwinCursorScreenPtr)
+ pScreen->devPrivates[darwinCursorScreenIndex].ptr;
+
+ if ((pCursor->bits->height > CURSORHEIGHT) ||
+ (pCursor->bits->width > CURSORWIDTH) ||
+ // FIXME: this condition is not needed after kernel cursor works
+ !ScreenPriv->canHWCursor) {
+ result = (*ScreenPriv->spriteFuncs->UnrealizeCursor)(pScreen, pCursor);
+ } else {
+ xfree( pCursor->devPriv[pScreen->myNum] );
+ result = TRUE;
+ }
+
+ return result;
+}
+
+
+/*
+ * DarwinSetCursor
+ * Set the cursor sprite and position
+ * Use hardware cursor if possible
+ */
+static void
+DarwinSetCursor(
+ ScreenPtr pScreen,
+ CursorPtr pCursor,
+ int x,
+ int y)
+{
+ kern_return_t kr;
+ StdFBShmem_t *cshmem = dfb.cursorShmem;
+ DarwinCursorScreenPtr ScreenPriv = (DarwinCursorScreenPtr)
+ pScreen->devPrivates[darwinCursorScreenIndex].ptr;
+
+ // are we supposed to remove the cursor?
+ if (!pCursor) {
+ if (ScreenPriv->cursorMode == 0)
+ (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y);
+ else {
+ if (!cshmem->cursorShow) {
+ cshmem->cursorShow++;
+ if (cshmem->hardwareCursorActive) {
+ kr = IOFBSetCursorVisible(dfb.fbService, FALSE);
+ kern_assert( kr );
+ }
+ }
+ }
+ return;
+ }
+
+ // can we use the kernel or hardware cursor?
+ if ((pCursor->bits->height <= CURSORHEIGHT) &&
+ (pCursor->bits->width <= CURSORWIDTH) &&
+ // FIXME: condition not needed when kernel cursor works
+ ScreenPriv->canHWCursor) {
+
+ if (ScreenPriv->cursorMode == 0) // remove the X cursor
+ (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y);
+ ScreenPriv->cursorMode = 1; // kernel cursor
+
+ // change the cursor image in shared memory
+ if (dfb.bitsPerPixel == 8) {
+ cursorPrivPtr newCursor =
+ (cursorPrivPtr) pCursor->devPriv[pScreen->myNum];
+ memcpy(cshmem->cursor.bw8.image[0], newCursor->image,
+ CURSORWIDTH*CURSORHEIGHT);
+ memcpy(cshmem->cursor.bw8.mask[0], newCursor->mask,
+ CURSORWIDTH*CURSORHEIGHT);
+ } else if (dfb.bitsPerPixel == 16) {
+ unsigned short *newCursor =
+ (unsigned short *) pCursor->devPriv[pScreen->myNum];
+ memcpy(cshmem->cursor.rgb.image[0], newCursor,
+ 2*CURSORWIDTH*CURSORHEIGHT);
+ } else {
+ unsigned int *newCursor =
+ (unsigned int *) pCursor->devPriv[pScreen->myNum];
+ memcpy(cshmem->cursor.rgb24.image[0], newCursor,
+ 4*CURSORWIDTH*CURSORHEIGHT);
+ }
+
+ // FIXME: We always use a full size cursor, even if the image
+ // is smaller because I couldn't get the padding to come out
+ // right otherwise.
+ cshmem->cursorSize[0].width = CURSORWIDTH;
+ cshmem->cursorSize[0].height = CURSORHEIGHT;
+ cshmem->hotSpot[0].x = pCursor->bits->xhot;
+ cshmem->hotSpot[0].y = pCursor->bits->yhot;
+
+ // try to use a hardware cursor
+ if (ScreenPriv->canHWCursor) {
+ kr = IOFBSetNewCursor(dfb.fbService, 0, 0, 0);
+ // FIXME: this is a fatal error without the kernel cursor
+ kern_assert( kr );
+#if 0
+ if (kr != KERN_SUCCESS) {
+ ErrorF("Could not set new cursor with kernel return 0x%x.\n", kr);
+ ScreenPriv->canHWCursor = FALSE;
+ }
+#endif
+ }
+
+ // make the new cursor visible
+ if (cshmem->cursorShow)
+ cshmem->cursorShow--;
+
+ if (!cshmem->cursorShow && ScreenPriv->canHWCursor) {
+ kr = IOFBSetCursorVisible(dfb.fbService, TRUE);
+ // FIXME: this is a fatal error without the kernel cursor
+ kern_assert( kr );
+#if 0
+ if (kr != KERN_SUCCESS) {
+ ErrorF("Couldn't set hardware cursor visible with kernel return 0x%x.\n", kr);
+ ScreenPriv->canHWCursor = FALSE;
+ } else
+#endif
+ ScreenPriv->cursorMode = 2; // hardware cursor
+ }
+
+ return;
+ }
+
+ // otherwise we use a software cursor
+ if (ScreenPriv->cursorMode) {
+ /* remove the kernel or hardware cursor */
+ DarwinSetCursor(pScreen, 0, x, y);
+ }
+
+ ScreenPriv->cursorMode = 0;
+ (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, pCursor, x, y);
+}
+
+
+/*
+ * DarwinMoveCursor
+ * Move the cursor. This is a noop for a kernel or hardware cursor.
+ */
+static void
+DarwinMoveCursor(
+ ScreenPtr pScreen,
+ int x,
+ int y)
+{
+ DarwinCursorScreenPtr ScreenPriv = (DarwinCursorScreenPtr)
+ pScreen->devPrivates[darwinCursorScreenIndex].ptr;
+
+ // only the X cursor needs to be explicitly moved
+ if (!ScreenPriv->cursorMode)
+ (*ScreenPriv->spriteFuncs->MoveCursor)(pScreen, x, y);
+}
+
+static miPointerSpriteFuncRec darwinSpriteFuncsRec = {
+ DarwinRealizeCursor,
+ DarwinUnrealizeCursor,
+ DarwinSetCursor,
+ DarwinMoveCursor
+};
+
+
+/*
+===========================================================================
+
+ Pointer screen functions
+
+===========================================================================
+*/
+
+/*
+ * DarwinCursorOffScreen
+ */
+static Bool DarwinCursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
+{ return FALSE;
+}
+
+
+/*
+ * DarwinCrossScreen
+ */
+static void DarwinCrossScreen(ScreenPtr pScreen, Bool entering)
+{ return;
+}
+
+
+/*
+ * DarwinWarpCursor
+ * Change the cursor position without generating an event or motion history
+ */
+static void
+DarwinWarpCursor(
+ ScreenPtr pScreen,
+ int x,
+ int y)
+{
+ kern_return_t kr;
+
+ kr = IOHIDSetMouseLocation( dfb.hidService, x, y );
+ if (kr != KERN_SUCCESS) {
+ ErrorF("Could not set cursor position with kernel return 0x%x.\n", kr);
+ }
+ miPointerWarpCursor(pScreen, x, y);
+}
+
+static miPointerScreenFuncRec darwinScreenFuncsRec = {
+ DarwinCursorOffScreen,
+ DarwinCrossScreen,
+ DarwinWarpCursor,
+};
+
+
+/*
+===========================================================================
+
+ Other screen functions
+
+===========================================================================
+*/
+
+/*
+ * DarwinCursorQueryBestSize
+ * Handle queries for best cursor size
+ */
+static void
+DarwinCursorQueryBestSize(
+ int class,
+ unsigned short *width,
+ unsigned short *height,
+ ScreenPtr pScreen)
+{
+ DarwinCursorScreenPtr ScreenPriv = (DarwinCursorScreenPtr)
+ pScreen->devPrivates[darwinCursorScreenIndex].ptr;
+
+ if (class == CursorShape) {
+ *width = CURSORWIDTH;
+ *height = CURSORHEIGHT;
+ } else
+ (*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
+}
+
+
+/*
+ * DarwinInitCursor
+ * Initialize cursor support
+ */
+Bool
+DarwinInitCursor(
+ ScreenPtr pScreen)
+{
+ DarwinCursorScreenPtr ScreenPriv;
+ miPointerScreenPtr PointPriv;
+ kern_return_t kr;
+
+ // start with no cursor displayed
+ if (!dfb.cursorShmem->cursorShow++) {
+ if (dfb.cursorShmem->hardwareCursorActive) {
+ kr = IOFBSetCursorVisible(dfb.fbService, FALSE);
+ kern_assert( kr );
+ }
+ }
+
+ // initialize software cursor handling (always needed as backup)
+ if (!miDCInitialize(pScreen, &darwinScreenFuncsRec)) {
+ return FALSE;
+ }
+
+ // allocate private storage for this screen's hardware cursor info
+ if (darwinCursorGeneration != serverGeneration) {
+ if ((darwinCursorScreenIndex = AllocateScreenPrivateIndex()) < 0)
+ return FALSE;
+ darwinCursorGeneration = serverGeneration;
+ }
+
+ ScreenPriv = xcalloc( 1, sizeof(DarwinCursorScreenRec) );
+ if (!ScreenPriv) return FALSE;
+
+ pScreen->devPrivates[darwinCursorScreenIndex].ptr = (pointer) ScreenPriv;
+
+ // check if a hardware cursor is supported
+ if (!dfb.cursorShmem->hardwareCursorCapable) {
+ ScreenPriv->canHWCursor = FALSE;
+ ErrorF("Hardware cursor not supported.\n");
+ } else {
+ // we need to make sure that the hardware cursor really works
+ ScreenPriv->canHWCursor = TRUE;
+ kr = IOFBSetNewCursor(dfb.fbService, 0, 0, 0);
+ if (kr != KERN_SUCCESS) {
+ ErrorF("Could not set hardware cursor with kernel return 0x%x.\n", kr);
+ ScreenPriv->canHWCursor = FALSE;
+ }
+ kr = IOFBSetCursorVisible(dfb.fbService, TRUE);
+ if (kr != KERN_SUCCESS) {
+ ErrorF("Couldn't set hardware cursor visible with kernel return 0x%x.\n", kr);
+ ScreenPriv->canHWCursor = FALSE;
+ }
+ IOFBSetCursorVisible(dfb.fbService, FALSE);
+ }
+
+ ScreenPriv->cursorMode = 0;
+ ScreenPriv->pInstalledMap = NULL;
+
+ // override some screen procedures
+ ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
+ pScreen->QueryBestSize = DarwinCursorQueryBestSize;
+// ScreenPriv->ConstrainCursor = pScreen->ConstrainCursor;
+// pScreen->ConstrainCursor = DarwinConstrainCursor;
+
+ // initialize hardware cursor handling
+ PointPriv = (miPointerScreenPtr)
+ pScreen->devPrivates[miPointerScreenIndex].ptr;
+
+ ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
+ PointPriv->spriteFuncs = &darwinSpriteFuncsRec;
+
+ /* Other routines that might be overridden */
+/*
+ CursorLimitsProcPtr CursorLimits;
+ RecolorCursorProcPtr RecolorCursor;
+*/
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/darwin/darwinKeyboard.c b/xc/programs/Xserver/hw/darwin/darwinKeyboard.c
new file mode 100644
index 000000000..78506587d
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/darwinKeyboard.c
@@ -0,0 +1,503 @@
+//=============================================================================
+//
+// Keyboard support for the Darwin X Server
+//
+// By Torrey T. Lyons
+//
+// The code to parse the Darwin keymap is derived from dumpkeymap.c
+// by Eric Sunshine, which includes the following license:
+//
+//-----------------------------------------------------------------------------
+//
+// Copyright (C) 1999,2000 by Eric Sunshine <sunshine@sunshineco.com>
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. The name of the author may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+// NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//=============================================================================
+
+/* $XFree86: xc/programs/Xserver/hw/darwin/darwinKeyboard.c,v 1.1 2000/11/15 01:36:14 dawes Exp $ */
+
+/*
+===========================================================================
+
+ An X keyCode must be in the range XkbMinLegalKeyCode (8) to
+ XkbMaxLegalKeyCode(255).
+
+ The keyCodes we get from the kernel range from 0 to 127, so we need to
+ offset the range before passing the keyCode to X.
+
+ An X KeySym is an extended ascii code that is device independent.
+
+ The modifier map is accessed by the keyCode, but the normal map is
+ accessed by keyCode - MIN_KEYCODE. Sigh.
+
+===========================================================================
+*/
+
+// Define this to get a diagnostic output to stderr which is helpful
+// in determining how the X server is interpreting the Darwin keymap.
+#undef DUMP_DARWIN_KEYMAP
+
+#include <drivers/event_status_driver.h>
+#include <IOKit/hidsystem/ev_keymap.h>
+#include "darwin.h"
+extern DarwinFramebufferRec dfb;
+extern unsigned char darwinKeyCommandL, darwinKeyOptionL;
+
+#define XK_TECHNICAL // needed to get XK_Escape
+#include "keysym.h"
+
+#define GLYPHS_PER_KEY 4
+#define NUM_KEYCODES 248 // NX_NUMKEYCODES might be better
+#define MAX_KEYCODE NUM_KEYCODES + MIN_KEYCODE - 1
+
+#define AltMask Mod1Mask
+#define NumLockMask Mod2Mask
+#define MetaMask Mod3Mask
+#define ScrollLockMask Mod4Mask
+
+static KeySym const ascii_to_x[256] = {
+ NoSymbol, NoSymbol, NoSymbol, XK_KP_Enter,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ XK_Delete, XK_Tab, XK_Linefeed, NoSymbol,
+ NoSymbol, XK_Return, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, XK_Escape,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ XK_space, XK_exclam, XK_quotedbl, XK_numbersign,
+ XK_dollar, XK_percent, XK_ampersand, XK_apostrophe,
+ XK_parenleft, XK_parenright, XK_asterisk, XK_plus,
+ XK_comma, XK_minus, XK_period, XK_slash,
+ XK_0, XK_1, XK_2, XK_3,
+ XK_4, XK_5, XK_6, XK_7,
+ XK_8, XK_9, XK_colon, XK_semicolon,
+ XK_less, XK_equal, XK_greater, XK_question,
+ XK_at, XK_A, XK_B, XK_C,
+ XK_D, XK_E, XK_F, XK_G,
+ XK_H, XK_I, XK_J, XK_K,
+ XK_L, XK_M, XK_N, XK_O,
+ XK_P, XK_Q, XK_R, XK_S,
+ XK_T, XK_U, XK_V, XK_W,
+ XK_X, XK_Y, XK_Z, XK_bracketleft,
+ XK_backslash, XK_bracketright,XK_asciicircum, XK_underscore,
+ XK_grave, XK_a, XK_b, XK_c,
+ XK_d, XK_e, XK_f, XK_g,
+ XK_h, XK_i, XK_j, XK_k,
+ XK_l, XK_m, XK_n, XK_o,
+ XK_p, XK_q, XK_r, XK_s,
+ XK_t, XK_u, XK_v, XK_w,
+ XK_x, XK_y, XK_z, XK_braceleft,
+ XK_bar, XK_braceright, XK_asciitilde, XK_BackSpace,
+// 128
+ XK_Ccedilla, XK_udiaeresis, XK_eacute, XK_acircumflex,
+ XK_adiaeresis, XK_agrave, XK_aring, XK_ccedilla,
+ XK_ecircumflex, XK_ediaeresis, XK_egrave, XK_idiaeresis,
+ XK_icircumflex, XK_igrave, XK_Adiaeresis, XK_Aring,
+ XK_Eacute, XK_ae, XK_AE, XK_ocircumflex,
+ XK_odiaeresis, XK_ograve, XK_ntilde, XK_ugrave,
+ XK_ydiaeresis, XK_Odiaeresis, XK_Udiaeresis, XK_cent,
+ XK_sterling, XK_yen, XK_paragraph, XK_section,
+// 160
+ XK_aacute, XK_degree, XK_cent, XK_sterling,
+ XK_ntilde, XK_Ntilde, XK_paragraph, XK_Greek_BETA,
+ XK_questiondown,XK_hyphen, XK_notsign, XK_onehalf,
+ XK_onequarter, XK_exclamdown, XK_guillemotleft,XK_guillemotright,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+// 192
+ XK_questiondown,XK_exclamdown, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, XK_AE, XK_ae,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+// 224
+ XK_Greek_alpha, XK_ssharp, XK_Greek_GAMMA, XK_Greek_pi,
+ XK_Greek_SIGMA, XK_Greek_sigma, XK_mu, XK_Greek_tau,
+ XK_Greek_PHI, XK_Greek_THETA, XK_Greek_OMEGA, XK_Greek_delta,
+ XK_infinity, XK_Ooblique, XK_Greek_epsilon, XK_intersection,
+ XK_identical, XK_plusminus, XK_greaterthanequal, XK_lessthanequal,
+ XK_topintegral, XK_botintegral, XK_division, XK_similarequal,
+ XK_degree, NoSymbol, NoSymbol, XK_radical,
+ XK_Greek_eta, XK_twosuperior, XK_periodcentered, NoSymbol,
+ };
+
+#define MIN_SYMBOL 0xAC
+static KeySym const symbol_to_x[] = {
+ XK_Left, XK_Up, XK_Right, XK_Down
+ };
+int const NUM_SYMBOL = sizeof(symbol_to_x) / sizeof(symbol_to_x[0]);
+
+#define MIN_FUNCKEY 0x20
+static KeySym const funckey_to_x[] = {
+ XK_F1, XK_F2, XK_F3, XK_F4,
+ XK_F5, XK_F6, XK_F7, XK_F8,
+ XK_F9, XK_F10, XK_F11, XK_F12,
+ XK_Insert, XK_Delete, XK_Home, XK_End,
+ XK_Page_Up, XK_Page_Down, XK_F13, XK_F14,
+ XK_F15
+ };
+int const NUM_FUNCKEY = sizeof(funckey_to_x) / sizeof(funckey_to_x[0]);
+
+typedef struct {
+ KeySym normalSym;
+ KeySym keypadSym;
+} darwinKeyPad_t;
+
+static darwinKeyPad_t const normal_to_keypad[] = {
+ { XK_0, XK_KP_0 },
+ { XK_1, XK_KP_1 },
+ { XK_2, XK_KP_2 },
+ { XK_3, XK_KP_3 },
+ { XK_4, XK_KP_4 },
+ { XK_5, XK_KP_5 },
+ { XK_6, XK_KP_6 },
+ { XK_7, XK_KP_7 },
+ { XK_8, XK_KP_8 },
+ { XK_9, XK_KP_9 },
+ { XK_equal, XK_KP_Equal },
+ { XK_asterisk, XK_KP_Multiply },
+ { XK_plus, XK_KP_Add },
+ { XK_comma, XK_KP_Separator },
+ { XK_minus, XK_KP_Subtract },
+ { XK_period, XK_KP_Decimal },
+ { XK_slash, XK_KP_Divide }
+};
+int const NUM_KEYPAD = sizeof(normal_to_keypad) / sizeof(normal_to_keypad[0]);
+
+static void DarwinBell( int loud, DeviceIntPtr pDevice, pointer ctrl, int fbclass) {
+ // FIXME
+}
+
+static void DarwinChangeKeyboardControl( DeviceIntPtr device, KeybdCtrl *ctrl ) {
+ // keyclick, bell volume / pitch, autorepead, LED's
+}
+
+static CARD8 modMap[MAP_LENGTH];
+static KeySym map[256 * GLYPHS_PER_KEY];
+
+//-----------------------------------------------------------------------------
+// Data Stream Object
+// Can be configured to treat embedded "numbers" as being composed of
+// either 1, 2, or 4 bytes, apiece.
+//-----------------------------------------------------------------------------
+typedef struct _DataStream
+{
+ unsigned char const *data;
+ unsigned char const *data_end;
+ short number_size; // Size in bytes of a "number" in the stream.
+} DataStream;
+
+static DataStream* new_data_stream( unsigned char const* data, int size )
+{
+ DataStream* s = (DataStream*)xalloc( sizeof(DataStream) );
+ s->data = data;
+ s->data_end = data + size;
+ s->number_size = 1; // Default to byte-sized numbers.
+ return s;
+}
+
+static void destroy_data_stream( DataStream* s )
+{
+ xfree(s);
+}
+
+static unsigned char get_byte( DataStream* s )
+{
+ assert(s->data + 1 <= s->data_end);
+ return *s->data++;
+}
+
+static short get_word( DataStream* s )
+{
+ short hi, lo;
+ assert(s->data + 2 <= s->data_end);
+ hi = *s->data++;
+ lo = *s->data++;
+ return ((hi << 8) | lo);
+}
+
+static int get_dword( DataStream* s )
+{
+ int b1, b2, b3, b4;
+ assert(s->data + 4 <= s->data_end);
+ b4 = *s->data++;
+ b3 = *s->data++;
+ b2 = *s->data++;
+ b1 = *s->data++;
+ return ((b4 << 24) | (b3 << 16) | (b2 << 8) | b1);
+}
+
+static int get_number( DataStream* s )
+{
+ switch (s->number_size) {
+ case 4: return get_dword(s);
+ case 2: return get_word(s);
+ default: return get_byte(s);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Utility functions to help parse Darwin keymap
+//-----------------------------------------------------------------------------
+
+/*
+ * bits_set
+ * Calculate number of bits set in the modifier mask.
+ */
+static short bits_set( short mask )
+{
+ short n = 0;
+
+ for ( ; mask != 0; mask >>= 1)
+ if ((mask & 0x01) != 0)
+ n++;
+ return n;
+}
+
+/*
+ * parse_next_char_code
+ * Read the next character code from the Darwin keymapping
+ * and write it to the X keymap.
+ */
+static void parse_next_char_code(
+ DataStream *s,
+ KeySym *k )
+{
+ const short charSet = get_number(s);
+ const short charCode = get_number(s);
+
+ if (charSet == 0) { // ascii character
+ if (charCode >= 0 && charCode < 256)
+ *k = ascii_to_x[charCode];
+ } else if (charSet == 0x01) { // symbol character
+ if (charCode >= MIN_SYMBOL &&
+ charCode <= MIN_SYMBOL + NUM_SYMBOL)
+ *k = symbol_to_x[charCode - MIN_SYMBOL];
+ } else if (charSet == 0xFE) { // function key
+ if (charCode >= MIN_FUNCKEY &&
+ charCode <= MIN_FUNCKEY + NUM_FUNCKEY)
+ *k = funckey_to_x[charCode - MIN_FUNCKEY];
+ }
+}
+
+/*
+ * DarwinKeyboardInit
+ * Get the Darwin keyboard map and compute an equivalent
+ * X keyboard map and modifier map. Set the new keyboard
+ * device structure.
+ */
+void DarwinKeyboardInit(
+ DeviceIntPtr pDev )
+{
+ KeySym *k;
+ int i;
+ short numMods, numKeys, numPadKeys = 0;
+ KeySymsRec keySyms;
+ NXKeyMapping keyMap;
+ DataStream *keyMapStream;
+ unsigned char const *numPadStart = 0;
+
+ memset( modMap, NoSymbol, sizeof( modMap ) );
+ memset( map, 0, sizeof( map ) );
+
+ // Open a shared connection to the HID System.
+ // Note that the Event Status Driver is really just a wrapper
+ // for a kIOHIDParamConnectType connection.
+ assert( dfb.hidParam = NXOpenEventStatus() );
+
+ // get the Darwin keyboard map
+ keyMap.size = NXKeyMappingLength( dfb.hidParam );
+ keyMap.mapping = (char*) xalloc( keyMap.size );
+ assert( NXGetKeyMapping( dfb.hidParam, &keyMap ));
+ keyMapStream = new_data_stream( (unsigned char const*)keyMap.mapping,
+ keyMap.size );
+
+ // check the type of map
+ if (get_word(keyMapStream)) {
+ keyMapStream->number_size = 2;
+ ErrorF("Current 16-bit keymapping may not be interpreted correctly.\n");
+ }
+
+ // Compute the modifier map and
+ // insert X modifier KeySyms into keyboard map.
+ numMods = get_number(keyMapStream);
+ while (numMods-- > 0) {
+ int left = 1; // first keycode is left
+ short const charCode = get_number(keyMapStream);
+ short numKeyCodes = get_number(keyMapStream);
+ if (charCode == NX_MODIFIERKEY_NUMERICPAD) {
+ numPadStart = keyMapStream->data;
+ numPadKeys = numKeyCodes;
+ }
+ while (numKeyCodes-- > 0) {
+ const short keyCode = get_number(keyMapStream);
+ if (charCode == NX_MODIFIERKEY_ALPHALOCK) {
+ modMap[keyCode + MIN_KEYCODE] = LockMask;
+ map[keyCode * GLYPHS_PER_KEY] = XK_Caps_Lock;
+ } else if (charCode == NX_MODIFIERKEY_SHIFT) {
+ modMap[keyCode + MIN_KEYCODE] = ShiftMask;
+ map[keyCode * GLYPHS_PER_KEY] =
+ (left ? XK_Shift_L : XK_Shift_R);
+ } else if (charCode == NX_MODIFIERKEY_CONTROL) {
+ modMap[keyCode + MIN_KEYCODE] = ControlMask;
+ map[keyCode * GLYPHS_PER_KEY] =
+ (left ? XK_Control_L : XK_Control_R);
+ } else if (charCode == NX_MODIFIERKEY_ALTERNATE) {
+ modMap[keyCode + MIN_KEYCODE] = AltMask;
+ if (left) {
+ map[keyCode * GLYPHS_PER_KEY] = XK_Alt_L;
+ darwinKeyOptionL = keyCode + MIN_KEYCODE;
+ } else
+ map[keyCode * GLYPHS_PER_KEY] = XK_Alt_R;
+ } else if (charCode == NX_MODIFIERKEY_COMMAND) {
+ modMap[keyCode + MIN_KEYCODE] = MetaMask;
+ if (left) {
+ map[keyCode * GLYPHS_PER_KEY] = XK_Meta_L;
+ darwinKeyCommandL = keyCode + MIN_KEYCODE;
+ } else
+ map[keyCode * GLYPHS_PER_KEY] = XK_Meta_R;
+ } else if (charCode == NX_MODIFIERKEY_NUMERICPAD) {
+ continue;
+ } else if (charCode == NX_MODIFIERKEY_HELP) {
+ map[keyCode * GLYPHS_PER_KEY] = XK_Help;
+ } else {
+ break;
+ }
+ left = 0;
+ }
+ }
+
+ // Convert the Darwin keyboard map to an X keyboard map.
+ // A key can have shifted and unshifted character codes.
+ // Other modifiers are ignored although they are
+ // present in the Darwin keyboard map.
+ numKeys = get_number(keyMapStream);
+ for (i = 0, k = map; i < numKeys; i++, k += GLYPHS_PER_KEY) {
+ short const charGenMask = get_number(keyMapStream);
+ if (charGenMask != 0xFF) { // is key bound?
+ short numKeyCodes = 1 << bits_set(charGenMask);
+
+ // If alphalock and shift modifiers produce different codes,
+ // we only need the shift case since X handles alphalock.
+ if (charGenMask & 0x01 && charGenMask & 0x02) {
+ // record unshifted case
+ parse_next_char_code( keyMapStream, k );
+ // skip alphalock case
+ get_number(keyMapStream); get_number(keyMapStream);
+ // record shifted case
+ parse_next_char_code( keyMapStream, k+1 );
+ if (k[1] == k[0]) k[1] = NoSymbol;
+ numKeyCodes -= 3;
+ // skip the rest
+ while (numKeyCodes-- > 0) {
+ get_number(keyMapStream); get_number(keyMapStream);
+ }
+
+ // If alphalock and shift modifiers produce same code, use it.
+ } else if (charGenMask & 0x03) {
+ // record unshifted case
+ parse_next_char_code( keyMapStream, k );
+ // record shifted case
+ parse_next_char_code( keyMapStream, k+1 );
+ if (k[1] == k[0]) k[1] = NoSymbol;
+ numKeyCodes -= 2;
+ // skip the rest
+ while (numKeyCodes-- > 0) {
+ get_number(keyMapStream); get_number(keyMapStream);
+ }
+
+ // If neither alphalock or shift produce characters,
+ // use only one character code for this key,
+ // but it can be a special character.
+ } else {
+ parse_next_char_code( keyMapStream, k );
+ numKeyCodes--;
+ while (numKeyCodes-- > 0) { // skip the rest
+ get_number(keyMapStream); get_number(keyMapStream);
+
+ }
+ }
+ }
+ }
+
+ // Now we have to go back through the list of keycodes that are on the
+ // numeric keypad and update the X keymap.
+ keyMapStream->data = numPadStart;
+ while(numPadKeys-- > 0) {
+ const short keyCode = get_number(keyMapStream);
+ k = &map[keyCode * GLYPHS_PER_KEY];
+ for (i = 0; i < NUM_KEYPAD; i++) {
+ if (*k == normal_to_keypad[i].normalSym) {
+ k[0] = normal_to_keypad[i].keypadSym;
+ break;
+ }
+ }
+ }
+
+ // free Darwin keyboard map
+ destroy_data_stream( keyMapStream );
+ xfree( keyMap.mapping );
+
+#ifdef DUMP_DARWIN_KEYMAP
+ ErrorF("Darwin -> X converted keyboard map\n");
+ for (i = 0, k = map; i < NX_NUMKEYCODES; i++, k += GLYPHS_PER_KEY) {
+ int j;
+ ErrorF("0x%02x:", i);
+ for (j = 0; j < GLYPHS_PER_KEY; j++) {
+ if (k[j] == NoSymbol) {
+ ErrorF("\tNoSym");
+ } else {
+ ErrorF("\t0x%x", k[j]);
+ }
+ }
+ ErrorF("\n");
+ }
+#endif
+
+ keySyms.map = map;
+ keySyms.mapWidth = GLYPHS_PER_KEY;
+ keySyms.minKeyCode = MIN_KEYCODE;
+ keySyms.maxKeyCode = MAX_KEYCODE;
+
+ assert( InitKeyboardDeviceStruct( (DevicePtr)pDev, &keySyms, modMap,
+ DarwinBell,
+ DarwinChangeKeyboardControl ));
+}
+
+/*
+ * LegalModifier
+ * This allows the driver level to prevent some keys from being remapped
+ * as modifier keys.
+ * I have no idea why this is useful.
+ */
+Bool LegalModifier(unsigned int key, DevicePtr pDev)
+{
+ return 1;
+}
diff --git a/xc/programs/Xserver/hw/darwin/utils/Imakefile b/xc/programs/Xserver/hw/darwin/utils/Imakefile
new file mode 100644
index 000000000..7947a14ce
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/utils/Imakefile
@@ -0,0 +1,11 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/darwin/utils/Imakefile,v 1.2 2000/11/16 03:22:18 dawes Exp $
+
+ SRCS = dumpkeymap.c
+ OBJS = dumpkeymap.o
+EXTRA_LOAD_FLAGS = -framework IOKit
+
+AllTarget(ProgramTargetName(dumpkeymap))
+
+SingleProgramTarget(dumpkeymap,$(OBJS),NullParameter,NullParameter)
+InstallProgram(dumpkeymap,$(BINDIR))
+
diff --git a/xc/programs/Xserver/hw/darwin/utils/dumpkeymap.c b/xc/programs/Xserver/hw/darwin/utils/dumpkeymap.c
new file mode 100644
index 000000000..a3b96ea45
--- /dev/null
+++ b/xc/programs/Xserver/hw/darwin/utils/dumpkeymap.c
@@ -0,0 +1,879 @@
+// $XFree86: xc/programs/Xserver/hw/darwin/utils/dumpkeymap.c,v 1.1 2000/11/15 01:36:14 dawes Exp $
+//
+//=============================================================================
+//
+// Copyright (C) 1999,2000 by Eric Sunshine <sunshine@sunshineco.com>
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. The name of the author may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+// NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//=============================================================================
+//-----------------------------------------------------------------------------
+// dumpkeymap.c
+//
+// Prints a textual representation of an Apple/NeXT .keymapping file, or
+// the currently active key map in use by the WindowServer and the AppKit
+// on the local machine.
+//
+// KEY MAPPING DESCRIPTION
+//
+// Types and Data
+// --------------
+// The following type definitions are employed throughout this
+// discussion:
+//
+// typedef unsigned char byte;
+// typedef unsigned short word;
+// typedef unsigned long dword;
+//
+// Additionally, the type definition `number' is used generically to
+// indicate a numeric value. The actual size of the `number' type may be
+// one or two bytes depending upon how the data is stored in the key map.
+// Although most key maps use byte-sized numeric values, word-sized
+// values are also allowed.
+//
+// Multi-byte values in a key mapping file are stored in big-endian byte
+// order.
+//
+// Key Mapping File and Device Mapping
+// -----------------------------------
+// A key mapping file begins with a magic-number and continues with a
+// variable number of device-specific key mappings.
+//
+// struct KeyMappingFile {
+// char magic_number[4]; // "KYM1"
+// DeviceMapping maps[...] // Variable number of maps
+// };
+//
+// struct DeviceMapping {
+// dword interface; // NX_EVS_DEVICE_INTERFACE_ACE, etc.
+// dword handler_id; // Interface subtype (0=101, 1=102 key, etc.)
+// dword map_size; // Byte count following this address
+// KeyMapping map;
+// };
+//
+// Together, `interface' and `handler_id' identify the exact keyboard
+// hardware to which this mapping applies. The `interface' value
+// represents a family of keyboard device types (such as Intel, ADB,
+// NeXT, Sun Type5, etc.) and `handler_id' represents a specific keyboard
+// layout within that family. On MacOS/X and Darwin, `interface'
+// constants can be found in IOHIDTypes.h, whereas on MacOS/X Server,
+// OpenStep, and NextStep, they can be found in ev_types.h. Programs
+// which display a visual representation of a keyboard layout, match
+// `interface' and `handler_id' from the .keymapping file against the
+// `interface' and `handler_id' values found in each .keyboard file.
+//
+// Key Mapping
+// -----------
+// A key mapping completely defines the relationship of all scan codes
+// with their associated functionality. A KeyMapping structure is
+// embedded within the DeviceMapping structure in a KeyMappingFile. The
+// currently active key mapping in use by the WindowServer and AppKit is
+// also represented by a KeyMapping structure, and can be referred to
+// directly by calling NXGetKeyMapping() and accessing the `mapping' data
+// member of the returned NXKeyMapping structure.
+//
+// struct KeyMapping {
+// word number_size; // 0=1 byte, non-zero=2 bytes
+// number num_modifier_groups; // Modifier groups
+// ModifierGroup modifier_groups[...];
+// number num_scan_codes; // Scan groups
+// ScanGroup scan_table[...];
+// number num_sequence_lists; // Sequence lists
+// Sequence sequence_lists[...];
+// number num_special_keys; // Special keys
+// SpecialKey special_key[...];
+// };
+//
+// The `number_size' flag determines the size, in bytes, of all remaining
+// numeric values (denoted by the type definition `number') within the
+// key mapping. If its value is zero, then numbers are represented by a
+// single byte. If it is non-zero, then numbers are represented by a
+// word (two bytes).
+//
+// Modifier Group
+// --------------
+// A modifier group defines all scan codes which map to a particular type
+// of modifier, such as "shift", "control", etc.
+//
+// enum Modifier {
+// ALPHALOCK = 0,
+// SHIFT,
+// CONTROL,
+// ALTERNATE,
+// COMMAND,
+// KEYPAD,
+// HELP
+// };
+//
+// struct ModifierGroup {
+// number modifier; // A Modifier constant
+// number num_scan_codes;
+// number scan_codes[...]; // Variable number of scan codes
+// };
+//
+// The scan_codes[] array contains a list of all scan codes which map to
+// the specified modifier. The "shift", "command", and "alternate"
+// modifiers are frequently mapped to two different scan codes, apiece,
+// since these modifiers often appear on both the left and right sides of
+// the keyboard.
+//
+// Scan Group
+// ----------
+// There is one ScanGroup for each scan code generated by the given
+// keyboard. This number is given by KeyMapping::num_scan_codes. The
+// first scan group represents hardware scan code 0, the second
+// represents scan code 1, etc.
+//
+// enum ModifierMask {
+// ALPHALOCK_MASK = 1 << 0,
+// SHIFT_MASK = 1 << 1,
+// CONTROL_MASK = 1 << 2,
+// ALTERNATE_MASK = 1 << 3,
+// CARRIAGE_RETURN_MASK = 1 << 4
+// };
+// #define NOT_BOUND 0xff
+//
+// struct ScanGroup {
+// number mask;
+// Character characters[...];
+// };
+//
+// For each scan code, `mask' defines which modifier combinations
+// generate characters. If `mask' is NOT_BOUND (0xff) then then this
+// scan code does not generate any characters ever, and its characters[]
+// array is zero length. Otherwise, the characters[] array contains one
+// Character record for each modifier combination.
+//
+// The number of records in characters[] is determined by computing
+// (1 << bits_set_in_mask). In other words, if mask is zero, then zero
+// bits are set, so characters[] contains only one record. If `mask' is
+// (SHIFT_MASK | CONTROL_MASK), then two bits are set, so characters[]
+// contains four records.
+//
+// The first record always represents the character which is generated by
+// that key when no modifiers are active. The remaining records
+// represent characters generated by the various modifier combinations.
+// Using the example with the "shift" and "control" masks set, record two
+// would represent the character with the shift modifier active; record
+// three, the control modifier active; and record four, both the shift
+// and control modifiers active.
+//
+// As a special case, ALPHALOCK_MASK implies SHIFT_MASK, though only
+// ALPHALOCK_MASK appears in `mask'. In this case the same character is
+// generated for both the shift and alpha-lock modifiers, but only needs
+// to appear once in the characters[] array.
+//
+// Character
+// ---------
+// Each Character record indicates the character generated when this key
+// is pressed, as well as the character set which contains the character.
+// Well known character Sets are "ASCII" and "Symbol". The character set
+// can also be one of the meta values FUNCTION_KEY or KEY_SEQUENCE. If
+// it is FUNCTION_KEY then `char_code' represents a generally well-known
+// function key such as those enumerated by FunctionKey. If the
+// character set is KEY_SEQUENCE then `char_code' represents is a
+// zero-base index into KeyMapping::sequence_lists[].
+//
+// enum CharacterSet {
+// ASCII = 0x00,
+// SYMBOL = 0x01,
+// ...
+// FUNCTION_KEY = 0xfe,
+// KEY_SEQUENCE = 0xff
+// };
+//
+// struct Character {
+// number set; // CharacterSet of generated character
+// number char_code; // Actual character generated
+// };
+//
+// enum FunctionKey {
+// F1 = 0x20, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
+// INSERT, DELETE, HOME, END, PAGE_UP, PAGE_DOWN, PRINT_SCREEN,
+// SCROLL_LOCK, PAUSE, SYS_REQUEST, BREAK, RESET, STOP, MENU, USER,
+// SYSTEM, PRINT, CLEAR_LINE, CLEAR_DISPLAY, INSERT_LINE,
+// DELETE_LINE, INSERT_CHAR, DELETE_CHAR, PREV, NEXT, SELECT
+// };
+//
+// Sequence
+// --------
+// When Character::set contains the meta value KEY_SEQUENCE, the scan
+// code is bound to a sequence of keys rather than a single character. A
+// sequence is a series of modifiers and characters which are
+// automatically generated when the associated key is depressed. Each
+// generated Character is represented as previously described, with the
+// exception that MODIFIER_KEY may appear in place of KEY_SEQUENCE. When
+// the value of Character::set is MODIFIER_KEY then Character::char_code
+// represents a modifier key rather than an actual character. If the
+// modifier represented by `char_code' is non-zero, then it indicates
+// that the associated modifier key has been depressed. In this case,
+// the value is one of the constants enumerated by Modifier (SHIFT,
+// CONTROL, ALTERNATE, etc.). If the value is zero then it means that
+// the modifier keys have been released.
+//
+// #define MODIFIER_KEY 0xff
+//
+// struct Sequence {
+// number num_chars;
+// Character characters[...];
+// };
+//
+// Special Key
+// -----------
+// A special key is one which is scanned directly by the Mach kernel
+// rather than by the WindowServer. In general, events are not generated
+// for special keys.
+//
+// enum SpecialKeyType {
+// VOLUME_UP = 0,
+// VOLUME_DOWN,
+// BRIGHTNESS_UP,
+// BRIGHTNESS_DOWN,
+// ALPHA_LOCK,
+// HELP,
+// POWER,
+// SECONDARY_ARROW_UP,
+// SECONDARY_ARROW_DOWN
+// };
+//
+// struct SpecialKey {
+// number type; // A SpecialKeyType constant
+// number scan_code; // Actual scan code
+// };
+//
+// COMPILATION INSTRUCTIONS
+//
+// MacOS/X, Darwin
+// cc -Wall -o dumpkeymap dumpkeymap.c -framework IOKit
+//
+// MacOS/X Server, OpenStep, NextStep
+// cc -Wall -o dumpkeymap dumpkeymap.c
+//
+// USAGE INSTRUCTIONS
+//
+// Usage: dumpkeymap [path-to-keymap ...]
+//
+// When provided with no arguments, this program dumps the currently
+// active key map. Otherwise, it prints out the contents of each
+// .keymapping files mentioned as an argument on the command line.
+//
+// CONCLUSION
+//
+// This program and its accompanying documentation were written by Eric
+// Sunshine and are copyright (C)1999,2000 by Eric Sunshine
+// <sunshine@sunshineco.com>. It is based on information gathered on
+// September 3, 1997 by Eric Sunshine and Paul S. McCarthy
+// <zarnuk@zarnuk.com> while reverse engineering the NeXT .keymapping
+// file format.
+//
+// HISTORY
+//
+// 2000/11/13 Eric Sunshine <sunshine@sunshineco.com>
+// Converted from C++ to plain-C.
+// Now parses and takes into account the "number-size" flag stored
+// with each key map. This flag indicates the size, in bytes, of
+// all remaining numeric values in the mapping. Updated all code
+// to respect the this flag. (Previously, the purpose of this
+// field was unknown, and it was thus denoted as
+// `KeyMapping::fill[2]'.)
+// Updated all documentation; especially the "KEY MAPPING
+// DESCRIPTION" section. Added discussion of the "number-size"
+// flag and revamped all structure definitions to use the generic
+// data type `number' instead of `uchar' or 'byte'. Clarified
+// several sections of the documentation and added missing
+// discussions about type definitions and the relationship of
+// `interface' and `handler_id' to .keymapping and .keyboard
+// files.
+// Updated compilation instructions to include directions for all
+// platforms on which this program might be built.
+// Now published under the formal BSD license rather than a
+// home-grown license.
+//
+// 1999/09/08 Eric Sunshine <sunshine@sunshineco.com>
+// Created.
+//-----------------------------------------------------------------------------
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <drivers/event_status_driver.h>
+#include <sys/stat.h>
+
+#define PROG_NAME "dumpkeymap"
+#define PROG_VERSION 2
+#define AUTHOR_NAME "Eric Sunshine"
+#define AUTHOR_EMAIL "sunshine@sunshineco.com"
+#define AUTHOR_INFO AUTHOR_NAME " <" AUTHOR_EMAIL ">"
+#define COPYRIGHT "Copyright (C) 1999,2000 by " AUTHOR_INFO
+
+typedef unsigned char byte;
+typedef unsigned short word;
+typedef unsigned int natural;
+typedef unsigned long dword;
+typedef dword number;
+
+#define ASCII_SET 0x00
+#define BIND_FUNCTION 0xfe
+#define BIND_SPECIAL 0xff
+
+//-----------------------------------------------------------------------------
+// Translation Tables
+//-----------------------------------------------------------------------------
+static char const* const SPECIAL_CODE[] =
+ {
+ "sound-up",
+ "sound-down",
+ "brightness-up",
+ "brightness-down",
+ "alpha-lock",
+ "help",
+ "power",
+ "secondary-up-arrow",
+ "secondary-down-arrow"
+ };
+#define N_SPECIAL_CODE (sizeof(SPECIAL_CODE) / sizeof(SPECIAL_CODE[0]))
+
+static char const* const MODIFIER_CODE[] =
+ {
+ "alpha-lock",
+ "shift",
+ "control",
+ "alternate",
+ "command",
+ "keypad",
+ "help"
+ };
+#define N_MODIFIER_CODE (sizeof(MODIFIER_CODE) / sizeof(MODIFIER_CODE[0]))
+
+static char const* const MODIFIER_MASK[] =
+ {
+ "-----", // R = carriage-return
+ "----L", // A = alternate
+ "---S-", // C = control
+ "---SL", // S = shift
+ "--C--", // L = alpha-lock
+ "--C-L",
+ "--CS-",
+ "--CSL",
+ "-A---",
+ "-A--L",
+ "-A-S-",
+ "-A-SL",
+ "-AC--",
+ "-AC-L",
+ "-ACS-",
+ "-ACSL",
+ "R----",
+ "R---L",
+ "R--S-",
+ "R--SL",
+ "R-C--",
+ "R-C-L",
+ "R-CS-",
+ "R-CSL",
+ "RA---",
+ "RA--L",
+ "RA-S-",
+ "RA-SL",
+ "RAC--",
+ "RAC-L",
+ "RACS-",
+ "RACSL",
+ };
+#define N_MODIFIER_MASK (sizeof(MODIFIER_MASK) / sizeof(MODIFIER_MASK[0]))
+
+#define FUNCTION_KEY_FIRST 0x20
+static char const* const FUNCTION_KEY[] =
+ {
+ "F1", // 0x20
+ "F2", // 0x21
+ "F3", // 0x22
+ "F4", // 0x23
+ "F5", // 0x24
+ "F6", // 0x25
+ "F7", // 0x26
+ "F8", // 0x27
+ "F9", // 0x28
+ "F10", // 0x29
+ "F11", // 0x2a
+ "F12", // 0x2b
+ "insert", // 0x2c
+ "delete", // 0x2d
+ "home", // 0x2e
+ "end", // 0x2f
+ "page up", // 0x30
+ "page down", // 0x31
+ "print screen", // 0x32
+ "scroll lock", // 0x33
+ "pause", // 0x34
+ "sys-request", // 0x35
+ "break", // 0x36
+ "reset (HIL)", // 0x37
+ "stop (HIL)", // 0x38
+ "menu (HIL)", // 0x39
+ "user (HIL)", // 0x3a
+ "system (HIL)", // 0x3b
+ "print (HIL)", // 0x3c
+ "clear line (HIL)", // 0x3d
+ "clear display (HIL)", // 0x3e
+ "insert line (HIL)", // 0x3f
+ "delete line (HIL)", // 0x40
+ "insert char (HIL)", // 0x41
+ "delete char (HIL)", // 0x42
+ "prev (HIL)", // 0x43
+ "next (HIL)", // 0x44
+ "select (HIL)", // 0x45
+ };
+#define N_FUNCTION_KEY (sizeof(FUNCTION_KEY) / sizeof(FUNCTION_KEY[0]))
+
+
+//-----------------------------------------------------------------------------
+// Data Stream Object
+// Can be configured to treat embedded "numbers" as being composed of
+// either 1, 2, or 4 bytes, apiece.
+//-----------------------------------------------------------------------------
+typedef struct _DataStream
+ {
+ byte const* data;
+ byte const* data_end;
+ natural number_size; // Size in bytes of a "number" in the stream.
+ } DataStream;
+
+static DataStream* new_data_stream( byte const* data, int size )
+ {
+ DataStream* s = (DataStream*)malloc( sizeof(DataStream) );
+ s->data = data;
+ s->data_end = data + size;
+ s->number_size = 1; // Default to byte-sized numbers.
+ return s;
+ }
+
+static void destroy_data_stream( DataStream* s )
+ {
+ free(s);
+ }
+
+static int end_of_stream( DataStream* s )
+ {
+ return (s->data >= s->data_end);
+ }
+
+static void expect_nbytes( DataStream* s, int nbytes )
+ {
+ if (s->data + nbytes > s->data_end)
+ {
+ fprintf( stderr, "Insufficient data in keymapping data stream.\n" );
+ exit(-1);
+ }
+ }
+
+static byte get_byte( DataStream* s )
+ {
+ expect_nbytes( s, 1 );
+ return *s->data++;
+ }
+
+static word get_word( DataStream* s )
+ {
+ word hi, lo;
+ expect_nbytes( s, 2 );
+ hi = *s->data++;
+ lo = *s->data++;
+ return ((hi << 8) | lo);
+ }
+
+static dword get_dword( DataStream* s )
+ {
+ dword b1, b2, b3, b4;
+ expect_nbytes( s, 4 );
+ b4 = *s->data++;
+ b3 = *s->data++;
+ b2 = *s->data++;
+ b1 = *s->data++;
+ return ((b4 << 24) | (b3 << 16) | (b2 << 8) | b1);
+ }
+
+static number get_number( DataStream* s )
+ {
+ switch (s->number_size)
+ {
+ case 4: return get_dword(s);
+ case 2: return get_word(s);
+ default: return get_byte(s);
+ }
+ }
+
+
+//-----------------------------------------------------------------------------
+// Translation Utility Functions
+//-----------------------------------------------------------------------------
+static char const* special_code_desc( number n )
+ {
+ if (n < N_SPECIAL_CODE)
+ return SPECIAL_CODE[n];
+ else
+ return "invalid";
+ }
+
+static char const* modifier_code_desc( number n )
+ {
+ if (n < N_MODIFIER_CODE)
+ return MODIFIER_CODE[n];
+ else
+ return "invalid";
+ }
+
+static char const* modifier_mask_desc( number n )
+ {
+ if (n < N_MODIFIER_MASK)
+ return MODIFIER_MASK[n];
+ else
+ return "?????";
+ }
+
+static char const* function_key_desc( number n )
+ {
+ if (n >= FUNCTION_KEY_FIRST && n < N_FUNCTION_KEY + FUNCTION_KEY_FIRST)
+ return FUNCTION_KEY[ n - FUNCTION_KEY_FIRST ];
+ else
+ return "unknown";
+ }
+
+static number bits_set( number mask )
+ {
+ number n = 0;
+ for ( ; mask != 0; mask >>= 1)
+ if ((mask & 0x01) != 0)
+ n++;
+ return n;
+ }
+
+
+//-----------------------------------------------------------------------------
+// Unparse a list of Modifier records.
+//-----------------------------------------------------------------------------
+static void unparse_modifiers( DataStream* s )
+ {
+ number nmod = get_number(s); // Modifier count
+ printf( "\nMODIFIERS [%lu]\n", nmod );
+ while (nmod-- > 0)
+ {
+ number nscan;
+ number const code = get_number(s);
+ printf( "%s:", modifier_code_desc(code) );
+ nscan = get_number(s);
+ while (nscan-- > 0)
+ printf( " 0x%02x", (natural)get_number(s) );
+ putchar( '\n' );
+ }
+ }
+
+
+//-----------------------------------------------------------------------------
+// Unparse a list of Character records.
+//-----------------------------------------------------------------------------
+typedef void (*UnparseSpecialFunc)( number code );
+
+static void unparse_char_codes(
+ DataStream* s, number ncodes, UnparseSpecialFunc unparse_special )
+ {
+ if (ncodes != 0)
+ {
+ while (ncodes-- > 0)
+ {
+ number const char_set = get_number(s);
+ number const code = get_number(s);
+ putchar(' ');
+ switch (char_set)
+ {
+ case ASCII_SET:
+ {
+ int const c = (int)code;
+ if (isprint(c))
+ printf( "\"%c\"", c );
+ else if (code < ' ')
+ printf( "\"^%c\"", c + '@' );
+ else
+ printf( "%02x", c );
+ break;
+ }
+ case BIND_FUNCTION:
+ printf( "[%s]", function_key_desc(code) );
+ break;
+ case BIND_SPECIAL:
+ unparse_special( code );
+ break;
+ default:
+ printf( "%02x/%02x", (natural)char_set, (natural)code );
+ break;
+ }
+ }
+ }
+ }
+
+
+//-----------------------------------------------------------------------------
+// Unparse a list of scan code bindings.
+//-----------------------------------------------------------------------------
+static void unparse_key_special( number code )
+ {
+ printf( "{seq#%lu}", code );
+ }
+
+static void unparse_keys( DataStream* s )
+ {
+ number const NOT_BOUND = 0xff;
+ number const nkeys = get_number(s);
+ number scan;
+ printf( "\nKEYS [%lu]\n", nkeys );
+ for (scan = 0; scan < nkeys; scan++)
+ {
+ number const mask = get_number(s);
+ printf( "scan 0x%02x: ", (natural)scan );
+ if (mask == NOT_BOUND)
+ printf( "not-bound\n" );
+ else
+ {
+ number const bits = bits_set( mask );
+ number const codes = 1 << bits;
+ printf( "%s ", modifier_mask_desc(mask) );
+ unparse_char_codes( s, codes, unparse_key_special );
+ putchar( '\n' );
+ }
+ }
+ }
+
+
+//-----------------------------------------------------------------------------
+// Unparse a list of key sequences.
+//-----------------------------------------------------------------------------
+static void unparse_sequence_special( number code )
+ {
+ printf( "{%s}", (code == 0 ? "unmodify" : modifier_code_desc(code)) );
+ }
+
+static void unparse_sequences( DataStream* s )
+ {
+ number const nseqs = get_number(s);
+ number seq;
+ printf( "\nSEQUENCES [%lu]\n", nseqs );
+ for (seq = 0; seq < nseqs; seq++)
+ {
+ number const nchars = get_number(s);
+ printf( "sequence %lu: ", seq );
+ unparse_char_codes( s, nchars, unparse_sequence_special );
+ putchar( '\n' );
+ }
+ }
+
+
+//-----------------------------------------------------------------------------
+// Unparse a list of special keys.
+//-----------------------------------------------------------------------------
+static void unparse_specials( DataStream* s )
+ {
+ number nspecials = get_number(s);
+ printf( "\nSPECIALS [%lu]\n", nspecials );
+ while (nspecials-- > 0)
+ {
+ number const special = get_number(s);
+ number const scan = get_number(s);
+ printf( "%s: 0x%02x\n", special_code_desc(special), (natural)scan );
+ }
+ }
+
+
+//-----------------------------------------------------------------------------
+// Unparse the number-size flag.
+//-----------------------------------------------------------------------------
+static void unparse_numeric_size( DataStream* s )
+ {
+ word const numbers_are_shorts = get_word(s);
+ s->number_size = numbers_are_shorts ? 2 : 1;
+ }
+
+
+//-----------------------------------------------------------------------------
+// Unparse an entire key map.
+//-----------------------------------------------------------------------------
+static void unparse_keymap_data( DataStream* s )
+ {
+ unparse_numeric_size(s);
+ unparse_modifiers(s);
+ unparse_keys(s);
+ unparse_sequences(s);
+ unparse_specials(s);
+ }
+
+
+//-----------------------------------------------------------------------------
+// Unparse the active key map.
+//-----------------------------------------------------------------------------
+static int unparse_active_keymap( void )
+ {
+ int rc = 1;
+ NXEventHandle const h = NXOpenEventStatus();
+ if (h == 0)
+ fprintf( stderr, "Unable to open event status driver.\n" );
+ else
+ {
+ NXKeyMapping km;
+ km.size = NXKeyMappingLength(h);
+ if (km.size <= 0)
+ fprintf( stderr, "Bad key mapping length (%d).\n", km.size );
+ else
+ {
+ km.mapping = (char*)malloc( km.size );
+ if (NXGetKeyMapping( h, &km ) == 0)
+ fprintf( stderr, "Unable to get current key mapping.\n" );
+ else
+ {
+ DataStream* stream =
+ new_data_stream( (byte const*)km.mapping, km.size );
+ unparse_keymap_data( stream );
+ destroy_data_stream( stream );
+ rc = 0;
+ }
+ free( km.mapping );
+ }
+ NXCloseEventStatus(h);
+ }
+ return rc;
+ }
+
+
+//-----------------------------------------------------------------------------
+// Unparse one key map from a keymapping file.
+//-----------------------------------------------------------------------------
+static void unparse_keymap( DataStream* s )
+ {
+ dword const interface = get_dword(s);
+ dword const handler_id = get_dword(s);
+ dword const map_size = get_dword(s);
+ printf( "interface=0x%02lx handler_id=0x%02lx map_size=%lu bytes\n",
+ interface, handler_id, map_size );
+ unparse_keymap_data(s);
+ }
+
+
+//-----------------------------------------------------------------------------
+// Check the magic number of a keymapping file.
+//-----------------------------------------------------------------------------
+static int check_magic_number( DataStream* s )
+ {
+ return (get_byte(s) == 'K' &&
+ get_byte(s) == 'Y' &&
+ get_byte(s) == 'M' &&
+ get_byte(s) == '1');
+ }
+
+
+//-----------------------------------------------------------------------------
+// Unparse all key maps within a keymapping file.
+//-----------------------------------------------------------------------------
+static int unparse_keymaps( DataStream* s )
+ {
+ int rc = 0;
+ if (check_magic_number(s))
+ {
+ int n = 0;
+ while (!end_of_stream(s))
+ {
+ printf( "\nKEYMAP #%d: ", n++ );
+ unparse_keymap(s);
+ }
+ }
+ else
+ {
+ fprintf( stderr, "Bad magic number.\n" );
+ rc = 1;
+ }
+ return rc;
+ }
+
+
+//-----------------------------------------------------------------------------
+// Unparse a keymapping file.
+//-----------------------------------------------------------------------------
+static int unparse_keymap_file( char const* const path )
+ {
+ int rc = 1;
+ FILE* file;
+ printf( "\nKEYMAP FILE: %s\n", path );
+ file = fopen( path, "rb" );
+ if (file == 0)
+ perror( "Unable to open keymap" );
+ else
+ {
+ struct stat st;
+ if (fstat( fileno(file), &st ) != 0)
+ perror( "Unable to determine file size" );
+ else
+ {
+ byte* buffer = (byte*)malloc( st.st_size );
+ if (fread( buffer, st.st_size, 1, file ) != 1)
+ perror( "Unable to read keymap" );
+ else
+ {
+ DataStream* stream = new_data_stream(buffer, (int)st.st_size);
+ fclose( file ); file = 0;
+ rc = unparse_keymaps( stream );
+ destroy_data_stream( stream );
+ }
+ free( buffer );
+ }
+ if (file != 0)
+ fclose( file );
+ }
+ return rc;
+ }
+
+
+//-----------------------------------------------------------------------------
+// Print an informational banner.
+//-----------------------------------------------------------------------------
+static void print_banner( void )
+ {
+ printf( "\n" PROG_NAME " v%d by " AUTHOR_INFO "\n" COPYRIGHT "\n",
+ PROG_VERSION );
+ }
+
+
+//-----------------------------------------------------------------------------
+// Master dispatcher.
+//-----------------------------------------------------------------------------
+int main( int const argc, char const* const argv[] )
+ {
+ int rc = 0;
+ print_banner();
+ if (argc == 1) // No arguments, unparse keymap currently in use.
+ rc = unparse_active_keymap();
+ else // Unparse keymaps specified on command line.
+ {
+ int i;
+ for (i = 1; i < argc; i++)
+ rc |= unparse_keymap_file( argv[i] );
+ }
+ return rc;
+ }
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ark/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/ark/Imakefile
new file mode 100644
index 000000000..ba5216709
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ark/Imakefile
@@ -0,0 +1,49 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ark/Imakefile,v 1.5 2000/11/15 23:13:08 dawes Exp $
+/*
+ *
+ * Copyright 2000 Ani Joshi <ajoshi@unixbox.com>
+ *
+ */
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = ark_driver.c ark_accel.c
+
+OBJS = ark_driver.o ark_accel.o
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \
+ -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$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(FONTINCSRC) \
+ -I$(EXTINCSRC) -I$(SERVERSRC)/render
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+NormalAsmObjectRule()
+
+ModuleObjectRule()
+ObjectModuleTarget(ark, $(OBJS))
+
+InstallObjectModule(ark,$(MODULEDIR),drivers)
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/ark)
+InstallDriverSDKNonExecFile(ark.h,$(DRIVERSDKDIR)/drivers/ark)
+InstallDriverSDKNonExecFile(ark_reg.h,$(DRIVERSDKDIR)/drivers/ark)
+InstallDriverSDKNonExecFile(ark_driver.c,$(DRIVERSDKDIR)/drivers/ark)
+InstallDriverSDKNonExecFile(ark_accel.c,$(DRIVERSDKDIR)/drivers/ark)
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ark/ark.h b/xc/programs/Xserver/hw/xfree86/drivers/ark/ark.h
new file mode 100644
index 000000000..6a95f8039
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ark/ark.h
@@ -0,0 +1,71 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ark/ark.h,v 1.1 2000/11/14 17:28:12 dawes Exp $ */
+/*
+ * ark
+ */
+
+#ifndef _ARK_H
+#define _ARK_H
+
+#include "xf86.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "xaa.h"
+#include "xf86_ansic.h"
+#include "vgaHW.h"
+
+typedef struct _ARKRegRec {
+ unsigned char sr10, sr11, sr12, sr13, sr14,
+ sr15, sr16, sr17, sr18, sr20,
+ sr21, sr22, sr23, sr24, sr25,
+ sr26, sr27, sr28, sr29, sr2a,
+ sr2b;
+ unsigned char sr1c, sr1d;
+ unsigned char cr40, cr41, cr42, cr44, cr46;
+ unsigned char dac_command;
+ unsigned char stg_17xx[3];
+ unsigned char gendac[6];
+} ARKRegRec, *ARKRegPtr;
+
+
+typedef struct _ARKRec {
+ 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;
+ CARD32 Bus;
+ XAAInfoRecPtr pXAA;
+ int Chipset, ChipRev;
+ int clock_mult;
+ int dac_width;
+ int multiplex_threshold;
+ int ramdac;
+ ARKRegRec SavedRegs; /* original mode */
+ ARKRegRec ModeRegs; /* current mode */
+ Bool (*CloseScreen)(int, ScreenPtr);
+} ARKRec, *ARKPtr;
+
+
+#define ARKPTR(p) ((ARKPtr)((p)->driverPrivate))
+
+
+#define DRIVER_NAME "ark"
+#define DRIVER_VERSION "0.5.0"
+#define VERSION_MAJOR 0
+#define VERSION_MINOR 5
+#define PATCHLEVEL 0
+#define ARK_VERSION ((VERSION_MAJOR << 24) | \
+ (VERSION_MINOR << 16) | \
+ PATCHLEVEL)
+
+#define ZOOMDAC 0x404
+#define ATT490 0x101
+
+
+#endif /* _ARK_H */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ark/ark_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/ark/ark_accel.c
new file mode 100644
index 000000000..c2cefce63
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ark/ark_accel.c
@@ -0,0 +1,227 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ark/ark_accel.c,v 1.4 2000/11/15 23:13:09 dawes Exp $ */
+/*
+ * Copyright 2000 Ani Joshi <ajoshi@unixbox.com>
+ *
+ * XFree86 4.x driver for ARK Logic chipset
+ *
+ * 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.
+ *
+ *
+ * Based on the 3.3.x driver by:
+ * Harm Hanemaayer <H.Hanemaayer@inter.nl.net>
+ *
+ */
+
+
+#include "Xarch.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+#include "xaa.h"
+#include "xf86PciInfo.h"
+#include "compiler.h"
+
+#include "ark.h"
+#include "ark_reg.h"
+
+
+int curx, cury, cmd_flags;
+
+
+static void ARKSync(ScrnInfoPtr pScrn)
+{
+ for (;;) {
+ if (!(inb(0x3cb) & 0x40))
+ break;
+ }
+}
+
+
+static void ARKSetupForSolidFill(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ ARKPtr pARK = ARKPTR(pScrn);
+
+ OUTREG16(FG_COLOR, color);
+ /* ARK color mix matches X raster-ops */
+ OUTREG16(COLOR_MIX_SEL, (rop | (rop << 8)));
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ if ((planemask & 0xff) == 0xff)
+ cmd_flags = DISABLE_PLANEMASK;
+ else {
+ OUTREG16(WRITE_PLANEMASK, planemask);
+ cmd_flags = 0;
+ }
+ break;
+ case 16:
+ if ((planemask & 0xffff) == 0xffff)
+ cmd_flags = DISABLE_PLANEMASK;
+ else {
+ OUTREG16(WRITE_PLANEMASK, planemask);
+ cmd_flags = 0;
+ }
+ break;
+ case 32:
+ OUTREG16(FG_COLOR_HI, color >> 16);
+ if ((planemask & 0xffffff) == 0xffffff)
+ cmd_flags = DISABLE_PLANEMASK;
+ else {
+ OUTREG16(WRITE_PLANEMASK, planemask);
+ cmd_flags = 0;
+ }
+ break;
+ }
+
+ curx = cury = -1;
+}
+
+
+static void ARKSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h)
+{
+ ARKPtr pARK = ARKPTR(pScrn);
+ int dst_addr;
+
+ OUTREG(WIDTH, ((h - 1) << 16) | (w - 1));
+ if (x != curx || y != cury) {
+ dst_addr = y * pScrn->displayWidth + x;
+ OUTREG(DST_ADDR, dst_addr);
+ curx = x;
+ cury = y;
+ }
+ OUTREG16(COMMAND, SELECT_BG_COLOR | SELECT_FG_COLOR |
+ STENCIL_ONES | DISABLE_CLIPPING | BITBLT |
+ cmd_flags);
+ cury += h;
+}
+
+
+
+static void ARKSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
+ int ydir, int rop, unsigned int planemask,
+ int trans_color)
+{
+ ARKPtr pARK = ARKPTR(pScrn);
+
+ cmd_flags = 0;
+ if (trans_color != -1) {
+ if (pScrn->bitsPerPixel <= 16)
+ OUTREG16(TRANS_COLOR, trans_color);
+ else {
+ OUTREG16(TRANS_COLOR, trans_color & 0xffff);
+ OUTREG16(TRANS_COLOR_HI, trans_color >> 16);
+ }
+ cmd_flags = STENCIL_GENERATED;
+ OUTREG16(COLOR_MIX_SEL, rop | 0x0500);
+ } else {
+ OUTREG16(COLOR_MIX_SEL, rop | (rop << 8));
+ }
+
+ if (ydir < 0)
+ cmd_flags |= UP;
+ if (xdir < 0)
+ cmd_flags |= LEFT;
+
+ /* yes, quite ugly */
+ if ((pScrn->bitsPerPixel == 8 && (planemask & 0xff) == 0xff) ||
+ (pScrn->bitsPerPixel == 16 && (planemask & 0xffff) == 0xffff) ||
+ (pScrn->bitsPerPixel == 32 && (planemask & 0xffffff) == 0xffffff))
+ cmd_flags |= DISABLE_PLANEMASK;
+ else
+ OUTREG16(WRITE_PLANEMASK, planemask);
+
+}
+
+
+
+static void ARKSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1,
+ int x2, int y2,
+ int w, int h)
+{
+ ARKPtr pARK = ARKPTR(pScrn);
+ int src_addr, dst_addr;
+
+ if (cmd_flags & UP) {
+ src_addr = (y1 + h - 1) * pScrn->displayWidth;
+ dst_addr = (y2 + h - 1) * pScrn->displayWidth;
+ } else {
+ src_addr = y1 * pScrn->displayWidth;
+ dst_addr = y2 * pScrn->displayWidth;
+ }
+ if (cmd_flags & LEFT) {
+ src_addr += x1 + w - 1;
+ dst_addr += x2 + w - 1;
+ } else {
+ src_addr += x1;
+ dst_addr += x2;
+ }
+
+ OUTREG(SRC_ADDR, src_addr);
+ OUTREG(DST_ADDR, dst_addr);
+ OUTREG(WIDTH, ((h - 1) << 16) | (w - 1));
+ OUTREG16(COMMAND, BG_BITMAP | FG_BITMAP | DISABLE_CLIPPING |
+ BITBLT | cmd_flags);
+}
+
+
+
+Bool ARKAccelInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ ARKPtr pARK = ARKPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ XAAInfoRecPtr pXAA;
+
+ if (!(pXAA = XAACreateInfoRec()))
+ return FALSE;
+
+ pXAA->Flags = LINEAR_FRAMEBUFFER;
+
+ pXAA->Sync = ARKSync;
+ pXAA->SetupForSolidFill = ARKSetupForSolidFill;
+ pXAA->SubsequentSolidFillRect = ARKSubsequentSolidFillRect;
+ pXAA->ScreenToScreenCopyFlags = 0;
+ pXAA->SetupForScreenToScreenCopy = ARKSetupForScreenToScreenCopy;
+ pXAA->SubsequentScreenToScreenCopy = ARKSubsequentScreenToScreenCopy;
+
+ OUTREG16(COLOR_MIX_SEL, 0x0303);
+ if (pARK->Chipset == PCI_CHIP_1000PV) {
+ OUTREG16(WRITE_PLANEMASK, 0xffff);
+ OUTREG16(TRANS_COLOR_MSK, 0xffff);
+ } else {
+ OUTREG16(TRANS_COLOR, 0xffff);
+ OUTREG16(TRANS_COLOR, 0xffffffff >> 16);
+ }
+ if (pARK->Chipset == PCI_CHIP_1000PV && pScrn->bitsPerPixel == 32) {
+ OUTREG16(STENCIL_PITCH, pScrn->displayWidth * 2);
+ OUTREG16(SRC_PITCH, pScrn->displayWidth * 2);
+ OUTREG16(DST_PITCH, pScrn->displayWidth * 2);
+ } else {
+ OUTREG16(STENCIL_PITCH, pScrn->displayWidth);
+ OUTREG16(SRC_PITCH, pScrn->displayWidth);
+ OUTREG16(DST_PITCH, pScrn->displayWidth);
+ }
+
+ OUTREG16(BITMAP_CONFIG, LINEAR_STENCIL_ADDR | LINEAR_SRC_ADDR |
+ LINEAR_DST_ADDR);
+
+ return XAAInit(pScreen, pXAA);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ark/ark_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/ark/ark_driver.c
new file mode 100644
index 000000000..b7e765b5c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ark/ark_driver.c
@@ -0,0 +1,1170 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ark/ark_driver.c,v 1.8 2000/11/15 23:13:09 dawes Exp $ */
+/*
+ * Copyright 2000 Ani Joshi <ajoshi@unixbox.com>
+ *
+ * XFree86 4.x driver for ARK Logic chipset
+ *
+ * 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.
+ *
+ *
+ * Based on the 3.3.x driver by:
+ * Harm Hanemaayer <H.Hanemaayer@inter.nl.net>
+ *
+ */
+
+
+#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 "ark.h"
+
+
+/*
+ * prototypes
+ */
+static OptionInfoPtr ARKAvailableOptions(int chipid, int busid);
+static void ARKIdentify(int flags);
+static Bool ARKProbe(DriverPtr drv, int flags);
+static Bool ARKPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool ARKEnterVT(int scrnIndex, int flags);
+static void ARKLeaveVT(int scrnIndex, int flags);
+static void ARKSave(ScrnInfoPtr pScrn);
+static Bool ARKScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool ARKMapMem(ScrnInfoPtr pScrn);
+static void ARKUnmapMem(ScrnInfoPtr pScrn);
+static Bool ARKModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static void ARKAdjustFrame(int scrnIndex, int x, int y, int flags);
+Bool ARKSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+Bool ARKCloseScreen(int scrnIndex, ScreenPtr pScreen);
+Bool ARKSaveScreen(ScreenPtr pScreen, int mode);
+static void ARKFreeScreen(int scrnIndex, int flags);
+static void ARKLoadPalette(ScrnInfoPtr pScrn, int numColors,
+ int *indicies, LOCO *colors,
+ VisualPtr pVisual);
+static void ARKWriteMode(ScrnInfoPtr pScrn, vgaRegPtr pVga, ARKRegPtr new);
+
+/* helpers */
+static unsigned char get_daccomm();
+static unsigned char set_daccom(unsigned char comm);
+
+
+DriverRec ARK =
+{
+ ARK_VERSION,
+ DRIVER_NAME,
+ ARKIdentify,
+ ARKProbe,
+ ARKAvailableOptions,
+ NULL,
+ 0
+};
+
+/* supported chipsets */
+static SymTabRec ARKChipsets[] = {
+ { PCI_CHIP_1000PV, "ark1000pv" },
+ { PCI_CHIP_2000PV, "ark2000pv" },
+ { PCI_CHIP_2000MT, "ark2000mt" },
+ { -1, NULL }
+};
+
+static PciChipsets ARKPciChipsets[] = {
+ { PCI_CHIP_1000PV, PCI_CHIP_1000PV, RES_SHARED_VGA },
+ { PCI_CHIP_2000PV, PCI_CHIP_2000PV, RES_SHARED_VGA },
+ { PCI_CHIP_2000MT, PCI_CHIP_2000MT, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED }
+};
+
+typedef enum {
+ OPTION_NOACCEL
+} ARKOpts;
+
+static OptionInfoRec ARKOptions[] = {
+ { OPTION_NOACCEL, "noaccel", OPTV_BOOLEAN, {0}, FALSE }
+};
+
+static const char *fbSymbols[] = {
+ "fbScreenInit",
+ NULL
+};
+
+static const char *vgaHWSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWFreeHWRec",
+ "vgaHWGetIOBase",
+ "vgaHWSave",
+ "vgaHWProtect",
+ "vgaHWRestore",
+ "vgaHWMapMem",
+ "vgaHWUnmapMem",
+ "vgaHWSaveScreen",
+ "vgaHWLock",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAACreateInfoRec",
+ "XAADestroyInfoRec",
+ "XAAInit",
+ "XAAScreenIndex",
+ NULL
+};
+
+#ifdef XFree86LOADER
+
+MODULESETUPPROTO(ARKSetup);
+
+static XF86ModuleVersionInfo ARKVersRec = {
+ "ark",
+ 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 arkModuleData = { &ARKVersRec, ARKSetup, NULL };
+
+pointer ARKSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&ARK, module, 0);
+ LoaderRefSymLists(fbSymbols, vgaHWSymbols, xaaSymbols, NULL);
+ return (pointer) 1;
+ } else {
+ if (errmaj)
+ *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+#endif /* XFree86LOADER */
+
+
+static Bool ARKGetRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(ARKRec), 1);
+
+ return TRUE;
+}
+
+static void ARKFreeRec(ScrnInfoPtr pScrn)
+{
+ if (!pScrn->driverPrivate)
+ return;
+
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+static OptionInfoPtr ARKAvailableOptions(int chipid, int busid)
+{
+ return ARKOptions;
+}
+
+static void ARKIdentify(int flags)
+{
+ xf86PrintChipsets("ark", "driver (version " DRIVER_VERSION " for ARK Logic chipset",
+ ARKChipsets);
+}
+
+static Bool ARKProbe(DriverPtr drv, int flags)
+{
+ int i;
+ GDevPtr *devSections = NULL;
+ int *usedChips;
+ int numDevSections;
+ int numUsed;
+ Bool foundScreen = FALSE;
+
+ /* sanity check */
+ if ((numDevSections = xf86MatchDevice("ark", &devSections)) <= 0)
+ return FALSE;
+
+ /* do ISA later */
+ numUsed = xf86MatchPciInstances("ark", PCI_VENDOR_ARK,
+ ARKChipsets, ARKPciChipsets,
+ devSections, numDevSections, drv,
+ &usedChips);
+
+ if (devSections)
+ 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 = "ark";
+ pScrn->Probe = ARKProbe;
+ pScrn->PreInit = ARKPreInit;
+ pScrn->ScreenInit = ARKScreenInit;
+ pScrn->SwitchMode = ARKSwitchMode;
+ pScrn->AdjustFrame = ARKAdjustFrame;
+ pScrn->EnterVT = ARKEnterVT;
+ pScrn->LeaveVT = ARKLeaveVT;
+ pScrn->FreeScreen = ARKFreeScreen;
+ foundScreen = TRUE;
+ xf86ConfigActivePciEntity(pScrn, usedChips[i], ARKPciChipsets,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+
+ xfree(usedChips);
+
+ return foundScreen;
+}
+
+
+static Bool ARKPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ EntityInfoPtr pEnt;
+ ARKPtr pARK;
+ vgaHWPtr hwp;
+ MessageType from = X_DEFAULT;
+ int i;
+ ClockRangePtr clockRanges;
+ char *mod = NULL;
+ const char *reqSym = NULL;
+ rgb zeros = {0, 0, 0};
+ Gamma gzeros = {0.0, 0.0, 0.0};
+ 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;
+ else {
+ switch (pScrn->depth) {
+ case 8:
+ 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 (pScrn->depth == 8)
+ pScrn->rgbBits = 8;
+
+ if (!xf86SetDefaultVisual(pScrn, -1))
+ return FALSE;
+
+ pScrn->progClock = TRUE;
+
+ if (!ARKGetRec(pScrn))
+ return FALSE;
+
+ pARK = ARKPTR(pScrn);
+
+ xf86CollectOptions(pScrn, NULL);
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ARKOptions);
+
+ if (xf86ReturnOptValBool(ARKOptions, OPTION_NOACCEL, FALSE)) {
+ pARK->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: NoAccel - acceleration disabled\n");
+ } else
+ pARK->NoAccel = FALSE;
+
+ if (pScrn->numEntities > 1) {
+ ARKFreeRec(pScrn);
+ return FALSE;
+ }
+
+ pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pEnt->resources) {
+ xfree(pEnt);
+ ARKFreeRec(pScrn);
+ return FALSE;
+ }
+
+ pARK->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;
+ pARK->Chipset = xf86StringToToken(ARKChipsets, pScrn->chipset);
+ } else if (pEnt->device->chipID >= 0) {
+ pARK->Chipset = pEnt->device->chipID;
+ pScrn->chipset = (char *)xf86TokenToString(ARKChipsets,
+ pARK->Chipset);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pARK->Chipset);
+ } else {
+ pARK->Chipset = pARK->PciInfo->chipType;
+ pScrn->chipset = (char *)xf86TokenToString(ARKChipsets,
+ pARK->Chipset);
+ }
+
+ if (pEnt->device->chipRev >= 0) {
+ pARK->ChipRev = pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pARK->ChipRev);
+ } else
+ pARK->ChipRev = pARK->PciInfo->chipRev;
+
+ xfree(pEnt);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Chipset: \"%s\"\n", pScrn->chipset);
+
+ pARK->PciTag = pciTag(pARK->PciInfo->bus, pARK->PciInfo->device,
+ pARK->PciInfo->func);
+
+ /* unlock CRTC[0-7] */
+ outb(hwp->IOBase + 4, 0x11);
+ tmp = inb(hwp->IOBase + 5);
+ outb(hwp->IOBase + 5, tmp & 0x7f);
+ modinx(0x3c4, 0x1d, 0x01, 0x01);
+
+ /* use membase's later on ??? */
+ pARK->FBAddress = (rdinx(0x3c4, 0x13) << 16) +
+ (rdinx(0x3c4, 0x14) << 24);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Framebuffer @ 0x%x\n",
+ pARK->FBAddress);
+
+ if (!xf86SetGamma(pScrn, gzeros))
+ return FALSE;
+
+ if (!pScrn->videoRam) {
+ unsigned char sr10;
+
+ sr10 = rdinx(0x3c4, 0x10);
+ if (pARK->Chipset == PCI_CHIP_1000PV) {
+ if ((sr10 & 0x40) == 0)
+ pScrn->videoRam = 1024;
+ else
+ pScrn->videoRam = 2048;
+ }
+ if (pARK->Chipset == PCI_CHIP_2000PV ||
+ pARK->Chipset == PCI_CHIP_2000MT) {
+ if ((sr10 & 0xc0) == 0)
+ pScrn->videoRam = 1024;
+ else if ((sr10 & 0xc0) == 0x40)
+ pScrn->videoRam = 2048;
+ else
+ pScrn->videoRam = 4096;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected %d bytes video ram\n",
+ pScrn->videoRam);
+
+ /* try to detect the RAMDAC */
+ {
+ int man_id, dev_id;
+
+ inb(0x3c6); /* skip command register */
+ man_id = inb(0x3c6); /* manufacturer id */
+ dev_id = inb(0x3c6); /* device id */
+ if (man_id == 0x84 && dev_id == 0x98) {
+ pARK->ramdac = ZOOMDAC;
+ pARK->dac_width = 16;
+ pARK->multiplex_threshold = 40000;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected ZOOMDAC\n");
+ }
+ }
+
+ /* hack for this Bali32 */
+ pARK->ramdac = ATT490;
+ pARK->dac_width = 8;
+
+ pARK->clock_mult = 1;
+ if (pARK->dac_width == 16) {
+ if (pScrn->bitsPerPixel == 32)
+ pARK->clock_mult = 2;
+ }
+
+ pScrn->numClocks = 1;
+ pScrn->clock[0] = 80000; /* safe */
+
+ clockRanges = xnfcalloc(sizeof(ClockRange), 1);
+ clockRanges->next = NULL;
+ clockRanges->minClock = 20000;
+ clockRanges->maxClock = 80000;
+ clockRanges->clockIndex = -1;
+ clockRanges->interlaceAllowed = FALSE; /* ? */
+ clockRanges->doubleScanAllowed = FALSE; /* ? */
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, 256, 2048, pScrn->bitsPerPixel,
+ 128, 2048, pScrn->virtualX,
+ pScrn->display->virtualY, pARK->videoRam * 1024,
+ LOOKUP_BEST_REFRESH);
+ if (i == -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes left\n");
+ ARKFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes found\n");
+ ARKFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86SetCrtcForModes(pScrn, 0);
+ pScrn->currentMode = pScrn->modes;
+ xf86PrintModes(pScrn);
+ xf86SetDpi(pScrn, 0, 0);
+
+ xf86LoadSubModule(pScrn, "fb");
+ xf86LoaderReqSymbols("fbScreenInit", NULL);
+
+ if (!pARK->NoAccel) {
+ xf86LoadSubModule(pScrn, "xaa");
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ return TRUE;
+}
+}
+
+static Bool ARKScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
+ char **argv)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ ARKPtr pARK = ARKPTR(pScrn);
+ BoxRec MemBox;
+ int i;
+
+ pScrn->fbOffset = 0;
+
+ if (!ARKMapMem(pScrn)) {
+ ARKFreeRec(pScrn);
+ return FALSE;
+ }
+
+ ARKSave(pScrn);
+
+/* vgaHWBlankScreen(pScrn, TRUE); */
+
+ if (!ARKModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ ARKSaveScreen(pScreen, SCREEN_SAVER_ON);
+
+ pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ 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;
+ }
+
+ if (!fbScreenInit(pScreen, pARK->FBBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth, pScrn->bitsPerPixel))
+ return FALSE;
+
+ 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;
+ }
+ }
+ }
+
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ if (!pARK->NoAccel) {
+ if (ARKAccelInit(pScreen)) {
+ xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n");
+ } else {
+ xf86DrvMsg(scrnIndex, X_ERROR, "Acceleration initialization failed\n");
+ xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n");
+ }
+ } else {
+ xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n");
+ }
+
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ if (!xf86HandleColormaps(pScreen, 256, 8, ARKLoadPalette, NULL,
+ CMAP_RELOAD_ON_MODE_SWITCH))
+ return FALSE;
+
+/* vgaHWBlankScreen(pScrn, TRUE); */
+
+ pScreen->SaveScreen = ARKSaveScreen;
+ pARK->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = ARKCloseScreen;
+
+ return TRUE;
+}
+
+
+
+static void ARKSave(ScrnInfoPtr pScrn)
+{
+ ARKPtr pARK = ARKPTR(pScrn);
+ ARKRegPtr save = &pARK->SavedRegs;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ int vgaIOBase = hwp->IOBase;
+
+ vgaHWUnlock(hwp);
+ vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL);
+ vgaHWLock(hwp);
+
+ /* set read and write aperture index to 0 */
+ wrinx(0x3c4, 0x15, 0x00);
+ wrinx(0x3c4, 0x16, 0x00);
+ outb(0x3c8, 0); /* reset DAC register access mode */
+
+ save->sr10 = rdinx(0x3c4, 0x10);
+ save->sr11 = rdinx(0x3c4, 0x11);
+ save->sr12 = rdinx(0x3c4, 0x12);
+ save->sr13 = rdinx(0x3c4, 0x13);
+ save->sr14 = rdinx(0x3c4, 0x14);
+ save->sr15 = rdinx(0x3c4, 0x15);
+ save->sr16 = rdinx(0x3c4, 0x16);
+ save->sr17 = rdinx(0x3c4, 0x17);
+ save->sr18 = rdinx(0x3c4, 0x18);
+
+#if 0
+ save->sr1d = rdinx(0x3c4, 0x1d);
+ save->sr1c = rdinx(0x3c4, 0x1c);
+
+ save->sr20 = rdinx(0x3c4, 0x20);
+ save->sr21 = rdinx(0x3c4, 0x21);
+ save->sr22 = rdinx(0x3c4, 0x22);
+ save->sr23 = rdinx(0x3c4, 0x23);
+ save->sr24 = rdinx(0x3c4, 0x24);
+ save->sr25 = rdinx(0x3c4, 0x25);
+ save->sr26 = rdinx(0x3c4, 0x26);
+ save->sr27 = rdinx(0x3c4, 0x27);
+ save->sr29 = rdinx(0x3c4, 0x29);
+ save->sr2a = rdinx(0x3c4, 0x2a);
+ if ((pARK->Chipset == PCI_CHIP_2000PV) ||
+ (pARK->Chipset == PCI_CHIP_2000MT)) {
+ save->sr28 = rdinx(0x3c4, 0x28);
+ save->sr2b = rdinx(0x3c4, 0x2b);
+ }
+#endif
+
+ save->cr40 = rdinx(vgaIOBase + 4, 0x40);
+ save->cr41 = rdinx(vgaIOBase + 4, 0x41);
+ save->cr42 = rdinx(vgaIOBase + 4, 0x42);
+ save->cr44 = rdinx(vgaIOBase + 4, 0x44);
+
+ if ((pARK->Chipset == PCI_CHIP_2000PV) ||
+ (pARK->Chipset == PCI_CHIP_2000MT))
+ save->cr46 = rdinx(vgaIOBase + 4, 0x46);
+
+ /* save RAMDAC regs here, based on type */
+ save->dac_command = get_daccomm();
+}
+
+
+
+static Bool ARKModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ ARKPtr pARK = ARKPTR(pScrn);
+ ARKRegPtr new = &pARK->ModeRegs;
+ int multiplexing, dac16, modepitch;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr pVga = &hwp->ModeReg;
+ int vgaIOBase = hwp->IOBase;
+ unsigned char tmp;
+ int offset;
+
+ multiplexing = 0;
+
+ if ((pScrn->bitsPerPixel == 8) && (pARK->dac_width == 16) &&
+ (mode->Clock > pARK->multiplex_threshold))
+ multiplexing = 1;
+
+ if (pARK->clock_mult == 2) {
+ if (!mode->CrtcHAdjusted) {
+ mode->CrtcHDisplay <<= 1;
+ mode->CrtcHSyncStart <<= 1;
+ mode->CrtcHSyncEnd <<= 1;
+ mode->CrtcHTotal <<= 1;
+ mode->CrtcHSkew <<= 1;
+ mode->CrtcHAdjusted = TRUE;
+ }
+ }
+
+ if (multiplexing) {
+ if (!mode->CrtcHAdjusted) {
+ mode->CrtcHDisplay >>= 1;
+ mode->CrtcHSyncStart >>= 1;
+ mode->CrtcHSyncEnd >>= 1;
+ mode->CrtcHTotal >>= 1;
+ mode->CrtcHSkew >>= 1;
+ mode->CrtcHAdjusted = TRUE;
+ }
+ }
+
+ if (!vgaHWInit(pScrn, mode))
+ return FALSE;
+
+ if ((pARK->Chipset == PCI_CHIP_2000PV) ||
+ (pARK->Chipset == PCI_CHIP_2000MT)) {
+ new->cr46 = rdinx(vgaIOBase + 4, 0x46) & ~0x04;
+ dac16 = 0;
+ if (pScrn->bitsPerPixel > 8)
+ dac16 = 1;
+ if (dac16)
+ new->cr46 |= 0x04;
+ }
+
+ offset = (pScrn->displayWidth * (pScrn->bitsPerPixel / 8)) >> 3;
+ pVga->CRTC[0x13] = offset;
+ pVga->Attribute[0x11] = 0x00;
+ new->cr41 = (offset & 0x100) >> 5;
+
+ pVga->MiscOutReg |= 0x0c;
+
+ new->sr11 = rdinx(0x3c4, 0x11) & ~0x0f;
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ new->sr11 |= 0x06;
+ break;
+ case 16:
+ new->sr11 |= 0x0a;
+ break;
+ case 24:
+ new->sr11 |= 0x06;
+ break;
+ case 32:
+ if ((pARK->Chipset == PCI_CHIP_2000PV) ||
+ (pARK->Chipset == PCI_CHIP_2000MT))
+ new->sr11 |= 0x0e;
+ else
+ new->sr11 |= 0x0a;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unsupported screen depth %d\n",
+ pScrn->bitsPerPixel);
+ return FALSE;
+ }
+
+ switch (pScrn->displayWidth) {
+ case 640:
+ modepitch = 0;
+ break;
+ case 800:
+ modepitch = 1;
+ break;
+ case 1024:
+ modepitch = 2;
+ break;
+ case 1280:
+ modepitch = 4;
+ break;
+ case 1600:
+ modepitch = 5;
+ break;
+ case 2048:
+ modepitch = 6;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unsupported screen width %d\n",
+ pScrn->displayWidth);
+ return FALSE;
+ }
+
+ new->sr17 &= ~0xc7;
+ new->sr17 |= modepitch;
+
+ new->sr10 = rdinx(0x3c4, 0x10) & ~0x1f;
+ new->sr10 |= 0x1f;
+
+ new->sr13 = pARK->FBAddress >> 16;
+ new->sr14 = pARK->FBAddress >> 24;
+
+ new->sr12 = rdinx(0x3c4, 0x12) & ~0x03;
+ switch (pScrn->videoRam) {
+ case 1024:
+ new->sr12 |= 0x01;
+ break;
+ case 2048:
+ new->sr12 |= 0x02;
+ break;
+ case 4096:
+ new->sr12 |= 0x03;
+ break;
+ default:
+ new->sr12 |= 0x01;
+ break;
+ }
+
+ new->sr15 = new->sr16 = 0;
+
+ tmp = 0;
+ if ((mode->CrtcVTotal - 2) & 0x400)
+ tmp |= 0x80;
+ if ((mode->CrtcVDisplay - 1) & 0x400)
+ tmp |= 0x40;
+ if (mode->CrtcVSyncStart & 0x400)
+ tmp |= 0x10;
+ new->cr40 = tmp;
+
+ tmp = new->cr41; /* initialized earlier */
+ if ((mode->CrtcHTotal / 8 - 5) & 0x100)
+ tmp |= 0x80;
+ if ((mode->CrtcHDisplay / 8 - 1) & 0x100)
+ tmp |= 0x40;
+ if ((mode->CrtcHSyncStart / 8 - 1) & 0x100)
+ tmp |= 0x20;
+ if ((mode->CrtcHSyncStart / 8) & 0x100)
+ tmp |= 0x10;
+ new->cr41 |= tmp;
+
+ new->cr44 = rdinx(vgaIOBase + 4, 0x44) & ~0x34;
+ new->cr44 &= ~0x01;
+ new->cr42 = 0;
+
+ /* check interlace here later */
+
+ /* set display FIFO threshold */
+ {
+ int threshold;
+ unsigned char tmp;
+ int bandwidthused, percentused;
+
+ /* mostly guesses here as I would need to know more about
+ * and from the ramdac...
+ */
+ bandwidthused = (mode->Clock / pARK->clock_mult) *
+ (pScrn->bitsPerPixel / 8);
+ /* 120000 is another guess */
+ percentused = (bandwidthused * 100) / 120000;
+ tmp = rdinx(0x3c4, 0x18);
+ if (pARK->Chipset == PCI_CHIP_1000PV) {
+ threshold = 4;
+ tmp |= 0x08; /* enable full FIFO (8 deep) */
+ tmp &= ~0x07;
+ tmp |= threshold;
+ }
+ if ((pARK->Chipset == PCI_CHIP_2000PV) ||
+ (pARK->Chipset == PCI_CHIP_2000MT)) {
+ threshold = 12;
+ if (percentused >= 45)
+ threshold = 8;
+ if (percentused >= 70)
+ threshold = 4;
+ tmp &= 0x40;
+ tmp |= 0x10;
+ tmp |= (threshold & 0x0e) >> 1;
+ if (threshold & 0x01)
+ tmp |= 0x80;
+ if (threshold & 0x10)
+ tmp |= 0x20;
+ }
+ new->sr18 = tmp;
+ }
+
+ /* setup the RAMDAC regs */
+ if (pARK->ramdac == ZOOMDAC) {
+ new->dac_command = 0x04;
+ if ((pScrn->bitsPerPixel == 8) && multiplexing)
+ new->dac_command = 0x24;
+ if ((pScrn->bitsPerPixel == 16) && (pARK->dac_width == 16))
+ /* assuming green weight is not 5 */
+ new->dac_command = 0x34;
+ if ((pScrn->bitsPerPixel == 16) && (pARK->dac_width == 8))
+ new->dac_command = 0x64;
+ if ((pScrn->bitsPerPixel == 24) && (pARK->dac_width == 16))
+ new->dac_command = 0xb4; /* packed */
+ if ((pScrn->bitsPerPixel == 32) && (pARK->dac_width == 16))
+ new->dac_command = 0x54;
+ } else if (pARK->ramdac == ATT490) {
+ new->dac_command = 0x00;
+ if (pScrn->bitsPerPixel == 16)
+ /* assuming green weight is 6 */
+ new->dac_command = 0xc0;
+ if (pScrn->bitsPerPixel == 24)
+ new->dac_command = 0xe0;
+ }
+
+ /* hrmm... */
+ new->dac_command |= 0x02;
+
+#if 0
+ /* hw cursor regs */
+ new->sr20 = rdinx(0x3c4, 0x20);
+ new->sr21 = rdinx(0x3c4, 0x21);
+ new->sr22 = rdinx(0x3c4, 0x22);
+ new->sr23 = rdinx(0x3c4, 0x23);
+ new->sr24 = rdinx(0x3c4, 0x24);
+ new->sr25 = rdinx(0x3c4, 0x25);
+ new->sr26 = rdinx(0x3c4, 0x26);
+ new->sr27 = rdinx(0x3c4, 0x27);
+ new->sr29 = rdinx(0x3c4, 0x29);
+ new->sr2a = rdinx(0x3c4, 0x2a);
+ if ((pARK->Chipset == PCI_CHIP_2000PV) ||
+ (pARK->Chipset == PCI_CHIP_2000MT)) {
+ new->sr28 = rdinx(0x3c4, 0x28);
+ new->sr2b = rdinx(0x3c4, 0x3b);
+ }
+#endif
+
+
+ ARKWriteMode(pScrn, pVga, new);
+
+ return TRUE;
+}
+
+
+static void ARKAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ ARKPtr pARK = ARKPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ int vgaIOBase = hwp->IOBase;
+ int base;
+
+ base = ((y * pScrn->displayWidth + x) *
+ (pScrn->bitsPerPixel / 8));
+
+ if (((pARK->Chipset == PCI_CHIP_2000PV) ||
+ (pARK->Chipset == PCI_CHIP_2000MT)) &&
+ (pScrn->videoRam >= 2048))
+ base >>= 3;
+ else
+ base >>= 2;
+ if (pScrn->bitsPerPixel == 24)
+ base -= base % 3;
+
+ outw(vgaIOBase + 4, (base & 0x00ff00) | 0x0c);
+ outw(vgaIOBase + 4, ((base & 0x00ff) << 8) | 0x0d);
+
+ modinx(vgaIOBase + 4, 0x40, 0x07, (base & 0x070000) >> 16);
+}
+
+
+
+static void ARKWriteMode(ScrnInfoPtr pScrn, vgaRegPtr pVga, ARKRegPtr new)
+{
+ ARKPtr pARK = ARKPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ int vgaIOBase = hwp->IOBase;
+
+ vgaHWProtect(pScrn, TRUE);
+
+ /* set read and write aperture index to 0 */
+ wrinx(0x3c4, 0x15, 0x00);
+ wrinx(0x3c4, 0x16, 0x00);
+
+ /* write the extended registers first so that textmode font
+ * restoration can suceed
+ */
+ wrinx(0x3c4, 0x10, new->sr10);
+ modinx(0x3c4, 0x11, 0x3f, new->sr11);
+ wrinx(0x3c4, 0x12, new->sr12);
+ wrinx(0x3c4, 0x13, new->sr13);
+ wrinx(0x3c4, 0x14, new->sr14);
+ wrinx(0x3c4, 0x15, new->sr15);
+ wrinx(0x3c4, 0x16, new->sr16);
+ wrinx(0x3c4, 0x17, new->sr17);
+
+#if 0
+ wrinx(0x3c4, 0x1c, new->sr1c);
+ wrinx(0x3c4, 0x1d, new->sr1d);
+
+ /* hw cursor regs */
+ wrinx(0x3c4, 0x20, new->sr20);
+ wrinx(0x3c4, 0x21, new->sr21);
+ wrinx(0x3c4, 0x22, new->sr22);
+ wrinx(0x3c4, 0x23, new->sr23);
+ wrinx(0x3c4, 0x24, new->sr24);
+ wrinx(0x3c4, 0x25, new->sr25);
+ wrinx(0x3c4, 0x26, new->sr26);
+ wrinx(0x3c4, 0x27, new->sr27);
+ wrinx(0x3c4, 0x29, new->sr29);
+ wrinx(0x3c4, 0x2a, new->sr2a);
+#endif
+
+ if ((pARK->Chipset == PCI_CHIP_2000PV) ||
+ (pARK->Chipset == PCI_CHIP_2000MT)) {
+ wrinx(0x3c4, 0x28, new->sr28);
+ wrinx(0x3c4, 0x2B, new->sr2b);
+ }
+
+ wrinx(vgaIOBase + 4, 0x40, new->cr40);
+ wrinx(vgaIOBase + 4, 0x41, new->cr41);
+ wrinx(vgaIOBase + 4, 0x42, new->cr42);
+ wrinx(vgaIOBase + 4, 0x44, new->cr44);
+
+ if ((pARK->Chipset == PCI_CHIP_2000PV) ||
+ (pARK->Chipset == PCI_CHIP_2000MT))
+ wrinx(vgaIOBase + 4, 0x46, new->cr46);
+
+ /* RAMDAC regs */
+ if (pARK->ramdac == ZOOMDAC) {
+ set_daccom(new->dac_command);
+ }
+
+ if (xf86IsPrimaryPci(pARK->PciInfo))
+ vgaHWRestore(pScrn, pVga, VGA_SR_ALL);
+ else
+ vgaHWRestore(pScrn, pVga, VGA_SR_MODE);
+
+ inb(0x3c8);
+ outb(0x3c6, 0xff);
+
+ vgaHWProtect(pScrn, FALSE);
+
+}
+
+
+static Bool ARKEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ if (!ARKModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ ARKAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ return TRUE;
+}
+
+
+
+static void ARKLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ ARKPtr pARK = ARKPTR(pScrn);
+ ARKRegPtr old = &pARK->SavedRegs;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ ARKWriteMode(pScrn, &hwp->ModeReg, old);
+
+ vgaHWUnlock(hwp);
+ vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS);
+ vgaHWLock(hwp);
+
+ return;
+}
+
+
+static Bool ARKMapMem(ScrnInfoPtr pScrn)
+{
+ ARKPtr pARK = ARKPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ /* extended to cover MMIO space at 0xB8000 */
+ hwp->MapSize = 0x20000;
+
+ pARK->MMIOBase = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ 0xb8000, 0x8000);
+
+ pARK->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pARK->PciTag, pARK->FBAddress,
+ pScrn->videoRam * 1024);
+ if (!pARK->FBBase) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Cound not map framebuffer\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+static void ARKUnmapMem(ScrnInfoPtr pScrn)
+{
+ ARKPtr pARK = ARKPTR(pScrn);
+
+ vgaHWUnmapMem(pScrn);
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pARK->FBBase,
+ pScrn->videoRam * 1024);
+
+ return;
+}
+
+
+Bool ARKCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ ARKPtr pARK = ARKPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ if (pScrn->vtSema) {
+ vgaHWUnlock(hwp);
+ ARKWriteMode(pScrn, &hwp->SavedReg, &pARK->SavedRegs);
+ vgaHWLock(hwp);
+ ARKUnmapMem(pScrn);
+ }
+
+ pScrn->vtSema = FALSE;
+ pScreen->CloseScreen = pARK->CloseScreen;
+
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+
+Bool ARKSaveScreen(ScreenPtr pScreen, int mode)
+{
+ return vgaHWSaveScreen(pScreen, mode);
+}
+
+
+Bool ARKSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return ARKModeInit(xf86Screens[scrnIndex], mode);
+}
+
+
+static void ARKLoadPalette(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 void ARKFreeScreen(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ vgaHWFreeHWRec(pScrn);
+
+ ARKFreeRec(pScrn);
+}
+
+
+static unsigned char get_daccomm()
+{
+ unsigned char tmp;
+
+ outb(0x3c8, 0);
+ inb(0x3c6);
+ inb(0x3c6);
+ inb(0x3c6);
+ inb(0x3c6);
+ tmp = inb(0x3c6);
+ outb(0x3c8, 0);
+
+ return tmp;
+}
+
+
+static unsigned char set_daccom(unsigned char comm)
+{
+#if 0
+ outb(0x3c8, 0);
+#else
+ inb(0x3c8);
+#endif
+ inb(0x3c6);
+ inb(0x3c6);
+ inb(0x3c6);
+ inb(0x3c6);
+ outb(0x3c6, comm);
+#if 0
+ outb(0x3c8, 0);
+#else
+ inb(0x3c8);
+#endif
+
+ return inb(0x3c6);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ark/ark_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/ark/ark_reg.h
new file mode 100644
index 000000000..43bb7838f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ark/ark_reg.h
@@ -0,0 +1,88 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ark/ark_reg.h,v 1.1 2000/11/14 17:28:13 dawes Exp $ */
+
+#ifndef _ARK_REG_H
+#define _ARK_REG_H
+
+/* and let there be no 'u' in color */
+#define BG_COLOR 0x00
+#define FG_COLOR 0x02
+#define BG_COLOR_HI 0x04
+#define FG_COLOR_HI 0x06
+#define TRANS_COLOR 0x08
+#define TRANS_COLOR_MSK 0x0a
+#define TRANS_COLOR_HI 0x0c
+#define TRANS_COLOR_MSK_HI 0x0e
+#define COLOR_MIX_SEL 0x18
+#define WRITE_PLANEMASK 0x1a
+#define ERROR_TERM 0x50
+#define AXIAL_ERROR_INC 0x54
+#define STENCIL_PITCH 0x60
+#define SRC_PITCH 0x62
+#define DST_PITCH 0x64
+#define STENCIL_ADDR 0x68
+#define STENCIL_X 0x68
+#define STENCIL_Y 0x6a
+#define SRC_ADDR 0x6c
+#define SRC_X 0x6c
+#define SRC_Y 0x6e
+#define DST_ADDR 0x70
+#define DST_X 0x70
+#define DST_Y 0x72
+#define WIDTH 0x74
+#define HEIGHT 0x76
+#define BITMAP_CONFIG 0x7c
+#define COMMAND 0x7e
+
+
+/* constants for COMMAND register */
+
+#define DRAWSTEP 0x0000
+#define LINEDRAW 0x1000
+#define BITBLT 0x2000
+#define TEXTBITBLT 0x3000
+#define USE_PLANEMASK 0x0000
+#define DISABLE_PLANEMASK 0x0800
+#define PATTERN_8X8 0x0400
+#define SELECT_BG_COLOR 0x0000
+#define BG_BITMAP 0x0200
+#define SELECT_FG_COLOR 0x0000
+#define FG_BITMAP 0x0100
+#define STENCIL_ONES 0x0000
+#define STENCIL_GENERATED 0x0040
+#define STENCIL_BITMAP 0x0080
+#define LINE_DRAWALL 0x0000
+#define LINE_SKIP_FIRST 0x0010
+#define LINE_SKIP_LAST 0x0020
+#define ENABLE_CLIPPING 0x0000
+#define DISABLE_CLIPPING 0x0008
+#undef DOWN
+#define DOWN 0x0000
+#undef UP
+#define UP 0x0002
+#define RIGHT 0x0000
+#define LEFT 0x0004
+#define DX_GREATER_THAN_DY 0x0000
+#define DY_GREATER_THAN_DX 0x0001
+
+
+/* constants for bitmap config register */
+
+#define SWAP_NIBLES 0x2000
+#define SWAP_BITS 0x1000
+#define SYSTEM_STENCIL 0x0200
+#define LINEAR_STENCIL_ADDR 0x0100
+#define SYSTEM_SRC 0x0020
+#define LINEAR_SRC_ADDR 0x0010
+#define SYSTEM_DST 0x0002
+#define LINEAR_DST_ADDR 0x0001
+
+
+/* IO macros */
+
+#define OUTREG16(offset, value) \
+ *(unsigned short *)(pARK->MMIOBase + offset) = value
+#define OUTREG(offset, value) \
+ *(unsigned int *)(pARK->MMIOBase + offset) = value
+
+
+#endif /* _ARK_REG_H */