diff -urN xfree-3.3.6/config/cf/host.def xc/config/cf/host.def
--- xfree-3.3.6/config/cf/host.def	Thu Jan  1 01:00:00 1970
+++ xc/config/cf/host.def	Sun Oct 15 20:00:51 2000
@@ -0,0 +1,164 @@
+/*
+ * Server identity
+ */
+#define XVendorString	"The GGI Project"
+
+/*
+ * The higly stripped down XGGI source tree doesn't contain this
+ *
+ */
+#define XprtServer			NO
+#define InstallXserverSetUID		NO
+#define BuildScreenSaverLibrary		NO
+#define BuildXF86MiscLibrary		NO
+#define BuildXF86DGALibrary		NO
+#define BuildXF86VidModeLibrary		NO
+#define BuildDPMSLibrary		NO
+#define BuildXF86VidModeExt		NO
+#define BuildXF86MiscExt		NO
+#define BuildXF86DGA			NO
+#define BuildDPMSExt			NO
+
+/*
+ * LBX isn't multihead safe
+ *
+ */
+#define BuildLBX			NO
+
+/*
+ * PEX and XIE are large and seldom used.
+ * Comment these three defines out if you need them.
+ *
+ */
+#define BuildPexExt			NO
+#define BuildXIE			NO
+#define BuildXIElib			NO
+
+/*
+ * If you have build-specific modifications in your host.def file, but
+ * want an empty host.def file installed when doing 'make install',
+ * uncomment the following
+ *
+ */
+#define InstallEmptyHostDef
+
+/*
+ * Which servers do you wish to build, you can save a lot of disk space
+ * by only compiling the server you will be using.  It will also save you
+ * considerable compile time. The default is to build all servers supported
+ * on your platform.
+ *
+ * The following servers are supported in Intel x86 platforms
+ *
+ */
+#define XF86SVGAServer          NO
+#define XF86VGA16Server         NO
+#define XF86VGA16DualServer	NO
+#define XF86MonoServer          NO
+#define XF86MonoDualServer	NO
+#define XF86S3Server            NO
+#define XF86S3VServer           NO
+#define XF86I8514Server         NO
+#define XF86Mach8Server         NO
+#define XF86Mach32Server        NO
+#define XF86Mach64Server        NO
+#define XF86P9000Server		NO
+#define XF86AGXServer		NO
+#define XF86W32Server		NO
+#define XF86I128Server		NO
+#define XF86GLINTServer		NO
+#define XF86FBDevServer		NO
+
+/*
+ * Which servers do you wish to build, you can save a lot of disk space
+ * by only compiling the server you will be using.  It will also save you
+ * considerable compile time.
+ *
+ * The following servers are supported on Digital Alpha platforms:
+ *
+ */
+#define XF86SVGAServer          NO
+#define XF86MonoServer          NO
+#define XF86S3Server            NO
+#define XF86S3VServer           NO
+#define XF86P9000Server		NO
+#define XF86TGAServer		NO
+#define XF86GLINTServer		NO
+#define XF86Mach64Server	NO
+#define XF86I128Server		NO
+
+/*
+ * Which servers do you wish to build, you can save a lot of disk space
+ * by only compiling the server you will be using.  It will also save you
+ * considerable compile time.
+ *
+ * The following server is supported on Mips/Arc platforms:
+ *
+ */
+#define XF86S3Server            NO
+
+/*
+ * The following server is supported on Motorola 68k platforms:
+ *
+ */
+#define XF68FBDevServer		NO
+
+/*
+ * To disable building the Xnest server, uncomment this.
+ *
+ */
+#define XnestServer		NO
+
+/*
+ * To disable building Xvfb, uncomment this.
+ *
+ */
+#define XVirtualFramebufferServer	NO
+
+/*
+ * To disable building the font server, uncomment this.
+ *
+ */
+#define BuildFontServer		NO
+
+/*
+ * Do you want to Build Fonts (Usually you only want to build and install
+ * fonts once, if this is a first time install you will want to build the
+ * fonts)
+ *
+ */
+#define BuildFonts		NO
+
+/*
+ * To not install the local font directory, uncomment the following
+ *
+ */
+#define MakeLocalFontDir	NO
+
+/*
+ * To build only the servers with a cut-down source tree, uncomment
+ * this.
+ *
+ */
+#define BuildServersOnly	YES
+
+/*
+ * To disable building XInput support, uncomment this
+ *
+ */
+#define BuildXInputExt		NO
+
+/*
+ * if your system supports dynamic loading of modules using
+ * dlopen set this to YES.
+ *
+ */
+#define BuildDynamicLoading	YES
+
+/*
+ * By default the application defaults files are always installed.
+ * Uncommenting the the following will prevent exising application
+ * defaults files from being over-written.
+ *
+ */
+#define InstallAppDefFiles	NO
diff -urN xfree-3.3.6/config/cf/xf86site.def xc/config/cf/xf86site.def
--- xfree-3.3.6/config/cf/xf86site.def	Sun Oct 15 19:07:28 2000
+++ xc/config/cf/xf86site.def	Sun Oct 15 19:14:40 2000
@@ -244,6 +244,13 @@
  */
 
 /*
+ * XGGI is supported on all platforms, but requires LibGGI.
+ * Uncomment this if you don't have LibGGI installed.
+ *
+#define XGGIServer		NO
+ */
+
+/*
  * To disable building the Xnest server, uncomment this.
  *
 #define XnestServer		NO
diff -urN xfree-3.3.6/config/cf/xfree86.cf xc/config/cf/xfree86.cf
--- xfree-3.3.6/config/cf/xfree86.cf	Sun Oct 15 19:07:28 2000
+++ xc/config/cf/xfree86.cf	Sun Oct 15 19:14:40 2000
@@ -24,6 +24,13 @@
  */
 
 /*
+ * XGGI is platform independent
+ */
+#ifndef XGGIServer
+#define XGGIServer		YES
+#endif
+
+/*
  * For Intel x86 platforms, the default is to build all X servers which
  * are supported on this platform.
  */
@@ -614,7 +621,8 @@
 #if XF86AccelServer || XF86SVGAServer || XF98AccelServer || \
     XF98GANBWAPServer || XF98NEC480Server || XF98NKVNECServer || \
     XF98WABSServer || XF98WABEPServer || XF98WSNAServer || XF98TGUIServer || \
-    XF98MGAServer || XF98SVGAServer || XF68FBDevServer || XF86FBDevServer
+    XF98MGAServer || XF98SVGAServer || XF68FBDevServer || XF86FBDevServer || \
+    XGGIServer
 #define BuildPexExt		YES
 #else
 #define BuildPexExt		NO
@@ -630,7 +638,8 @@
 #  if XF86AccelServer || XF86SVGAServer || XF98AccelServer || \
       XF98GANBWAPServer || XF98NEC480Server || XF98NKVNECServer || \
       XF98WABSServer || XF98WABEPServer || XF98WSNAServer || XF98TGUIServer || \
-      XF98MGAServer || XF98SVGAServer || XF68FBDevServer || XF86FBDevServer
+      XF98MGAServer || XF98SVGAServer || XF68FBDevServer || XF86FBDevServer || \
+      XGGIServer
 #    define BuildGlxExt             YES
 #  else
 #    define BuildGlxExt             NO
@@ -645,7 +654,8 @@
 #if XF86AccelServer || XF86SVGAServer || XF98AccelServer || \
     XF98GANBWAPServer || XF98NEC480Server || XF98NKVNECServer || \
     XF98WABSServer || XF98WABEPServer || XF98WSNAServer || XF98TGUIServer || \
-    XF98MGAServer || XF98SVGAServer || XF68FBDevServer || XF86FBDevServer
+    XF98MGAServer || XF98SVGAServer || XF68FBDevServer || XF86FBDevServer || \
+    XGGIServer
 #define BuildXIE		YES
 #else
 #define BuildXIE		NO
diff -urN xfree-3.3.6/programs/Xserver/Imakefile xc/programs/Xserver/Imakefile
--- xfree-3.3.6/programs/Xserver/Imakefile	Sun Oct 15 19:07:30 2000
+++ xc/programs/Xserver/Imakefile	Sun Oct 15 19:14:40 2000
@@ -207,6 +207,25 @@
  *  even if multiple servers that share subdirectories are being built.
  */
 
+#if XGGIServer
+XCOMM
+XCOMM LibGGI based server
+XCOMM
+MFBDIR = mfb
+CFB8DIR = cfb
+CFB16DIR = cfb16
+CFB24DIR = cfb24
+CFB32DIR = cfb32
+DDXDIR1 = hw/ggi
+GGIDIRS = $(STDDIRS) $(MFBDIR) $(CFB8DIR) $(CFB16DIR) $(CFB24DIR) $(CFB32DIR) $(DDXDIR1) $(DEPDIRS)
+GGIOBJS = hw/ggi/input.o hw/ggi/keyboard.o hw/ggi/graphics.o hw/ggi/accel.o
+GGILIBS = CFB8Libs CFB16Libs CFB24Libs CFB32Libs
+ServerTarget(XGGI,$(GGIDIRS),$(GGIOBJS),$(GGILIBS),$(SYSLIBS) -lgg -lggi)
+#ifndef ServerToInstall
+#define ServerToInstall XGGI
+#endif
+#endif /* XGGIServer */
+
 #if XdecServer
 XCOMM
 XCOMM Digital MIPS based WS server (ultrix 4.2 and beyond)
diff -urN xfree-3.3.6/programs/Xserver/cfb/cfballpriv.c xc/programs/Xserver/cfb/cfballpriv.c
--- xfree-3.3.6/programs/Xserver/cfb/cfballpriv.c	Sun Oct 15 13:33:30 2000
+++ xc/programs/Xserver/cfb/cfballpriv.c	Sun Oct 15 14:27:48 2000
@@ -46,6 +46,7 @@
 int cfbGCPrivateIndex;
 #ifdef CFB_NEED_SCREEN_PRIVATE
 int cfbScreenPrivateIndex;
+static unsigned long cfbScreenPrivateGeneration = 0;
 #endif
 
 extern RegionPtr (*cfbPuntCopyPlane)();
@@ -77,9 +78,12 @@
 	return FALSE;
     cfbPuntCopyPlane = miCopyPlane;
 #ifdef CFB_NEED_SCREEN_PRIVATE
-    cfbScreenPrivateIndex = AllocateScreenPrivateIndex ();
-    if (cfbScreenPrivateIndex == -1)
-	return FALSE;
+    if (cfbScreenPrivateGeneration != serverGeneration) {
+	    cfbScreenPrivateIndex = AllocateScreenPrivateIndex ();
+	    if (cfbScreenPrivateIndex == -1)
+		    return FALSE;
+	    cfbScreenPrivateGeneration = serverGeneration;
+    }
 #endif
     return TRUE;
 }
diff -urN xfree-3.3.6/programs/Xserver/cfb/cfbmskbits.h xc/programs/Xserver/cfb/cfbmskbits.h
--- xfree-3.3.6/programs/Xserver/cfb/cfbmskbits.h	Sun Oct 15 13:33:30 2000
+++ xc/programs/Xserver/cfb/cfbmskbits.h	Sun Oct 15 13:54:49 2000
@@ -37,6 +37,8 @@
 #if defined(XFREE86) || ( defined(__OpenBSD__) && defined(__alpha__) )
 #define NO_COMPILER_H_EXTRAS
 #include	"compiler.h"
+#else
+#define ldq_u(p) (*((unsigned long  *)(p)))
 #endif
 
 /*
diff -urN xfree-3.3.6/programs/Xserver/cfb/cfbpntwin.c xc/programs/Xserver/cfb/cfbpntwin.c
--- xfree-3.3.6/programs/Xserver/cfb/cfbpntwin.c	Sun Oct 15 13:33:30 2000
+++ xc/programs/Xserver/cfb/cfbpntwin.c	Sun Oct 15 14:27:48 2000
@@ -1,3 +1,5 @@
+#define USE_GGI
+
 /* $XConsortium: cfbpntwin.c,v 5.18 94/04/17 20:28:57 dpw Exp $ */
 /* $XFree86: xc/programs/Xserver/cfb/cfbpntwin.c,v 3.0 1996/06/29 09:05:45 dawes Exp $ */
 /***********************************************************
@@ -59,6 +61,11 @@
 #include "cfbmskbits.h"
 #include "mi.h"
 
+#ifdef USE_GGI
+#include <ggi/ggi.h>
+#include "../hw/ggi/xggi.h"
+#endif
+
 void
 cfbPaintWindow(pWin, pRegion, what)
     WindowPtr	pWin;
@@ -202,16 +209,36 @@
     int		    nmiddle;
     register int    m;
     int		    w;
+    int		    scr;
 #if PSZ == 24
     int leftIndex, rightIndex;
     unsigned long piQxelArray[3], xOffset, *pdstULC; /*upper left corner*/
+#endif
+
+    cfbGetLongWidthAndPointer(pDrawable, widthDst, pdstBase);
+
+    scr = xggiGetScreenIdx(pDrawable->pScreen);
+#ifdef USE_GGI
+    if (pdstBase == (unsigned long*) xggiScreens[scr].pfbMemory) {
+	    ggiResourceRelease(xggiScreens[scr].dbuf->resource);
+	    ggiSetGCForeground(xggiScreens[scr].vis, pixel);
+	    for (; nBox; nBox--, pBox++) {
+		    ggiDrawBox(xggiScreens[scr].vis, pBox->x1, pBox->y1,
+			       pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+	    }
+	    if (ggiResourceAcquire(xggiScreens[scr].dbuf->resource,
+				   GGI_ACTYPE_WRITE | GGI_ACTYPE_READ) != 0) {
+		    FatalError("Unable to re-acquire DirectBuffer\n");
+	    }
+	    return;
+    }
+#endif
 
+#if PSZ == 24
     piQxelArray[0] = (pixel&0xFFFFFF) | ((pixel&0xFF)<<24);
     piQxelArray[1] = ((pixel&0xFFFF00)>>8) | ((pixel&0xFFFF)<<16);
     piQxelArray[2] = ((pixel&0xFFFFFF)<<8) | ((pixel&0xFF0000)>>16);
 #endif
-
-    cfbGetLongWidthAndPointer(pDrawable, widthDst, pdstBase);
 
     rrop_xor = PFILL(pixel);
     for (; nBox; nBox--, pBox++)
diff -urN xfree-3.3.6/programs/Xserver/hw/ggi/Imakefile xc/programs/Xserver/hw/ggi/Imakefile
--- xfree-3.3.6/programs/Xserver/hw/ggi/Imakefile	Thu Jan  1 01:00:00 1970
+++ xc/programs/Xserver/hw/ggi/Imakefile	Sun Oct 15 14:41:09 2000
@@ -0,0 +1,21 @@
+XCOMM Makefile for XGGI files
+
+#include <Server.tmpl>
+
+SRCS = 	input.c keyboard.c graphics.c accel.c
+
+OBJS = 	input.o keyboard.o graphics.o accel.o
+
+INCLUDES = -I../../mi -I../../include -I../../os -I../../../../include \
+	-I../../cfb -I../../cfb16 -I../../mfb -I../../../../include/fonts
+
+DEFINES = ServerOSDefines $(SHMDEF) $(MMAPDEF)
+
+CCOPTIONS=
+
+all:: $(OBJS)
+
+XCOMM SpecialCObjectRule(input,$(ICONFIGFILES),$(EXT_DEFINES))
+NormalLibraryObjectRule()
+
+DependTarget()
diff -urN xfree-3.3.6/programs/Xserver/hw/ggi/accel.c xc/programs/Xserver/hw/ggi/accel.c
--- xfree-3.3.6/programs/Xserver/hw/ggi/accel.c	Thu Jan  1 01:00:00 1970
+++ xc/programs/Xserver/hw/ggi/accel.c	Sun Oct 15 14:30:12 2000
@@ -0,0 +1,479 @@
+/* $Id: XFree3.3.diff,v 1.3 2000/10/15 18:25:29 marcus Exp $
+***************************************************************************
+
+   X server for LibGGI - Graphics acceleration
+
+   Copyright (C) 1997	   Michael Krause	[rawstyle@ms.demo.org]
+   Copyright (C) 1998-1999 Marcus Sundberg	[marcus@ggi-project.org]
+
+   Permission is hereby granted, free of charge, to any person obtaining a
+   copy of this software and associated documentation files (the "Software"),
+   to deal in the Software without restriction, including without limitation
+   the rights to use, copy, modify, merge, publish, distribute, sublicense,
+   and/or sell copies of the Software, and to permit persons to whom the
+   Software is furnished to do so, subject to the following conditions:
+
+   The above copyright notice and this permission notice shall be included in
+   all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+   THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+   IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+***************************************************************************
+*/
+
+#define PSZ 8
+#include "mi.h"
+#include "cfb.h"
+#include "../../hw/xfree86/common/cfb16.h"
+#include "../../hw/xfree86/common/cfb24.h"
+#include "../../hw/xfree86/common/cfb32.h"
+
+#include "scrnintstr.h"
+#include "mibstore.h"
+#include "gcstruct.h"
+
+#include "xggi.h"
+
+
+static unsigned long
+mask2offset(unsigned long mask)
+{
+	int i;
+	
+	for (i = 0; (mask & 1) == 0; i++) {
+		mask >>= 1;
+	}
+	
+	return i;
+}
+
+/* dump_region, just here for debugging..
+ */
+#if 0
+static void dump_region(RegionPtr p)
+{
+	BoxPtr box;
+	int n;
+
+	box = REGION_RECTS(p);
+	n = REGION_NUM_RECTS(p);
+
+	for (;n--;box++) {
+		ErrorF("%d %d %d %d\n", box->x1, box->y1, box->x2, box->y2);
+	}
+}
+#endif
+
+/*
+ * Ripped from hw/xfree86/accel/s3/s3blt.c
+ */
+
+static void
+xggiFindOrdering(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GC *pGC,
+		 int numRects, BoxPtr boxes, int srcx, int srcy,
+		 int dstx, int dsty, unsigned int *ordering)
+{
+	int   i, j, y;
+	int   xMax, yMin, yMax;
+
+	/*
+	 * If not the same drawable then order of move doesn't matter. Following
+	 * assumes that boxes are sorted from top to bottom and left to right.
+	 */
+	if ((pSrcDrawable != pDstDrawable) &&
+	    ((pGC->subWindowMode != IncludeInferiors) ||
+	     (pSrcDrawable->type == DRAWABLE_PIXMAP) ||
+	     (pDstDrawable->type == DRAWABLE_PIXMAP))) {
+		for (i = 0; i < numRects; i++)
+			ordering[i] = i;
+	} else {	/* within same drawable, must sequence moves
+			 * carefully! */
+		if (dsty <= srcy) {	/* Scroll up or stationary vertical. Vertical
+					 * order OK */
+			if (dstx <= srcx) {	/* Scroll left or stationary horizontal.
+						 * Horizontal order OK as well */
+				for (i = 0; i < numRects; i++)
+					ordering[i] = i;
+			} else {	/* scroll right. must reverse horizontal
+					 * banding of rects. */
+				for (i = 0, j = 1, xMax = 0; i < numRects; j = i + 1, xMax = i) {
+					/* find extent of current horizontal band */
+					y = boxes[i].y1;	/* band has this y coordinate */
+					while ((j < numRects) && (boxes[j].y1 == y))
+						j++;
+					/* reverse the horizontal band in the output ordering */
+					for (j--; j >= xMax; j--, i++)
+						ordering[i] = j;
+				}
+			}
+		} else {			/* Scroll down. Must reverse vertical
+						 * banding. */
+			if (dstx < srcx) {	/* Scroll left. Horizontal order OK. */
+				for (i = numRects - 1, j = i - 1, yMin = i,
+					     yMax = 0; i >= 0;
+				     j = i - 1, yMin = i) {
+					/* find extent of current horizontal
+					   band */
+					/* band has this y coordinate */
+					y = boxes[i].y1;
+					while ((j >= 0) && (boxes[j].y1 == y))
+						j--;
+					/* reverse the horizontal band in the
+					   output ordering */
+					for (j++; j <= yMin; j++, i--, yMax++)
+						ordering[yMax] = j;
+				}
+			} else {/* Scroll right or horizontal stationary.
+				 * Reverse horizontal order as well (if
+				 * stationary, horizontal order can be
+				 * swapped without penalty and this is faster
+				 * to compute). */
+				for (i = 0, j = numRects - 1; i < numRects;
+				     i++, j--) {
+					ordering[i] = j;
+				}
+			}
+		}
+	}
+}
+
+/*
+ * xggiCopyWindow - accelerated replacement for cfbCopyWindow
+ *
+ * pWin->drawable.x/y contains the destination position
+ * ptOldOrg contains the old position
+ * prgnSrc is a region describing the part of the source to be moved
+ *  (this is padded by one pixel at all four edges of a window?!?!?)
+ *
+ * I don't really understand this, BTW ;)
+ *
+ */
+
+static void
+xggiCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+	RegionRec rgnDst;
+	BoxPtr pboxOrig, pbox;
+	int dx, dy;
+	int i, nbox;
+	unsigned int *ordering;
+	GC    dummyGC;
+    
+	dummyGC.subWindowMode = ~IncludeInferiors;
+    
+	REGION_INIT(pWin->drawable.pScreen, &rgnDst, NullBox, 0);
+    
+	dx = ptOldOrg.x - pWin->drawable.x;
+	dy = ptOldOrg.y - pWin->drawable.y;
+    
+	REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
+	REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst,
+			 &pWin->borderClip, prgnSrc);
+    
+	pboxOrig = REGION_RECTS(&rgnDst);
+	nbox = REGION_NUM_RECTS(&rgnDst);
+    
+	ordering = (unsigned int *)ALLOCATE_LOCAL(nbox * sizeof(unsigned int));
+
+	if (ordering) {
+		int scr = xggiGetScreenIdx(pWin->drawable.pScreen);
+
+		xggiFindOrdering((DrawablePtr)pWin, (DrawablePtr)pWin,
+				 &dummyGC, nbox, pboxOrig,
+				 ptOldOrg.x, ptOldOrg.y,
+				 pWin->drawable.x, pWin->drawable.y, ordering);
+		ggiResourceRelease(xggiScreens[scr].dbuf->resource);
+		for (i = 0; i < nbox; i++) {
+			pbox = &pboxOrig[ordering[i]];
+			ggiCopyBox(xggiScreens[scr].vis,
+				   pbox->x1 + dx, pbox->y1 + dy,
+				   pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+				   pbox->x1, pbox->y1);
+		}
+		if (ggiResourceAcquire(xggiScreens[scr].dbuf->resource,
+				       GGI_ACTYPE_WRITE | GGI_ACTYPE_READ)
+		    != 0) {
+			FatalError("Unable to re-acquire DirectBuffer\n");
+		}
+		DEALLOCATE_LOCAL(ordering);
+	}
+	
+	REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+}
+
+
+/*
+ * xggiScreenInit
+ *
+ */
+extern miBSFuncRec mfbBSFuncRec, cfbBSFuncRec, cfb16BSFuncRec;
+extern miBSFuncRec cfb24BSFuncRec, cfb32BSFuncRec;
+
+Bool
+xggiScreenInit(ScreenPtr pScreen, pointer pbits,
+	       int xsize, int ysize, int dpix, int dpiy, int width)
+{
+	VisualPtr visuals;
+	DepthPtr depths;
+	int nvisuals;
+	int ndepths;
+	int rootdepth = 0;
+	VisualID defaultVisual;
+	int bitsPerRGB;
+	int	i;
+	Bool Rstatus;
+	VisualPtr visual;
+	pointer oldDevPrivate = 0;
+	int scr;
+	miBSFuncPtr bsFuncs;
+
+	scr = xggiGetScreenIdx(pScreen);
+
+#ifdef XGGI_DEBUG
+	ErrorF("scr: %d, depth: %d, bpp:%d\n", scr, xggiScreens[scr].depth,
+	       xggiScreens[scr].bitsPerPixel);
+#endif
+
+	switch (xggiScreens[scr].depth) {
+	case 8:
+		bitsPerRGB = 8;
+		break;
+	case 15:
+		bitsPerRGB = 5;
+		break;
+	case 16:
+		bitsPerRGB = 6;
+		break;
+	default:
+		bitsPerRGB = 8;
+		break;
+	}
+
+	if (xggiScreens[scr].bitsPerPixel > 8) {
+		if (!cfbSetVisualTypes(xggiScreens[scr].depth,
+				       1 << TrueColor, bitsPerRGB)) {
+			ErrorF("cfbSetVisualTypes failed\n");
+			return FALSE;
+		}
+	}
+	if (!cfbInitVisuals(&visuals, &depths, &nvisuals, 
+			    &ndepths, &rootdepth, &defaultVisual,
+			    1 << (xggiScreens[scr].bitsPerPixel - 1),
+			    bitsPerRGB)) {
+		ErrorF("cfbInitVisuals failed\n");
+		return FALSE;
+	}
+
+#ifdef XGGI_DEBUG
+	ErrorF("rootdepth: %d\n", rootdepth);
+#endif
+
+	if (rootdepth > 8) {
+		for (i = 0, visual = visuals; i < nvisuals; i++, visual++) {
+			if (visual->class == DirectColor
+			    || visual->class == TrueColor) {
+#define PIXFMT(scr)	((scr).dbuf->buffer.plb.pixelformat)
+				visual->redMask
+					= PIXFMT(xggiScreens[scr])->red_mask;
+				visual->greenMask
+					= PIXFMT(xggiScreens[scr])->green_mask;
+				visual->blueMask
+					= PIXFMT(xggiScreens[scr])->blue_mask;
+#undef PIXFMT
+				visual->offsetRed
+					= mask2offset(visual->redMask);
+				visual->offsetGreen
+					= mask2offset(visual->greenMask);
+				visual->offsetBlue
+					= mask2offset(visual->blueMask);
+			}
+		}
+	}
+
+	if (scr == 0) {
+		cfbWindowPrivateIndex = cfbGCPrivateIndex = -1;
+	}
+	pScreen->defColormap = FakeClientID(0);
+	pScreen->whitePixel = (Pixel) 1;
+	pScreen->blackPixel = (Pixel) 0;
+	pScreen->QueryBestSize = mfbQueryBestSize;
+	pScreen->RealizeFont = mfbRealizeFont;
+	pScreen->UnrealizeFont = mfbUnrealizeFont;
+
+	pScreen->CopyWindow = xggiCopyWindow;
+
+	switch (rootdepth) {
+	case 1:
+		bsFuncs = &mfbBSFuncRec;
+		pScreen->GetImage = mfbGetImage;
+		pScreen->GetSpans = mfbGetSpans;
+		pScreen->PaintWindowBackground = mfbPaintWindow;
+		pScreen->PaintWindowBorder = mfbPaintWindow;
+		pScreen->CreateGC = mfbCreateGC;
+		if (!mfbAllocatePrivates(pScreen, NULL, NULL)) {
+			ErrorF("mfbAllocatePrivates failed\n");
+			return FALSE;
+		}
+		pScreen->CreateWindow = mfbCreateWindow;
+		pScreen->DestroyWindow = mfbDestroyWindow;
+		pScreen->PositionWindow = mfbPositionWindow;
+		pScreen->ChangeWindowAttributes = mfbChangeWindowAttributes;
+		pScreen->RealizeWindow = mfbMapWindow;
+		pScreen->UnrealizeWindow = mfbUnmapWindow;
+		pScreen->CreatePixmap = mfbCreatePixmap;
+		pScreen->DestroyPixmap = mfbDestroyPixmap;
+		mfbRegisterCopyPlaneProc(pScreen, mfbCopyPlane);
+		break;
+	case 8:
+		bsFuncs = &cfbBSFuncRec;
+		pScreen->GetImage = cfbGetImage;
+		pScreen->GetSpans = cfbGetSpans;
+		pScreen->PaintWindowBackground = cfbPaintWindow;
+		pScreen->PaintWindowBorder = cfbPaintWindow;
+		pScreen->CreateGC = cfbCreateGC;
+		if (!cfbAllocatePrivates(pScreen, NULL, NULL)) {
+			ErrorF("cfbAllocatePrivates failed\n");
+			return FALSE;
+		}
+		pScreen->CreateWindow = cfbCreateWindow;
+		pScreen->DestroyWindow = cfbDestroyWindow;
+		pScreen->PositionWindow = cfbPositionWindow;
+		pScreen->ChangeWindowAttributes = cfbChangeWindowAttributes;
+		pScreen->RealizeWindow = cfbMapWindow;
+		pScreen->UnrealizeWindow = cfbUnmapWindow;
+		pScreen->CreatePixmap = cfbCreatePixmap;
+		pScreen->DestroyPixmap = cfbDestroyPixmap;
+		mfbRegisterCopyPlaneProc(pScreen, cfbCopyPlane);
+		break;
+	case 15:
+	case 16:
+		bsFuncs = &cfb16BSFuncRec;
+		pScreen->GetImage = cfb16GetImage;
+		pScreen->GetSpans = cfb16GetSpans;
+		pScreen->PaintWindowBackground = cfb16PaintWindow;
+		pScreen->PaintWindowBorder = cfb16PaintWindow;
+		pScreen->CreateGC = cfb16CreateGC;
+		if (!cfb16AllocatePrivates(pScreen, NULL, NULL)) {
+			ErrorF("cfb16AllocatePrivates failed\n");
+			return FALSE;
+		}
+		pScreen->CreateWindow = cfb16CreateWindow;
+		pScreen->DestroyWindow = cfb16DestroyWindow;
+		pScreen->PositionWindow = cfb16PositionWindow;
+		pScreen->ChangeWindowAttributes = cfb16ChangeWindowAttributes;
+		pScreen->RealizeWindow = cfb16MapWindow;
+		pScreen->UnrealizeWindow = cfb16UnmapWindow;
+		pScreen->CreatePixmap = cfb16CreatePixmap;
+		pScreen->DestroyPixmap = cfb16DestroyPixmap;
+		mfbRegisterCopyPlaneProc(pScreen, cfb16CopyPlane);
+		break;
+	case 24:
+	case 32:
+		if (xggiScreens[scr].bitsPerPixel == 24) {
+			bsFuncs = &cfb24BSFuncRec;
+			pScreen->GetImage = cfb24GetImage;
+			pScreen->GetSpans = cfb24GetSpans;
+			pScreen->PaintWindowBackground = cfb24PaintWindow;
+			pScreen->PaintWindowBorder = cfb24PaintWindow;
+			pScreen->CreateGC = cfb24CreateGC;
+			if (!cfb24AllocatePrivates(pScreen, NULL, NULL)) {
+				ErrorF("cfb24AllocatePrivates failed\n");
+				return FALSE;
+			}
+			pScreen->CreateWindow = cfb24CreateWindow;
+			pScreen->DestroyWindow = cfb24DestroyWindow;
+			pScreen->PositionWindow = cfb24PositionWindow;
+			pScreen->ChangeWindowAttributes
+				= cfb24ChangeWindowAttributes;
+			pScreen->RealizeWindow = cfb24MapWindow;
+			pScreen->UnrealizeWindow = cfb24UnmapWindow;
+			pScreen->CreatePixmap = cfb24CreatePixmap;
+			pScreen->DestroyPixmap = cfb24DestroyPixmap;
+			mfbRegisterCopyPlaneProc(pScreen, cfb24CopyPlane);
+		} else {
+			bsFuncs = &cfb32BSFuncRec;
+			pScreen->GetImage = cfb32GetImage;
+			pScreen->GetSpans = cfb32GetSpans;
+			pScreen->PaintWindowBackground = cfb32PaintWindow;
+			pScreen->PaintWindowBorder = cfb32PaintWindow;
+			pScreen->CreateGC = cfb32CreateGC;
+			if (!cfb32AllocatePrivates(pScreen, NULL, NULL)) {
+				ErrorF("cfb32AllocatePrivates failed\n");
+				return FALSE;
+			}
+			pScreen->CreateWindow = cfb32CreateWindow;
+			pScreen->DestroyWindow = cfb32DestroyWindow;
+			pScreen->PositionWindow = cfb32PositionWindow;
+			pScreen->ChangeWindowAttributes
+				= cfb32ChangeWindowAttributes;
+			pScreen->RealizeWindow = cfb32MapWindow;
+			pScreen->UnrealizeWindow = cfb32UnmapWindow;
+			pScreen->CreatePixmap = cfb32CreatePixmap;
+			pScreen->DestroyPixmap = cfb32DestroyPixmap;
+			mfbRegisterCopyPlaneProc(pScreen, cfb32CopyPlane);
+		}
+		break;
+	default:
+		FatalError("root depth %d not supported\n", rootdepth);
+	}
+
+	pScreen->CreateColormap = cfbInitializeColormap;
+	pScreen->DestroyColormap = (DestroyColormapProcPtr)NoopDDA;
+	if (rootdepth == 1) {
+		pScreen->ResolveColor = mfbResolveColor;
+	} else {
+		pScreen->ResolveColor = cfbResolveColor;
+	}
+	pScreen->BitmapToRegion = mfbPixmapToRegion;
+
+	if (rootdepth != 8) {
+		oldDevPrivate = pScreen->devPrivate;
+	}
+
+	Rstatus = miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
+			       rootdepth, ndepths, depths, defaultVisual,
+			       nvisuals, visuals, bsFuncs);
+
+	switch (rootdepth) {
+	case 1:
+		pScreen->CloseScreen = mfbCloseScreen;
+		break;
+	case 8:
+		pScreen->CloseScreen = cfbCloseScreen;
+		break;
+	case 15:
+	case 16:
+		pScreen->CloseScreen = cfb16CloseScreen;
+		pScreen->CreateScreenResources = cfb16CreateScreenResources;
+		pScreen->devPrivates[cfb16ScreenPrivateIndex].ptr
+			= pScreen->devPrivate;
+		pScreen->devPrivate = oldDevPrivate;
+		break;
+	case 24:
+	case 32:
+		if (xggiScreens[scr].bitsPerPixel == 24) {
+			pScreen->CloseScreen = cfb24CloseScreen;
+			pScreen->CreateScreenResources
+				= cfb24CreateScreenResources;
+			pScreen->devPrivates[cfb24ScreenPrivateIndex].ptr
+				= pScreen->devPrivate;
+			pScreen->devPrivate = oldDevPrivate;
+		} else {
+			pScreen->CloseScreen = cfb32CloseScreen;
+			pScreen->CreateScreenResources 
+				= cfb32CreateScreenResources;
+			pScreen->devPrivates[cfb32ScreenPrivateIndex].ptr
+				= pScreen->devPrivate;
+			pScreen->devPrivate = oldDevPrivate;
+		}
+		break;
+	}
+	
+	return Rstatus;
+}
+
diff -urN xfree-3.3.6/programs/Xserver/hw/ggi/graphics.c xc/programs/Xserver/hw/ggi/graphics.c
--- xfree-3.3.6/programs/Xserver/hw/ggi/graphics.c	Thu Jan  1 01:00:00 1970
+++ xc/programs/Xserver/hw/ggi/graphics.c	Sun Oct 15 20:18:28 2000
@@ -0,0 +1,867 @@
+/* $Id: XFree3.3.diff,v 1.3 2000/10/15 18:25:29 marcus Exp $
+***************************************************************************
+
+   X server for LibGGI - Handling of graphics output
+
+   Copyright (C) 1997	   Jason McMullan	[jmcc@cs.cmu.edu]
+   Copyright (C) 1997	   Michael Krause	[rawstyle@ms.demo.org]
+   Copyright (C) 1998-2000 Marcus Sundberg	[marcus@ggi-project.org]
+
+   Permission is hereby granted, free of charge, to any person obtaining a
+   copy of this software and associated documentation files (the "Software"),
+   to deal in the Software without restriction, including without limitation
+   the rights to use, copy, modify, merge, publish, distribute, sublicense,
+   and/or sell copies of the Software, and to permit persons to whom the
+   Software is furnished to do so, subject to the following conditions:
+
+   The above copyright notice and this permission notice shall be included in
+   all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+   THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+   IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+***************************************************************************
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "X11/Xos.h"
+
+#define PSZ 8
+#include "cfb.h"
+#include "../../hw/xfree86/common/cfb16.h"
+#include "../../hw/xfree86/common/cfb24.h"
+#include "../../hw/xfree86/common/cfb32.h"
+
+#include "scrnintstr.h"
+#include "servermd.h"
+#include "colormapst.h"
+#include "mipointer.h"
+
+#include "xggi.h"
+
+#define MAX_COLORS 256 /* For the PseudoColor modes.. */
+
+struct xggiGlobalInfo xggiInfo = {
+	0,	/* Number of screens */
+	1, 1,	/* Screen rows and columns */
+	1,	/* Allow zapping ? */
+	1,	/* Automaticly set GII_CTRLALT_VTSWITCH */
+	0	/* Don't open new VT by default. */
+};
+
+struct xggiScreenInfo *xggiScreens;
+
+static char *targetlist = NULL, *modelist = NULL;
+static int defaultbpp = 0;
+static int ggiinit = 0;
+
+
+static void *
+safe_alloc(long siz)
+{
+	void *ret;
+
+	ret = xalloc(siz);
+	if (!ret) FatalError("Unable to allocate %d bytes of memory\n", siz);
+
+	return ret;
+}
+
+
+static void
+_ggiexit(void)
+{
+	int i;
+
+	for (i = 0; i < xggiInfo.numscreens; i++) {
+		if (xggiScreens[i].vis != NULL) {
+			ggiClose(xggiScreens[i].vis);
+			xggiScreens[i].vis = NULL;
+		}
+	}
+	if (ggiinit) {
+		ggiExit();
+		ggiinit = 0;
+	}
+}
+	
+void
+AbortDDX(void)
+{
+	_ggiexit();
+}
+
+void
+ddxGiveUp(void)
+{
+	_ggiexit();
+}
+
+
+void
+OsVendorInit(void)
+{
+}
+
+void
+OsVendorFatalError(void)
+{
+	_ggiexit();
+}
+
+void
+ddxUseMsg(void)
+{
+	ErrorF(
+"XGGI adds the following arguments:\n"
+"-targets targetlist    the target(s) we should open the screen(s) on\n"
+"-modes ggimodelist     the mode(s) we should use\n"
+"-bpp bitdepth          XFree86 compability option\n"
+"-rows numrows          number of screen rows in multihead configurations\n"
+#if 0 /* Rows are enough to describe the layout */
+"-columns               number of screen columns in multihead configurations\n"
+#endif
+"-buttons nr-buttons    specify number of pointer buttons\n"
+"-dontzap               disable the <Crtl><Alt><BS> server abort sequence\n"
+"-ggivtswitch           don't set GII_CTRLALT_VTSWITCH automaticly\n"
+"-newvt                 set GGI_NEWVT environment variable\n"
+"-noxfreeemu            provided only for backward compability\n");
+}
+
+int
+ddxProcessArgument(int argc, char *argv[], int i)
+{
+	if (!strcmp(argv[i], "-targets")) {
+		if (i + 1 >= argc) {
+			ErrorF("Option `-targets' requires an argument\n");
+			return 1;
+		}
+		targetlist = safe_alloc(strlen(argv[i+1])+1);
+		strcpy(targetlist, argv[i+1]);
+		return 2;
+	}
+	if (!strcmp(argv[i], "-modes")) {
+		if (i + 1 >= argc) {
+			ErrorF("Option `-modes' requires an argument\n");
+			return 1;
+		}
+	        modelist = safe_alloc(strlen(argv[i+1])+1);
+		strcpy(modelist, argv[i+1]);
+		return 2;
+	}
+	if (!strcmp(argv[i], "-bpp")) {
+		if (i + 1 >= argc) {
+			ErrorF("Option `-bpp' requires an argument\n");
+			return 1;
+		}
+		defaultbpp = atoi(argv[i+1]);
+		return 2;
+	}
+	if (!strcmp(argv[i], "-rows")) {
+		if (i + 1 >= argc) {
+			ErrorF("Option `-rows' requires an argument\n");
+			return 1;
+		}
+		xggiInfo.rows = atoi(argv[i+1]);
+		return 2;
+	}
+#if 0
+	if (!strcmp(argv[i], "-columns")) {
+		if (i + 1 >= argc) {
+			ErrorF("Option `-columns' requires an argument\n");
+			return 1;
+		}
+		xggiInfo.columns = atoi(argv[i+1]);
+		return 2;
+	}
+#endif
+	if (!strcmp(argv[i], "-buttons")) {
+		if (i + 1 >= argc) {
+			ErrorF("Option `-buttons' requires an argument\n");
+			return 1;
+		}
+		xggiScreens[0].ptrbuttons = atoi(argv[i+1]);
+		return 2;
+	}
+	if (!strcmp(argv[i], "-dontzap")) {
+		xggiInfo.allowzap = 0;
+		return 1;
+	}
+	if (!strcmp(argv[i], "-ggivtswitch")) {
+		xggiInfo.ctrlalt_vtswitch = 0;
+		return 1;
+	}	
+	if (!strcmp(argv[i], "-newvt")) {
+		xggiInfo.newvt = 1;
+		return 1;
+	}	
+	if (!strcmp(argv[i], "-noxfreeemu")) {
+		return 1;
+	}	
+
+	return 0;
+}
+
+#ifdef DDXTIME /* from ServerOSDefines */
+CARD32
+GetTimeInMillis(void)
+{
+	struct timeval  tp;
+
+	X_GETTIMEOFDAY(&tp);
+	return TVAL2TIME(tp);
+}
+#endif
+
+int
+xggiGetScreenIdx(ScreenPtr screen)
+{
+	int i;
+
+	for (i = 0; i < xggiInfo.numscreens; i++) {
+		if (xggiScreens[i].screen == screen) return i;
+	}
+
+	*((uint32*)0) = 43;
+	FatalError("Tried to operate on invalid screen\n");
+
+	/* Never reached */
+	return -1;
+}
+
+
+static ColormapPtr InstalledMaps[MAXSCREENS];
+
+static int
+xggiListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
+{
+	/* By the time we are processing requests, we can guarantee that there
+	 * is always a colormap installed */
+	*pmaps = InstalledMaps[pScreen->myNum]->mid;
+	return (1);
+}
+
+
+static void
+xggiInstallColormap(ColormapPtr pmap)
+{
+	int index = pmap->pScreen->myNum;
+	ColormapPtr oldpmap = InstalledMaps[index];
+
+	if (pmap != oldpmap) {
+			int entries;
+			VisualPtr pVisual;
+			Pixel *     ppix;
+			xrgb *      prgb;
+			xColorItem *defs;
+			int i;
+
+			if (oldpmap != (ColormapPtr)None)
+				WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
+			/* Install pmap */
+			InstalledMaps[index] = pmap;
+			WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
+
+			entries = pmap->pVisual->ColormapEntries;
+			pVisual = pmap->pVisual;
+
+			ppix = (Pixel *)ALLOCATE_LOCAL(entries * sizeof(Pixel));
+			prgb = (xrgb *)ALLOCATE_LOCAL(entries * sizeof(xrgb));
+			defs = (xColorItem *)ALLOCATE_LOCAL(entries * sizeof(xColorItem));
+
+			for (i = 0; i < entries; i++)  ppix[i] = i;
+			/* XXX truecolor */
+			QueryColors(pmap, entries, ppix, prgb);
+
+			for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
+				defs[i].pixel = ppix[i] & 0xff; /* change pixel to index */
+				defs[i].red = prgb[i].red;
+				defs[i].green = prgb[i].green;
+				defs[i].blue = prgb[i].blue;
+				defs[i].flags =  DoRed|DoGreen|DoBlue;
+			}
+			(*pmap->pScreen->StoreColors)(pmap, entries, defs);
+
+			DEALLOCATE_LOCAL(ppix);
+			DEALLOCATE_LOCAL(prgb);
+			DEALLOCATE_LOCAL(defs);
+		}
+}
+
+static void
+xggiUninstallColormap(ColormapPtr pmap)
+{
+	ColormapPtr curpmap = InstalledMaps[pmap->pScreen->myNum];
+
+	if (pmap == curpmap) {
+		if (pmap->mid != pmap->pScreen->defColormap) {
+			curpmap = (ColormapPtr)
+				LookupIDByType(pmap->pScreen->defColormap,
+					       RT_COLORMAP);
+			(*pmap->pScreen->InstallColormap)(curpmap);
+		}
+	}
+}
+
+static void
+xggiStoreColors(ColormapPtr pmap, int ndef, xColorItem  *pdefs)
+{
+	int i;
+	ggi_color cmap[MAX_COLORS];
+	int scr;
+
+	if (pmap != InstalledMaps[pmap->pScreen->myNum]) {
+		return;
+	}
+
+	if ((pmap->pVisual->class | DynamicClass) == DirectColor) {
+		return;
+	}
+
+	scr = xggiGetScreenIdx(pmap->pScreen);
+
+	ggiGetPalette(xggiScreens[scr].vis, 0, MAX_COLORS, cmap);
+
+	for (i = 0; i < ndef; i++) {
+		if (pdefs[i].pixel >= MAX_COLORS) continue;
+
+		if (pdefs[i].flags & DoRed) {
+			cmap[pdefs[i].pixel].r = pdefs[i].red;
+		}
+		if (pdefs[i].flags & DoGreen) {
+			cmap[pdefs[i].pixel].g = pdefs[i].green;
+		}
+		if (pdefs[i].flags & DoBlue) {
+			cmap[pdefs[i].pixel].b = pdefs[i].blue;
+		}
+	}
+
+	ggiSetPalette(xggiScreens[scr].vis, 0, MAX_COLORS, cmap);
+}
+
+static Bool
+xggiSaveScreen(ScreenPtr pScreen, int on)
+{
+#if 0
+	switch (what) {
+	case SCREEN_SAVER_ON:
+		break;
+      
+	case SCREEN_SAVER_OFF:
+		break;
+      
+	case SCREEN_SAVER_FORCER:
+		break;
+      
+	case SCREEN_SAVER_CYCLE:
+		break;
+	}
+#endif
+
+	return TRUE;
+}
+
+
+static void
+do_blit(ScreenPtr pScreen, int bits_per_pixel,
+	DrawablePtr src, DrawablePtr dest)
+{
+	DDXPointRec pixPt;
+	BoxRec    pixBox;
+	RegionRec pixReg;
+
+	pixBox.x1 = 0;
+	pixBox.x2 = pScreen->width;
+	pixBox.y1 = 0;
+	pixBox.y2 = pScreen->height;
+	pixPt.x = pixPt.y = 0;
+	pScreen->RegionInit(&pixReg, &pixBox, 1);
+
+	if (bits_per_pixel == 1) {
+		mfbDoBitblt(src, dest, GXcopy, &pixReg, &pixPt);
+	} else if (bits_per_pixel == 8) { 
+		cfbDoBitblt(src, dest, GXcopy, &pixReg, &pixPt, 0xFF);
+	} else if (bits_per_pixel == 16) {
+		cfb16DoBitblt(src, dest, GXcopy, &pixReg, &pixPt, 0xFFFF);
+	} else if (bits_per_pixel == 24) {
+		cfb24DoBitblt(src, dest, GXcopy, &pixReg, &pixPt, 0xFFFFFF);
+	} else if (bits_per_pixel == 32) {
+		cfb32DoBitblt(src, dest, GXcopy, &pixReg, &pixPt, 0xFFFFFFFF);
+	}
+}
+
+
+static void
+dounmap(int idx)
+{
+	ScreenPtr pScreen = xggiScreens[idx].screen;
+	int bits_per_pixel = xggiScreens[idx].bitsPerPixel;
+	PixmapPtr frontbuf;
+
+        xggiScreens[idx].backbuffer
+		= pScreen->CreatePixmap(pScreen, pScreen->width,
+					pScreen->height, pScreen->rootDepth);
+	if (!xggiScreens[idx].backbuffer) {
+		FatalError("Unable to allocate backbuffer!\n");
+	}
+
+	if (bits_per_pixel == 16) {
+		frontbuf = (PixmapPtr)pScreen->devPrivates[cfb16ScreenPrivateIndex].ptr;
+	} else if (bits_per_pixel == 24) {
+		frontbuf = (PixmapPtr)pScreen->devPrivates[cfb24ScreenPrivateIndex].ptr;
+	} else if (bits_per_pixel == 32) {
+		frontbuf = (PixmapPtr)pScreen->devPrivates[cfb32ScreenPrivateIndex].ptr;
+	} else {
+		frontbuf = (PixmapPtr)pScreen->devPrivate;
+	}
+
+	do_blit(pScreen, bits_per_pixel,
+		&frontbuf->drawable,
+		&xggiScreens[idx].backbuffer->drawable);
+
+	frontbuf->devPrivate.ptr = xggiScreens[idx].backbuffer->devPrivate.ptr;
+	xggiScreens[idx].ismapped = 0;
+}
+
+	
+static void
+domap(int idx)
+{
+	ScreenPtr pScreen = xggiScreens[idx].screen;
+	int bits_per_pixel = xggiScreens[idx].bitsPerPixel;
+	PixmapPtr frontbuf;
+
+	if (bits_per_pixel == 16) {
+		frontbuf = (PixmapPtr)pScreen->devPrivates[cfb16ScreenPrivateIndex].ptr;
+	} else if (bits_per_pixel == 24) {
+		frontbuf = (PixmapPtr)pScreen->devPrivates[cfb24ScreenPrivateIndex].ptr;
+	} else if (bits_per_pixel == 32) {
+		frontbuf = (PixmapPtr)pScreen->devPrivates[cfb32ScreenPrivateIndex].ptr;
+	} else {
+		frontbuf = (PixmapPtr)pScreen->devPrivate;
+	}
+
+	frontbuf->devPrivate.ptr = xggiScreens[idx].pfbMemory;
+
+	do_blit(pScreen, bits_per_pixel,
+		&xggiScreens[idx].backbuffer->drawable,
+		&frontbuf->drawable);
+	
+	pScreen->DestroyPixmap(xggiScreens[idx].backbuffer);
+	xggiScreens[idx].backbuffer = NULL;
+	xggiScreens[idx].ismapped = 1;
+}
+
+
+void
+xggiUnmapDisplay(void)
+{
+	int i;
+
+	for (i = 0; i < xggiInfo.numscreens; i++) {
+		dounmap(i);
+	}
+}
+
+
+void
+xggiMapDisplay(void)
+{
+	int i;
+
+	for (i = 0; i < xggiInfo.numscreens; i++) {
+		domap(i);
+	}
+}
+
+
+#define XYtoI(x,y)	((y) * xggiInfo.columns + (x))
+#define ItoXY(x,y,i) \
+do { \
+	(x) = (i) % xggiInfo.columns; \
+	(y) = (i) / xggiInfo.columns; \
+}while(0)
+
+static Bool
+xggiCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
+{
+	int scr = xggiGetScreenIdx(*ppScreen);
+	int maxscr = xggiInfo.numscreens-1;
+	int newscr;
+	int xs, ys;
+	
+	if (maxscr < 1) return FALSE;
+
+	if (*x >= xggiScreens[scr].mode.visible.x) {
+		ItoXY(xs, ys, scr);
+		xs++;
+		if (xs >= xggiInfo.columns) return FALSE;
+		newscr = XYtoI(xs, ys);
+		if (newscr > maxscr) return FALSE;
+
+		*ppScreen = xggiScreens[newscr].screen;
+		*x = 0;
+		return TRUE;
+	} else if (*x < 0) {
+		ItoXY(xs, ys, scr);
+		xs--;
+		if (xs < 0) return FALSE;
+		newscr = XYtoI(xs, ys);
+		if (newscr < 0) return FALSE;
+
+		*ppScreen = xggiScreens[newscr].screen;
+		*x = xggiScreens[newscr].mode.visible.x - 1;
+		return TRUE;
+	} else if (*y >= xggiScreens[scr].mode.visible.y) {
+		ItoXY(xs, ys, scr);
+		ys++;
+		if (ys >= xggiInfo.rows) return FALSE;
+		newscr = XYtoI(xs, ys);
+		if (newscr > maxscr) return FALSE;
+
+		*ppScreen = xggiScreens[newscr].screen;
+		*y = 0;
+		return TRUE;
+	} else if (*y < 0) {
+		ItoXY(xs, ys, scr);
+		ys--;
+		if (ys < 0) return FALSE;
+		newscr = XYtoI(xs, ys);
+		if (newscr < 0) return FALSE;
+
+		*ppScreen = xggiScreens[newscr].screen;
+		*y = xggiScreens[newscr].mode.visible.y - 1;
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static void
+xggiCrossScreen(ScreenPtr pScreen, Bool entering)
+{
+}
+
+static miPointerScreenFuncRec xggiPointerCursorFuncs =
+{
+	xggiCursorOffScreen,
+	xggiCrossScreen,
+	miPointerWarpCursor
+};
+
+static Bool
+xggiFBInitProc(int index, ScreenPtr pScreen,
+	       int argc, char *argv[])
+{
+	const int dpix = 100, dpiy = 100;
+	int scr = index;
+	Bool ret;
+
+#ifdef XGGI_DEBUG
+	ErrorF("Index: %d, pScreen %p, depth: %d\n", index, pScreen,
+	       xggiScreens[scr].depth);
+#endif
+
+	xggiScreens[scr].screen = pScreen;
+	
+	if (!xggiScreenInit(pScreen, xggiScreens[scr].pfbMemory,
+			    xggiScreens[scr].width, xggiScreens[scr].height,
+			    dpix, dpiy, xggiScreens[scr].stride)) {
+		ErrorF("xggiScreenInit failed\n");
+		return FALSE;
+	}
+
+	pScreen->SaveScreen = xggiSaveScreen;
+
+	switch (xggiScreens[scr].depth) {
+	case 1:
+		pScreen->InstallColormap = mfbInstallColormap;
+		pScreen->UninstallColormap = mfbUninstallColormap;
+		pScreen->ListInstalledColormaps = mfbListInstalledColormaps;
+		pScreen->StoreColors = (void (*)())NoopDDA;
+		break;
+	case 15:
+	case 16:
+	case 24:
+	case 32:
+		pScreen->InstallColormap = cfbInstallColormap;
+		pScreen->UninstallColormap = cfbUninstallColormap;
+		pScreen->ListInstalledColormaps = cfbListInstalledColormaps;
+		pScreen->StoreColors = (void (*)())NoopDDA;
+		break;
+	default:
+		pScreen->InstallColormap = xggiInstallColormap;
+		pScreen->UninstallColormap = xggiUninstallColormap;
+		pScreen->ListInstalledColormaps = xggiListInstalledColormaps;
+		pScreen->StoreColors = xggiStoreColors;
+		break;
+	}
+
+	miDCInitialize(pScreen, &xggiPointerCursorFuncs);
+
+	if (xggiScreens[scr].depth == 1) {
+		ret = mfbCreateDefColormap(pScreen);
+	} else {
+		ret = cfbCreateDefColormap(pScreen);
+	}
+	if (!ret) ErrorF("[c|m]fbCreateDefColormap failed\n");
+
+	return ret;
+} 
+
+
+static int
+count_targets(char *targets)
+{
+	char tgttemp[2048];
+	int count = 0;
+
+	while (1) {
+		targets = ggParseTarget(targets, tgttemp, 2048);
+
+		if (targets == NULL) break;
+
+		count++;
+
+		while (*targets && isspace((int)*targets)) targets++;
+		if (*targets == '\0') {
+			break;
+		}
+
+		if (*targets != ':') {
+			FatalError("Missing ':' between targets: %c\n", *targets);
+		}
+
+		targets++;  /* skip ':' */
+	}
+
+	return count;
+}	
+
+
+static void
+reset_xggiscreen(int i)
+{
+	xggiScreens[i].vis		= NULL;
+	xggiScreens[i].ptrbuttons	= DEFAULT_PTRBUTTONS;
+	xggiScreens[i].width		= GGI_AUTO;
+	xggiScreens[i].height		= GGI_AUTO;
+	xggiScreens[i].depth		= 0;
+	xggiScreens[i].stride		= 0;
+	xggiScreens[i].bitsPerPixel	= 0;
+	/* xggiScreens[i].mode		= */
+	xggiScreens[i].dbuf		= NULL;
+	xggiScreens[i].pfbMemory	= NULL;
+	xggiScreens[i].screen		= NULL;
+	xggiScreens[i].backbuffer	= NULL;
+	xggiScreens[i].ismapped		= 1;
+}
+
+
+static ggi_graphtype
+bpp2gt(int bpp)
+{
+	switch (bpp) {
+	case 1:		return GT_1BIT;
+	case 2:		return GT_2BIT;
+	case 4:		return GT_4BIT;
+	case 8:		return GT_8BIT;
+	case 15:	return GT_15BIT;
+	case 16:	return GT_16BIT;
+	case 24:	return GT_24BIT;
+	case 32:	return GT_32BIT;
+	}
+	
+	return GT_AUTO;
+}
+
+
+
+static void
+InitGGI(ScreenInfo *screenInfo, int argc, char *argv[])
+{
+	int i, size;
+	ggi_graphtype gt;
+	const ggi_directbuffer *dbuf = NULL;
+	char *targets = targetlist;
+	char *modes = modelist;
+
+	if (targets != NULL) {
+		xggiInfo.numscreens = count_targets(targets);
+		if (xggiInfo.rows < 1) {
+			xggiInfo.rows = 1;
+			xggiInfo.columns = xggiInfo.numscreens;
+		} else if (xggiInfo.rows > xggiInfo.numscreens) {
+			xggiInfo.rows = xggiInfo.numscreens;
+			xggiInfo.columns = 1;
+		} else {
+			xggiInfo.columns = xggiInfo.numscreens / xggiInfo.rows;
+			if (xggiInfo.numscreens % xggiInfo.rows) {
+				xggiInfo.columns++;
+			}
+		}
+	} else {
+		/* One screen on default LibGGI visual */
+		xggiInfo.numscreens = xggiInfo.rows = xggiInfo.columns = 1;
+	}
+
+	xggiScreens = safe_alloc(sizeof(struct xggiScreenInfo)
+				 * xggiInfo.numscreens);
+
+	for (i = 0; i < xggiInfo.numscreens; i++) {
+		reset_xggiscreen(i);
+	}
+
+	if (xggiInfo.ctrlalt_vtswitch) {
+		putenv("GII_CTRLALT_VTSWITCH=1");
+	}
+	if (xggiInfo.newvt) {
+		putenv("GGI_NEWVT=1");
+	}
+
+	if (ggiInit() < 0) {
+		FatalError("Unable to init LibGGI!\n");
+	}
+	ggiinit = 1;
+
+	for (i = 0; i < xggiInfo.numscreens; i++) {
+		char tgttemp[2048];
+		char *currtarget = NULL;
+		int j;
+
+		if (targets) {
+			targets = ggParseTarget(targets, tgttemp, 2048);
+
+			if (*tgttemp != '\0') {
+				currtarget = tgttemp;
+			}
+
+			while (*targets && isspace((int)*targets)) targets++;
+			targets++;  /* skip ':' */
+		}
+
+		if ((xggiScreens[i].vis = ggiOpen(currtarget)) == NULL) {
+			FatalError("Unable to open LibGGI visual: \"%s\"\n",
+				   currtarget ? currtarget : "(NULL)");
+		}
+
+#if 0	/* Can we hook in ggiFlush() somewhere? */
+		ggiSetFlags(xggiScreens[i].vis, GGIFLAG_ASYNC);
+#endif
+
+		if (modes != NULL &&
+		    (modes = ggParseTarget(modes, tgttemp, 2048)) != NULL) {
+			ggiParseMode(tgttemp, &xggiScreens[i].mode);
+			
+			while (*modes && isspace((int)*modes)) modes++;
+			if (*modes == '\0') {
+				modes = NULL;
+				goto end_of_modeparsing;
+			}
+			if (*modes != ':') {
+				FatalError("Missing ':' between modes\n");
+			}
+
+			modes++;  /* skip ':' */
+		} else {
+			ggiParseMode("", &xggiScreens[i].mode);
+		}
+	  end_of_modeparsing:
+
+		if (xggiScreens[i].mode.graphtype == GT_AUTO &&
+		    defaultbpp != 0) {
+			xggiScreens[i].mode.graphtype = bpp2gt(defaultbpp);
+		}
+		ggiCheckMode(xggiScreens[i].vis, &xggiScreens[i].mode);
+
+		if (i == 0) {
+			gt = xggiScreens[i].mode.graphtype;
+		}
+
+		if (GT_SIZE(xggiScreens[i].mode.graphtype) != 1 &&
+		    GT_SIZE(xggiScreens[i].mode.graphtype) != 8 &&
+		    GT_SIZE(xggiScreens[i].mode.graphtype) != 16 &&
+		    GT_SIZE(xggiScreens[i].mode.graphtype) != 24 &&
+		    GT_SIZE(xggiScreens[i].mode.graphtype) != 32) {
+			FatalError("XGGI doesn't support %d bpp screens.\n",
+				   GT_SIZE(xggiScreens[i].mode.graphtype));
+		}
+		if (xggiScreens[i].mode.graphtype != gt) {
+			FatalError("All GGI visuals must be of the same depth.\n");
+		}
+
+		xggiScreens[i].width  = xggiScreens[i].mode.visible.x;
+		xggiScreens[i].height = xggiScreens[i].mode.visible.y;
+		xggiScreens[i].depth
+			= GT_DEPTH(xggiScreens[i].mode.graphtype);
+		xggiScreens[i].bitsPerPixel
+			= GT_SIZE(xggiScreens[i].mode.graphtype);
+
+		if (ggiSetMode(xggiScreens[i].vis, &xggiScreens[i].mode)) {
+			FatalError("LibGGI can not set any modes at all!\n");
+		}
+	
+		size = GT_SIZE(xggiScreens[i].mode.graphtype);
+		for (j = 0;
+		     (dbuf = ggiDBGetBuffer(xggiScreens[i].vis, j)) != NULL;
+		     j++) {
+			if ((dbuf->type & GGI_DB_SIMPLE_PLB)
+			    && ((8*dbuf->buffer.plb.stride) % size) == 0) {
+				xggiScreens[i].dbuf = dbuf;
+				break;
+			}
+		}
+		    
+		if (!xggiScreens[i].dbuf) {
+			FatalError("This mode and target has no suitable DirectBuffer\n");
+		}
+
+		if (ggiResourceAcquire(xggiScreens[i].dbuf->resource,
+				       GGI_ACTYPE_WRITE | GGI_ACTYPE_READ)
+		    != 0) {
+			FatalError("Unable to acquire DirectBuffer\n");
+		}
+
+		xggiScreens[i].pfbMemory = dbuf->write;
+		xggiScreens[i].stride = 8 * dbuf->buffer.plb.stride / size;
+		xggiScreens[i].dbuf = dbuf;
+	}
+}
+
+
+void
+InitOutput(ScreenInfo *screenInfo, int argc, char *argv[])
+{
+	int i;
+
+	if (!ggiinit) {
+		InitGGI(screenInfo, argc, argv);
+	}
+
+	screenInfo->formats[0].depth = 1;
+	screenInfo->formats[0].bitsPerPixel = 1;
+	screenInfo->formats[0].scanlinePad = BITMAP_SCANLINE_PAD;
+	screenInfo->formats[1].depth = xggiScreens[0].depth;
+	screenInfo->formats[1].bitsPerPixel = xggiScreens[0].bitsPerPixel;
+	screenInfo->formats[1].scanlinePad = BITMAP_SCANLINE_PAD;
+
+	screenInfo->numPixmapFormats = 2;
+
+	screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
+	screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+	screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+	screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
+
+	/* Add screens */
+	for (i = 0; i < xggiInfo.numscreens; i++) {
+		if (AddScreen(xggiFBInitProc, argc, argv) == -1) {
+			FatalError("Couldn't add screen");
+		}
+	}
+}
diff -urN xfree-3.3.6/programs/Xserver/hw/ggi/input.c xc/programs/Xserver/hw/ggi/input.c
--- xfree-3.3.6/programs/Xserver/hw/ggi/input.c	Thu Jan  1 01:00:00 1970
+++ xc/programs/Xserver/hw/ggi/input.c	Sun Oct 15 20:00:52 2000
@@ -0,0 +1,348 @@
+/* $Id: XFree3.3.diff,v 1.3 2000/10/15 18:25:29 marcus Exp $
+***************************************************************************
+
+   X server for LibGGI - Handling of input devices
+
+   Copyright (C) 1997	   Jason McMullan	[jmcc@cs.cmu.edu]
+   Copyright (C) 1997	   Michael Krause	[rawstyle@ms.demo.org]
+   Copyright (C) 1998-2000 Marcus Sundberg	[marcus@ggi-project.org]
+
+   Permission is hereby granted, free of charge, to any person obtaining a
+   copy of this software and associated documentation files (the "Software"),
+   to deal in the Software without restriction, including without limitation
+   the rights to use, copy, modify, merge, publish, distribute, sublicense,
+   and/or sell copies of the Software, and to permit persons to whom the
+   Software is furnished to do so, subject to the following conditions:
+
+   The above copyright notice and this permission notice shall be included in
+   all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+   THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+   IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+***************************************************************************
+*/
+
+#include <stdlib.h>
+#include "X11/X.h"
+#define NEED_EVENTS
+#include "X11/Xproto.h"
+
+#include "scrnintstr.h"
+#include "inputstr.h"
+#include "mipointer.h"
+#include "input.h"
+#include "mi.h"
+
+#include "xggi.h"
+
+
+struct xggi_hotkeys {
+	uint32 keys[4];
+	void (*handler)(void);
+	int mask;
+};
+
+static void handle_serverkill(void);
+
+static struct xggi_hotkeys hotkeys[] = {
+    {{ GIIK_Ctrl, GIIK_Alt, GIIUC_BackSpace, GIIK_VOID },
+     handle_serverkill, },
+};
+#define NUMHANDLERS	(sizeof(hotkeys)/sizeof(struct xggi_hotkeys))
+
+
+static void
+MouseQueueMovement(DeviceIntPtr device, int dx, int dy, Time tm)
+{
+	PtrCtrl *pCtrl = &device->ptrfeed->ctrl;
+
+	if ((abs(dx) + abs(dy)) >= pCtrl->threshold) {
+		dx = (dx * pCtrl->num) / pCtrl->den;
+		dy = (dy * pCtrl->num)/ pCtrl->den;
+	}
+
+	miPointerDeltaCursor(dx, dy, tm);
+}
+
+static void
+xggiQueueMouseEvent(ggi_event *ev)
+{
+	DevicePtr pMouse;
+	xEvent xev;
+	static int oldx = 0, oldy = 0;
+    
+	pMouse = LookupPointerDevice();
+	if (!pMouse->on) return;
+    
+	switch (ev->any.type) {
+	case evPtrAbsolute:
+		miPointerDeltaCursor(ev->pmove.x - oldx, ev->pmove.y - oldy,
+				     TVAL2TIME(ev->any.time));
+		oldx = ev->pmove.x;
+		oldy = ev->pmove.y;
+		return;
+
+	case evPtrRelative:
+		MouseQueueMovement((DeviceIntPtr)pMouse,
+				   ev->pmove.x, ev->pmove.y,
+				   TVAL2TIME(ev->any.time));
+		oldx += ev->pmove.x;
+		oldy += ev->pmove.y;
+		return;
+
+	case evPtrButtonPress:
+		xev.u.u.type = ButtonPress;
+		break;
+
+	case evPtrButtonRelease:
+		xev.u.u.type = ButtonRelease;
+		break;
+	default:
+		/* Unknown pointer event */
+		return;
+	}
+
+	switch (ev->pbutton.button) {
+	case 2:
+		/* Right button */
+		xev.u.u.detail = 3;
+		break;
+	case 3:
+		/* Middle button */
+		xev.u.u.detail = 2;
+		break;
+	default:
+		/* Other button */
+		xev.u.u.detail = ev->pbutton.button;
+		break;
+	}
+	xev.u.keyButtonPointer.time = TVAL2TIME(ev->any.time);
+	mieqEnqueue(&xev);
+
+	return;
+}
+  
+static int
+xggiMouseProc(DeviceIntPtr pDevice, int onoff)
+{
+	BYTE *map;
+	int i;
+	DevicePtr pDev = (DevicePtr)pDevice;
+
+	switch (onoff) {
+	case DEVICE_INIT:
+		if ((map = malloc(sizeof(BYTE)*(xggiScreens[0].ptrbuttons+1)))
+		    == NULL) {
+			FatalError("xggiMouseProc: Cannot allocate temporary memory!\n");
+		}
+		for (i = 0; i <= xggiScreens[0].ptrbuttons; i++) {
+			map[i] = i;
+		}
+		InitPointerDeviceStruct(pDev, map, xggiScreens[0].ptrbuttons,
+					miPointerGetMotionEvents,
+					(PtrCtrlProcPtr)NoopDDA,
+					miPointerGetMotionBufferSize());
+		free(map);
+		break;
+	
+	case DEVICE_ON:
+		pDev->on = TRUE;
+		break;
+	
+	case DEVICE_OFF:
+		pDev->on = FALSE;
+		break;
+	
+	case DEVICE_CLOSE:
+		break;
+	}
+
+	return Success;
+}
+
+void
+ProcessInputEvents(void)
+{
+	mieqProcessInputEvents();
+	miPointerUpdate();
+}
+
+
+static void
+hotkeys_reset(void)
+{
+	int i, j;
+
+	for (i = 0; i < NUMHANDLERS; i++) {
+		hotkeys[i].mask = 0;
+		for (j = 0; hotkeys[i].keys[j] != GIIK_VOID; j++) {
+			hotkeys[i].mask |= (1 << j);
+		}
+	}
+}
+
+
+static void
+handle_serverkill(void)
+{
+	if (xggiInfo.allowzap) {
+		FatalError("Server killed by Ctrl-Alt-Backspace\n");
+	}
+}
+
+
+static void
+handle_hotkeys(ggi_event *ev)
+{
+	if (ev->any.type == evKeyPress) {
+		int i, j;
+		for (i = 0; i < NUMHANDLERS; i++) {
+			for (j = 0; hotkeys[i].keys[j] != GIIK_VOID; j++) {
+				if (ev->key.sym == hotkeys[i].keys[j]) {
+					hotkeys[i].mask &= ~(1 << j);
+					if (hotkeys[i].mask == 0) {
+						hotkeys[i].handler();
+					}
+				}
+			}
+		}
+	} else {
+		int i, j;
+		for (i = 0; i < NUMHANDLERS; i++) {
+			for (j = 0; hotkeys[i].keys[j] != GIIK_VOID; j++) {
+				if (ev->key.sym == hotkeys[i].keys[j]) {
+					hotkeys[i].mask |= (1 << j);
+				}
+			}
+		}
+	}
+}
+
+
+static void
+xggiDispatchEvents(void)
+{
+	struct timeval tv = {0,0};
+	int n;
+	int screen = 0;
+
+	if (! ggiEventPoll(MASTER_VIS, emAll, &tv)) return;
+
+	n = ggiEventsQueued(MASTER_VIS, emAll);
+	while (n--) {
+		ggi_event ev;
+
+		ggiEventRead(MASTER_VIS, &ev, emAll);
+		
+		switch (ev.any.type) {
+		case evPtrRelative:
+		case evPtrAbsolute:
+		case evPtrButtonPress:
+		case evPtrButtonRelease:
+			xggiQueueMouseEvent(&ev);
+			break;
+
+		case evKeyPress:
+		case evKeyRelease:
+			handle_hotkeys(&ev);
+		case evKeyRepeat:
+			xggiQueueKeyboardEvent(&ev);
+			break;
+
+		case evCommand:
+			if (!xggiScreens[screen].ismapped) break;
+
+			if (ev.cmd.code == GGICMD_REQUEST_SWITCH) {
+				ggi_cmddata_switchrequest *data = (void*)
+					ev.cmd.data;
+				if (data->request == GGI_REQSW_UNMAP) {
+					ggi_event ev;
+
+					ev.cmd.size = sizeof(gii_cmd_nodata_event);
+					ev.cmd.type = evCommand;
+					ev.cmd.code =GGICMD_ACKNOWLEDGE_SWITCH;
+
+					/* Map X display away */
+					xggiUnmapDisplay();
+					/* Reset hotkey state */
+					hotkeys_reset();
+					/* Acknowledge unmap */
+					ggiEventSend(MASTER_VIS, &ev);
+					/* Disable pointer events */
+					ggiSetEventMask(MASTER_VIS, emCommand |
+							emExpose | emKeyboard);
+					/* We don't want any more events now */
+					goto end_of_eventloop;
+				}
+			}
+			break;
+
+		case evExpose:
+			if (!xggiScreens[screen].ismapped) {
+				xggiMapDisplay();
+				/* Enable pointer events */
+				ggiSetEventMask(MASTER_VIS, emCommand |
+						emExpose |
+						emKeyboard | emPointer);
+			}
+			break;
+
+		default:
+			break;
+		}
+	}
+  end_of_eventloop:
+}
+
+
+static CARD32
+xggiSnarf(OsTimerPtr timer, CARD32 time, pointer data)
+{
+	xggiDispatchEvents();
+
+	return 20 /* Millis */;
+}
+
+static void
+xggiInputTimer(void)
+{
+	static OsTimerPtr timer;
+	timer = TimerSet(NULL, 0, 20 /* Millis */, xggiSnarf, NULL);
+}
+
+/*****************************
+ * Initailize input handlers *
+ *****************************/
+void
+InitInput(int argc, char *argv[])
+{
+	ggi_event ev;
+
+	DeviceIntPtr p, k;
+
+	ggiSetEventMask(MASTER_VIS, emCommand | emExpose
+			| emKeyboard | emPointer);
+
+	p = AddInputDevice(xggiMouseProc, TRUE);
+	k = AddInputDevice(xggiKeybdProc, TRUE);
+	RegisterPointerDevice(p);
+	RegisterKeyboardDevice(k);
+	miRegisterPointerDevice(screenInfo.screens[0], p);
+	mieqInit((DevicePtr) k, (DevicePtr) p);
+	
+	xggiInputTimer();
+
+	/* Don't halt the application on unmap */
+	ev.cmd.size = sizeof(gii_cmd_nodata_event);
+	ev.cmd.type = evCommand;
+	ev.cmd.code = GGICMD_NOHALT_ON_UNMAP;
+	ggiEventSend(MASTER_VIS, &ev);
+
+	/* Init hotkey stuff */
+	hotkeys_reset();
+}
diff -urN xfree-3.3.6/programs/Xserver/hw/ggi/keyboard.c xc/programs/Xserver/hw/ggi/keyboard.c
--- xfree-3.3.6/programs/Xserver/hw/ggi/keyboard.c	Thu Jan  1 01:00:00 1970
+++ xc/programs/Xserver/hw/ggi/keyboard.c	Sun Oct 15 14:30:12 2000
@@ -0,0 +1,444 @@
+/* $Id: XFree3.3.diff,v 1.3 2000/10/15 18:25:29 marcus Exp $
+***************************************************************************
+
+   X server for LibGGI - Keyboard handling
+
+   Copyright (C) 1997	   Michael Krause	[rawstyle@ms.demo.org]
+   Copyright (C) 1998-1999 Marcus Sundberg	[marcus@ggi-project.org]
+
+   Permission is hereby granted, free of charge, to any person obtaining a
+   copy of this software and associated documentation files (the "Software"),
+   to deal in the Software without restriction, including without limitation
+   the rights to use, copy, modify, merge, publish, distribute, sublicense,
+   and/or sell copies of the Software, and to permit persons to whom the
+   Software is furnished to do so, subject to the following conditions:
+
+   The above copyright notice and this permission notice shall be included in
+   all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+   THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+   IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+***************************************************************************
+*/
+
+#include "X.h"
+#include "inputstr.h"
+#include "input.h"
+#include "mi.h"
+
+#include "keysym.h"
+#include "keysymdef.h"
+
+#include "xggi.h"
+#include "keymap.h"
+
+
+static uint32 ggicodemap[NUM_KEYCODES] = {
+	GIIK_F1,
+	GIIK_F2,
+	GIIK_F3,
+	GIIK_F4,
+	GIIK_F5,
+	GIIK_F6,
+	GIIK_F7,
+	GIIK_F8,
+	GIIK_F9,
+	GIIK_F10,
+	GIIK_F11,
+	GIIK_F12,
+	GIIK_F13,
+	GIIK_F14,
+	GIIK_F15,
+	GIIK_F16,
+	GIIK_F17,
+	GIIK_F18,
+	GIIK_F19,
+	GIIK_F20,
+	GIIK_F21,
+	GIIK_F22,
+	GIIK_F23,
+	GIIK_F24,
+	GIIK_F25,
+	GIIK_F26,
+	GIIK_F27,
+	GIIK_F28,
+	GIIK_F29,
+	GIIK_F30,
+	GIIK_F31,
+	GIIK_F32,
+	GIIK_F33,
+	GIIK_F34,
+	GIIK_F35,
+	GIIK_CapsLock,			/* Locked keys */
+	GIIK_NumLock,
+	GIIK_ScrollLock,
+
+	GIIK_Compose,			/* Misc keys */
+	GIIK_Undo,		/* 40 */
+	GIIK_Redo,
+	GIIK_Menu,
+	GIIK_Cancel,
+	GIIK_PrintScreen,
+	GIIK_Execute,
+	GIIK_Find,
+	GIIK_Begin,
+	GIIK_Clear,
+	GIIK_Insert,
+	GIIK_Select,		/* 50 */
+	GIIK_Macro,
+	GIIK_Help,
+	GIIK_Do,
+	GIIK_Pause,
+	GIIK_SysRq,
+	GIIK_ModeSwitch,
+	GIIK_Up,
+	GIIK_Down,
+	GIIK_Left,
+	GIIK_Right,		/* 60 */
+	GIIK_Prior, /* PageUp */
+	GIIK_Next,  /* PageDown */
+	GIIK_Home,
+	GIIK_End,
+
+	GIIK_P0,			/* Keys on numeric pad */
+	GIIK_P1,
+	GIIK_P2,
+	GIIK_P3,
+	GIIK_P4,
+	GIIK_P5,		/* 70 */
+	GIIK_P6,
+	GIIK_P7,
+	GIIK_P8,
+	GIIK_P9,
+	GIIK_PA,
+	GIIK_PB,
+	GIIK_PC,
+	GIIK_PD,
+	GIIK_PE,
+	GIIK_PF,		/* 80 */
+	GIIK_PPlus,
+	GIIK_PMinus,
+	GIIK_PAsterisk,	/* Star */
+	GIIK_PSlash,
+	GIIK_PEnter,
+	GIIK_VOID,
+	GIIK_VOID,
+	GIIK_PPlusMinus,
+	GIIK_PParenLeft,
+	GIIK_PParenRight,	/* 90 */
+	GIIK_PSpace,
+	GIIK_PTab,
+	GIIK_PBegin,
+	GIIK_VOID,
+
+	GIIK_PEqual,
+	GIIK_PSeparator,
+	GIIK_PDecimal,
+	GIIK_PF1,
+	GIIK_PF2,
+	GIIK_PF3,		/* 100 */
+	GIIK_PF4,
+	GIIK_PF5,
+	GIIK_PF6,
+	GIIK_PF7,
+	GIIK_PF8,
+	GIIK_PF9,
+
+	GIIK_ShiftL,			/* Modifiers */
+	GIIK_ShiftR,
+	GIIK_CtrlL,
+	GIIK_CtrlR,		/* 110 */
+	GIIK_AltL,
+	GIIK_AltR,
+	GIIK_MetaL,
+	GIIK_MetaR,
+	GIIK_SuperL,
+	GIIK_SuperR,
+	GIIK_HyperL,
+	GIIK_HyperR,
+	GIIK_ShiftLock,			/* New keys */
+	GIIK_VOID,		/* 120 */
+	GIIK_VOID,
+	GIIK_VOID,
+
+	GIIUC_BackSpace,		/* "Easily" mapped keys */
+	GIIUC_Tab,
+	GIIUC_Linefeed,
+	GIIUC_Return,
+	GIIUC_Escape,
+	GIIUC_Delete,
+	GIIUC_Space,
+	GIIUC_0,		/* 130 */
+	GIIUC_1,
+	GIIUC_2,
+	GIIUC_3,
+	GIIUC_4,
+	GIIUC_5,
+	GIIUC_6,
+	GIIUC_7,
+	GIIUC_8,
+	GIIUC_9,
+	
+	GIIUC_A,		/* 140 */
+	GIIUC_B,
+	GIIUC_C,
+	GIIUC_D,
+	GIIUC_E,
+	GIIUC_F,
+	GIIUC_G,
+	GIIUC_H,
+	GIIUC_I,
+	GIIUC_J,
+	GIIUC_K,		/* 150 */
+	GIIUC_L,
+	GIIUC_M,
+	GIIUC_N,
+	GIIUC_O,
+	GIIUC_P,
+	GIIUC_Q,
+	GIIUC_R,
+	GIIUC_S,
+	GIIUC_T,
+	GIIUC_U,		/* 160 */
+	GIIUC_V,
+	GIIUC_W,
+	GIIUC_X,
+	GIIUC_Y,
+	GIIUC_Z,
+
+	GIIUC_Agrave,		/* 166 */
+	GIIUC_Aacute,
+	GIIUC_Acircumflex,
+	GIIUC_Atilde,
+	GIIUC_Adiaeresis,/* Aumlaut */ 	/* 170 */
+	GIIUC_Aring,
+	GIIUC_AE,
+	GIIUC_Ccedilla,
+	GIIUC_Egrave,
+	GIIUC_Eacute,
+	GIIUC_Ecircumflex,
+	GIIUC_Ediaeresis,/* Eumlaut */
+	GIIUC_Igrave,
+	GIIUC_Iacute,
+	GIIUC_Icircumflex,	/* 180 */
+	GIIUC_Idiaeresis,/* Iumlaut */
+	GIIUC_ETH,
+	GIIUC_Ntilde,
+	GIIUC_Ograve,
+	GIIUC_Oacute,
+	GIIUC_Ocircumflex,
+	GIIUC_Otilde,
+	GIIUC_Odiaeresis,/* Oumlaut */
+	GIIUC_Multiply,
+	GIIUC_Ooblique,		/* 190 */
+	GIIUC_Ugrave,
+	GIIUC_Uacute,
+	GIIUC_Ucircumflex,
+	GIIUC_Udiaeresis,/* Uumlaut */
+	GIIUC_Yacute,
+	GIIUC_THORN,
+	GIIUC_ssharp,		/* 197 */
+
+	GIIUC_Grave,			/* The nasty ones - 102-key US */
+	GIIUC_Minus,
+	GIIUC_Equal,		/* 200 */
+	GIIUC_BracketLeft,
+	GIIUC_BracketRight,
+	GIIUC_Semicolon,
+	GIIUC_Apostrophe,
+	GIIUC_BackSlash,
+	GIIUC_Less,		/* 206 */
+	GIIUC_Comma,
+	GIIUC_Period,
+	GIIUC_Slash,
+	
+	GIIUC_Paragraph,	/* 210 */ /*The nasty ones - other keyboards */
+	GIIUC_Plus,
+	GIIUC_Acute,
+	GIIUC_Diaeresis,
+
+	GIIUC_NumberSign,
+	GIIUC_BackSlash,
+	
+	GIIUC_Tilde,
+	GIIUC_Section,
+
+	GIIK_DeadAcute,			/* Dead keys */
+	GIIK_DeadDiaeresis,
+	GIIK_DeadCircumflex,	/* 220 */
+	GIIK_DeadTilde,
+	GIIK_DeadCedilla,
+	GIIK_DeadGrave,
+
+	GIIUC_Bar,
+	GIIUC_Circumflex,	/* 225 */
+	
+};
+
+#define LETTERSTART 	(140-1)
+#define LETTEREND	(197-1)
+#define NOCAPSDEC	0x20
+
+Bool
+LegalModifier(unsigned int key, DevicePtr pDev)
+{
+	return TRUE;
+}
+
+static int
+translate_key(uint32 sym, uint32 label)
+{
+	int i;
+    
+	for (i=0; i < LETTERSTART; i++) {
+		if (label == ggicodemap[i]) {
+			return i+8;
+		}
+	}
+	while (i <= LETTEREND) {
+		if (label == ggicodemap[i]
+		    || (label - NOCAPSDEC) == ggicodemap[i]) {
+			return i+8;
+		}
+		i++;
+	}
+	while (i < NUM_KEYCODES) {
+		if (label == ggicodemap[i]) {
+			return i+8;
+		}
+		i++;
+	}	    
+
+	return 0;
+}
+
+void
+xggiQueueKeyboardEvent(ggi_event *ev)
+{
+	DevicePtr pKeyboard;
+	xEvent xev;
+	int k;
+
+	pKeyboard = LookupKeyboardDevice();
+	if (!pKeyboard->on)
+		return;
+    
+	k = translate_key(ev->key.sym, ev->key.label);
+
+	if (k) {
+		xev.u.keyButtonPointer.time = TVAL2TIME(ev->any.time);
+		xev.u.u.detail = k;
+	    
+		switch (ev->any.type) {
+		case evKeyPress:
+		case evKeyRepeat:
+			xev.u.u.type = KeyPress;
+			break;
+	    
+		case evKeyRelease:
+			xev.u.u.type = KeyRelease;
+			break;
+	    
+		default:
+			return;
+		}
+	
+#if 0
+		ErrorF("Enqueueing: 0x%x, %d\n", ev->key.label, k);
+#endif
+		mieqEnqueue(&xev);
+	} 
+#if 0	
+	else {
+		ErrorF("Skipping: 0x%x\n", ev->key.label);
+	}
+#endif
+}
+
+int
+xggiKeybdProc(DeviceIntPtr pDevice, int onoff)
+{
+	KeySymsRec keySyms;
+	CARD8 modMap[MAP_LENGTH];
+	DevicePtr pDev = (DevicePtr)pDevice;
+	KeySym *ksym;
+	int i;
+	
+	switch (onoff) {
+	case DEVICE_INIT:
+		/* Clear map */
+		for (i = 0; i < MAP_LENGTH; i++) {
+			modMap[i] = NoSymbol;
+		}
+  
+		for (ksym = xggiKeymap, i = MIN_KEYCODE;
+		     i < (NUM_KEYCODES + MIN_KEYCODE);
+		     i++, ksym += 4) {
+			switch (*ksym) {
+			case XK_Shift_L:
+			case XK_Shift_R:
+				modMap[i] = ShiftMask;
+				break;
+				
+			case XK_Control_L:
+			case XK_Control_R:
+				modMap[i] = ControlMask;
+				break;
+      
+			case XK_Caps_Lock:
+				modMap[i] = LockMask;
+				break;
+      
+			case XK_Alt_L:
+			case XK_Alt_R:
+				modMap[i] = AltMask;
+				break;
+      
+			case XK_Num_Lock:
+				modMap[i] = NumLockMask;
+				break;
+
+			case XK_Scroll_Lock:
+				modMap[i] = ScrollLockMask;
+				break;
+
+			case XK_Kana_Lock:
+			case XK_Kana_Shift:
+				modMap[i] = KanaMask;
+				break;
+
+			case XK_Mode_switch:
+				modMap[i] = AltLangMask;
+				break;
+
+			}
+		}
+		keySyms.minKeyCode = MIN_KEYCODE;
+		keySyms.maxKeyCode = MAX_KEYCODE;
+		keySyms.mapWidth = GLYPHS_PER_KEY;
+		keySyms.map = xggiKeymap;
+		InitKeyboardDeviceStruct(pDev, &keySyms, modMap,
+					 (BellProcPtr)NoopDDA,
+					 (KbdCtrlProcPtr)NoopDDA);
+		break;
+		
+	case DEVICE_ON: 
+		pDev->on = TRUE;
+		break;
+		
+	case DEVICE_OFF: 
+		pDev->on = FALSE;
+		break;
+		
+	case DEVICE_CLOSE:
+		pDev->on = FALSE;
+		break;
+	}
+	
+	return Success;
+}
diff -urN xfree-3.3.6/programs/Xserver/hw/ggi/keymap.h xc/programs/Xserver/hw/ggi/keymap.h
--- xfree-3.3.6/programs/Xserver/hw/ggi/keymap.h	Thu Jan  1 01:00:00 1970
+++ xc/programs/Xserver/hw/ggi/keymap.h	Sun Oct 15 14:30:12 2000
@@ -0,0 +1,279 @@
+/*
+***************************************************************************
+
+   X server for LibGGI - Default Keymap
+
+   Copyright (C) 1999 Marcus Sundberg	[marcus@ggi-project.org]
+
+   Permission is hereby granted, free of charge, to any person obtaining a
+   copy of this software and associated documentation files (the "Software"),
+   to deal in the Software without restriction, including without limitation
+   the rights to use, copy, modify, merge, publish, distribute, sublicense,
+   and/or sell copies of the Software, and to permit persons to whom the
+   Software is furnished to do so, subject to the following conditions:
+
+   The above copyright notice and this permission notice shall be included in
+   all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+   THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+   IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+***************************************************************************
+*/
+
+#ifndef _XGGI_KEYMAP_H
+#define _XGGI_KEYMAP_H
+
+/* XFree86 compability */
+#define AltMask         Mod1Mask
+#define NumLockMask     Mod2Mask
+#define AltLangMask     Mod3Mask
+#define KanaMask        Mod4Mask
+#define ScrollLockMask  Mod5Mask
+
+
+#define MIN_KEYCODE  8
+#define MAX_KEYCODE  255
+#define NUM_KEYCODES (MAX_KEYCODE - MIN_KEYCODE + 1)
+#define GLYPHS_PER_KEY 4
+
+static KeySym xggiKeymap[NUM_KEYCODES * GLYPHS_PER_KEY] = {
+	XK_F1,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F2,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F3,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F4,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F5,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F6,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F7,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F8,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F9,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F10,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F11,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F12,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F13,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F14,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F15,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F16,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F17,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F18,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F19,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F20,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F21,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F22,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F23,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F24,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F25,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F26,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F27,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F28,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F29,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F30,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F31,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F32,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F33,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F34,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_F35,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Caps_Lock,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Num_Lock,	XK_Pointer_EnableKeys,NoSymbol,	NoSymbol,
+	XK_Scroll_Lock,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Multi_key,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Undo,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Redo,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Menu,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Cancel,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Print,	XK_Execute,	NoSymbol,	NoSymbol,
+	XK_Execute,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Find,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Begin,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Clear,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Insert,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Select,	NoSymbol,	NoSymbol,	NoSymbol,
+/*XK_Macro*/NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Help,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Execute,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Pause,	XK_Break,	NoSymbol,	NoSymbol,
+	XK_Sys_Req,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Mode_switch,	XK_Multi_key,	NoSymbol,	NoSymbol,
+	XK_Up,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Down,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Left,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Right,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Prior,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Next,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Home,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_End,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_KP_Insert,	XK_KP_0,	NoSymbol,	NoSymbol,
+	XK_KP_End,	XK_KP_1,	NoSymbol,	NoSymbol,
+	XK_KP_Down,	XK_KP_2,	NoSymbol,	NoSymbol,
+	XK_KP_Next,	XK_KP_3,	NoSymbol,	NoSymbol,
+	XK_KP_Left,	XK_KP_4,	NoSymbol,	NoSymbol,
+	XK_KP_Begin,	XK_KP_5,	NoSymbol,	NoSymbol,
+	XK_KP_Right,	XK_KP_6,	NoSymbol,	NoSymbol,
+	XK_KP_Home,	XK_KP_7,	NoSymbol,	NoSymbol,
+	XK_KP_Up,	XK_KP_8,	NoSymbol,	NoSymbol,
+	XK_KP_Prior,	XK_KP_9,	NoSymbol,	NoSymbol,
+	XK_KP_F1,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_KP_F2,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_KP_F3,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_KP_F4,	NoSymbol,	NoSymbol,	NoSymbol,
+	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_KP_Add,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_KP_Subtract,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_KP_Multiply,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_KP_Divide,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_KP_Enter,	NoSymbol,	NoSymbol,	NoSymbol,
+	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_KP_Begin,	NoSymbol,	NoSymbol,	NoSymbol,
+	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_KP_Equal,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_KP_Delete,	XK_KP_Separator,NoSymbol,	NoSymbol,
+	XK_KP_Delete,	XK_KP_Decimal,	NoSymbol,	NoSymbol,
+	XK_KP_F1,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_KP_F2,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_KP_F3,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_KP_F4,	NoSymbol,	NoSymbol,	NoSymbol,
+	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+	NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Shift_L,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Shift_R,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Control_L,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Control_R,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Alt_L,	XK_Meta_L,	NoSymbol,	NoSymbol,
+	XK_Alt_R,	XK_Meta_R,	NoSymbol,	NoSymbol,
+	XK_Meta_L,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Meta_R,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Super_L,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Super_R,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Hyper_L,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Hyper_R,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Shift_Lock,	NoSymbol,	NoSymbol,	NoSymbol,
+/*XK_Top_R*/NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+/*XK_Front_L*/NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+/*XK_Front_R*/NoSymbol,	NoSymbol,	NoSymbol,	NoSymbol,
+
+	XK_BackSpace,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Tab,		XK_ISO_Left_Tab,NoSymbol,	NoSymbol,
+	XK_Linefeed,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Return,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Escape,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_Delete,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_space,	NoSymbol,	NoSymbol,	NoSymbol,
+
+	XK_0,		XK_parenright,	NoSymbol,	NoSymbol,
+	XK_1,		XK_exclam,	NoSymbol,	NoSymbol,
+	XK_2,		XK_at,		NoSymbol,	NoSymbol,
+	XK_3,		XK_numbersign,	NoSymbol,	NoSymbol,
+	XK_4,		XK_dollar,	NoSymbol,	NoSymbol,
+	XK_5,		XK_percent,	NoSymbol,	NoSymbol,
+	XK_6,		XK_asciicircum,	NoSymbol,	NoSymbol,
+	XK_7,		XK_ampersand,	NoSymbol,	NoSymbol,
+	XK_8,		XK_asterisk,	NoSymbol,	NoSymbol,
+	XK_9,		XK_parenleft,	NoSymbol,	NoSymbol,
+
+	XK_a,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_b,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_c,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_d,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_e,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_f,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_g,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_h,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_i,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_j,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_k,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_l,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_m,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_n,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_o,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_p,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_q,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_r,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_s,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_t,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_u,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_v,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_w,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_x,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_y,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_z,		NoSymbol,	NoSymbol,	NoSymbol,
+
+	XK_agrave,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_aacute,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_acircumflex,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_atilde,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_adiaeresis,	XK_Adiaeresis,	XK_dead_circumflex, XK_dead_caron,
+	XK_aring,	XK_Aring,	XK_dead_diaeresis, XK_dead_abovering,
+	XK_ae,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_ccedilla,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_egrave,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_eacute,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_ecircumflex,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_ediaeresis,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_igrave,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_iacute,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_icircumflex,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_idiaeresis,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_eth,		NoSymbol,	NoSymbol,	NoSymbol,
+	XK_ntilde,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_ograve,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_oacute,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_ocircumflex,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_otilde,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_odiaeresis,	XK_Odiaeresis,	XK_dead_acute,	XK_dead_doubleacute,
+	XK_multiply,	XK_division,	NoSymbol,	NoSymbol,
+	XK_oslash,	XK_Ooblique,	NoSymbol,	NoSymbol,
+	XK_ugrave,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_uacute,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_ucircumflex,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_udiaeresis,	XK_Udiaeresis,	XK_dead_diaeresis, NoSymbol,
+	XK_yacute,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_thorn,	NoSymbol,	NoSymbol,	NoSymbol,
+	XK_ssharp,	XK_question,	XK_backslash,   XK_questiondown,
+
+	XK_grave,	XK_asciitilde,	NoSymbol,	NoSymbol,
+	XK_minus,	XK_underscore,	NoSymbol,	NoSymbol,
+	XK_equal,	XK_plus,	NoSymbol,	NoSymbol,
+	XK_bracketleft,	XK_braceleft,	NoSymbol,	NoSymbol,
+	XK_bracketright,XK_braceright,	NoSymbol,	NoSymbol,
+	XK_semicolon,	XK_colon,	NoSymbol,	NoSymbol,
+	XK_apostrophe,	XK_quotedbl,	NoSymbol,	NoSymbol,
+	XK_backslash,	XK_bar,		NoSymbol,	NoSymbol,
+	XK_less,	XK_greater,	XK_bar,		XK_brokenbar,
+	XK_comma,	XK_less,	NoSymbol,	NoSymbol,
+	XK_period,	XK_greater,	NoSymbol,	NoSymbol,
+	XK_slash,	XK_question,	NoSymbol,	NoSymbol,
+
+	XK_paragraph,	XK_onehalf,	XK_notsign,	NoSymbol,
+	XK_plus,	XK_question,	XK_backslash,	XK_questiondown,
+	XK_acute,	XK_grave,	XK_dead_cedilla,XK_dead_ogonek,
+	XK_diaeresis,	XK_asciicircum,	XK_dead_tilde,	XK_dead_macron,
+	XK_numbersign,	XK_asciitilde,	NoSymbol,	NoSymbol,
+	XK_backslash,	XK_bar,		NoSymbol,	NoSymbol,
+	XK_asciitilde,	XK_onehalf,	XK_notsign,	NoSymbol,
+	XK_section,	XK_onehalf,	NoSymbol,	NoSymbol,
+	XK_dead_acute,	XK_dead_grave,	XK_dead_cedilla,XK_dead_ogonek,
+	XK_dead_diaeresis, XK_dead_circumflex, XK_dead_tilde, XK_dead_macron,
+	XK_dead_circumflex, XK_degree,	XK_notsign,	NoSymbol,
+	XK_dead_tilde,	XK_dead_circumflex, XK_asciitilde, XK_asciicircum,
+	XK_dead_cedilla,XK_dead_diaeresis, XK_bracketright, NoSymbol,
+	XK_dead_grave,	XK_dead_circumflex, XK_bracketleft, NoSymbol,
+
+	XK_bar,		XK_section,	NoSymbol,	NoSymbol,
+	XK_asciicircum,	XK_degree,	XK_notsign,	NoSymbol,
+};
+
+#endif /* _XGGI_KEYMAP_H */
diff -urN xfree-3.3.6/programs/Xserver/hw/ggi/xggi.h xc/programs/Xserver/hw/ggi/xggi.h
--- xfree-3.3.6/programs/Xserver/hw/ggi/xggi.h	Thu Jan  1 01:00:00 1970
+++ xc/programs/Xserver/hw/ggi/xggi.h	Sun Oct 15 20:19:41 2000
@@ -0,0 +1,85 @@
+/*
+***************************************************************************
+
+   X server for LibGGI - Basic definitions
+
+   Copyright (C) 1998-2000 Marcus Sundberg	[marcus@ggi-project.org]
+
+   Permission is hereby granted, free of charge, to any person obtaining a
+   copy of this software and associated documentation files (the "Software"),
+   to deal in the Software without restriction, including without limitation
+   the rights to use, copy, modify, merge, publish, distribute, sublicense,
+   and/or sell copies of the Software, and to permit persons to whom the
+   Software is furnished to do so, subject to the following conditions:
+
+   The above copyright notice and this permission notice shall be included in
+   all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+   THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+   IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+***************************************************************************
+*/
+
+#ifndef _XGGI_H
+#define _XGGI_H
+
+#include <ggi/gg.h>
+#include <ggi/ggi.h>
+
+#define DEFAULT_PTRBUTTONS	5
+
+struct xggiGlobalInfo {
+	int numscreens;
+	int rows, columns;	/* Screen layout */
+	int allowzap;
+	int ctrlalt_vtswitch;
+	int newvt;
+};	
+	
+struct xggiScreenInfo {
+	ggi_visual_t vis;
+	uint32 ptrbuttons;
+	int width;
+	int height;
+	int depth;
+	int stride;
+	int bitsPerPixel;
+	ggi_mode mode;
+	const ggi_directbuffer *dbuf;
+	char *pfbMemory;
+	ScreenPtr screen;
+	PixmapPtr backbuffer;
+	int ismapped;
+};
+
+extern struct xggiGlobalInfo xggiInfo;
+extern struct xggiScreenInfo *xggiScreens;
+
+#define MASTER_VIS	(xggiScreens[0].vis)
+
+extern Bool
+xggiScreenInit();
+
+extern void
+xggiQueueKeyboardEvent();
+
+extern int
+xggiKeybdProc();
+
+extern void
+xggiUnmapDisplay(void);
+
+extern void
+xggiMapDisplay(void);
+
+extern int
+xggiGetScreenIdx(ScreenPtr screen);
+
+#define TVAL2TIME(tv)	((tv).tv_sec*1000 + (tv).tv_usec/1000)
+
+#endif /* _XGGI_H */
diff -urN xfree-3.3.6/programs/Xserver/include/misc.h xc/programs/Xserver/include/misc.h
--- xfree-3.3.6/programs/Xserver/include/misc.h	Sun Oct 15 13:33:31 2000
+++ xc/programs/Xserver/include/misc.h	Sun Oct 15 14:27:48 2000
@@ -92,7 +92,7 @@
 #endif
 
 #ifndef MAXSCREENS
-#define MAXSCREENS	3
+#define MAXSCREENS	9
 #endif
 #define MAXCLIENTS	128
 #define MAXDITS		1
