diff options
Diffstat (limited to 'hw/kdrive/src')
-rw-r--r-- | hw/kdrive/src/kcmap.c | 231 | ||||
-rw-r--r-- | hw/kdrive/src/kcolor.c | 883 | ||||
-rw-r--r-- | hw/kdrive/src/kdrive.c | 872 | ||||
-rw-r--r-- | hw/kdrive/src/kdrive.h | 362 | ||||
-rw-r--r-- | hw/kdrive/src/kinfo.c | 110 | ||||
-rw-r--r-- | hw/kdrive/src/kinput.c | 1331 | ||||
-rw-r--r-- | hw/kdrive/src/kkeymap.c | 235 | ||||
-rw-r--r-- | hw/kdrive/src/kkeymap.h | 53 | ||||
-rw-r--r-- | hw/kdrive/src/kloadmap.c | 200 | ||||
-rw-r--r-- | hw/kdrive/src/kmap.c | 86 | ||||
-rw-r--r-- | hw/kdrive/src/knoop.c | 294 | ||||
-rw-r--r-- | hw/kdrive/src/ktest.c | 76 | ||||
-rw-r--r-- | hw/kdrive/src/vga.c | 288 | ||||
-rw-r--r-- | hw/kdrive/src/vga.h | 132 |
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_ */ |