summaryrefslogtreecommitdiff
path: root/hw/kdrive/src
diff options
context:
space:
mode:
Diffstat (limited to 'hw/kdrive/src')
-rw-r--r--hw/kdrive/src/kcmap.c231
-rw-r--r--hw/kdrive/src/kcolor.c883
-rw-r--r--hw/kdrive/src/kdrive.c872
-rw-r--r--hw/kdrive/src/kdrive.h362
-rw-r--r--hw/kdrive/src/kinfo.c110
-rw-r--r--hw/kdrive/src/kinput.c1331
-rw-r--r--hw/kdrive/src/kkeymap.c235
-rw-r--r--hw/kdrive/src/kkeymap.h53
-rw-r--r--hw/kdrive/src/kloadmap.c200
-rw-r--r--hw/kdrive/src/kmap.c86
-rw-r--r--hw/kdrive/src/knoop.c294
-rw-r--r--hw/kdrive/src/ktest.c76
-rw-r--r--hw/kdrive/src/vga.c288
-rw-r--r--hw/kdrive/src/vga.h132
14 files changed, 5153 insertions, 0 deletions
diff --git a/hw/kdrive/src/kcmap.c b/hw/kdrive/src/kcmap.c
new file mode 100644
index 000000000..ed482a080
--- /dev/null
+++ b/hw/kdrive/src/kcmap.c
@@ -0,0 +1,231 @@
+/*
+ * $Id$
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: $ */
+
+#include "kdrive.h"
+
+/*
+ * Put the entire colormap into the DAC
+ */
+
+void
+KdSetColormap (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ ColormapPtr pCmap = pScreenPriv->pInstalledmap;
+ Pixel pixels[KD_MAX_PSEUDO_SIZE];
+ xrgb colors[KD_MAX_PSEUDO_SIZE];
+ xColorItem defs[KD_MAX_PSEUDO_SIZE];
+ int i;
+
+ if (!pScreenPriv->card->cfuncs->putColors)
+ return;
+ if (pScreenPriv->screen->depth > KD_MAX_PSEUDO_DEPTH)
+ return;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ if (!pCmap)
+ return;
+
+ /*
+ * Make DIX convert pixels into RGB values -- this handles
+ * true/direct as well as pseudo/static visuals
+ */
+
+ for (i = 0; i < (1 << pScreenPriv->screen->depth); i++)
+ pixels[i] = i;
+
+ QueryColors (pCmap, (1 << pScreenPriv->screen->depth), pixels, colors);
+
+ for (i = 0; i < (1 << pScreenPriv->screen->depth); i++)
+ {
+ defs[i].pixel = i;
+ defs[i].red = colors[i].red;
+ defs[i].green = colors[i].green;
+ defs[i].blue = colors[i].blue;
+ defs[i].flags = DoRed|DoGreen|DoBlue;
+ }
+
+ (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen,
+ (1 << pScreenPriv->screen->depth),
+ defs);
+
+ /* recolor hardware cursor */
+ if (pScreenPriv->card->cfuncs->recolorCursor)
+ (*pScreenPriv->card->cfuncs->recolorCursor) (pCmap->pScreen, 0, 0);
+}
+
+/*
+ * When the hardware is enabled, save the hardware colors and store
+ * the current colormap
+ */
+void
+KdEnableColormap (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ int i;
+
+ if (!pScreenPriv->card->cfuncs->putColors)
+ return;
+ if (pScreenPriv->screen->depth <= KD_MAX_PSEUDO_DEPTH)
+ {
+ for (i = 0; i < (1 << pScreenPriv->screen->depth); i++)
+ pScreenPriv->systemPalette[i].pixel = i;
+ (*pScreenPriv->card->cfuncs->getColors) (pScreen,
+ (1 << pScreenPriv->screen->depth),
+ pScreenPriv->systemPalette);
+ }
+ KdSetColormap (pScreen);
+}
+
+void
+KdDisableColormap (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+
+ if (!pScreenPriv->card->cfuncs->putColors)
+ return;
+ if (pScreenPriv->screen->depth > KD_MAX_PSEUDO_DEPTH)
+ return;
+
+ (*pScreenPriv->card->cfuncs->putColors) (pScreen,
+ (1 << pScreenPriv->screen->depth),
+ pScreenPriv->systemPalette);
+}
+
+/*
+ * KdInstallColormap
+ *
+ * This function is called when the server receives a request to install a
+ * colormap or when the server needs to install one on its own, like when
+ * there's no window manager running and the user has moved the pointer over
+ * an X client window. It needs to build an identity Windows palette for the
+ * colormap and realize it into the Windows system palette.
+ */
+void
+KdInstallColormap (ColormapPtr pCmap)
+{
+ KdScreenPriv(pCmap->pScreen);
+
+ if (pCmap == pScreenPriv->pInstalledmap)
+ return;
+
+ /* Tell X clients that the installed colormap is going away. */
+ if (pScreenPriv->pInstalledmap)
+ WalkTree(pScreenPriv->pInstalledmap->pScreen, TellLostMap,
+ (pointer) &(pScreenPriv->pInstalledmap->mid));
+
+ /* Take note of the new installed colorscreen-> */
+ pScreenPriv->pInstalledmap = pCmap;
+
+ KdSetColormap (pCmap->pScreen);
+
+ /* Tell X clients of the new colorscreen-> */
+ WalkTree(pCmap->pScreen, TellGainedMap, (pointer) &(pCmap->mid));
+}
+
+/*
+ * KdUninstallColormap
+ *
+ * This function uninstalls a colormap by installing the default X colorscreen->
+ * The default X colormap itself cannot be uninstalled.
+ */
+void
+KdUninstallColormap (ColormapPtr pCmap)
+{
+ KdScreenPriv(pCmap->pScreen);
+
+ if (pCmap == pScreenPriv->pInstalledmap)
+ {
+ Colormap defMapID = pCmap->pScreen->defColormap;
+
+ if ((Colormap) pCmap->mid != defMapID)
+ {
+ ColormapPtr defMap = (ColormapPtr) LookupIDByType(defMapID,
+ RT_COLORMAP);
+ if (defMap)
+ (*pCmap->pScreen->InstallColormap)(defMap);
+ }
+ }
+}
+
+int
+KdListInstalledColormaps (ScreenPtr pScreen, Colormap *pCmaps)
+{
+ KdScreenPriv(pScreen);
+
+ if (pScreenPriv->pInstalledmap)
+ {
+ *pCmaps = pScreenPriv->pInstalledmap->mid;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * KdStoreColors
+ *
+ * This function is called whenever the server receives a request to store
+ * color values into one or more entries in the currently installed X
+ * colormap; it can be either the default colormap or a private colorscreen->
+ */
+void
+KdStoreColors (ColormapPtr pCmap, int ndef, xColorItem *pdefs)
+{
+ KdScreenPriv(pCmap->pScreen);
+ VisualPtr pVisual;
+ xColorItem expanddefs[KD_MAX_PSEUDO_SIZE];
+
+ if (pCmap != pScreenPriv->pInstalledmap)
+ return;
+
+ if (!pScreenPriv->card->cfuncs->putColors)
+ return;
+
+ if (pScreenPriv->screen->depth > KD_MAX_PSEUDO_DEPTH)
+ return;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ /* Check for DirectColor or TrueColor being simulated on a PseudoColor device. */
+ pVisual = pCmap->pVisual;
+ if ((pVisual->class | DynamicClass) == DirectColor)
+ {
+ /*
+ * Expand DirectColor or TrueColor color values into a PseudoColor
+ * format. Defer to the Color Framebuffer (CFB) code to do that.
+ */
+ ndef = fbExpandDirectColors(pCmap, ndef, pdefs, expanddefs);
+ pdefs = expanddefs;
+ }
+
+ (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen, ndef, pdefs);
+
+ /* recolor hardware cursor */
+ if (pScreenPriv->card->cfuncs->recolorCursor)
+ (*pScreenPriv->card->cfuncs->recolorCursor) (pCmap->pScreen, ndef, pdefs);
+}
diff --git a/hw/kdrive/src/kcolor.c b/hw/kdrive/src/kcolor.c
new file mode 100644
index 000000000..b2ef89e19
--- /dev/null
+++ b/hw/kdrive/src/kcolor.c
@@ -0,0 +1,883 @@
+/*
+ * $Id$
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: $ */
+
+/* $XConsortium: oscolor.c,v 1.23 94/04/17 20:27:04 dpw Exp $ */
+
+#include "kdrive.h"
+#include <stdio.h>
+#include "os.h"
+#include "opaque.h"
+#include <X11/keysym.h>
+
+unsigned char
+KdToLower (unsigned char a)
+{
+ if ((a >= XK_A) && (a <= XK_Z))
+ return a + (XK_a - XK_A);
+ else if ((a >= XK_Agrave) && (a <= XK_Odiaeresis))
+ return a + (XK_agrave - XK_Agrave);
+ else if ((a >= XK_Ooblique) && (a <= XK_Thorn))
+ return a + (XK_oslash - XK_Ooblique);
+ else
+ return a;
+}
+
+int
+KdStrCaseCmp (unsigned char *s1, unsigned char *s2, int l2)
+{
+ unsigned char c1, c2;
+
+ for (;;)
+ {
+ c1 = KdToLower (*s1++);
+ if (l2 == 0)
+ c2 = '\0';
+ else
+ c2 = KdToLower (*s2++);
+ if (!c1 || !c2)
+ break;
+ if (c1 != c2)
+ break;
+ l2--;
+ }
+ return c2 - c1;
+}
+
+typedef struct _kdNamedColor {
+ unsigned short red;
+ unsigned short green;
+ unsigned short blue;
+ unsigned char *name;
+} KdNamedColor;
+
+#define C 0x101
+
+KdNamedColor KdColors[] = {
+240*C, 248*C, 255*C, "alice blue",
+240*C, 248*C, 255*C, "AliceBlue",
+250*C, 235*C, 215*C, "antique white",
+250*C, 235*C, 215*C, "AntiqueWhite",
+255*C, 239*C, 219*C, "AntiqueWhite1",
+238*C, 223*C, 204*C, "AntiqueWhite2",
+205*C, 192*C, 176*C, "AntiqueWhite3",
+139*C, 131*C, 120*C, "AntiqueWhite4",
+127*C, 255*C, 212*C, "aquamarine",
+127*C, 255*C, 212*C, "aquamarine1",
+118*C, 238*C, 198*C, "aquamarine2",
+102*C, 205*C, 170*C, "aquamarine3",
+ 69*C, 139*C, 116*C, "aquamarine4",
+240*C, 255*C, 255*C, "azure",
+240*C, 255*C, 255*C, "azure1",
+224*C, 238*C, 238*C, "azure2",
+193*C, 205*C, 205*C, "azure3",
+131*C, 139*C, 139*C, "azure4",
+245*C, 245*C, 220*C, "beige",
+255*C, 228*C, 196*C, "bisque",
+255*C, 228*C, 196*C, "bisque1",
+238*C, 213*C, 183*C, "bisque2",
+205*C, 183*C, 158*C, "bisque3",
+139*C, 125*C, 107*C, "bisque4",
+ 0*C, 0*C, 0*C, "black",
+255*C, 235*C, 205*C, "blanched almond",
+255*C, 235*C, 205*C, "BlanchedAlmond",
+ 0*C, 0*C, 255*C, "blue",
+138*C, 43*C, 226*C, "blue violet",
+ 0*C, 0*C, 255*C, "blue1",
+ 0*C, 0*C, 238*C, "blue2",
+ 0*C, 0*C, 205*C, "blue3",
+ 0*C, 0*C, 139*C, "blue4",
+138*C, 43*C, 226*C, "BlueViolet",
+165*C, 42*C, 42*C, "brown",
+255*C, 64*C, 64*C, "brown1",
+238*C, 59*C, 59*C, "brown2",
+205*C, 51*C, 51*C, "brown3",
+139*C, 35*C, 35*C, "brown4",
+222*C, 184*C, 135*C, "burlywood",
+255*C, 211*C, 155*C, "burlywood1",
+238*C, 197*C, 145*C, "burlywood2",
+205*C, 170*C, 125*C, "burlywood3",
+139*C, 115*C, 85*C, "burlywood4",
+ 95*C, 158*C, 160*C, "cadet blue",
+ 95*C, 158*C, 160*C, "CadetBlue",
+152*C, 245*C, 255*C, "CadetBlue1",
+142*C, 229*C, 238*C, "CadetBlue2",
+122*C, 197*C, 205*C, "CadetBlue3",
+ 83*C, 134*C, 139*C, "CadetBlue4",
+127*C, 255*C, 0*C, "chartreuse",
+127*C, 255*C, 0*C, "chartreuse1",
+118*C, 238*C, 0*C, "chartreuse2",
+102*C, 205*C, 0*C, "chartreuse3",
+69*C, 139*C, 0*C, "chartreuse4",
+210*C, 105*C, 30*C, "chocolate",
+255*C, 127*C, 36*C, "chocolate1",
+238*C, 118*C, 33*C, "chocolate2",
+205*C, 102*C, 29*C, "chocolate3",
+139*C, 69*C, 19*C, "chocolate4",
+255*C, 127*C, 80*C, "coral",
+255*C, 114*C, 86*C, "coral1",
+238*C, 106*C, 80*C, "coral2",
+205*C, 91*C, 69*C, "coral3",
+139*C, 62*C, 47*C, "coral4",
+100*C, 149*C, 237*C, "cornflower blue",
+100*C, 149*C, 237*C, "CornflowerBlue",
+255*C, 248*C, 220*C, "cornsilk",
+255*C, 248*C, 220*C, "cornsilk1",
+238*C, 232*C, 205*C, "cornsilk2",
+205*C, 200*C, 177*C, "cornsilk3",
+139*C, 136*C, 120*C, "cornsilk4",
+ 0*C, 255*C, 255*C, "cyan",
+ 0*C, 255*C, 255*C, "cyan1",
+ 0*C, 238*C, 238*C, "cyan2",
+ 0*C, 205*C, 205*C, "cyan3",
+ 0*C, 139*C, 139*C, "cyan4",
+0*C, 0*C, 139*C, "dark blue",
+0*C, 139*C, 139*C, "dark cyan",
+184*C, 134*C, 11*C, "dark goldenrod",
+169*C, 169*C, 169*C, "dark gray",
+ 0*C, 100*C, 0*C, "dark green",
+169*C, 169*C, 169*C, "dark grey",
+189*C, 183*C, 107*C, "dark khaki",
+139*C, 0*C, 139*C, "dark magenta",
+ 85*C, 107*C, 47*C, "dark olive green",
+255*C, 140*C, 0*C, "dark orange",
+153*C, 50*C, 204*C, "dark orchid",
+139*C, 0*C, 0*C, "dark red",
+233*C, 150*C, 122*C, "dark salmon",
+143*C, 188*C, 143*C, "dark sea green",
+ 72*C, 61*C, 139*C, "dark slate blue",
+ 47*C, 79*C, 79*C, "dark slate gray",
+ 47*C, 79*C, 79*C, "dark slate grey",
+ 0*C, 206*C, 209*C, "dark turquoise",
+148*C, 0*C, 211*C, "dark violet",
+0*C, 0*C, 139*C, "DarkBlue",
+0*C, 139*C, 139*C, "DarkCyan",
+184*C, 134*C, 11*C, "DarkGoldenrod",
+255*C, 185*C, 15*C, "DarkGoldenrod1",
+238*C, 173*C, 14*C, "DarkGoldenrod2",
+205*C, 149*C, 12*C, "DarkGoldenrod3",
+139*C, 101*C, 8*C, "DarkGoldenrod4",
+169*C, 169*C, 169*C, "DarkGray",
+ 0*C, 100*C, 0*C, "DarkGreen",
+169*C, 169*C, 169*C, "DarkGrey",
+189*C, 183*C, 107*C, "DarkKhaki",
+139*C, 0*C, 139*C, "DarkMagenta",
+ 85*C, 107*C, 47*C, "DarkOliveGreen",
+202*C, 255*C, 112*C, "DarkOliveGreen1",
+188*C, 238*C, 104*C, "DarkOliveGreen2",
+162*C, 205*C, 90*C, "DarkOliveGreen3",
+110*C, 139*C, 61*C, "DarkOliveGreen4",
+255*C, 140*C, 0*C, "DarkOrange",
+255*C, 127*C, 0*C, "DarkOrange1",
+238*C, 118*C, 0*C, "DarkOrange2",
+205*C, 102*C, 0*C, "DarkOrange3",
+139*C, 69*C, 0*C, "DarkOrange4",
+153*C, 50*C, 204*C, "DarkOrchid",
+191*C, 62*C, 255*C, "DarkOrchid1",
+178*C, 58*C, 238*C, "DarkOrchid2",
+154*C, 50*C, 205*C, "DarkOrchid3",
+104*C, 34*C, 139*C, "DarkOrchid4",
+139*C, 0*C, 0*C, "DarkRed",
+233*C, 150*C, 122*C, "DarkSalmon",
+143*C, 188*C, 143*C, "DarkSeaGreen",
+193*C, 255*C, 193*C, "DarkSeaGreen1",
+180*C, 238*C, 180*C, "DarkSeaGreen2",
+155*C, 205*C, 155*C, "DarkSeaGreen3",
+105*C, 139*C, 105*C, "DarkSeaGreen4",
+ 72*C, 61*C, 139*C, "DarkSlateBlue",
+ 47*C, 79*C, 79*C, "DarkSlateGray",
+151*C, 255*C, 255*C, "DarkSlateGray1",
+141*C, 238*C, 238*C, "DarkSlateGray2",
+121*C, 205*C, 205*C, "DarkSlateGray3",
+ 82*C, 139*C, 139*C, "DarkSlateGray4",
+ 47*C, 79*C, 79*C, "DarkSlateGrey",
+ 0*C, 206*C, 209*C, "DarkTurquoise",
+148*C, 0*C, 211*C, "DarkViolet",
+255*C, 20*C, 147*C, "deep pink",
+ 0*C, 191*C, 255*C, "deep sky blue",
+255*C, 20*C, 147*C, "DeepPink",
+255*C, 20*C, 147*C, "DeepPink1",
+238*C, 18*C, 137*C, "DeepPink2",
+205*C, 16*C, 118*C, "DeepPink3",
+139*C, 10*C, 80*C, "DeepPink4",
+ 0*C, 191*C, 255*C, "DeepSkyBlue",
+ 0*C, 191*C, 255*C, "DeepSkyBlue1",
+ 0*C, 178*C, 238*C, "DeepSkyBlue2",
+ 0*C, 154*C, 205*C, "DeepSkyBlue3",
+ 0*C, 104*C, 139*C, "DeepSkyBlue4",
+105*C, 105*C, 105*C, "dim gray",
+105*C, 105*C, 105*C, "dim grey",
+105*C, 105*C, 105*C, "DimGray",
+105*C, 105*C, 105*C, "DimGrey",
+ 30*C, 144*C, 255*C, "dodger blue",
+ 30*C, 144*C, 255*C, "DodgerBlue",
+ 30*C, 144*C, 255*C, "DodgerBlue1",
+ 28*C, 134*C, 238*C, "DodgerBlue2",
+ 24*C, 116*C, 205*C, "DodgerBlue3",
+ 16*C, 78*C, 139*C, "DodgerBlue4",
+178*C, 34*C, 34*C, "firebrick",
+255*C, 48*C, 48*C, "firebrick1",
+238*C, 44*C, 44*C, "firebrick2",
+205*C, 38*C, 38*C, "firebrick3",
+139*C, 26*C, 26*C, "firebrick4",
+255*C, 250*C, 240*C, "floral white",
+255*C, 250*C, 240*C, "FloralWhite",
+ 34*C, 139*C, 34*C, "forest green",
+ 34*C, 139*C, 34*C, "ForestGreen",
+220*C, 220*C, 220*C, "gainsboro",
+248*C, 248*C, 255*C, "ghost white",
+248*C, 248*C, 255*C, "GhostWhite",
+255*C, 215*C, 0*C, "gold",
+255*C, 215*C, 0*C, "gold1",
+238*C, 201*C, 0*C, "gold2",
+205*C, 173*C, 0*C, "gold3",
+139*C, 117*C, 0*C, "gold4",
+218*C, 165*C, 32*C, "goldenrod",
+255*C, 193*C, 37*C, "goldenrod1",
+238*C, 180*C, 34*C, "goldenrod2",
+205*C, 155*C, 29*C, "goldenrod3",
+139*C, 105*C, 20*C, "goldenrod4",
+190*C, 190*C, 190*C, "gray",
+ 0*C, 0*C, 0*C, "gray0",
+ 3*C, 3*C, 3*C, "gray1",
+ 26*C, 26*C, 26*C, "gray10",
+255*C, 255*C, 255*C, "gray100",
+ 28*C, 28*C, 28*C, "gray11",
+ 31*C, 31*C, 31*C, "gray12",
+ 33*C, 33*C, 33*C, "gray13",
+ 36*C, 36*C, 36*C, "gray14",
+ 38*C, 38*C, 38*C, "gray15",
+ 41*C, 41*C, 41*C, "gray16",
+ 43*C, 43*C, 43*C, "gray17",
+ 46*C, 46*C, 46*C, "gray18",
+ 48*C, 48*C, 48*C, "gray19",
+ 5*C, 5*C, 5*C, "gray2",
+ 51*C, 51*C, 51*C, "gray20",
+ 54*C, 54*C, 54*C, "gray21",
+ 56*C, 56*C, 56*C, "gray22",
+ 59*C, 59*C, 59*C, "gray23",
+ 61*C, 61*C, 61*C, "gray24",
+ 64*C, 64*C, 64*C, "gray25",
+ 66*C, 66*C, 66*C, "gray26",
+ 69*C, 69*C, 69*C, "gray27",
+ 71*C, 71*C, 71*C, "gray28",
+ 74*C, 74*C, 74*C, "gray29",
+ 8*C, 8*C, 8*C, "gray3",
+ 77*C, 77*C, 77*C, "gray30",
+ 79*C, 79*C, 79*C, "gray31",
+ 82*C, 82*C, 82*C, "gray32",
+ 84*C, 84*C, 84*C, "gray33",
+ 87*C, 87*C, 87*C, "gray34",
+ 89*C, 89*C, 89*C, "gray35",
+ 92*C, 92*C, 92*C, "gray36",
+ 94*C, 94*C, 94*C, "gray37",
+ 97*C, 97*C, 97*C, "gray38",
+ 99*C, 99*C, 99*C, "gray39",
+ 10*C, 10*C, 10*C, "gray4",
+102*C, 102*C, 102*C, "gray40",
+105*C, 105*C, 105*C, "gray41",
+107*C, 107*C, 107*C, "gray42",
+110*C, 110*C, 110*C, "gray43",
+112*C, 112*C, 112*C, "gray44",
+115*C, 115*C, 115*C, "gray45",
+117*C, 117*C, 117*C, "gray46",
+120*C, 120*C, 120*C, "gray47",
+122*C, 122*C, 122*C, "gray48",
+125*C, 125*C, 125*C, "gray49",
+ 13*C, 13*C, 13*C, "gray5",
+127*C, 127*C, 127*C, "gray50",
+130*C, 130*C, 130*C, "gray51",
+133*C, 133*C, 133*C, "gray52",
+135*C, 135*C, 135*C, "gray53",
+138*C, 138*C, 138*C, "gray54",
+140*C, 140*C, 140*C, "gray55",
+143*C, 143*C, 143*C, "gray56",
+145*C, 145*C, 145*C, "gray57",
+148*C, 148*C, 148*C, "gray58",
+150*C, 150*C, 150*C, "gray59",
+ 15*C, 15*C, 15*C, "gray6",
+153*C, 153*C, 153*C, "gray60",
+156*C, 156*C, 156*C, "gray61",
+158*C, 158*C, 158*C, "gray62",
+161*C, 161*C, 161*C, "gray63",
+163*C, 163*C, 163*C, "gray64",
+166*C, 166*C, 166*C, "gray65",
+168*C, 168*C, 168*C, "gray66",
+171*C, 171*C, 171*C, "gray67",
+173*C, 173*C, 173*C, "gray68",
+176*C, 176*C, 176*C, "gray69",
+ 18*C, 18*C, 18*C, "gray7",
+179*C, 179*C, 179*C, "gray70",
+181*C, 181*C, 181*C, "gray71",
+184*C, 184*C, 184*C, "gray72",
+186*C, 186*C, 186*C, "gray73",
+189*C, 189*C, 189*C, "gray74",
+191*C, 191*C, 191*C, "gray75",
+194*C, 194*C, 194*C, "gray76",
+196*C, 196*C, 196*C, "gray77",
+199*C, 199*C, 199*C, "gray78",
+201*C, 201*C, 201*C, "gray79",
+ 20*C, 20*C, 20*C, "gray8",
+204*C, 204*C, 204*C, "gray80",
+207*C, 207*C, 207*C, "gray81",
+209*C, 209*C, 209*C, "gray82",
+212*C, 212*C, 212*C, "gray83",
+214*C, 214*C, 214*C, "gray84",
+217*C, 217*C, 217*C, "gray85",
+219*C, 219*C, 219*C, "gray86",
+222*C, 222*C, 222*C, "gray87",
+224*C, 224*C, 224*C, "gray88",
+227*C, 227*C, 227*C, "gray89",
+ 23*C, 23*C, 23*C, "gray9",
+229*C, 229*C, 229*C, "gray90",
+232*C, 232*C, 232*C, "gray91",
+235*C, 235*C, 235*C, "gray92",
+237*C, 237*C, 237*C, "gray93",
+240*C, 240*C, 240*C, "gray94",
+242*C, 242*C, 242*C, "gray95",
+245*C, 245*C, 245*C, "gray96",
+247*C, 247*C, 247*C, "gray97",
+250*C, 250*C, 250*C, "gray98",
+252*C, 252*C, 252*C, "gray99",
+ 0*C, 255*C, 0*C, "green",
+173*C, 255*C, 47*C, "green yellow",
+0*C, 255*C, 0*C, "green1",
+0*C, 238*C, 0*C, "green2",
+0*C, 205*C, 0*C, "green3",
+0*C, 139*C, 0*C, "green4",
+173*C, 255*C, 47*C, "GreenYellow",
+190*C, 190*C, 190*C, "grey",
+ 0*C, 0*C, 0*C, "grey0",
+ 3*C, 3*C, 3*C, "grey1",
+ 26*C, 26*C, 26*C, "grey10",
+255*C, 255*C, 255*C, "grey100",
+ 28*C, 28*C, 28*C, "grey11",
+ 31*C, 31*C, 31*C, "grey12",
+ 33*C, 33*C, 33*C, "grey13",
+ 36*C, 36*C, 36*C, "grey14",
+ 38*C, 38*C, 38*C, "grey15",
+ 41*C, 41*C, 41*C, "grey16",
+ 43*C, 43*C, 43*C, "grey17",
+ 46*C, 46*C, 46*C, "grey18",
+ 48*C, 48*C, 48*C, "grey19",
+ 5*C, 5*C, 5*C, "grey2",
+ 51*C, 51*C, 51*C, "grey20",
+ 54*C, 54*C, 54*C, "grey21",
+ 56*C, 56*C, 56*C, "grey22",
+ 59*C, 59*C, 59*C, "grey23",
+ 61*C, 61*C, 61*C, "grey24",
+ 64*C, 64*C, 64*C, "grey25",
+ 66*C, 66*C, 66*C, "grey26",
+ 69*C, 69*C, 69*C, "grey27",
+ 71*C, 71*C, 71*C, "grey28",
+ 74*C, 74*C, 74*C, "grey29",
+ 8*C, 8*C, 8*C, "grey3",
+ 77*C, 77*C, 77*C, "grey30",
+ 79*C, 79*C, 79*C, "grey31",
+ 82*C, 82*C, 82*C, "grey32",
+ 84*C, 84*C, 84*C, "grey33",
+ 87*C, 87*C, 87*C, "grey34",
+ 89*C, 89*C, 89*C, "grey35",
+ 92*C, 92*C, 92*C, "grey36",
+ 94*C, 94*C, 94*C, "grey37",
+ 97*C, 97*C, 97*C, "grey38",
+ 99*C, 99*C, 99*C, "grey39",
+ 10*C, 10*C, 10*C, "grey4",
+102*C, 102*C, 102*C, "grey40",
+105*C, 105*C, 105*C, "grey41",
+107*C, 107*C, 107*C, "grey42",
+110*C, 110*C, 110*C, "grey43",
+112*C, 112*C, 112*C, "grey44",
+115*C, 115*C, 115*C, "grey45",
+117*C, 117*C, 117*C, "grey46",
+120*C, 120*C, 120*C, "grey47",
+122*C, 122*C, 122*C, "grey48",
+125*C, 125*C, 125*C, "grey49",
+ 13*C, 13*C, 13*C, "grey5",
+127*C, 127*C, 127*C, "grey50",
+130*C, 130*C, 130*C, "grey51",
+133*C, 133*C, 133*C, "grey52",
+135*C, 135*C, 135*C, "grey53",
+138*C, 138*C, 138*C, "grey54",
+140*C, 140*C, 140*C, "grey55",
+143*C, 143*C, 143*C, "grey56",
+145*C, 145*C, 145*C, "grey57",
+148*C, 148*C, 148*C, "grey58",
+150*C, 150*C, 150*C, "grey59",
+ 15*C, 15*C, 15*C, "grey6",
+153*C, 153*C, 153*C, "grey60",
+156*C, 156*C, 156*C, "grey61",
+158*C, 158*C, 158*C, "grey62",
+161*C, 161*C, 161*C, "grey63",
+163*C, 163*C, 163*C, "grey64",
+166*C, 166*C, 166*C, "grey65",
+168*C, 168*C, 168*C, "grey66",
+171*C, 171*C, 171*C, "grey67",
+173*C, 173*C, 173*C, "grey68",
+176*C, 176*C, 176*C, "grey69",
+ 18*C, 18*C, 18*C, "grey7",
+179*C, 179*C, 179*C, "grey70",
+181*C, 181*C, 181*C, "grey71",
+184*C, 184*C, 184*C, "grey72",
+186*C, 186*C, 186*C, "grey73",
+189*C, 189*C, 189*C, "grey74",
+191*C, 191*C, 191*C, "grey75",
+194*C, 194*C, 194*C, "grey76",
+196*C, 196*C, 196*C, "grey77",
+199*C, 199*C, 199*C, "grey78",
+201*C, 201*C, 201*C, "grey79",
+ 20*C, 20*C, 20*C, "grey8",
+204*C, 204*C, 204*C, "grey80",
+207*C, 207*C, 207*C, "grey81",
+209*C, 209*C, 209*C, "grey82",
+212*C, 212*C, 212*C, "grey83",
+214*C, 214*C, 214*C, "grey84",
+217*C, 217*C, 217*C, "grey85",
+219*C, 219*C, 219*C, "grey86",
+222*C, 222*C, 222*C, "grey87",
+224*C, 224*C, 224*C, "grey88",
+227*C, 227*C, 227*C, "grey89",
+ 23*C, 23*C, 23*C, "grey9",
+229*C, 229*C, 229*C, "grey90",
+232*C, 232*C, 232*C, "grey91",
+235*C, 235*C, 235*C, "grey92",
+237*C, 237*C, 237*C, "grey93",
+240*C, 240*C, 240*C, "grey94",
+242*C, 242*C, 242*C, "grey95",
+245*C, 245*C, 245*C, "grey96",
+247*C, 247*C, 247*C, "grey97",
+250*C, 250*C, 250*C, "grey98",
+252*C, 252*C, 252*C, "grey99",
+240*C, 255*C, 240*C, "honeydew",
+240*C, 255*C, 240*C, "honeydew1",
+224*C, 238*C, 224*C, "honeydew2",
+193*C, 205*C, 193*C, "honeydew3",
+131*C, 139*C, 131*C, "honeydew4",
+255*C, 105*C, 180*C, "hot pink",
+255*C, 105*C, 180*C, "HotPink",
+255*C, 110*C, 180*C, "HotPink1",
+238*C, 106*C, 167*C, "HotPink2",
+205*C, 96*C, 144*C, "HotPink3",
+139*C, 58*C, 98*C, "HotPink4",
+205*C, 92*C, 92*C, "indian red",
+205*C, 92*C, 92*C, "IndianRed",
+255*C, 106*C, 106*C, "IndianRed1",
+238*C, 99*C, 99*C, "IndianRed2",
+205*C, 85*C, 85*C, "IndianRed3",
+139*C, 58*C, 58*C, "IndianRed4",
+255*C, 255*C, 240*C, "ivory",
+255*C, 255*C, 240*C, "ivory1",
+238*C, 238*C, 224*C, "ivory2",
+205*C, 205*C, 193*C, "ivory3",
+139*C, 139*C, 131*C, "ivory4",
+240*C, 230*C, 140*C, "khaki",
+255*C, 246*C, 143*C, "khaki1",
+238*C, 230*C, 133*C, "khaki2",
+205*C, 198*C, 115*C, "khaki3",
+139*C, 134*C, 78*C, "khaki4",
+230*C, 230*C, 250*C, "lavender",
+255*C, 240*C, 245*C, "lavender blush",
+255*C, 240*C, 245*C, "LavenderBlush",
+255*C, 240*C, 245*C, "LavenderBlush1",
+238*C, 224*C, 229*C, "LavenderBlush2",
+205*C, 193*C, 197*C, "LavenderBlush3",
+139*C, 131*C, 134*C, "LavenderBlush4",
+124*C, 252*C, 0*C, "lawn green",
+124*C, 252*C, 0*C, "LawnGreen",
+255*C, 250*C, 205*C, "lemon chiffon",
+255*C, 250*C, 205*C, "LemonChiffon",
+255*C, 250*C, 205*C, "LemonChiffon1",
+238*C, 233*C, 191*C, "LemonChiffon2",
+205*C, 201*C, 165*C, "LemonChiffon3",
+139*C, 137*C, 112*C, "LemonChiffon4",
+173*C, 216*C, 230*C, "light blue",
+240*C, 128*C, 128*C, "light coral",
+224*C, 255*C, 255*C, "light cyan",
+238*C, 221*C, 130*C, "light goldenrod",
+250*C, 250*C, 210*C, "light goldenrod yellow",
+211*C, 211*C, 211*C, "light gray",
+144*C, 238*C, 144*C, "light green",
+211*C, 211*C, 211*C, "light grey",
+255*C, 182*C, 193*C, "light pink",
+255*C, 160*C, 122*C, "light salmon",
+ 32*C, 178*C, 170*C, "light sea green",
+135*C, 206*C, 250*C, "light sky blue",
+132*C, 112*C, 255*C, "light slate blue",
+119*C, 136*C, 153*C, "light slate gray",
+119*C, 136*C, 153*C, "light slate grey",
+176*C, 196*C, 222*C, "light steel blue",
+255*C, 255*C, 224*C, "light yellow",
+173*C, 216*C, 230*C, "LightBlue",
+191*C, 239*C, 255*C, "LightBlue1",
+178*C, 223*C, 238*C, "LightBlue2",
+154*C, 192*C, 205*C, "LightBlue3",
+104*C, 131*C, 139*C, "LightBlue4",
+240*C, 128*C, 128*C, "LightCoral",
+224*C, 255*C, 255*C, "LightCyan",
+224*C, 255*C, 255*C, "LightCyan1",
+209*C, 238*C, 238*C, "LightCyan2",
+180*C, 205*C, 205*C, "LightCyan3",
+122*C, 139*C, 139*C, "LightCyan4",
+238*C, 221*C, 130*C, "LightGoldenrod",
+255*C, 236*C, 139*C, "LightGoldenrod1",
+238*C, 220*C, 130*C, "LightGoldenrod2",
+205*C, 190*C, 112*C, "LightGoldenrod3",
+139*C, 129*C, 76*C, "LightGoldenrod4",
+250*C, 250*C, 210*C, "LightGoldenrodYellow",
+211*C, 211*C, 211*C, "LightGray",
+144*C, 238*C, 144*C, "LightGreen",
+211*C, 211*C, 211*C, "LightGrey",
+255*C, 182*C, 193*C, "LightPink",
+255*C, 174*C, 185*C, "LightPink1",
+238*C, 162*C, 173*C, "LightPink2",
+205*C, 140*C, 149*C, "LightPink3",
+139*C, 95*C, 101*C, "LightPink4",
+255*C, 160*C, 122*C, "LightSalmon",
+255*C, 160*C, 122*C, "LightSalmon1",
+238*C, 149*C, 114*C, "LightSalmon2",
+205*C, 129*C, 98*C, "LightSalmon3",
+139*C, 87*C, 66*C, "LightSalmon4",
+ 32*C, 178*C, 170*C, "LightSeaGreen",
+135*C, 206*C, 250*C, "LightSkyBlue",
+176*C, 226*C, 255*C, "LightSkyBlue1",
+164*C, 211*C, 238*C, "LightSkyBlue2",
+141*C, 182*C, 205*C, "LightSkyBlue3",
+ 96*C, 123*C, 139*C, "LightSkyBlue4",
+132*C, 112*C, 255*C, "LightSlateBlue",
+119*C, 136*C, 153*C, "LightSlateGray",
+119*C, 136*C, 153*C, "LightSlateGrey",
+176*C, 196*C, 222*C, "LightSteelBlue",
+202*C, 225*C, 255*C, "LightSteelBlue1",
+188*C, 210*C, 238*C, "LightSteelBlue2",
+162*C, 181*C, 205*C, "LightSteelBlue3",
+110*C, 123*C, 139*C, "LightSteelBlue4",
+255*C, 255*C, 224*C, "LightYellow",
+255*C, 255*C, 224*C, "LightYellow1",
+238*C, 238*C, 209*C, "LightYellow2",
+205*C, 205*C, 180*C, "LightYellow3",
+139*C, 139*C, 122*C, "LightYellow4",
+ 50*C, 205*C, 50*C, "lime green",
+ 50*C, 205*C, 50*C, "LimeGreen",
+250*C, 240*C, 230*C, "linen",
+255*C, 0*C, 255*C, "magenta",
+255*C, 0*C, 255*C, "magenta1",
+238*C, 0*C, 238*C, "magenta2",
+205*C, 0*C, 205*C, "magenta3",
+139*C, 0*C, 139*C, "magenta4",
+176*C, 48*C, 96*C, "maroon",
+255*C, 52*C, 179*C, "maroon1",
+238*C, 48*C, 167*C, "maroon2",
+205*C, 41*C, 144*C, "maroon3",
+139*C, 28*C, 98*C, "maroon4",
+102*C, 205*C, 170*C, "medium aquamarine",
+ 0*C, 0*C, 205*C, "medium blue",
+186*C, 85*C, 211*C, "medium orchid",
+147*C, 112*C, 219*C, "medium purple",
+ 60*C, 179*C, 113*C, "medium sea green",
+123*C, 104*C, 238*C, "medium slate blue",
+ 0*C, 250*C, 154*C, "medium spring green",
+ 72*C, 209*C, 204*C, "medium turquoise",
+199*C, 21*C, 133*C, "medium violet red",
+102*C, 205*C, 170*C, "MediumAquamarine",
+ 0*C, 0*C, 205*C, "MediumBlue",
+186*C, 85*C, 211*C, "MediumOrchid",
+224*C, 102*C, 255*C, "MediumOrchid1",
+209*C, 95*C, 238*C, "MediumOrchid2",
+180*C, 82*C, 205*C, "MediumOrchid3",
+122*C, 55*C, 139*C, "MediumOrchid4",
+147*C, 112*C, 219*C, "MediumPurple",
+171*C, 130*C, 255*C, "MediumPurple1",
+159*C, 121*C, 238*C, "MediumPurple2",
+137*C, 104*C, 205*C, "MediumPurple3",
+ 93*C, 71*C, 139*C, "MediumPurple4",
+ 60*C, 179*C, 113*C, "MediumSeaGreen",
+123*C, 104*C, 238*C, "MediumSlateBlue",
+ 0*C, 250*C, 154*C, "MediumSpringGreen",
+ 72*C, 209*C, 204*C, "MediumTurquoise",
+199*C, 21*C, 133*C, "MediumVioletRed",
+ 25*C, 25*C, 112*C, "midnight blue",
+ 25*C, 25*C, 112*C, "MidnightBlue",
+245*C, 255*C, 250*C, "mint cream",
+245*C, 255*C, 250*C, "MintCream",
+255*C, 228*C, 225*C, "misty rose",
+255*C, 228*C, 225*C, "MistyRose",
+255*C, 228*C, 225*C, "MistyRose1",
+238*C, 213*C, 210*C, "MistyRose2",
+205*C, 183*C, 181*C, "MistyRose3",
+139*C, 125*C, 123*C, "MistyRose4",
+255*C, 228*C, 181*C, "moccasin",
+255*C, 222*C, 173*C, "navajo white",
+255*C, 222*C, 173*C, "NavajoWhite",
+255*C, 222*C, 173*C, "NavajoWhite1",
+238*C, 207*C, 161*C, "NavajoWhite2",
+205*C, 179*C, 139*C, "NavajoWhite3",
+139*C, 121*C, 94*C, "NavajoWhite4",
+ 0*C, 0*C, 128*C, "navy",
+ 0*C, 0*C, 128*C, "navy blue",
+ 0*C, 0*C, 128*C, "NavyBlue",
+253*C, 245*C, 230*C, "old lace",
+253*C, 245*C, 230*C, "OldLace",
+107*C, 142*C, 35*C, "olive drab",
+107*C, 142*C, 35*C, "OliveDrab",
+192*C, 255*C, 62*C, "OliveDrab1",
+179*C, 238*C, 58*C, "OliveDrab2",
+154*C, 205*C, 50*C, "OliveDrab3",
+105*C, 139*C, 34*C, "OliveDrab4",
+255*C, 165*C, 0*C, "orange",
+255*C, 69*C, 0*C, "orange red",
+255*C, 165*C, 0*C, "orange1",
+238*C, 154*C, 0*C, "orange2",
+205*C, 133*C, 0*C, "orange3",
+139*C, 90*C, 0*C, "orange4",
+255*C, 69*C, 0*C, "OrangeRed",
+255*C, 69*C, 0*C, "OrangeRed1",
+238*C, 64*C, 0*C, "OrangeRed2",
+205*C, 55*C, 0*C, "OrangeRed3",
+139*C, 37*C, 0*C, "OrangeRed4",
+218*C, 112*C, 214*C, "orchid",
+255*C, 131*C, 250*C, "orchid1",
+238*C, 122*C, 233*C, "orchid2",
+205*C, 105*C, 201*C, "orchid3",
+139*C, 71*C, 137*C, "orchid4",
+238*C, 232*C, 170*C, "pale goldenrod",
+152*C, 251*C, 152*C, "pale green",
+175*C, 238*C, 238*C, "pale turquoise",
+219*C, 112*C, 147*C, "pale violet red",
+238*C, 232*C, 170*C, "PaleGoldenrod",
+152*C, 251*C, 152*C, "PaleGreen",
+154*C, 255*C, 154*C, "PaleGreen1",
+144*C, 238*C, 144*C, "PaleGreen2",
+124*C, 205*C, 124*C, "PaleGreen3",
+84*C, 139*C, 84*C, "PaleGreen4",
+175*C, 238*C, 238*C, "PaleTurquoise",
+187*C, 255*C, 255*C, "PaleTurquoise1",
+174*C, 238*C, 238*C, "PaleTurquoise2",
+150*C, 205*C, 205*C, "PaleTurquoise3",
+102*C, 139*C, 139*C, "PaleTurquoise4",
+219*C, 112*C, 147*C, "PaleVioletRed",
+255*C, 130*C, 171*C, "PaleVioletRed1",
+238*C, 121*C, 159*C, "PaleVioletRed2",
+205*C, 104*C, 137*C, "PaleVioletRed3",
+139*C, 71*C, 93*C, "PaleVioletRed4",
+255*C, 239*C, 213*C, "papaya whip",
+255*C, 239*C, 213*C, "PapayaWhip",
+255*C, 218*C, 185*C, "peach puff",
+255*C, 218*C, 185*C, "PeachPuff",
+255*C, 218*C, 185*C, "PeachPuff1",
+238*C, 203*C, 173*C, "PeachPuff2",
+205*C, 175*C, 149*C, "PeachPuff3",
+139*C, 119*C, 101*C, "PeachPuff4",
+205*C, 133*C, 63*C, "peru",
+255*C, 192*C, 203*C, "pink",
+255*C, 181*C, 197*C, "pink1",
+238*C, 169*C, 184*C, "pink2",
+205*C, 145*C, 158*C, "pink3",
+139*C, 99*C, 108*C, "pink4",
+221*C, 160*C, 221*C, "plum",
+255*C, 187*C, 255*C, "plum1",
+238*C, 174*C, 238*C, "plum2",
+205*C, 150*C, 205*C, "plum3",
+139*C, 102*C, 139*C, "plum4",
+176*C, 224*C, 230*C, "powder blue",
+176*C, 224*C, 230*C, "PowderBlue",
+160*C, 32*C, 240*C, "purple",
+155*C, 48*C, 255*C, "purple1",
+145*C, 44*C, 238*C, "purple2",
+125*C, 38*C, 205*C, "purple3",
+ 85*C, 26*C, 139*C, "purple4",
+255*C, 0*C, 0*C, "red",
+255*C, 0*C, 0*C, "red1",
+238*C, 0*C, 0*C, "red2",
+205*C, 0*C, 0*C, "red3",
+139*C, 0*C, 0*C, "red4",
+188*C, 143*C, 143*C, "rosy brown",
+188*C, 143*C, 143*C, "RosyBrown",
+255*C, 193*C, 193*C, "RosyBrown1",
+238*C, 180*C, 180*C, "RosyBrown2",
+205*C, 155*C, 155*C, "RosyBrown3",
+139*C, 105*C, 105*C, "RosyBrown4",
+ 65*C, 105*C, 225*C, "royal blue",
+ 65*C, 105*C, 225*C, "RoyalBlue",
+ 72*C, 118*C, 255*C, "RoyalBlue1",
+ 67*C, 110*C, 238*C, "RoyalBlue2",
+ 58*C, 95*C, 205*C, "RoyalBlue3",
+ 39*C, 64*C, 139*C, "RoyalBlue4",
+139*C, 69*C, 19*C, "saddle brown",
+139*C, 69*C, 19*C, "SaddleBrown",
+250*C, 128*C, 114*C, "salmon",
+255*C, 140*C, 105*C, "salmon1",
+238*C, 130*C, 98*C, "salmon2",
+205*C, 112*C, 84*C, "salmon3",
+139*C, 76*C, 57*C, "salmon4",
+244*C, 164*C, 96*C, "sandy brown",
+244*C, 164*C, 96*C, "SandyBrown",
+ 46*C, 139*C, 87*C, "sea green",
+ 46*C, 139*C, 87*C, "SeaGreen",
+ 84*C, 255*C, 159*C, "SeaGreen1",
+ 78*C, 238*C, 148*C, "SeaGreen2",
+ 67*C, 205*C, 128*C, "SeaGreen3",
+46*C, 139*C, 87*C, "SeaGreen4",
+255*C, 245*C, 238*C, "seashell",
+255*C, 245*C, 238*C, "seashell1",
+238*C, 229*C, 222*C, "seashell2",
+205*C, 197*C, 191*C, "seashell3",
+139*C, 134*C, 130*C, "seashell4",
+160*C, 82*C, 45*C, "sienna",
+255*C, 130*C, 71*C, "sienna1",
+238*C, 121*C, 66*C, "sienna2",
+205*C, 104*C, 57*C, "sienna3",
+139*C, 71*C, 38*C, "sienna4",
+135*C, 206*C, 235*C, "sky blue",
+135*C, 206*C, 235*C, "SkyBlue",
+135*C, 206*C, 255*C, "SkyBlue1",
+126*C, 192*C, 238*C, "SkyBlue2",
+108*C, 166*C, 205*C, "SkyBlue3",
+ 74*C, 112*C, 139*C, "SkyBlue4",
+106*C, 90*C, 205*C, "slate blue",
+112*C, 128*C, 144*C, "slate gray",
+112*C, 128*C, 144*C, "slate grey",
+106*C, 90*C, 205*C, "SlateBlue",
+131*C, 111*C, 255*C, "SlateBlue1",
+122*C, 103*C, 238*C, "SlateBlue2",
+105*C, 89*C, 205*C, "SlateBlue3",
+ 71*C, 60*C, 139*C, "SlateBlue4",
+112*C, 128*C, 144*C, "SlateGray",
+198*C, 226*C, 255*C, "SlateGray1",
+185*C, 211*C, 238*C, "SlateGray2",
+159*C, 182*C, 205*C, "SlateGray3",
+108*C, 123*C, 139*C, "SlateGray4",
+112*C, 128*C, 144*C, "SlateGrey",
+255*C, 250*C, 250*C, "snow",
+255*C, 250*C, 250*C, "snow1",
+238*C, 233*C, 233*C, "snow2",
+205*C, 201*C, 201*C, "snow3",
+139*C, 137*C, 137*C, "snow4",
+ 0*C, 255*C, 127*C, "spring green",
+ 0*C, 255*C, 127*C, "SpringGreen",
+ 0*C, 255*C, 127*C, "SpringGreen1",
+ 0*C, 238*C, 118*C, "SpringGreen2",
+ 0*C, 205*C, 102*C, "SpringGreen3",
+0*C, 139*C, 69*C, "SpringGreen4",
+ 70*C, 130*C, 180*C, "steel blue",
+ 70*C, 130*C, 180*C, "SteelBlue",
+ 99*C, 184*C, 255*C, "SteelBlue1",
+ 92*C, 172*C, 238*C, "SteelBlue2",
+ 79*C, 148*C, 205*C, "SteelBlue3",
+ 54*C, 100*C, 139*C, "SteelBlue4",
+210*C, 180*C, 140*C, "tan",
+255*C, 165*C, 79*C, "tan1",
+238*C, 154*C, 73*C, "tan2",
+205*C, 133*C, 63*C, "tan3",
+139*C, 90*C, 43*C, "tan4",
+216*C, 191*C, 216*C, "thistle",
+255*C, 225*C, 255*C, "thistle1",
+238*C, 210*C, 238*C, "thistle2",
+205*C, 181*C, 205*C, "thistle3",
+139*C, 123*C, 139*C, "thistle4",
+255*C, 99*C, 71*C, "tomato",
+255*C, 99*C, 71*C, "tomato1",
+238*C, 92*C, 66*C, "tomato2",
+205*C, 79*C, 57*C, "tomato3",
+139*C, 54*C, 38*C, "tomato4",
+ 64*C, 224*C, 208*C, "turquoise",
+ 0*C, 245*C, 255*C, "turquoise1",
+ 0*C, 229*C, 238*C, "turquoise2",
+ 0*C, 197*C, 205*C, "turquoise3",
+ 0*C, 134*C, 139*C, "turquoise4",
+238*C, 130*C, 238*C, "violet",
+208*C, 32*C, 144*C, "violet red",
+208*C, 32*C, 144*C, "VioletRed",
+255*C, 62*C, 150*C, "VioletRed1",
+238*C, 58*C, 140*C, "VioletRed2",
+205*C, 50*C, 120*C, "VioletRed3",
+139*C, 34*C, 82*C, "VioletRed4",
+245*C, 222*C, 179*C, "wheat",
+255*C, 231*C, 186*C, "wheat1",
+238*C, 216*C, 174*C, "wheat2",
+205*C, 186*C, 150*C, "wheat3",
+139*C, 126*C, 102*C, "wheat4",
+255*C, 255*C, 255*C, "white",
+245*C, 245*C, 245*C, "white smoke",
+245*C, 245*C, 245*C, "WhiteSmoke",
+255*C, 255*C, 0*C, "yellow",
+154*C, 205*C, 50*C, "yellow green",
+255*C, 255*C, 0*C, "yellow1",
+238*C, 238*C, 0*C, "yellow2",
+205*C, 205*C, 0*C, "yellow3",
+139*C, 139*C, 0*C, "yellow4",
+154*C, 205*C, 50*C, "YellowGreen",
+};
+
+#undef C
+
+#define NUM_KD_COLORS (sizeof (KdColors) / sizeof (KdColors[0]))
+
+Bool
+OsInitColors()
+{
+ return TRUE;
+}
+
+Bool
+OsLookupColor(int screen,
+ char *s_name,
+ unsigned int len,
+ unsigned short *pred,
+ unsigned short *pgreen,
+ unsigned short *pblue)
+{
+ KdNamedColor *c;
+ unsigned char *name = (unsigned char *) s_name;
+ int low, mid, high;
+ int r;
+
+ low = 0;
+ high = NUM_KD_COLORS;
+ while (high - low > 0)
+ {
+ mid = (low + high) / 2;
+ c = &KdColors[mid];
+ r = KdStrCaseCmp (c->name, name, len);
+ if (r == 0)
+ {
+ *pred = c->red;
+ *pgreen = c->green;
+ *pblue = c->blue;
+ return TRUE;
+ }
+ if (r < 0)
+ {
+ if (high == mid)
+ break;
+ high = mid;
+ }
+ else
+ {
+ if (low == mid)
+ break;
+ low = mid;
+ }
+ }
+ return FALSE;
+}
diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c
new file mode 100644
index 000000000..b17fb0fc4
--- /dev/null
+++ b/hw/kdrive/src/kdrive.c
@@ -0,0 +1,872 @@
+/*
+ * $Id$
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: $ */
+
+#include "kdrive.h"
+#include <mivalidate.h>
+#include <dixstruct.h>
+
+CARD8 kdBpp[] = { 1, 4, 8, 16, 24, 32 };
+
+#define NUM_KD_BPP (sizeof (kdBpp) / sizeof (kdBpp[0]))
+
+int kdScreenPrivateIndex;
+unsigned long kdGeneration;
+
+Bool kdVideoTest;
+unsigned long kdVideoTestTime;
+Bool kdEmulateMiddleButton;
+Bool kdDisableZaphod;
+Bool kdEnabled;
+Bool kdSwitchPending;
+
+void (*restoreHardware)(void);
+
+/*
+ * Carry arguments from InitOutput through driver initialization
+ * to KdScreenInit
+ */
+
+KdOsFuncs *kdOsFuncs;
+extern WindowPtr *WindowTable;
+
+void
+KdSetRootClip (ScreenPtr pScreen, BOOL enable)
+{
+ WindowPtr pWin = WindowTable[pScreen->myNum];
+ WindowPtr pChild;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ Bool anyMarked;
+ RegionPtr pOldClip, bsExposed;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+ BoxRec box;
+
+ if (WasViewable)
+ {
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ (void) (*pScreen->MarkOverlappedWindows)(pChild,
+ pChild,
+ &pLayerWin);
+ }
+ (*pScreen->MarkWindow) (pWin);
+ anyMarked = TRUE;
+ if (pWin->valdata)
+ {
+ if (HasBorder (pWin))
+ {
+ RegionPtr borderVisible;
+
+ borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ pWin->valdata->before.resized = TRUE;
+ }
+ }
+
+ if (enable)
+ {
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ REGION_RESET(pScreen, &pWin->borderClip, &box);
+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+ }
+ else
+ {
+ REGION_EMPTY(pScreen, &pWin->borderClip);
+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+ }
+
+ ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pWin->backStorage)
+ {
+ pOldClip = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, pOldClip, &pWin->clipList);
+ }
+
+ if (pWin->firstChild)
+ {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
+ pWin->firstChild,
+ (WindowPtr *)NULL);
+ }
+ else
+ {
+ (*pScreen->MarkWindow) (pWin);
+ anyMarked = TRUE;
+ }
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
+ }
+
+ if (pWin->backStorage &&
+ ((pWin->backingStore == Always) || WasViewable))
+ {
+ if (!WasViewable)
+ pOldClip = &pWin->clipList; /* a convenient empty region */
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, 0, 0, pOldClip,
+ pWin->drawable.x, pWin->drawable.y);
+ if (WasViewable)
+ REGION_DESTROY(pScreen, pOldClip);
+ if (bsExposed)
+ {
+ RegionPtr valExposed = NullRegion;
+
+ if (pWin->valdata)
+ valExposed = &pWin->valdata->after.exposed;
+ (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+ if (valExposed)
+ REGION_EMPTY(pScreen, valExposed);
+ REGION_DESTROY(pScreen, bsExposed);
+ }
+ }
+ if (WasViewable)
+ {
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pWin);
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+void
+KdDisableScreen (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+
+ if (!pScreenPriv->enabled)
+ return;
+ KdSetRootClip (pScreen, FALSE);
+ KdDisableColormap (pScreen);
+ if (!pScreenPriv->screen->dumb)
+ (*pScreenPriv->card->cfuncs->disableAccel) (pScreen);
+ if (!pScreenPriv->screen->softCursor)
+ (*pScreenPriv->card->cfuncs->disableCursor) (pScreen);
+ if (pScreenPriv->card->cfuncs->dpms)
+ (*pScreenPriv->card->cfuncs->dpms) (pScreen, KD_DPMS_NORMAL);
+ pScreenPriv->enabled = FALSE;
+ (*pScreenPriv->card->cfuncs->disable) (pScreen);
+}
+
+void
+KdDisableScreens (void)
+{
+ KdCardInfo *card;
+ KdScreenInfo *screen;
+
+ if (kdEnabled)
+ {
+ kdEnabled = FALSE;
+ for (card = kdCardInfo; card; card = card->next)
+ {
+ for (screen = card->screenList; screen; screen = screen->next)
+ if (screen->mynum == card->selected && screen->pScreen)
+ KdDisableScreen (screen->pScreen);
+ if (card->driver)
+ (*card->cfuncs->restore) (card);
+ }
+ (*kdOsFuncs->Disable) ();
+ KdDisableInput ();
+ }
+}
+
+void
+KdEnableScreen (ScreenPtr pScreen)
+{
+ KdScreenPriv (pScreen);
+
+ if (pScreenPriv->enabled)
+ return;
+ (*pScreenPriv->card->cfuncs->enable) (pScreen);
+ pScreenPriv->enabled = TRUE;
+ pScreenPriv->card->selected = pScreenPriv->screen->mynum;
+ if (!pScreenPriv->screen->softCursor)
+ (*pScreenPriv->card->cfuncs->enableCursor) (pScreen);
+ if (!pScreenPriv->screen->dumb)
+ (*pScreenPriv->card->cfuncs->enableAccel) (pScreen);
+ KdEnableColormap (pScreen);
+ KdSetRootClip (pScreen, TRUE);
+ if (pScreenPriv->card->cfuncs->dpms)
+ (*pScreenPriv->card->cfuncs->dpms) (pScreen, pScreenPriv->dpmsState);
+}
+
+void
+KdEnableScreens (void)
+{
+ KdCardInfo *card;
+ KdScreenInfo *screen;
+
+ if (!kdEnabled)
+ {
+ kdEnabled = TRUE;
+ (*kdOsFuncs->Enable) ();
+ for (card = kdCardInfo; card; card = card->next)
+ {
+ (*card->cfuncs->preserve) (card);
+ for (screen = card->screenList; screen; screen = screen->next)
+ if (screen->mynum == card->selected && screen->pScreen)
+ KdEnableScreen (screen->pScreen);
+ }
+ KdEnableInput ();
+ }
+}
+
+void
+KdProcessSwitch (void)
+{
+ if (kdEnabled)
+ KdDisableScreens ();
+ else
+ {
+ KdReleaseAllKeys ();
+ KdEnableScreens ();
+ }
+}
+
+void
+AbortDDX(void)
+{
+ KdDisableScreens ();
+ if (kdOsFuncs)
+ {
+ if (kdEnabled)
+ (*kdOsFuncs->Disable) ();
+ (*kdOsFuncs->Fini) ();
+ }
+}
+
+void
+ddxUseMsg()
+{
+}
+
+void
+ddxGiveUp ()
+{
+ AbortDDX ();
+}
+
+void
+KdParseScreen (KdScreenInfo *screen,
+ char *arg)
+{
+ screen->width = 0;
+ screen->height = 0;
+ screen->depth = 0;
+ screen->rate = 0;
+ if (!arg)
+ return;
+
+ screen->width = atoi(arg);
+ arg = strchr (arg, 'x');
+ if (!arg)
+ return;
+ arg++;
+
+ screen->height = atoi(arg);
+ arg = strchr (arg, 'x');
+ if (!arg)
+ return;
+ arg++;
+
+ screen->depth = atoi(arg);
+ arg = strchr (arg, 'x');
+ if (!arg)
+ return;
+ arg++;
+
+ screen->rate = atoi(arg);
+ arg = strchr (arg, 'x');
+ if (!arg)
+ return;
+ arg++;
+}
+
+Bool kdDumbDriver;
+Bool kdSoftCursor;
+
+int
+ddxProcessArgument (int argc, char **argv, int i)
+{
+ KdCardInfo *card;
+ KdScreenInfo *screen;
+
+ if (!strcmp (argv[i], "-card"))
+ {
+ if ((i+1) < argc)
+ InitCard (argv[i+1]);
+ else
+ UseMsg ();
+ return 2;
+ }
+ if (!strcmp (argv[i], "-screen"))
+ {
+ if ((i+1) < argc)
+ {
+ card = KdCardInfoLast ();
+ if (!card)
+ {
+ InitCard (0);
+ card = KdCardInfoLast ();
+ }
+ screen = KdScreenInfoAdd (card);
+ KdParseScreen (screen, argv[i+1]);
+ screen->dumb = kdDumbDriver;
+ screen->softCursor = kdSoftCursor;
+ kdDumbDriver = FALSE;
+ kdSoftCursor = FALSE;
+ }
+ else
+ UseMsg ();
+ return 2;
+ }
+ if (!strcmp (argv[i], "-zaphod"))
+ {
+ kdDisableZaphod = TRUE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-3button"))
+ {
+ kdEmulateMiddleButton = FALSE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-2button"))
+ {
+ kdEmulateMiddleButton = TRUE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-dumb"))
+ {
+ kdDumbDriver = TRUE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-softCursor"))
+ {
+ kdSoftCursor = TRUE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-videoTest"))
+ {
+ kdVideoTest = TRUE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-standalone"))
+ return 1;
+ return 0;
+}
+
+/*
+ * These are getting tossed in here until I can think of where
+ * they really belong
+ */
+
+void
+KdOsInit (KdOsFuncs *pOsFuncs)
+{
+ kdOsFuncs = pOsFuncs;
+ if (pOsFuncs)
+ {
+ if (serverGeneration == 1)
+ (*pOsFuncs->Init) ();
+ }
+}
+
+Bool
+KdAllocatePrivates (ScreenPtr pScreen)
+{
+ KdPrivScreenPtr pScreenPriv;
+
+ if (kdGeneration != serverGeneration)
+ {
+ kdScreenPrivateIndex = AllocateScreenPrivateIndex();
+ kdGeneration = serverGeneration;
+ }
+ pScreenPriv = (KdPrivScreenPtr) xalloc(sizeof (*pScreenPriv));
+ memset (pScreenPriv, '\0', sizeof (KdPrivScreenRec));
+ if (!pScreenPriv)
+ return FALSE;
+ KdSetScreenPriv (pScreen, pScreenPriv);
+ return TRUE;
+}
+
+Bool
+KdCloseScreen (int index, ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ KdCardInfo *card = pScreenPriv->card;
+ Bool ret;
+
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ ret = (*pScreen->CloseScreen) (index, pScreen);
+
+ if (pScreenPriv->dpmsState != KD_DPMS_NORMAL)
+ (*card->cfuncs->dpms) (pScreen, KD_DPMS_NORMAL);
+
+ if (screen->mynum == card->selected)
+ KdDisableScreen (pScreen);
+
+ /*
+ * Restore video hardware when last screen is closed
+ */
+ if (screen == card->screenList)
+ (*card->cfuncs->restore) (card);
+
+ if (!pScreenPriv->screen->dumb)
+ (*card->cfuncs->finiAccel) (pScreen);
+
+ if (!pScreenPriv->screen->softCursor)
+ (*card->cfuncs->finiCursor) (pScreen);
+
+ (*card->cfuncs->scrfini) (screen);
+
+ /*
+ * Clean up card when last screen is closed, DIX closes them in
+ * reverse order, thus we check for when the first in the list is closed
+ */
+ if (screen == card->screenList)
+ {
+ (*card->cfuncs->cardfini) (card);
+ /*
+ * Clean up OS when last card is closed
+ */
+ if (card == kdCardInfo)
+ {
+ if (kdEnabled)
+ {
+ kdEnabled = FALSE;
+ (*kdOsFuncs->Disable) ();
+ }
+ }
+ }
+
+ pScreenPriv->screen->pScreen = 0;
+
+ xfree ((pointer) pScreenPriv);
+ return ret;
+}
+
+Bool
+KdSaveScreen (ScreenPtr pScreen, int on)
+{
+ KdScreenPriv(pScreen);
+ int dpmsState;
+
+ if (!pScreenPriv->card->cfuncs->dpms)
+ return FALSE;
+
+ dpmsState = pScreenPriv->dpmsState;
+ switch (on) {
+ case SCREEN_SAVER_OFF:
+ dpmsState = KD_DPMS_NORMAL;
+ break;
+ case SCREEN_SAVER_ON:
+ if (dpmsState == KD_DPMS_NORMAL)
+ dpmsState = KD_DPMS_NORMAL+1;
+ break;
+ case SCREEN_SAVER_CYCLE:
+ if (dpmsState < KD_DPMS_MAX)
+ dpmsState++;
+ break;
+ case SCREEN_SAVER_FORCER:
+ break;
+ }
+ if (dpmsState != pScreenPriv->dpmsState)
+ {
+ if (pScreenPriv->enabled)
+ (*pScreenPriv->card->cfuncs->dpms) (pScreen, dpmsState);
+ pScreenPriv->dpmsState = dpmsState;
+ }
+ return TRUE;
+}
+
+Bool
+KdCreateWindow (WindowPtr pWin)
+{
+ if (!pWin->parent)
+ {
+ KdScreenPriv(pWin->drawable.pScreen);
+
+ if (!pScreenPriv->enabled)
+ {
+ REGION_EMPTY (pWin->drawable.pScreen, &pWin->borderClip);
+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+ }
+ }
+ return TRUE;
+}
+
+/* Pass through AddScreen, which doesn't take any closure */
+static KdScreenInfo *kdCurrentScreen;
+
+Bool
+KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
+{
+ KdScreenInfo *screen = kdCurrentScreen;
+ KdCardInfo *card = screen->card;
+ KdPrivScreenPtr pScreenPriv;
+
+ KdAllocatePrivates (pScreen);
+
+ pScreenPriv = KdGetScreenPriv(pScreen);
+
+ screen->pScreen = pScreen;
+ pScreenPriv->screen = screen;
+ pScreenPriv->card = card;
+ pScreenPriv->bytesPerPixel = screen->bitsPerPixel >> 3;
+ pScreenPriv->dpmsState = KD_DPMS_NORMAL;
+
+ /*
+ * This is done in this order so that backing store wraps
+ * our GC functions; fbFinishScreenInit initializes MI
+ * backing store
+ */
+ if (!fbSetupScreen (pScreen,
+ screen->frameBuffer,
+ screen->width, screen->height,
+ screen->dpix, screen->dpiy,
+ screen->pixelStride,
+ screen->bitsPerPixel))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Set colormap functions
+ */
+ pScreen->InstallColormap = KdInstallColormap;
+ pScreen->UninstallColormap = KdUninstallColormap;
+ pScreen->ListInstalledColormaps = KdListInstalledColormaps;
+ pScreen->StoreColors = KdStoreColors;
+
+ pScreen->SaveScreen = KdSaveScreen;
+ pScreen->CreateWindow = KdCreateWindow;
+
+ if (!screen->dumb && card->cfuncs->initAccel)
+ if (!(*card->cfuncs->initAccel) (pScreen))
+ screen->dumb = TRUE;
+
+ if (!fbFinishScreenInit (pScreen,
+ screen->frameBuffer,
+ screen->width, screen->height,
+ screen->dpix, screen->dpiy,
+ screen->pixelStride,
+ screen->bitsPerPixel))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Plug in our own block/wakeup handlers.
+ * miScreenInit installs NoopDDA in both places
+ */
+ pScreen->BlockHandler = KdBlockHandler;
+ pScreen->WakeupHandler = KdWakeupHandler;
+
+ /*
+ * Wrap CloseScreen, the order now is:
+ * KdCloseScreen
+ * miBSCloseScreen
+ * fbCloseScreen
+ */
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = KdCloseScreen;
+
+ if (screen->softCursor ||
+ !card->cfuncs->initCursor ||
+ !(*card->cfuncs->initCursor) (pScreen))
+ {
+ /* Use MI for cursor display and event queueing. */
+ screen->softCursor = TRUE;
+ miDCInitialize(pScreen, &kdPointerScreenFuncs);
+ }
+
+ if (!fbCreateDefColormap (pScreen))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Enable the hardware
+ */
+ if (!kdEnabled)
+ {
+ kdEnabled = TRUE;
+ (*kdOsFuncs->Enable) ();
+ }
+
+ if (screen->mynum == card->selected)
+ {
+ (*card->cfuncs->preserve) (card);
+ (*card->cfuncs->enable) (pScreen);
+ pScreenPriv->enabled = TRUE;
+ if (!screen->softCursor)
+ (*card->cfuncs->enableCursor) (pScreen);
+ KdEnableColormap (pScreen);
+ if (!screen->dumb)
+ (*card->cfuncs->enableAccel) (pScreen);
+ }
+
+ return TRUE;
+}
+
+void
+KdInitScreen (ScreenInfo *pScreenInfo,
+ KdScreenInfo *screen,
+ int argc,
+ char **argv)
+{
+ KdCardInfo *card = screen->card;
+ int i;
+
+ (*card->cfuncs->scrinit) (screen);
+
+ if (!screen->dpix)
+ screen->dpix = 75;
+
+ if (!screen->dpiy)
+ screen->dpiy = 75;
+ if (!card->cfuncs->initAccel)
+ screen->dumb = TRUE;
+ if (!card->cfuncs->initCursor)
+ screen->softCursor = TRUE;
+
+}
+
+Bool
+KdSetPixmapFormats (ScreenInfo *pScreenInfo)
+{
+ CARD8 depthToBpp[33]; /* depth -> bpp map */
+ CARD8 bppToDepth[33]; /* bpp -> depth map */
+ KdCardInfo *card;
+ KdScreenInfo *screen;
+ int i;
+ PixmapFormatRec *format;
+
+ for (i = 1; i <= 32; i++)
+ {
+ depthToBpp[i] = 0;
+ bppToDepth[i] = 0;
+ }
+
+ /*
+ * Generate mappings between bitsPerPixel and depth,
+ * also ensure that all screens comply with protocol
+ * restrictions on equivalent formats for the same
+ * depth on different screens
+ */
+ for (card = kdCardInfo; card; card = card->next)
+ {
+ for (screen = card->screenList; screen; screen = screen->next)
+ {
+ if (!depthToBpp[screen->depth])
+ depthToBpp[screen->depth] = screen->bitsPerPixel;
+ else if (depthToBpp[screen->depth] != screen->bitsPerPixel)
+ return FALSE;
+ if (!bppToDepth[screen->bitsPerPixel])
+ bppToDepth[screen->bitsPerPixel] = screen->depth;
+ }
+ }
+
+ /*
+ * Fill in additional formats
+ */
+ for (i = 0; i < NUM_KD_BPP; i++)
+ if (!bppToDepth[kdBpp[i]] && !depthToBpp[kdBpp[i]])
+ {
+ bppToDepth[kdBpp[i]] = kdBpp[i];
+ depthToBpp[kdBpp[i]] = kdBpp[i];
+ }
+
+ pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
+ pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+ pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+ pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
+
+ pScreenInfo->numPixmapFormats = 0;
+
+ for (i = 1; i <= 32; i++)
+ {
+ if (depthToBpp[i])
+ {
+ format = &pScreenInfo->formats[pScreenInfo->numPixmapFormats++];
+ format->depth = i;
+ format->bitsPerPixel = depthToBpp[i];
+ format->scanlinePad = BITMAP_SCANLINE_PAD;
+ }
+ }
+
+ return TRUE;
+}
+
+void
+KdAddScreen (ScreenInfo *pScreenInfo,
+ KdScreenInfo *screen,
+ int argc,
+ char **argv)
+{
+ int i;
+ /*
+ * Fill in fb visual type masks for this screen
+ */
+ for (i = 0; i < pScreenInfo->numPixmapFormats; i++)
+ {
+ unsigned long visuals;
+ Pixel rm, gm, bm;
+
+ if (pScreenInfo->formats[i].depth == screen->depth)
+ {
+ visuals = screen->visuals;
+ rm = screen->redMask;
+ gm = screen->greenMask;
+ bm = screen->blueMask;
+ }
+ else
+ {
+ visuals = 0;
+ rm = gm = bm = 0;
+ }
+ fbSetVisualTypesAndMasks (pScreenInfo->formats[i].depth,
+ visuals,
+ 8,
+ rm, gm, bm);
+ }
+
+ kdCurrentScreen = screen;
+
+ AddScreen (KdScreenInit, argc, argv);
+}
+
+void
+KdInitOutput (ScreenInfo *pScreenInfo,
+ int argc,
+ char **argv)
+{
+ int i;
+ KdCardInfo *card;
+ KdScreenInfo *screen;
+
+ if (!kdCardInfo)
+ {
+ InitCard (0);
+ card = KdCardInfoLast ();
+ screen = KdScreenInfoAdd (card);
+ KdParseScreen (screen, 0);
+ }
+ /*
+ * Initialize all of the screens for all of the cards
+ */
+ for (card = kdCardInfo; card; card = card->next)
+ {
+ if ((*card->cfuncs->cardinit) (card))
+ {
+ for (screen = card->screenList; screen; screen = screen->next)
+ KdInitScreen (pScreenInfo, screen, argc, argv);
+ }
+ }
+
+ /*
+ * Merge the various pixmap formats together, this can fail
+ * when two screens share depth but not bitsPerPixel
+ */
+ if (!KdSetPixmapFormats (pScreenInfo))
+ return;
+
+ /*
+ * Add all of the screens
+ */
+ for (card = kdCardInfo; card; card = card->next)
+ for (screen = card->screenList; screen; screen = screen->next)
+ KdAddScreen (pScreenInfo, screen, argc, argv);
+}
+
+#ifdef XTESTEXT1
+void
+XTestGenerateEvent(dev_type, keycode, keystate, mousex, mousey)
+ int dev_type;
+ int keycode;
+ int keystate;
+ int mousex;
+ int mousey;
+{
+}
+
+void
+XTestGetPointerPos(fmousex, fmousey)
+ short *fmousex, *fmousey;
+{
+}
+
+void
+XTestJumpPointer(jx, jy, dev_type)
+ int jx;
+ int jy;
+ int dev_type;
+{
+}
+#endif
+
+#ifdef DPMSExtension
+void
+DPMSSet(int level)
+{
+}
+
+int
+DPMSGet (int *level)
+{
+ return -1;
+}
+
+Bool
+DPMSSupported (void)
+{
+ return FALSE;
+}
+#endif
diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h
new file mode 100644
index 000000000..50601d690
--- /dev/null
+++ b/hw/kdrive/src/kdrive.h
@@ -0,0 +1,362 @@
+/*
+ * $Id$
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: $ */
+
+#include <stdio.h>
+#include "X.h"
+#define NEED_EVENTS
+#include "Xproto.h"
+#include "Xos.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mibstore.h"
+#include "colormapst.h"
+#include "gcstruct.h"
+#include "input.h"
+#include "mipointer.h"
+#include "mi.h"
+#include "dix.h"
+#include "fb.h"
+
+extern WindowPtr *WindowTable;
+
+#define KD_DPMS_NORMAL 0
+#define KD_DPMS_STANDBY 1
+#define KD_DPMS_SUSPEND 2
+#define KD_DPMS_POWERDOWN 3
+#define KD_DPMS_MAX KD_DPMS_POWERDOWN
+
+/*
+ * Configuration information per video card
+ */
+#define KD_MAX_CARD_ADDRESS 8
+typedef struct _KdCardAttr {
+ CARD32 io;
+ CARD32 address[KD_MAX_CARD_ADDRESS];
+ int naddr;
+} KdCardAttr;
+
+typedef struct _KdCardInfo {
+ struct _KdCardFuncs *cfuncs;
+ void *closure;
+ KdCardAttr attr;
+ void *driver;
+ struct _KdScreenInfo *screenList;
+ int selected;
+ struct _KdCardInfo *next;
+} KdCardInfo;
+
+extern KdCardInfo *kdCardInfo;
+
+/*
+ * Configuration information per X screen
+ */
+typedef struct _KdScreenInfo {
+ struct _KdScreenInfo *next;
+ KdCardInfo *card;
+ ScreenPtr pScreen;
+ void *driver;
+ CARD8 *frameBuffer;
+ int width;
+ int height;
+ int depth;
+ int rate;
+ int bitsPerPixel;
+ int pixelStride;
+ int byteStride;
+ int dpix, dpiy;
+ unsigned long visuals;
+ Pixel redMask, greenMask, blueMask;
+ Bool dumb;
+ Bool softCursor;
+ int mynum;
+} KdScreenInfo;
+
+typedef struct _KdCardFuncs {
+ Bool (*cardinit) (KdCardInfo *); /* detect and map device */
+ Bool (*scrinit) (KdScreenInfo *);/* initialize screen information */
+ void (*preserve) (KdCardInfo *); /* save graphics card state */
+ void (*enable) (ScreenPtr); /* set up for rendering */
+ Bool (*dpms) (ScreenPtr, int); /* set DPMS screen saver */
+ void (*disable) (ScreenPtr); /* turn off rendering */
+ void (*restore) (KdCardInfo *); /* restore graphics card state */
+ void (*scrfini) (KdScreenInfo *);/* close down screen */
+ void (*cardfini) (KdCardInfo *); /* close down */
+
+ Bool (*initCursor) (ScreenPtr); /* detect and map cursor */
+ void (*enableCursor) (ScreenPtr); /* enable cursor */
+ void (*disableCursor) (ScreenPtr); /* disable cursor */
+ void (*finiCursor) (ScreenPtr); /* close down */
+ void (*recolorCursor) (ScreenPtr, int, xColorItem *);
+
+ Bool (*initAccel) (ScreenPtr);
+ void (*enableAccel) (ScreenPtr);
+ void (*disableAccel) (ScreenPtr);
+ void (*finiAccel) (ScreenPtr);
+
+ void (*getColors) (ScreenPtr, int, xColorItem *);
+ void (*putColors) (ScreenPtr, int, xColorItem *);
+} KdCardFuncs;
+
+#define KD_MAX_PSEUDO_DEPTH 8
+#define KD_MAX_PSEUDO_SIZE (1 << KD_MAX_PSEUDO_DEPTH)
+
+typedef struct {
+ KdScreenInfo *screen;
+ KdCardInfo *card;
+
+ Bool enabled;
+ int bytesPerPixel;
+
+ int dpmsState;
+
+ ColormapPtr pInstalledmap; /* current colormap */
+ xColorItem systemPalette[KD_MAX_PSEUDO_SIZE];/* saved windows colors */
+
+ CloseScreenProcPtr CloseScreen;
+} KdPrivScreenRec, *KdPrivScreenPtr;
+
+typedef struct _KdMouseFuncs {
+ int (*Init) (void);
+ void (*Read) (int);
+ void (*Fini) (int);
+} KdMouseFuncs;
+
+typedef struct _KdKeyboardFuncs {
+ void (*Load) (void);
+ int (*Init) (void);
+ void (*Read) (int);
+ void (*Leds) (int);
+ void (*Bell) (int, int, int);
+ void (*Fini) (int);
+ int LockLed;
+} KdKeyboardFuncs;
+
+typedef struct _KdOsFuncs {
+ int (*Init) (void);
+ void (*Enable) (void);
+ Bool (*SpecialKey) (KeySym);
+ void (*Disable) (void);
+ void (*Fini) (void);
+} KdOsFuncs;
+
+/*
+ * This is the only completely portable way to
+ * compute this info.
+ */
+
+#ifndef BitsPerPixel
+#define BitsPerPixel(d) (\
+ PixmapWidthPaddingInfo[d].notPower2 ? \
+ (PixmapWidthPaddingInfo[d].bytesPerPixel * 8) : \
+ ((1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \
+ (PixmapWidthPaddingInfo[d].padRoundUp+1)))
+#endif
+
+extern int kdScreenPrivateIndex;
+extern unsigned long kdGeneration;
+extern Bool kdEnabled;
+extern Bool kdSwitchPending;
+extern Bool kdEmulateMiddleButton;
+extern Bool kdDisableZaphod;
+extern KdOsFuncs *kdOsFuncs;
+
+#define KdGetScreenPriv(pScreen) ((KdPrivScreenPtr) \
+ (pScreen)->devPrivates[kdScreenPrivateIndex].ptr)
+#define KdSetScreenPriv(pScreen,v) ((pScreen)->devPrivates[kdScreenPrivateIndex].ptr = \
+ (pointer) v)
+#define KdScreenPriv(pScreen) KdPrivScreenPtr pScreenPriv = KdGetScreenPriv(pScreen)
+
+/* knoop.c */
+extern GCOps kdNoopOps;
+
+/* kcmap.c */
+void
+KdSetColormap (ScreenPtr pScreen);
+
+void
+KdEnableColormap (ScreenPtr pScreen);
+
+void
+KdDisableColormap (ScreenPtr pScreen);
+
+void
+KdInstallColormap (ColormapPtr pCmap);
+
+void
+KdUninstallColormap (ColormapPtr pCmap);
+
+int
+KdListInstalledColormaps (ScreenPtr pScreen, Colormap *pCmaps);
+
+void
+KdStoreColors (ColormapPtr pCmap, int ndef, xColorItem *pdefs);
+
+/* kdrive.c */
+extern miPointerScreenFuncRec kdPointerScreenFuncs;
+
+void
+KdSetRootClip (ScreenPtr pScreen, BOOL enable);
+
+void
+KdDisableScreen (ScreenPtr pScreen);
+
+void
+KdDisableScreens (void);
+
+void
+KdEnableScreen (ScreenPtr pScreen);
+
+void
+KdEnableScreens (void);
+
+void
+KdProcessSwitch (void);
+
+void
+KdParseScreen (KdScreenInfo *screen,
+ char *arg);
+
+void
+KdOsInit (KdOsFuncs *pOsFuncs);
+
+Bool
+KdAllocatePrivates (ScreenPtr pScreen);
+
+Bool
+KdCloseScreen (int index, ScreenPtr pScreen);
+
+Bool
+KdSaveScreen (ScreenPtr pScreen, int on);
+
+Bool
+KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv);
+
+void
+KdInitScreen (ScreenInfo *pScreenInfo,
+ KdScreenInfo *screen,
+ int argc,
+ char **argv);
+
+void
+KdInitCard (ScreenInfo *pScreenInfo,
+ KdCardInfo *card,
+ int argc,
+ char **argv);
+
+void
+KdInitOutput (ScreenInfo *pScreenInfo,
+ int argc,
+ char **argv);
+
+
+
+void
+KdInitOutput (ScreenInfo *pScreenInfo,
+ int argc, char **argv);
+
+/* kinfo.c */
+KdCardInfo *
+KdCardInfoAdd (KdCardFuncs *funcs,
+ KdCardAttr *attr,
+ void *closure);
+
+KdCardInfo *
+KdCardInfoLast (void);
+
+void
+KdCardInfoDispose (KdCardInfo *ci);
+
+KdScreenInfo *
+KdScreenInfoAdd (KdCardInfo *ci);
+
+void
+KdScreenInfoDispose (KdScreenInfo *si);
+
+
+/* kinput.c */
+void
+KdInitInput(KdMouseFuncs *, KdKeyboardFuncs *);
+
+void
+KdEnqueueKeyboardEvent(unsigned char scan_code,
+ unsigned char is_up);
+
+#define KD_BUTTON_1 0x01
+#define KD_BUTTON_2 0x02
+#define KD_BUTTON_3 0x04
+#define KD_MOUSE_DELTA 0x80000000
+
+void
+KdEnqueueMouseEvent(unsigned long flags, int x, int y);
+
+void
+KdEnqueueMotionEvent (int x, int y);
+
+void
+KdReleaseAllKeys (void);
+
+void
+KdSetLed (int led, Bool on);
+
+void
+KdBlockHandler (int screen,
+ pointer blockData,
+ pointer timeout,
+ pointer readmask);
+
+void
+KdWakeupHandler (int screen,
+ pointer data,
+ unsigned long result,
+ pointer readmask);
+
+void
+KdDisableInput (void);
+
+void
+KdEnableInput (void);
+
+void
+ProcessInputEvents ();
+
+extern KdMouseFuncs Ps2MouseFuncs;
+extern KdKeyboardFuncs LinuxKeyboardFuncs;
+extern KdOsFuncs LinuxFuncs;
+
+/* kmap.c */
+void *
+KdMapDevice (CARD32 addr, CARD32 size);
+
+void
+KdUnmapDevice (void *addr, CARD32 size);
+
+/* ktest.c */
+Bool
+KdFrameBufferValid (CARD8 *base, int size);
+
+int
+KdFrameBufferSize (CARD8 *base, int max);
diff --git a/hw/kdrive/src/kinfo.c b/hw/kdrive/src/kinfo.c
new file mode 100644
index 000000000..6c5d2cec9
--- /dev/null
+++ b/hw/kdrive/src/kinfo.c
@@ -0,0 +1,110 @@
+/*
+ * $Id$
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: $ */
+
+#include "kdrive.h"
+
+KdCardInfo *kdCardInfo;
+
+KdCardInfo *
+KdCardInfoAdd (KdCardFuncs *funcs,
+ KdCardAttr *attr,
+ void *closure)
+{
+ KdCardInfo *ci, **prev;
+
+ ci = (KdCardInfo *) xalloc (sizeof (KdCardInfo));
+ if (!ci)
+ return 0;
+ bzero (ci, sizeof (KdCardInfo));
+ for (prev = &kdCardInfo; *prev; prev = &(*prev)->next);
+ *prev = ci;
+ ci->cfuncs = funcs;
+ ci->attr = *attr;
+ ci->closure = closure;
+ ci->screenList = 0;
+ ci->selected = 0;
+ ci->next = 0;
+ return ci;
+}
+
+KdCardInfo *
+KdCardInfoLast (void)
+{
+ KdCardInfo *ci;
+
+ if (!kdCardInfo)
+ return 0;
+ for (ci = kdCardInfo; ci->next; ci = ci->next);
+ return ci;
+}
+
+void
+KdCardInfoDispose (KdCardInfo *ci)
+{
+ KdCardInfo **prev;
+
+ for (prev = &kdCardInfo; *prev; prev = &(*prev)->next)
+ if (*prev == ci)
+ {
+ *prev = ci->next;
+ xfree (ci);
+ break;
+ }
+}
+
+KdScreenInfo *
+KdScreenInfoAdd (KdCardInfo *ci)
+{
+ KdScreenInfo *si, **prev;
+ int n;
+
+ si = (KdScreenInfo *) xalloc (sizeof (KdScreenInfo));
+ if (!si)
+ return 0;
+ bzero (si, sizeof (KdScreenInfo));
+ for (prev = &ci->screenList, n = 0; *prev; prev = &(*prev)->next, n++);
+ *prev = si;
+ si->next = 0;
+ si->card = ci;
+ si->mynum = n;
+ return si;
+}
+
+void
+KdScreenInfoDispose (KdScreenInfo *si)
+{
+ KdCardInfo *ci = si->card;
+ KdScreenInfo **prev;
+
+ for (prev = &ci->screenList; *prev; prev = &(*prev)->next)
+ if (*prev == si)
+ {
+ *prev = si->next;
+ xfree (si);
+ if (!ci->screenList)
+ KdCardInfoDispose (ci);
+ break;
+ }
+}
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
new file mode 100644
index 000000000..27207ac1e
--- /dev/null
+++ b/hw/kdrive/src/kinput.c
@@ -0,0 +1,1331 @@
+/*
+ * $Id$
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: $ */
+
+#include "kdrive.h"
+#include "inputstr.h"
+
+#include <X11/keysym.h>
+#include "kkeymap.h"
+#include <signal.h>
+#include <stdio.h>
+
+static DeviceIntPtr pKdKeyboard, pKdPointer;
+
+static KdMouseFuncs *kdMouseFuncs;
+static KdKeyboardFuncs *kdKeyboardFuncs;
+static int kdMouseFd = -1;
+static int kdKeyboardFd = -1;
+static unsigned long kdEmulationTimeout;
+static Bool kdTimeoutPending;
+static int kdBellPitch;
+static int kdBellDuration;
+static int kdLeds;
+
+int kdMinScanCode;
+int kdMaxScanCode;
+int kdMinKeyCode;
+int kdMaxKeyCode;
+int kdKeymapWidth = KD_MAX_WIDTH;
+KeySym kdKeymap[KD_MAX_LENGTH * KD_MAX_WIDTH];
+CARD8 kdModMap[MAP_LENGTH];
+KeySymsRec kdKeySyms;
+
+
+void
+KdResetInputMachine (void);
+
+#define KD_MOUSEBUTTON_COUNT 3
+
+#define KD_KEY_COUNT 248
+
+CARD8 kdKeyState[KD_KEY_COUNT/8];
+
+#define IsKeyDown(key) ((kdKeyState[(key) >> 3] >> ((key) & 7)) & 1)
+
+void
+KdSigio (int sig)
+{
+ if (kdMouseFd >= 0)
+ (*kdMouseFuncs->Read) (kdMouseFd);
+ if (kdKeyboardFd >= 0)
+ (*kdKeyboardFuncs->Read) (kdKeyboardFd);
+}
+
+void
+KdBlockSigio (void)
+{
+ sigset_t set;
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGIO);
+ sigprocmask (SIG_BLOCK, &set, 0);
+}
+
+void
+KdUnblockSigio (void)
+{
+ sigset_t set;
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGIO);
+ sigprocmask (SIG_UNBLOCK, &set, 0);
+}
+
+#define VERIFY_SIGIO
+#ifdef VERIFY_SIGIO
+
+void
+KdAssertSigioBlocked (char *where)
+{
+ sigset_t set, old;
+
+ sigemptyset (&set);
+ sigprocmask (SIG_BLOCK, &set, &old);
+ if (!sigismember (&old, SIGIO))
+ ErrorF ("SIGIO not blocked at %s\n", where);
+}
+
+#else
+
+#define KdVerifySigioBlocked(s)
+
+#endif
+
+static int kdnFds;
+
+#ifdef FNONBLOCK
+#define NOBLOCK FNONBLOCK
+#else
+#define NOBLOCK FNDELAY
+#endif
+
+void
+KdAddFd (int fd)
+{
+ int flags;
+ struct sigaction act;
+ sigset_t set;
+
+ kdnFds++;
+ fcntl (fd, F_SETOWN, getpid());
+ flags = fcntl (fd, F_GETFL);
+ flags |= FASYNC|NOBLOCK;
+ fcntl (fd, F_SETFL, flags);
+ AddEnabledDevice (fd);
+ act.sa_handler = KdSigio;
+ sigemptyset (&act.sa_mask);
+ act.sa_flags = 0;
+ act.sa_restorer = 0;
+ sigaction (SIGIO, &act, 0);
+ sigemptyset (&set);
+ sigprocmask (SIG_SETMASK, &set, 0);
+}
+
+void
+KdRemoveFd (int fd)
+{
+ struct sigaction act;
+ int flags;
+
+ kdnFds--;
+ RemoveEnabledDevice (fd);
+ flags = fcntl (fd, F_GETFL);
+ flags &= ~(FASYNC|NOBLOCK);
+ fcntl (fd, F_SETFL, flags);
+ if (kdnFds == 0)
+ {
+ act.sa_handler = SIG_IGN;
+ sigemptyset (&act.sa_mask);
+ act.sa_flags = 0;
+ act.sa_restorer = 0;
+ sigaction (SIGIO, &act, 0);
+ }
+}
+
+void
+KdDisableInput (void)
+{
+ if (kdMouseFd >= 0)
+ KdRemoveFd (kdMouseFd);
+ if (kdKeyboardFd >= 0)
+ KdRemoveFd (kdKeyboardFd);
+}
+
+void
+KdEnableInput (void)
+{
+ if (kdMouseFd >= 0)
+ KdAddFd (kdMouseFd);
+ if (kdKeyboardFd >= 0)
+ KdAddFd (kdKeyboardFd);
+}
+
+static int
+KdMouseProc(DeviceIntPtr pDevice, int onoff)
+{
+ BYTE map[4];
+ DevicePtr pDev = (DevicePtr)pDevice;
+ int i;
+
+ if (!pDev)
+ return BadImplementation;
+
+ switch (onoff)
+ {
+ case DEVICE_INIT:
+ for (i = 1; i <= KD_MOUSEBUTTON_COUNT; i++)
+ map[i] = i;
+ InitPointerDeviceStruct(pDev, map, KD_MOUSEBUTTON_COUNT,
+ miPointerGetMotionEvents,
+ (PtrCtrlProcPtr)NoopDDA,
+ miPointerGetMotionBufferSize());
+ break;
+
+ case DEVICE_ON:
+ pDev->on = TRUE;
+ pKdPointer = pDevice;
+ if (kdMouseFuncs)
+ {
+ kdMouseFd = (*kdMouseFuncs->Init) ();
+ if (kdMouseFd >= 0)
+ KdAddFd (kdMouseFd);
+ }
+ break;
+ case DEVICE_OFF:
+ case DEVICE_CLOSE:
+ if (pDev->on)
+ {
+ pDev->on = FALSE;
+ pKdPointer = 0;
+ if (kdMouseFd >= 0)
+ {
+ KdRemoveFd (kdMouseFd);
+ (*kdMouseFuncs->Fini) (kdMouseFd);
+ kdMouseFd = -1;
+ }
+ }
+ break;
+ }
+ return Success;
+}
+
+Bool
+LegalModifier(unsigned int key, DevicePtr pDev)
+{
+ return TRUE;
+}
+
+static void
+KdBell (int volume, DeviceIntPtr pDev, pointer ctrl, int something)
+{
+ (*kdKeyboardFuncs->Bell) (volume, kdBellPitch, kdBellDuration);
+}
+
+
+static void
+KdSetLeds (void)
+{
+ (*kdKeyboardFuncs->Leds) (kdLeds);
+}
+
+void
+KdSetLed (int led, Bool on)
+{
+ NoteLedState (pKdKeyboard, led, on);
+ kdLeds = pKdKeyboard->kbdfeed->ctrl.leds;
+ KdSetLeds ();
+}
+
+static void
+KdKbdCtrl (DeviceIntPtr pDevice, KeybdCtrl *ctrl)
+{
+ kdLeds = ctrl->leds;
+ kdBellPitch = ctrl->bell_pitch;
+ kdBellDuration = ctrl->bell_duration;
+ KdSetLeds ();
+}
+
+static int
+KdKeybdProc(DeviceIntPtr pDevice, int onoff)
+{
+ Bool ret;
+ DevicePtr pDev = (DevicePtr)pDevice;
+
+ if (!pDev)
+ return BadImplementation;
+
+ switch (onoff)
+ {
+ case DEVICE_INIT:
+ if (pDev != LookupKeyboardDevice())
+ {
+ return !Success;
+ }
+ ret = InitKeyboardDeviceStruct(pDev,
+ &kdKeySyms,
+ kdModMap,
+ KdBell, KdKbdCtrl);
+ if (!ret)
+ return BadImplementation;
+ break;
+ case DEVICE_ON:
+ pDev->on = TRUE;
+ pKdKeyboard = pDevice;
+ if (kdKeyboardFuncs)
+ {
+ kdKeyboardFd = (*kdKeyboardFuncs->Init) ();
+ if (kdKeyboardFd >= 0)
+ KdAddFd (kdKeyboardFd);
+ }
+ break;
+ case DEVICE_OFF:
+ case DEVICE_CLOSE:
+ pKdKeyboard = 0;
+ if (pDev->on)
+ {
+ pDev->on = FALSE;
+ if (kdKeyboardFd >= 0)
+ {
+ KdRemoveFd (kdKeyboardFd);
+ (*kdKeyboardFuncs->Fini) (kdKeyboardFd);
+ kdKeyboardFd = -1;
+ }
+ }
+ break;
+ }
+ return Success;
+}
+
+extern KeybdCtrl defaultKeyboardControl;
+
+void
+InitAutoRepeats (void)
+{
+ int key_code;
+ unsigned char mask;
+ int i;
+ unsigned char *repeats;
+
+ repeats = defaultKeyboardControl.autoRepeats;
+ memset (repeats, '\0', 32);
+ for (key_code = KD_MIN_KEYCODE; key_code <= KD_MAX_KEYCODE; key_code++)
+ {
+ if (!kdModMap[key_code])
+ {
+ i = key_code >> 3;
+ mask = 1 << (key_code & 7);
+ repeats[i] |= mask;
+ }
+ }
+}
+
+void
+InitModMap (void)
+{
+ int key_code;
+ int row;
+ int width;
+ KeySym *syms;
+
+ width = kdKeySyms.mapWidth;
+ for (key_code = kdMinKeyCode; key_code <= kdMaxKeyCode; key_code++)
+ {
+ kdModMap[key_code] = 0;
+ syms = kdKeymap + (key_code - kdMinKeyCode) * width;
+ for (row = 0; row < width; row++, syms++)
+ {
+ switch (*syms) {
+ case XK_Control_L:
+ case XK_Control_R:
+ kdModMap[key_code] |= ControlMask;
+ break;
+ case XK_Shift_L:
+ case XK_Shift_R:
+ kdModMap[key_code] |= ShiftMask;
+ break;
+ case XK_Caps_Lock:
+ case XK_Shift_Lock:
+ kdModMap[key_code] |= LockMask;
+ break;
+ case XK_Alt_L:
+ case XK_Alt_R:
+ case XK_Meta_L:
+ case XK_Meta_R:
+ kdModMap[key_code] |= Mod1Mask;
+ break;
+ case XK_Num_Lock:
+ kdModMap[key_code] |= Mod2Mask;
+ break;
+ case XK_Super_L:
+ case XK_Super_R:
+ case XK_Hyper_L:
+ case XK_Hyper_R:
+ kdModMap[key_code] |= Mod3Mask;
+ break;
+ case XK_Mode_switch:
+ kdModMap[key_code] |= Mod4Mask;
+ break;
+ }
+ }
+ }
+}
+
+void
+KdInitInput(KdMouseFuncs *pMouseFuncs,
+ KdKeyboardFuncs *pKeyboardFuncs)
+{
+ DeviceIntPtr pKeyboard, pPointer;
+
+ kdMouseFuncs = pMouseFuncs;
+ kdKeyboardFuncs = pKeyboardFuncs;
+ memset (kdKeyState, '\0', sizeof (kdKeyState));
+ if (kdKeyboardFuncs)
+ (*kdKeyboardFuncs->Load) ();
+ kdMinKeyCode = kdMinScanCode + KD_KEY_OFFSET;
+ kdMaxKeyCode = kdMaxScanCode + KD_KEY_OFFSET;
+ kdKeySyms.map = kdKeymap;
+ kdKeySyms.minKeyCode = kdMinKeyCode;
+ kdKeySyms.maxKeyCode = kdMaxKeyCode;
+ kdKeySyms.mapWidth = kdKeymapWidth;
+ kdLeds = 0;
+ kdBellPitch = 1000;
+ kdBellDuration = 200;
+ InitModMap ();
+ InitAutoRepeats ();
+ KdResetInputMachine ();
+ pPointer = AddInputDevice(KdMouseProc, TRUE);
+ pKeyboard = AddInputDevice(KdKeybdProc, TRUE);
+ RegisterPointerDevice(pPointer);
+ RegisterKeyboardDevice(pKeyboard);
+ miRegisterPointerDevice(screenInfo.screens[0], pPointer);
+ mieqInit(&pKeyboard->public, &pPointer->public);
+}
+
+/*
+ * Middle button emulation state machine
+ *
+ * Possible transitions:
+ * Button 1 press v1
+ * Button 1 release ^1
+ * Button 2 press v2
+ * Button 2 release ^2
+ * Button 3 press v3
+ * Button 3 release ^3
+ * Mouse motion <>
+ * Keyboard event k
+ * timeout ...
+ * outside box <->
+ *
+ * States:
+ * start
+ * button_1_pend
+ * button_1_down
+ * button_2_down
+ * button_3_pend
+ * button_3_down
+ * synthetic_2_down_13
+ * synthetic_2_down_3
+ * synthetic_2_down_1
+ *
+ * Transition diagram
+ *
+ * start
+ * v1 -> (hold) (settimeout) button_1_pend
+ * ^1 -> (deliver) start
+ * v2 -> (deliver) button_2_down
+ * ^2 -> (deliever) start
+ * v3 -> (hold) (settimeout) button_3_pend
+ * ^3 -> (deliver) start
+ * <> -> (deliver) start
+ * k -> (deliver) start
+ *
+ * button_1_pend (button 1 is down, timeout pending)
+ * ^1 -> (release) (deliver) start
+ * v2 -> (release) (deliver) button_1_down
+ * ^2 -> (release) (deliver) button_1_down
+ * v3 -> (cleartimeout) (generate v2) synthetic_2_down_13
+ * ^3 -> (release) (deliver) button_1_down
+ * <-> -> (release) (deliver) button_1_down
+ * <> -> (deliver) button_1_pend
+ * k -> (release) (deliver) button_1_down
+ * ... -> (release) button_1_down
+ *
+ * button_1_down (button 1 is down)
+ * ^1 -> (deliver) start
+ * v2 -> (deliver) button_1_down
+ * ^2 -> (deliver) button_1_down
+ * v3 -> (deliver) button_1_down
+ * ^3 -> (deliver) button_1_down
+ * <> -> (deliver) button_1_down
+ * k -> (deliver) button_1_down
+ *
+ * button_2_down (button 2 is down)
+ * v1 -> (deliver) button_2_down
+ * ^1 -> (deliver) button_2_down
+ * ^2 -> (deliver) start
+ * v3 -> (deliver) button_2_down
+ * ^3 -> (deliver) button_2_down
+ * <> -> (deliver) button_2_down
+ * k -> (deliver) button_2_down
+ *
+ * button_3_pend (button 3 is down, timeout pending)
+ * v1 -> (generate v2) synthetic_2_down
+ * ^1 -> (release) (deliver) button_3_down
+ * v2 -> (release) (deliver) button_3_down
+ * ^2 -> (release) (deliver) button_3_down
+ * ^3 -> (release) (deliver) start
+ * <-> -> (release) (deliver) button_3_down
+ * <> -> (deliver) button_3_pend
+ * k -> (release) (deliver) button_3_down
+ * ... -> (release) button_3_down
+ *
+ * button_3_down (button 3 is down)
+ * v1 -> (deliver) button_3_down
+ * ^1 -> (deliver) button_3_down
+ * v2 -> (deliver) button_3_down
+ * ^2 -> (deliver) button_3_down
+ * ^3 -> (deliver) start
+ * <> -> (deliver) button_3_down
+ * k -> (deliver) button_3_down
+ *
+ * synthetic_2_down_13 (button 1 and 3 are down)
+ * ^1 -> (generate ^2) synthetic_2_down_3
+ * v2 -> synthetic_2_down_13
+ * ^2 -> synthetic_2_down_13
+ * ^3 -> (generate ^2) synthetic_2_down_1
+ * <> -> (deliver) synthetic_2_down_13
+ * k -> (deliver) synthetic_2_down_13
+ *
+ * synthetic_2_down_3 (button 3 is down)
+ * v1 -> (deliver) synthetic_2_down_3
+ * ^1 -> (deliver) synthetic_2_down_3
+ * v2 -> synthetic_2_down_3
+ * ^2 -> synthetic_2_down_3
+ * ^3 -> start
+ * <> -> (deliver) synthetic_2_down_3
+ * k -> (deliver) synthetic_2_down_3
+ *
+ * synthetic_2_down_1 (button 1 is down)
+ * ^1 -> start
+ * v2 -> synthetic_2_down_1
+ * ^2 -> synthetic_2_down_1
+ * v3 -> (deliver) synthetic_2_down_1
+ * ^3 -> (deliver) synthetic_2_down_1
+ * <> -> (deliver) synthetic_2_down_1
+ * k -> (deliver) synthetic_2_down_1
+ */
+
+typedef enum _inputState {
+ start,
+ button_1_pend,
+ button_1_down,
+ button_2_down,
+ button_3_pend,
+ button_3_down,
+ synth_2_down_13,
+ synth_2_down_3,
+ synth_2_down_1,
+ num_input_states
+} KdInputState;
+
+typedef enum _inputClass {
+ down_1, up_1,
+ down_2, up_2,
+ down_3, up_3,
+ motion, outside_box,
+ keyboard, timeout,
+ num_input_class
+} KdInputClass;
+
+typedef enum _inputAction {
+ noop,
+ hold,
+ setto,
+ deliver,
+ release,
+ clearto,
+ gen_down_2,
+ gen_up_2
+} KdInputAction;
+
+#define MAX_ACTIONS 2
+
+typedef struct _inputTransition {
+ KdInputAction actions[MAX_ACTIONS];
+ KdInputState nextState;
+} KdInputTransition;
+
+KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
+ /* start */
+ {
+ { { hold, setto }, button_1_pend }, /* v1 */
+ { { deliver, noop }, start }, /* ^1 */
+ { { deliver, noop }, button_2_down }, /* v2 */
+ { { deliver, noop }, start }, /* ^2 */
+ { { hold, setto }, button_3_pend }, /* v3 */
+ { { deliver, noop }, start }, /* ^3 */
+ { { deliver, noop }, start }, /* <> */
+ { { deliver, noop }, start }, /* <-> */
+ { { deliver, noop }, start }, /* k */
+ { { noop, noop }, start }, /* ... */
+ },
+ /* button_1_pend */
+ {
+ { { noop, noop }, button_1_pend }, /* v1 */
+ { { release, deliver }, start }, /* ^1 */
+ { { release, deliver }, button_1_down }, /* v2 */
+ { { release, deliver }, button_1_down }, /* ^2 */
+ { { clearto, gen_down_2 }, synth_2_down_13 }, /* v3 */
+ { { release, deliver }, button_1_down }, /* ^3 */
+ { { deliver, noop }, button_1_pend }, /* <> */
+ { { release, deliver }, button_1_down }, /* <-> */
+ { { release, deliver }, button_1_down }, /* k */
+ { { release, noop }, button_1_down }, /* ... */
+ },
+ /* button_1_down */
+ {
+ { { noop, noop }, button_1_down }, /* v1 */
+ { { deliver, noop }, start }, /* ^1 */
+ { { deliver, noop }, button_1_down }, /* v2 */
+ { { deliver, noop }, button_1_down }, /* ^2 */
+ { { deliver, noop }, button_1_down }, /* v3 */
+ { { deliver, noop }, button_1_down }, /* ^3 */
+ { { deliver, noop }, button_1_down }, /* <> */
+ { { deliver, noop }, button_1_down }, /* <-> */
+ { { deliver, noop }, button_1_down }, /* k */
+ { { noop, noop }, button_1_down }, /* ... */
+ },
+ /* button_2_down */
+ {
+ { { deliver, noop }, button_2_down }, /* v1 */
+ { { deliver, noop }, button_2_down }, /* ^1 */
+ { { noop, noop }, button_2_down }, /* v2 */
+ { { deliver, noop }, start }, /* ^2 */
+ { { deliver, noop }, button_2_down }, /* v3 */
+ { { deliver, noop }, button_2_down }, /* ^3 */
+ { { deliver, noop }, button_2_down }, /* <> */
+ { { deliver, noop }, button_2_down }, /* <-> */
+ { { deliver, noop }, button_2_down }, /* k */
+ { { noop, noop }, button_2_down }, /* ... */
+ },
+ /* button_3_pend */
+ {
+ { { clearto, gen_down_2 }, synth_2_down_13 }, /* v1 */
+ { { release, deliver }, button_3_down }, /* ^1 */
+ { { release, deliver }, button_3_down }, /* v2 */
+ { { release, deliver }, button_3_down }, /* ^2 */
+ { { release, deliver }, button_3_down }, /* v3 */
+ { { release, deliver }, start }, /* ^3 */
+ { { deliver, noop }, button_3_pend }, /* <> */
+ { { release, deliver }, button_3_down }, /* <-> */
+ { { release, deliver }, button_3_down }, /* k */
+ { { release, noop }, button_3_down }, /* ... */
+ },
+ /* button_3_down */
+ {
+ { { deliver, noop }, button_3_down }, /* v1 */
+ { { deliver, noop }, button_3_down }, /* ^1 */
+ { { deliver, noop }, button_3_down }, /* v2 */
+ { { deliver, noop }, button_3_down }, /* ^2 */
+ { { noop, noop }, button_3_down }, /* v3 */
+ { { deliver, noop }, start }, /* ^3 */
+ { { deliver, noop }, button_3_down }, /* <> */
+ { { deliver, noop }, button_3_down }, /* <-> */
+ { { deliver, noop }, button_3_down }, /* k */
+ { { noop, noop }, button_3_down }, /* ... */
+ },
+ /* synthetic_2_down_13 */
+ {
+ { { noop, noop }, synth_2_down_13 }, /* v1 */
+ { { gen_up_2, noop }, synth_2_down_3 }, /* ^1 */
+ { { noop, noop }, synth_2_down_13 }, /* v2 */
+ { { noop, noop }, synth_2_down_13 }, /* ^2 */
+ { { noop, noop }, synth_2_down_13 }, /* v3 */
+ { { gen_up_2, noop }, synth_2_down_1 }, /* ^3 */
+ { { deliver, noop }, synth_2_down_13 }, /* <> */
+ { { deliver, noop }, synth_2_down_13 }, /* <-> */
+ { { deliver, noop }, synth_2_down_13 }, /* k */
+ { { noop, noop }, synth_2_down_13 }, /* ... */
+ },
+ /* synthetic_2_down_3 */
+ {
+ { { deliver, noop }, synth_2_down_3 }, /* v1 */
+ { { deliver, noop }, synth_2_down_3 }, /* ^1 */
+ { { deliver, noop }, synth_2_down_3 }, /* v2 */
+ { { deliver, noop }, synth_2_down_3 }, /* ^2 */
+ { { noop, noop }, synth_2_down_3 }, /* v3 */
+ { { noop, noop }, start }, /* ^3 */
+ { { deliver, noop }, synth_2_down_3 }, /* <> */
+ { { deliver, noop }, synth_2_down_3 }, /* <-> */
+ { { deliver, noop }, synth_2_down_3 }, /* k */
+ { { noop, noop }, synth_2_down_3 }, /* ... */
+ },
+ /* synthetic_2_down_1 */
+ {
+ { { noop, noop }, synth_2_down_1 }, /* v1 */
+ { { noop, noop }, start }, /* ^1 */
+ { { deliver, noop }, synth_2_down_1 }, /* v2 */
+ { { deliver, noop }, synth_2_down_1 }, /* ^2 */
+ { { deliver, noop }, synth_2_down_1 }, /* v3 */
+ { { deliver, noop }, synth_2_down_1 }, /* ^3 */
+ { { deliver, noop }, synth_2_down_1 }, /* <> */
+ { { deliver, noop }, synth_2_down_1 }, /* <-> */
+ { { deliver, noop }, synth_2_down_1 }, /* k */
+ { { noop, noop }, synth_2_down_1 }, /* ... */
+ },
+};
+
+Bool kdEventHeld;
+xEvent kdHeldEvent;
+int kdEmulationDx, kdEmulationDy;
+
+#define EMULATION_WINDOW 10
+#define EMULATION_TIMEOUT 30
+
+#define EventX(e) ((e)->u.keyButtonPointer.rootX)
+#define EventY(e) ((e)->u.keyButtonPointer.rootY)
+
+KdInsideEmulationWindow (xEvent *ev)
+{
+ if (ev->u.keyButtonPointer.pad1)
+ {
+ kdEmulationDx += EventX(ev);
+ kdEmulationDy += EventY(ev);
+ }
+ else
+ {
+ kdEmulationDx = EventX(&kdHeldEvent) - EventX(ev);
+ kdEmulationDy = EventY(&kdHeldEvent) - EventY(ev);
+ }
+ return (abs (kdEmulationDx) < EMULATION_WINDOW &&
+ abs (kdEmulationDy) < EMULATION_WINDOW);
+}
+
+KdInputClass
+KdClassifyInput (xEvent *ev)
+{
+ switch (ev->u.u.type) {
+ case ButtonPress:
+ switch (ev->u.u.detail) {
+ case 1: return down_1;
+ case 2: return down_2;
+ case 3: return down_3;
+ }
+ break;
+ case ButtonRelease:
+ switch (ev->u.u.detail) {
+ case 1: return up_1;
+ case 2: return up_2;
+ case 3: return up_3;
+ }
+ break;
+ case MotionNotify:
+ if (kdEventHeld && !KdInsideEmulationWindow(ev))
+ return outside_box;
+ else
+ return motion;
+ default:
+ return keyboard;
+ }
+}
+
+#ifndef NDEBUG
+char *kdStateNames[] = {
+ "start",
+ "button_1_pend",
+ "button_1_down",
+ "button_2_down",
+ "button_3_pend",
+ "button_3_down",
+ "synth_2_down_13",
+ "synth_2_down_3",
+ "synthetic_2_down_1",
+ "num_input_states"
+};
+
+char *kdClassNames[] = {
+ "down_1", "up_1",
+ "down_2", "up_2",
+ "down_3", "up_3",
+ "motion", "ouside_box",
+ "keyboard", "timeout",
+ "num_input_class"
+};
+
+char *kdActionNames[] = {
+ "noop",
+ "hold",
+ "setto",
+ "deliver",
+ "release",
+ "clearto",
+ "gen_down_2",
+ "gen_up_2",
+};
+#endif
+
+static void
+KdQueueEvent (xEvent *ev)
+{
+ KdAssertSigioBlocked ("KdQueueEvent");
+ if (ev->u.u.type == MotionNotify)
+ {
+ if (ev->u.keyButtonPointer.pad1)
+ {
+ ev->u.keyButtonPointer.pad1 = 0;
+ miPointerDeltaCursor (ev->u.keyButtonPointer.rootX,
+ ev->u.keyButtonPointer.rootY,
+ ev->u.keyButtonPointer.time);
+ }
+ else
+ {
+ miPointerAbsoluteCursor(ev->u.keyButtonPointer.rootX,
+ ev->u.keyButtonPointer.rootY,
+ ev->u.keyButtonPointer.time);
+ }
+ }
+ else
+ {
+ mieqEnqueue (ev);
+ }
+}
+
+KdInputState kdInputState;
+
+static void
+KdRunInputMachine (KdInputClass c, xEvent *ev)
+{
+ KdInputTransition *t;
+ int a;
+
+ t = &kdInputMachine[kdInputState][c];
+ for (a = 0; a < MAX_ACTIONS; a++)
+ {
+ switch (t->actions[a]) {
+ case noop:
+ break;
+ case hold:
+ kdEventHeld = TRUE;
+ kdEmulationDx = 0;
+ kdEmulationDy = 0;
+ kdHeldEvent = *ev;
+ break;
+ case setto:
+ kdEmulationTimeout = GetTimeInMillis () + EMULATION_TIMEOUT;
+ kdTimeoutPending = TRUE;
+ break;
+ case deliver:
+ KdQueueEvent (ev);
+ break;
+ case release:
+ kdEventHeld = FALSE;
+ kdTimeoutPending = FALSE;
+ KdQueueEvent (&kdHeldEvent);
+ break;
+ case clearto:
+ kdTimeoutPending = FALSE;
+ break;
+ case gen_down_2:
+ ev->u.u.detail = 2;
+ kdEventHeld = FALSE;
+ KdQueueEvent (ev);
+ break;
+ case gen_up_2:
+ ev->u.u.detail = 2;
+ KdQueueEvent (ev);
+ break;
+ }
+ }
+ kdInputState = t->nextState;
+}
+
+void
+KdResetInputMachine (void)
+{
+ kdInputState = start;
+ kdEventHeld = FALSE;
+}
+
+void
+KdHandleEvent (xEvent *ev)
+{
+ if (kdEmulateMiddleButton)
+ KdRunInputMachine (KdClassifyInput (ev), ev);
+ else
+ KdQueueEvent (ev);
+}
+
+void
+KdReceiveTimeout (void)
+{
+ KdRunInputMachine (timeout, 0);
+}
+
+#define KILL_SEQUENCE ((1L << KK_CONTROL)|(1L << KK_ALT)|(1L << KK_F8)|(1L << KK_F10))
+#define SPECIAL_SEQUENCE ((1L << KK_CONTROL) | (1L << KK_ALT))
+#define SETKILLKEY(b) (KdSpecialKeys |= (1L << (b)))
+#define CLEARKILLKEY(b) (KdSpecialKeys &= ~(1L << (b)))
+#define KEYMAP (pKdKeyboard->key->curKeySyms)
+#define KEYCOL1(k) (KEYMAP.map[((k)-kdMinKeyCode)*KEYMAP.mapWidth])
+
+CARD32 KdSpecialKeys = 0;
+
+extern char dispatchException;
+
+/*
+ * kdCheckTermination
+ *
+ * This function checks for the key sequence that terminates the server. When
+ * detected, it sets the dispatchException flag and returns. The key sequence
+ * is:
+ * Control-Alt
+ * It's assumed that the server will be waken up by the caller when this
+ * function returns.
+ */
+
+extern int nClients;
+
+void
+KdCheckSpecialKeys(xEvent *xE)
+{
+ KeySym sym;
+
+ if (!pKdKeyboard) return;
+
+ /*
+ * Ignore key releases
+ */
+
+ if (xE->u.u.type == KeyRelease) return;
+
+ /*
+ * Check for control/alt pressed
+ */
+ if ((pKdKeyboard->key->state & (ControlMask|Mod1Mask)) !=
+ (ControlMask|Mod1Mask))
+ return;
+
+ sym = KEYCOL1(xE->u.u.detail);
+
+ /*
+ * Let OS function see keysym first
+ */
+
+ if (kdOsFuncs->SpecialKey)
+ if ((*kdOsFuncs->SpecialKey) (sym))
+ return;
+
+ /*
+ * Now check for backspace or delete; these signal the
+ * X server to terminate
+ */
+ switch (sym) {
+ case XK_BackSpace:
+ case XK_Delete:
+ case XK_KP_Delete:
+ /*
+ * Set the dispatch exception flag so the server will terminate the
+ * next time through the dispatch loop.
+ */
+ dispatchException |= DE_TERMINATE;
+ break;
+ }
+}
+
+/*
+ * kdEnqueueKeyboardEvent
+ *
+ * This function converts hardware keyboard event information into an X event
+ * and enqueues it using MI. It wakes up the server before returning so that
+ * the event will be processed normally.
+ *
+ */
+
+void
+KdHandleKeyboardEvent (xEvent *ev)
+{
+ int key = ev->u.u.detail;
+ int byte;
+ CARD8 bit;
+
+ byte = key >> 3;
+ bit = 1 << (key & 7);
+ switch (ev->u.u.type) {
+ case KeyPress:
+ kdKeyState[byte] |= bit;
+ break;
+ case KeyRelease:
+ kdKeyState[byte] &= ~bit;
+ break;
+ }
+ KdHandleEvent (ev);
+}
+
+void
+KdReleaseAllKeys (void)
+{
+ xEvent xE;
+ int key;
+
+ for (key = 0; key < KD_KEY_COUNT; key++)
+ if (IsKeyDown(key))
+ {
+ xE.u.keyButtonPointer.time = GetTimeInMillis();
+ xE.u.u.type = KeyRelease;
+ xE.u.u.detail = key;
+ KdHandleKeyboardEvent (&xE);
+ }
+}
+
+void
+KdCheckLock (void)
+{
+ KeyClassPtr keyc = pKdKeyboard->key;
+ Bool isSet, shouldBeSet;
+
+ if (kdKeyboardFuncs->LockLed)
+ {
+ isSet = (kdLeds & (1 << (kdKeyboardFuncs->LockLed-1))) != 0;
+ shouldBeSet = (keyc->state & LockMask) != 0;
+ if (isSet != shouldBeSet)
+ {
+ KdSetLed (kdKeyboardFuncs->LockLed, shouldBeSet);
+ }
+ }
+}
+
+void
+KdEnqueueKeyboardEvent(unsigned char scan_code,
+ unsigned char is_up)
+{
+ unsigned char key_code;
+ xEvent xE;
+ int e;
+ KeyClassPtr keyc;
+
+ if (!pKdKeyboard)
+ return;
+ keyc = pKdKeyboard->key;
+
+ xE.u.keyButtonPointer.time = GetTimeInMillis();
+
+ if (kdMinScanCode <= scan_code && scan_code <= kdMaxScanCode)
+ {
+ key_code = scan_code + KD_MIN_KEYCODE - kdMinScanCode;
+
+ /*
+ * Set up this event -- the type may be modified below
+ */
+ if (is_up)
+ xE.u.u.type = KeyRelease;
+ else
+ xE.u.u.type = KeyPress;
+ xE.u.u.detail = key_code;
+
+ switch (KEYCOL1(key_code))
+ {
+ case XK_Num_Lock:
+ case XK_Scroll_Lock:
+ case XK_Shift_Lock:
+ case XK_Caps_Lock:
+ if (xE.u.u.type == KeyRelease)
+ return;
+ if (IsKeyDown (key_code))
+ xE.u.u.type = KeyRelease;
+ else
+ xE.u.u.type = KeyPress;
+ }
+
+ /*
+ * Check pressed keys which are already down
+ */
+ if (IsKeyDown (key_code) && xE.u.u.type == KeyPress)
+ {
+ KeybdCtrl *ctrl = &pKdKeyboard->kbdfeed->ctrl;
+
+ /*
+ * Check auto repeat
+ */
+ if (!ctrl->autoRepeat || keyc->modifierMap[key_code] ||
+ !(ctrl->autoRepeats[key_code >> 3] & (1 << (key_code & 7))))
+ {
+ return;
+ }
+ }
+ if (xE.u.u.type == KeyRelease && !IsKeyDown (key_code))
+ {
+ xE.u.u.type = KeyPress;
+ KdHandleKeyboardEvent (&xE);
+ xE.u.u.type = KeyRelease;
+ }
+ KdCheckSpecialKeys (&xE);
+ KdHandleKeyboardEvent (&xE);
+ }
+}
+
+#define SetButton(b,v, s) \
+{\
+ xE.u.u.detail = b; \
+ xE.u.u.type = v; \
+ KdHandleEvent (&xE); \
+}
+
+#define Press(b) SetButton(b+1,ButtonPress,"Down")
+#define Release(b) SetButton(b+1,ButtonRelease,"Up")
+
+unsigned char ButtonState = 0;
+
+/*
+ * kdEnqueueMouseEvent
+ *
+ * This function converts hardware mouse event information into X event
+ * information. A mouse movement event is passed off to MI to generate
+ * a MotionNotify event, if appropriate. Button events are created and
+ * passed off to MI for enqueueing.
+ */
+
+static int
+KdMouseAccelerate (DeviceIntPtr device, int delta)
+{
+ PtrCtrl *pCtrl = &device->ptrfeed->ctrl;
+
+ if (abs(delta) > pCtrl->threshold)
+ delta = (delta * pCtrl->num) / pCtrl->den;
+ return delta;
+}
+
+void
+KdEnqueueMouseEvent(unsigned long flags, int x, int y)
+{
+ CARD32 ms;
+ xEvent xE;
+ unsigned char buttons;
+
+ if (!pKdPointer)
+ return;
+
+ ms = GetTimeInMillis();
+
+ if (flags & KD_MOUSE_DELTA)
+ {
+ x = KdMouseAccelerate (pKdPointer, x);
+ y = KdMouseAccelerate (pKdPointer, y);
+ xE.u.keyButtonPointer.pad1 = 1;
+ }
+ else
+ xE.u.keyButtonPointer.pad1 = 0;
+ xE.u.keyButtonPointer.time = ms;
+ xE.u.keyButtonPointer.rootX = x;
+ xE.u.keyButtonPointer.rootY = y;
+
+ xE.u.u.type = MotionNotify;
+ xE.u.u.detail = 0;
+ KdHandleEvent (&xE);
+
+ buttons = flags;
+
+ if ((ButtonState & KD_BUTTON_1) ^ (buttons & KD_BUTTON_1))
+ {
+ if (buttons & KD_BUTTON_1)
+ {
+ Press(0);
+ }
+ else
+ {
+ Release(0);
+ }
+ }
+ if ((ButtonState & KD_BUTTON_2) ^ (buttons & KD_BUTTON_2))
+ {
+ if (buttons & KD_BUTTON_2)
+ {
+ Press(1);
+ }
+ else
+ {
+ Release(1);
+ }
+ }
+ if ((ButtonState & KD_BUTTON_3) ^ (buttons & KD_BUTTON_3))
+ {
+ if (buttons & KD_BUTTON_3)
+ {
+ Press(2);
+ }
+ else
+ {
+ Release(2);
+ }
+ }
+ ButtonState = buttons;
+}
+
+void
+KdEnqueueMotionEvent (int x, int y)
+{
+ xEvent xE;
+ CARD32 ms;
+
+ ms = GetTimeInMillis();
+
+ xE.u.u.type = MotionNotify;
+ xE.u.keyButtonPointer.time = ms;
+ xE.u.keyButtonPointer.rootX = x;
+ xE.u.keyButtonPointer.rootY = y;
+
+ KdHandleEvent (&xE);
+}
+
+void
+KdBlockHandler (int screen,
+ pointer blockData,
+ pointer timeout,
+ pointer readmask)
+{
+ struct timeval **pTimeout = timeout;
+
+ if (kdTimeoutPending)
+ {
+ static struct timeval tv;
+ int ms;
+
+ ms = kdEmulationTimeout - GetTimeInMillis ();
+ if (ms < 0)
+ ms = 0;
+ tv.tv_sec = ms / 1000;
+ tv.tv_usec = (ms % 1000) * 1000;
+ if (*pTimeout)
+ {
+ if ((*pTimeout)->tv_sec > tv.tv_sec ||
+ ((*pTimeout)->tv_sec == tv.tv_sec &&
+ (*pTimeout)->tv_usec > tv.tv_usec))
+ {
+ *pTimeout = &tv;
+ }
+ }
+ else
+ *pTimeout = &tv;
+ }
+}
+
+void
+KdWakeupHandler (int screen,
+ pointer data,
+ unsigned long result,
+ pointer readmask)
+{
+ fd_set *pReadmask = (fd_set *) readmask;
+
+ if (kdMouseFd >= 0 && FD_ISSET (kdMouseFd, pReadmask))
+ {
+ KdBlockSigio ();
+ (*kdMouseFuncs->Read) (kdMouseFd);
+ KdUnblockSigio ();
+ }
+ if (kdKeyboardFd >= 0 && FD_ISSET (kdKeyboardFd, pReadmask))
+ {
+ KdBlockSigio ();
+ (*kdKeyboardFuncs->Read) (kdKeyboardFd);
+ KdUnblockSigio ();
+ }
+ if (kdTimeoutPending)
+ {
+ if ((long) (GetTimeInMillis () - kdEmulationTimeout) >= 0)
+ {
+ kdTimeoutPending = FALSE;
+ KdBlockSigio ();
+ KdReceiveTimeout ();
+ KdUnblockSigio ();
+ }
+ }
+ if (kdSwitchPending)
+ KdProcessSwitch ();
+}
+
+static Bool
+KdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
+{
+ ScreenPtr pScreen = *ppScreen;
+ int n;
+
+ if (kdDisableZaphod || screenInfo.numScreens <= 1)
+ return FALSE;
+ if (*x < 0)
+ {
+ n = pScreen->myNum - 1;
+ if (n < 0)
+ n = screenInfo.numScreens - 1;
+ pScreen = screenInfo.screens[n];
+ *x += pScreen->width;
+ *ppScreen = pScreen;
+ return TRUE;
+ }
+ else if (*x >= pScreen->width)
+ {
+ n = pScreen->myNum + 1;
+ if (n >= screenInfo.numScreens)
+ n = 0;
+ *x -= pScreen->width;
+ pScreen = screenInfo.screens[n];
+ *ppScreen = pScreen;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+KdCrossScreen(ScreenPtr pScreen, Bool entering)
+{
+ if (entering)
+ KdEnableScreen (pScreen);
+ else
+ KdDisableScreen (pScreen);
+}
+
+static void
+KdWarpCursor (ScreenPtr pScreen, int x, int y)
+{
+ KdBlockSigio ();
+ miPointerWarpCursor (pScreen, x, y);
+ KdUnblockSigio ();
+}
+
+miPointerScreenFuncRec kdPointerScreenFuncs =
+{
+ KdCursorOffScreen,
+ KdCrossScreen,
+ KdWarpCursor
+};
+
+void
+ProcessInputEvents ()
+{
+ (void)mieqProcessInputEvents();
+ miPointerUpdate();
+ if (kdSwitchPending)
+ KdProcessSwitch ();
+ KdCheckLock ();
+}
+
diff --git a/hw/kdrive/src/kkeymap.c b/hw/kdrive/src/kkeymap.c
new file mode 100644
index 000000000..2ec89b96d
--- /dev/null
+++ b/hw/kdrive/src/kkeymap.c
@@ -0,0 +1,235 @@
+/*
+ * $Id$
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: $ */
+
+#include "kdrive.h"
+#include <X11/keysym.h>
+#include "kkeymap.h"
+
+/*
+ * Map scan codes (both regular and synthesized from extended keys)
+ * to X keysyms
+ */
+
+KeySym kdKeymap[(MAX_SCANCODE - MIN_SCANCODE + 1) * MAX_WIDTH] = {
+/* These are directly mapped from DOS scanset 0 */
+/* 1 8 */ XK_Escape, NoSymbol,
+/* 2 9 */ XK_1, XK_exclam,
+/* 3 10 */ XK_2, XK_at,
+/* 4 11 */ XK_3, XK_numbersign,
+/* 5 12 */ XK_4, XK_dollar,
+/* 6 13 */ XK_5, XK_percent,
+/* 7 14 */ XK_6, XK_asciicircum,
+/* 8 15 */ XK_7, XK_ampersand,
+/* 9 16 */ XK_8, XK_asterisk,
+/* 10 17 */ XK_9, XK_parenleft,
+/* 11 18 */ XK_0, XK_parenright,
+/* 12 19 */ XK_minus, XK_underscore,
+/* 13 20 */ XK_equal, XK_plus,
+/* 14 21 */ XK_BackSpace, NoSymbol,
+/* 15 22 */ XK_Tab, NoSymbol,
+/* 16 23 */ XK_Q, NoSymbol,
+/* 17 24 */ XK_W, NoSymbol,
+/* 18 25 */ XK_E, NoSymbol,
+/* 19 26 */ XK_R, NoSymbol,
+/* 20 27 */ XK_T, NoSymbol,
+/* 21 28 */ XK_Y, NoSymbol,
+/* 22 29 */ XK_U, NoSymbol,
+/* 23 30 */ XK_I, NoSymbol,
+/* 24 31 */ XK_O, NoSymbol,
+/* 25 32 */ XK_P, NoSymbol,
+/* 26 33 */ XK_bracketleft, XK_braceleft,
+/* 27 34 */ XK_bracketright, XK_braceright,
+/* 28 35 */ XK_Return, NoSymbol,
+/* 29 36 */ XK_Control_L, NoSymbol,
+/* 30 37 */ XK_A, NoSymbol,
+/* 31 38 */ XK_S, NoSymbol,
+/* 32 39 */ XK_D, NoSymbol,
+/* 33 40 */ XK_F, NoSymbol,
+/* 34 41 */ XK_G, NoSymbol,
+/* 35 42 */ XK_H, NoSymbol,
+/* 36 43 */ XK_J, NoSymbol,
+/* 37 44 */ XK_K, NoSymbol,
+/* 38 45 */ XK_L, NoSymbol,
+/* 39 46 */ XK_semicolon, XK_colon,
+/* 40 47 */ XK_apostrophe, XK_quotedbl,
+/* 41 48 */ XK_grave, XK_asciitilde,
+/* 42 49 */ XK_Shift_L, NoSymbol,
+/* 43 50 */ XK_backslash, XK_bar,
+/* 44 51 */ XK_Z, NoSymbol,
+/* 45 52 */ XK_X, NoSymbol,
+/* 46 53 */ XK_C, NoSymbol,
+/* 47 54 */ XK_V, NoSymbol,
+/* 48 55 */ XK_B, NoSymbol,
+/* 49 56 */ XK_N, NoSymbol,
+/* 50 57 */ XK_M, NoSymbol,
+/* 51 58 */ XK_comma, XK_less,
+/* 52 59 */ XK_period, XK_greater,
+/* 53 60 */ XK_slash, XK_question,
+/* 54 61 */ XK_Shift_R, NoSymbol,
+/* 55 62 */ XK_KP_Multiply, NoSymbol,
+/* 56 63 */ XK_Alt_L, XK_Meta_L,
+/* 57 64 */ XK_space, NoSymbol,
+/* 58 65 */ XK_Caps_Lock, NoSymbol,
+/* 59 66 */ XK_F1, NoSymbol,
+/* 60 67 */ XK_F2, NoSymbol,
+/* 61 68 */ XK_F3, NoSymbol,
+/* 62 69 */ XK_F4, NoSymbol,
+/* 63 70 */ XK_F5, NoSymbol,
+/* 64 71 */ XK_F6, NoSymbol,
+/* 65 72 */ XK_F7, NoSymbol,
+/* 66 73 */ XK_F8, NoSymbol,
+/* 67 74 */ XK_F9, NoSymbol,
+/* 68 75 */ XK_F10, NoSymbol,
+/* 69 76 */ XK_Break, XK_Pause,
+/* 70 77 */ XK_Scroll_Lock, NoSymbol,
+/* 71 78 */ XK_KP_Home, XK_KP_7,
+/* 72 79 */ XK_KP_Up, XK_KP_8,
+/* 73 80 */ XK_KP_Page_Up, XK_KP_9,
+/* 74 81 */ XK_KP_Subtract, NoSymbol,
+/* 75 82 */ XK_KP_Left, XK_KP_4,
+/* 76 83 */ XK_KP_5, NoSymbol,
+/* 77 84 */ XK_KP_Right, XK_KP_6,
+/* 78 85 */ XK_KP_Add, NoSymbol,
+/* 79 86 */ XK_KP_End, XK_KP_1,
+/* 80 87 */ XK_KP_Down, XK_KP_2,
+/* 81 88 */ XK_KP_Page_Down, XK_KP_3,
+/* 82 89 */ XK_KP_Insert, XK_KP_0,
+/* 83 90 */ XK_KP_Delete, XK_KP_Decimal,
+/* 84 91 */ NoSymbol, NoSymbol,
+/* 85 92 */ NoSymbol, NoSymbol,
+/* 86 93 */ NoSymbol, NoSymbol,
+/* 87 94 */ XK_F11, NoSymbol,
+/* 88 95 */ XK_F12, NoSymbol,
+
+/* These are remapped from the extended set (using ExtendMap) */
+
+/* 89 96 */ XK_Control_R, NoSymbol,
+/* 90 97 */ XK_KP_Enter, NoSymbol,
+/* 91 98 */ XK_KP_Divide, NoSymbol,
+/* 92 99 */ XK_Sys_Req, XK_Print,
+/* 93 100 */ XK_Alt_R, XK_Meta_R,
+/* 94 101 */ XK_Num_Lock, NoSymbol,
+/* 95 102 */ XK_Home, NoSymbol,
+/* 96 103 */ XK_Up, NoSymbol,
+/* 97 104 */ XK_Page_Up, NoSymbol,
+/* 98 105 */ XK_Left, NoSymbol,
+/* 99 106 */ XK_Right, NoSymbol,
+/* 100 107 */ XK_End, NoSymbol,
+/* 101 108 */ XK_Down, NoSymbol,
+/* 102 109 */ XK_Page_Down, NoSymbol,
+/* 103 110 */ XK_Insert, NoSymbol,
+/* 104 111 */ XK_Delete, NoSymbol,
+/* 105 112 */ XK_Super_L, NoSymbol,
+/* 106 113 */ XK_Super_R, NoSymbol,
+/* 107 114 */ XK_Menu, NoSymbol,
+/* 108 115 */ NoSymbol, NoSymbol,
+/* 109 116 */ NoSymbol, NoSymbol,
+/* 110 117 */ NoSymbol, NoSymbol,
+/* 111 118 */ NoSymbol, NoSymbol,
+/* 112 119 */ NoSymbol, NoSymbol,
+;
+
+/*
+ * Map extended keys to additional scancodes
+ */
+KdExtendMap kdExtendMap[] = {
+ 0x1d, 89, /* Control_R */
+ 0x1c, 90, /* KP_Enter */
+ 0x35, 91, /* KP_Divide */
+ 0x37, 92, /* Sys_Req */
+ 0x38, 93, /* Alt_R */
+ 0x45, 94, /* Num_Lock */
+ 0x47, 95, /* Home */
+ 0x48, 96, /* Up */
+ 0x49, 97, /* Page_Up */
+ 0x4b, 98, /* Left */
+ 0x4d, 99, /* Right */
+ 0x4f, 100, /* End */
+ 0x50, 101, /* Down */
+ 0x51, 102, /* Page_Down */
+ 0x52, 103, /* Insert */
+ 0x53, 104, /* Delete */
+ 0x5b, 105, /* Super_L (Windows_L) */
+ 0x5c, 106, /* Super_R (Windows_R) */
+ 0x5d, 107, /* Menu */
+ 0x46, 69, /* Break (with control pressed) */
+};
+
+#define NUM_EXTEND (sizeof (kdExtendMap)/ sizeof (kdExtendMap[0]))
+
+int kdNumExtend = NUM_EXTEND;
+
+/*
+ * Map keys on Japanese keyboard far from zero back to reasonable values
+ */
+KdExtendMap kdJapanMap[] = {
+ 0x70, 108, /* next to Alt key */
+ 0x73, 109, /* dash/vbar */
+ 0x79, 110, /* right of space bar */
+ 0x7b, 111, /* left of space bar */
+ 0x7d, 112, /* Yen */
+};
+
+#define NUM_JAPAN (sizeof (kdJapanMap)/sizeof (kdJapanMap[0]))
+
+int kdNumJapan = NUM_JAPAN;
+
+/*
+ * List of locking key codes
+ */
+
+CARD8 kdLockMap[] = {
+ 65,
+ 101,
+ 77,
+};
+
+#define NUM_LOCK (sizeof (kdLockMap) / sizeof (kdLockMap[0]))
+
+int kdNumLock = NUM_LOCK;
+
+/*
+ * Map containing list of keys which the X server makes locking when
+ * the KEYMAP_LOCKING_ALTGR flag is set in CEKeymapFlags
+ */
+
+CARD8 kdOptionalLockMap[] = {
+ 100,
+};
+
+#define NUM_OPTIONAL_LOCK (sizeof (kdOptionalLockMap) / sizeof (kdOptionalLockMap[0]))
+
+int kdNumOptionalLock = NUM_OPTIONAL_LOCK;
+
+CARD8 kdModMap[MAP_LENGTH];
+
+unsigned long kdKeymapFlags = 0;
+
+KeySymsRec kdKeySyms = {
+ kdKeymap,
+ MIN_KEYCODE,
+ MAX_KEYCODE,
+ 2
+};
diff --git a/hw/kdrive/src/kkeymap.h b/hw/kdrive/src/kkeymap.h
new file mode 100644
index 000000000..d97d7370e
--- /dev/null
+++ b/hw/kdrive/src/kkeymap.h
@@ -0,0 +1,53 @@
+/*
+ * $Id$
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: $ */
+/*
+ * All global variables and functions pertaining to keyboard key mapping
+ * live in this header file.
+ */
+
+#ifndef _KDKEYMP_H
+#define _KDKEYMP_H
+
+/* Offset of MIN_SCANCODE to 8 (X minimum scancode value) */
+#define KD_KEY_OFFSET (8 - kdMinScanCode)
+
+#define KD_MIN_KEYCODE 8
+#define KD_MAX_KEYCODE 254
+#define KD_MAX_WIDTH 4
+#define KD_MAX_LENGTH (KD_MAX_KEYCODE - KD_MIN_KEYCODE + 1)
+
+extern int kdMinScanCode;
+extern int kdMaxScanCode;
+extern int kdMinKeyCode;
+extern int kdMaxKeyCode;
+extern int kdKeymapWidth;
+
+extern KeySym kdKeymap[KD_MAX_LENGTH * KD_MAX_WIDTH];
+
+extern CARD8 kdModMap[MAP_LENGTH];
+
+extern KeySymsRec kdKeySyms;
+
+#endif /* _WINKEYMP_H */
diff --git a/hw/kdrive/src/kloadmap.c b/hw/kdrive/src/kloadmap.c
new file mode 100644
index 000000000..bd8e31cbd
--- /dev/null
+++ b/hw/kdrive/src/kloadmap.c
@@ -0,0 +1,200 @@
+/*
+ * $Id$
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: $ */
+
+#include "kdrive.h"
+#include "kkeymap.h"
+
+#ifdef WINDOWS
+#define KM_BUF 1024
+#define KM_EOF -1
+
+typedef struct _km_file {
+ HANDLE handle;
+ char buf[KM_BUF];
+ char *bufptr;
+ DWORD remain;
+} km_file;
+
+int
+km_fill (km_file *kf)
+{
+ BOOL r;
+
+ NCD_DEBUG ((DEBUG_INIT, "km_fill"));
+ r = ReadFile (kf->handle, kf->buf, KM_BUF,
+ &kf->remain, NULL);
+ NCD_DEBUG ((DEBUG_INIT, "Got %d", kf->remain));
+ if (!r || !kf->remain)
+ return KM_EOF;
+ kf->bufptr = kf->buf;
+ --kf->remain;
+ return *kf->bufptr++;
+}
+
+#define km_getchar(kf) ((kf)->remain-- ? *kf->bufptr++ : km_fill (kf))
+#else
+#define km_getchar(kf) getc(kf)
+#endif
+
+BOOL
+km_word (km_file *kf, char *buf, int len)
+{
+ int c;
+
+ for (;;)
+ {
+ switch (c = km_getchar (kf)) {
+ case KM_EOF:
+ return FALSE;
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ continue;
+ }
+ break;
+ }
+ len--;
+ while (len--)
+ {
+ *buf++ = c;
+ switch (c = km_getchar (kf)) {
+ case KM_EOF:
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ *buf++ = '\0';
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+BOOL
+km_int (km_file *kf, int *r)
+{
+ char word[64];
+
+ if (km_word (kf, word, sizeof (word)))
+ {
+ *r = strtol (word, NULL, 0);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+WCHAR *winKbdExtensions[] = {
+ L".xku",
+ L".xkb"
+};
+
+#define NUM_KBD_EXTENSIONS (sizeof (winKbdExtensions) / sizeof (winKbdExtensions[0]))
+
+BOOL
+winLoadKeymap (void)
+{
+ WCHAR file[32 + KL_NAMELENGTH];
+ WCHAR name[KL_NAMELENGTH];
+ HKL layout;
+ km_file kf;
+ int width;
+ BOOL ret;
+ KeySym *m;
+ int scancode;
+ int w;
+ int e;
+
+ layout = GetKeyboardLayout (0);
+ /*
+ * Pre-build 46 versions of ThinSTAR software return 0
+ * for all layouts
+ */
+ if (!layout)
+ return FALSE;
+ NCD_DEBUG ((DEBUG_INIT, "Keyboard layout 0x%x", layout));
+ for (e = 0; e < NUM_KBD_EXTENSIONS; e++)
+ {
+ wstrcpy (file, L"\\Storage Card\\");
+ wsprintf (name, TEXT("%08x"), layout);
+ wstrcat (file, name);
+ wstrcat (file, winKbdExtensions[e]);
+ NCD_DEBUG ((DEBUG_INIT, "Loading keymap from %S", file));
+ kf.handle = CreateFile (file,
+ GENERIC_READ,
+ FILE_SHARE_READ|FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (kf.handle != INVALID_HANDLE_VALUE)
+ break;
+ }
+ if (kf.handle == INVALID_HANDLE_VALUE)
+ {
+ NCD_DEBUG ((DEBUG_INIT, "No such file"));
+ return FALSE;
+ }
+ ret = FALSE;
+ kf.remain = 0;
+ /*
+ * Keymap format:
+ *
+ * flags (optional)
+ * width
+ * keycode -> keysym array (num_keycodes * width)
+ */
+ if (!km_int (&kf, &width))
+ goto bail1;
+ if (width & KEYMAP_FLAGS)
+ {
+ CEKeymapFlags = (unsigned long) width;
+ if (!km_int (&kf, &width))
+ goto bail1;
+ }
+ else
+ CEKeymapFlags = 0;
+ if (width > MAX_WIDTH)
+ goto bail1;
+ NCD_DEBUG ((DEBUG_INIT, "Keymap width %d flags 0x%x",
+ width, CEKeymapFlags));
+ m = CEKeymap;
+ for (scancode = MIN_SCANCODE; scancode <= MAX_SCANCODE; scancode++)
+ {
+ for (w = 0; w < width; w++)
+ {
+ if (!km_int (&kf, m))
+ break;
+ m++;
+ }
+ if (w != width)
+ break;
+ }
+ CEKeySyms.mapWidth = width;
+ ret = TRUE;
+bail1:
+ CloseHandle (kf.handle);
+ return ret;
+}
diff --git a/hw/kdrive/src/kmap.c b/hw/kdrive/src/kmap.c
new file mode 100644
index 000000000..fdd0f36d6
--- /dev/null
+++ b/hw/kdrive/src/kmap.c
@@ -0,0 +1,86 @@
+/*
+ * $Id$
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: $ */
+
+#include "kdrive.h"
+
+#ifdef linux
+#include <errno.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#endif
+
+void *
+KdMapDevice (CARD32 addr, CARD32 size)
+{
+#ifdef WINDOWS
+ void *a;
+ void *d;
+
+ d = VirtualAlloc (NULL, size, MEM_RESERVE, PAGE_NOACCESS);
+ if (!d)
+ return NULL;
+ DRAW_DEBUG ((DEBUG_S3INIT, "Virtual address of 0x%x is 0x%x", addr, d));
+ a = VirtualCopyAddr (addr);
+ DRAW_DEBUG ((DEBUG_S3INIT, "Translated address is 0x%x", a));
+ if (!VirtualCopy (d, a, size,
+ PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL))
+ {
+ DRAW_DEBUG ((DEBUG_FAILURE, "VirtualCopy failed %d",
+ GetLastError ()));
+ return NULL;
+ }
+ DRAW_DEBUG ((DEBUG_S3INIT, "Device mapped successfully"));
+ return d;
+#endif
+#ifdef linux
+ void *a;
+ int fd;
+
+ fd = open ("/dev/mem", O_RDWR);
+ if (fd < 0)
+ FatalError ("KdMapDevice: failed to open /dev/mem (%s)\n",
+ strerror (errno));
+
+ a = mmap ((caddr_t) 0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, addr);
+ close (fd);
+ if ((long) a == -1)
+ FatalError ("KdMapDevice: failed to map frame buffer (%s)\n",
+ strerror (errno));
+ return a;
+#endif
+}
+
+void
+KdUnmapDevice (void *addr, CARD32 size)
+{
+#ifdef WINDOWS
+ VirtualFree (addr, size, MEM_DECOMMIT);
+ VirtualFree (addr, 0, MEM_RELEASE);
+#endif
+#ifdef linux
+ munmap (addr, size);
+#endif
+}
+
diff --git a/hw/kdrive/src/knoop.c b/hw/kdrive/src/knoop.c
new file mode 100644
index 000000000..483047f22
--- /dev/null
+++ b/hw/kdrive/src/knoop.c
@@ -0,0 +1,294 @@
+/*
+ * $Id$
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: $ */
+
+/*
+ * GC ops that don't do anything
+ */
+
+#include "kdrive.h"
+#include <gcstruct.h>
+
+typedef void (* typeFillSpans)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+typedef void (* typeSetSpans)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ char * /*psrc*/,
+ DDXPointPtr /*ppt*/,
+ int * /*pwidth*/,
+ int /*nspans*/,
+ int /*fSorted*/
+#endif
+);
+
+typedef void (* typePutImage)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*depth*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ int /*leftPad*/,
+ int /*format*/,
+ char * /*pBits*/
+#endif
+);
+
+typedef RegionPtr (* typeCopyArea)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ GCPtr /*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*w*/,
+ int /*h*/,
+ int /*dstx*/,
+ int /*dsty*/
+#endif
+);
+
+typedef RegionPtr (* typeCopyPlane)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ GCPtr /*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*width*/,
+ int /*height*/,
+ int /*dstx*/,
+ int /*dsty*/,
+ unsigned long /*bitPlane*/
+#endif
+);
+typedef void (* typePolyPoint)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/
+#endif
+);
+
+typedef void (* typePolylines)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/
+#endif
+);
+
+typedef void (* typePolySegment)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nseg*/,
+ xSegment * /*pSegs*/
+#endif
+);
+
+typedef void (* typePolyRectangle)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nrects*/,
+ xRectangle * /*pRects*/
+#endif
+);
+
+typedef void (* typePolyArc)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+
+typedef void (* typeFillPolygon)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*shape*/,
+ int /*mode*/,
+ int /*count*/,
+ DDXPointPtr /*pPts*/
+#endif
+);
+
+typedef void (* typePolyFillRect)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nrectFill*/,
+ xRectangle * /*prectInit*/
+#endif
+);
+
+typedef void (* typePolyFillArc)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+
+typedef int (* typePolyText8)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/
+#endif
+);
+
+typedef int (* typePolyText16)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ unsigned short * /*chars*/
+#endif
+);
+
+typedef void (* typeImageText8)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/
+#endif
+);
+
+typedef void (* typeImageText16)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ unsigned short * /*chars*/
+#endif
+);
+
+typedef void (* typeImageGlyphBlt)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+
+typedef void (* typePolyGlyphBlt)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+
+typedef void (* typePushPixels)(
+#if NeedNestedPrototypes
+ GCPtr /*pGC*/,
+ PixmapPtr /*pBitMap*/,
+ DrawablePtr /*pDst*/,
+ int /*w*/,
+ int /*h*/,
+ int /*x*/,
+ int /*y*/
+#endif
+);
+
+RegionPtr
+KdNoopCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height, int dstx, int dsty)
+{
+ return NullRegion;
+}
+
+RegionPtr
+KdNoopCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height,
+ int dstx, int dsty, unsigned long bitPlane)
+{
+ return NullRegion;
+}
+
+GCOps kdNoopOps = {
+ (typeFillSpans) NoopDDA, /* fill spans */
+ (typeSetSpans) NoopDDA, /* set spans */
+ (typePutImage) NoopDDA, /* put image */
+ KdNoopCopyArea, /* copy area */
+ KdNoopCopyPlane, /* copy plane */
+ (typePolyPoint) NoopDDA, /* poly point */
+ (typePolylines) NoopDDA, /* poly lines */
+ (typePolySegment) NoopDDA, /* poly segment */
+ (typePolyRectangle) NoopDDA, /* poly rectangle */
+ (typePolyArc) NoopDDA, /* poly arc */
+ (typeFillPolygon) NoopDDA, /* fill polygon */
+ (typePolyFillRect) NoopDDA, /* poly fillrect */
+ (typePolyFillArc) NoopDDA, /* poly fillarc */
+ (typePolyText8) NoopDDA, /* text 8 */
+ (typePolyText16) NoopDDA, /* text 16 */
+ (typeImageText8) NoopDDA, /* itext 8 */
+ (typeImageText16) NoopDDA, /* itext 16 */
+ (typePolyGlyphBlt) NoopDDA, /* glyph blt */
+ (typeImageGlyphBlt) NoopDDA, /* iglyph blt */
+ (typePushPixels) NoopDDA, /* push pixels */
+#ifdef NEED_LINEHELPER
+ (typeLineHelper) NULL,
+#endif
+};
diff --git a/hw/kdrive/src/ktest.c b/hw/kdrive/src/ktest.c
new file mode 100644
index 000000000..f4505406d
--- /dev/null
+++ b/hw/kdrive/src/ktest.c
@@ -0,0 +1,76 @@
+/*
+ * $Id$
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: $ */
+
+#include "kdrive.h"
+
+
+static CARD8 memoryPatterns[] = { 0xff, 0x00, 0x5a, 0xa5, 0xaa, 0x55 };
+
+#define NUM_PATTERNS (sizeof (memoryPatterns) / sizeof (memoryPatterns[0]))
+
+Bool
+KdFrameBufferValid (CARD8 *base, int size)
+{
+ volatile CARD8 *b = (volatile CARD8 *) base;
+ CARD8 save, test, compare;
+ int i, j;
+
+ b = base + (size - 1);
+ save = *b;
+
+ for (i = 0; i < NUM_PATTERNS; i++)
+ {
+ test = memoryPatterns[i];
+ *b = test;
+ for (j = 0; j < 1000; j++)
+ {
+ compare = *b;
+ if (compare != test)
+ return FALSE;
+ }
+ }
+ *b = save;
+ return TRUE;
+}
+
+int
+KdFrameBufferSize (CARD8 *base, int max)
+{
+ int min, cur;
+
+ min = 0;
+ while (min + 1 < max)
+ {
+ cur = (max + min) / 2;
+ if (KdFrameBufferValid (base, cur))
+ min = cur;
+ else
+ max = cur;
+ }
+ if (KdFrameBufferValid (base, max))
+ return max;
+ else
+ return min;
+}
diff --git a/hw/kdrive/src/vga.c b/hw/kdrive/src/vga.c
new file mode 100644
index 000000000..0e0c53878
--- /dev/null
+++ b/hw/kdrive/src/vga.c
@@ -0,0 +1,288 @@
+/*
+ * $Id$
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: $ */
+
+#include "vga.h"
+#include <stdio.h>
+
+#ifdef linux
+#define extern
+#include <asm/io.h>
+#undef extern
+
+#define _VgaInb(r) inb(r)
+#define _VgaOutb(v,r) outb(v,r)
+
+#endif
+
+#if 0
+#define VGA_DEBUG(a) fprintf a
+#else
+#define VGA_DEBUG(a)
+#endif
+
+VGA8
+VgaInb (VGA16 r)
+{
+ return _VgaInb(r);
+}
+
+void
+VgaOutb (VGA8 v, VGA16 r)
+{
+ _VgaOutb (v,r);
+}
+
+VGA8
+VgaFetch (VgaCard *card, VGA16 reg)
+{
+ VgaMap map;
+ VGAVOL8 *mem;
+ VGA8 value;
+
+ (*card->map) (card, reg, &map, VGAFALSE);
+ switch (map.access) {
+ case VgaAccessMem:
+ mem = (VGAVOL8 *) map.port;
+ value = *mem;
+ break;
+ case VgaAccessIo:
+ value = _VgaInb (map.port);
+ VGA_DEBUG ((stderr, "%4x -> %2x\n", map.port, value));
+ break;
+ case VgaAccessIndMem:
+ mem = (VGAVOL8 *) map.port;
+ mem[map.addr] = map.index;
+ value = mem[map.value];
+ break;
+ case VgaAccessIndIo:
+ _VgaOutb (map.index, map.port + map.addr);
+ value = _VgaInb (map.port + map.value);
+ VGA_DEBUG ((stderr, "%4x/%2x -> %2x\n", map.port, map.index, value));
+ break;
+ case VgaAccessDone:
+ value = map.value;
+ VGA_DEBUG ((stderr, "direct %4x -> %2x\n", reg, value));
+ break;
+ }
+ return value;
+}
+
+void
+VgaStore (VgaCard *card, VGA16 reg, VGA8 value)
+{
+ VgaMap map;
+ VGAVOL8 *mem;
+
+ map.value = value;
+ (*card->map) (card, reg, &map, VGATRUE);
+ switch (map.access) {
+ case VgaAccessMem:
+ mem = (VGAVOL8 *) map.port;
+ *mem = value;
+ break;
+ case VgaAccessIo:
+ VGA_DEBUG ((stderr, "%4x <- %2x\n", map.port, value));
+ _VgaOutb (value, map.port);
+ break;
+ case VgaAccessIndMem:
+ mem = (VGAVOL8 *) map.port;
+ mem[map.addr] = map.index;
+ mem[map.value] = value;
+ break;
+ case VgaAccessIndIo:
+ VGA_DEBUG ((stderr, "%4x/%2x <- %2x\n", map.port, map.index, value));
+ _VgaOutb (map.index, map.port + map.addr);
+ _VgaOutb (value, map.port + map.value);
+ break;
+ case VgaAccessDone:
+ VGA_DEBUG ((stderr, "direct %4x <- %2x\n", reg, value));
+ break;
+ }
+}
+
+void
+VgaPreserve (VgaCard *card)
+{
+ VgaSave *s;
+ VGA16 id;
+
+ for (s = card->saves; s->first != VGA_REG_NONE; s++)
+ {
+ for (id = s->first; id <= s->last; id++)
+ {
+ card->values[id].cur = VgaFetch (card, id);
+ card->values[id].save = card->values[id].cur;
+ card->values[id].flags = VGA_VALUE_VALID | VGA_VALUE_SAVED;
+ }
+ }
+}
+
+void
+VgaRestore (VgaCard *card)
+{
+ VgaSave *s;
+ VGA16 id;
+
+ for (s = card->saves; s->first != VGA_REG_NONE; s++)
+ {
+ for (id = s->first; id <= s->last; id++)
+ {
+ if (card->values[id].flags & VGA_VALUE_SAVED)
+ {
+ VgaStore (card, id, card->values[id].save);
+ card->values[id].cur = card->values[id].save;
+ }
+ }
+ }
+}
+
+void
+VgaFinish (VgaCard *card)
+{
+ VGA16 id;
+
+ for (id = 0; id < card->max; id++)
+ card->values[id].flags = 0;
+}
+
+void
+_VgaSync (VgaCard *card, VGA16 id)
+{
+ if (!(card->values[id].flags & VGA_VALUE_VALID))
+ {
+ card->values[id].cur = VgaFetch (card, id);
+ card->values[id].flags |= VGA_VALUE_VALID;
+ }
+}
+
+void
+VgaSet (VgaCard *card, VgaReg *reg, VGA32 value)
+{
+ VGA8 v, mask, new;
+
+ while (reg->len)
+ {
+ if (reg->id != VGA_REG_NONE)
+ {
+ _VgaSync (card, reg->id);
+ mask = ((1 << reg->len) - 1);
+ new = value & mask;
+ mask <<= reg->base;
+ new <<= reg->base;
+ v = card->values[reg->id].cur;
+ v = v & ~mask | new;
+ card->values[reg->id].cur = v;
+ card->values[reg->id].flags |= VGA_VALUE_MODIFIED|VGA_VALUE_DIRTY;
+ }
+ value >>= reg->len;
+ reg++;
+ }
+}
+
+void
+VgaFlushReg (VgaCard *card, VgaReg *reg)
+{
+ while (reg->len)
+ {
+ if (reg->id != VGA_REG_NONE)
+ {
+ if (card->values[reg->id].flags & VGA_VALUE_DIRTY)
+ {
+ VgaStore (card, reg->id, card->values[reg->id].cur);
+ card->values[reg->id].flags &= ~VGA_VALUE_DIRTY;
+ }
+ }
+ reg++;
+ }
+
+}
+
+void
+VgaSetImm (VgaCard *card, VgaReg *reg, VGA32 value)
+{
+ VgaSet (card, reg, value);
+ VgaFlushReg (card, reg);
+}
+
+VGA32
+VgaGet (VgaCard *card, VgaReg *reg)
+{
+ VGA32 value, offset, v;
+ VGA8 mask;
+
+ value = 0;
+ offset = 0;
+ while (reg->len)
+ {
+ if (reg->id != VGA_REG_NONE)
+ {
+ _VgaSync (card, reg->id);
+ mask = ((1 << reg->len) - 1);
+ v = (card->values[reg->id].cur >> reg->base) & mask;
+ value |= (v << offset);
+ }
+ offset += reg->len;
+ reg++;
+ }
+ return value;
+}
+
+VGA32
+VgaGetImm (VgaCard *card, VgaReg *reg)
+{
+ VgaReg *r = reg;
+
+ while (r->len)
+ {
+ if (r->id != VGA_REG_NONE)
+ card->values[r->id].flags &= ~VGA_VALUE_VALID;
+ r++;
+ }
+ return VgaGet (card, reg);
+}
+
+void
+VgaFlush (VgaCard *card)
+{
+ VGA16 id;
+
+ for (id = 0; id < card->max; id++)
+ {
+ if (card->values[id].flags & VGA_VALUE_DIRTY)
+ {
+ VgaStore (card, id, card->values[id].cur);
+ card->values[id].flags &= ~VGA_VALUE_DIRTY;
+ }
+ }
+}
+
+void
+VgaFill (VgaCard *card, VGA16 low, VGA16 high)
+{
+ VGA16 id;
+
+ for (id = low; id < high; id++)
+ _VgaSync (card, id);
+}
diff --git a/hw/kdrive/src/vga.h b/hw/kdrive/src/vga.h
new file mode 100644
index 000000000..b254152cb
--- /dev/null
+++ b/hw/kdrive/src/vga.h
@@ -0,0 +1,132 @@
+/*
+ * $Id$
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: $ */
+
+#ifndef _VGA_H_
+#define _VGA_H_
+
+typedef unsigned long VGA32;
+typedef unsigned short VGA16;
+typedef unsigned char VGA8;
+typedef int VGABOOL;
+typedef volatile VGA8 VGAVOL8;
+
+#define VGATRUE 1
+#define VGAFALSE 0
+
+typedef struct _vgaReg {
+ VGA16 id;
+ VGA8 base;
+ VGA8 len;
+} VgaReg;
+
+#define VGA_REG_NONE 0xffff
+#define VGA_REG_END VGA_REG_NONE, 0, 0
+
+typedef struct _vgaValue {
+ VGA8 save;
+ VGA8 cur;
+ VGA16 flags;
+} VgaValue;
+
+#define VGA_VALUE_VALID 1 /* value ever fetched */
+#define VGA_VALUE_MODIFIED 2 /* value ever changed */
+#define VGA_VALUE_DIRTY 4 /* value needs syncing */
+#define VGA_VALUE_SAVED 8 /* value preserved */
+
+typedef enum _vgaAccess {
+ VgaAccessMem, VgaAccessIo, VgaAccessIndMem, VgaAccessIndIo,
+ VgaAccessDone,
+} VgaAccess;
+
+typedef struct _vgaMap {
+ VgaAccess access;
+ VGA32 port;
+ VGA8 addr; /* for Ind access; addr offset from port */
+ VGA8 value; /* for Ind access; value offset from port */
+ VGA8 index; /* for Ind access; index value */
+} VgaMap;
+
+#define VGA_UNLOCK_FIXED 1 /* dont save current value */
+#define VGA_UNLOCK_LOCK 2 /* execute only on relock */
+#define VGA_UNLOCK_UNLOCK 4 /* execute only on unlock */
+
+typedef struct _vgaSave {
+ VGA16 first;
+ VGA16 last;
+} VgaSave;
+
+#define VGA_SAVE_END VGA_REG_NONE, VGA_REG_NONE
+
+typedef struct _vgaCard {
+ void (*map) (struct _vgaCard *card, VGA16 reg, VgaMap *map, VGABOOL write);
+ void *closure;
+ int max;
+ VgaValue *values;
+ VgaSave *saves;
+} VgaCard;
+
+VGA8
+VgaInb (VGA16 r);
+
+void
+VgaOutb (VGA8 v, VGA16 r);
+
+void
+VgaSetImm (VgaCard *card, VgaReg *reg, VGA32 value);
+
+VGA32
+VgaGetImm (VgaCard *card, VgaReg *reg);
+
+void
+VgaSet (VgaCard *card, VgaReg *reg, VGA32 value);
+
+VGA32
+VgaGet (VgaCard *card, VgaReg *reg);
+
+void
+VgaFlush (VgaCard *card);
+
+void
+VgaFill (VgaCard *card, VGA16 low, VGA16 high);
+
+void
+VgaPreserve (VgaCard *card);
+
+void
+VgaRestore (VgaCard *card);
+
+VGA8
+VgaFetch (VgaCard *card, VGA16 id);
+
+void
+VgaStore (VgaCard *card, VGA16 id, VGA8 value);
+
+VGA8
+_VgaFetchInd (VGA16 port, VGA8 reg);
+
+void
+_VgaStoreInd (VGA16 port, VGA8 reg, VGA8 value);
+
+#endif /* _VGA_H_ */