[X2Go-Commits] [nx-libs] 79/108: Lift xkb to XORG-1.2.0 state

git-admin at x2go.org git-admin at x2go.org
Fri Nov 9 20:35:54 CET 2018


This is an automated email from the git hooks/post-receive script.

x2go pushed a commit to branch master
in repository nx-libs.

commit 9808c66ec37d5d99f58bdb6136ae96381cb9cfc8
Author: Ulrich Sibiller <uli42 at gmx.de>
Date:   Fri Jun 29 22:34:32 2018 +0200

    Lift xkb to XORG-1.2.0 state
---
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.c |    2 +-
 nx-X11/programs/Xserver/include/xkbfile.h     |   32 +-
 nx-X11/programs/Xserver/include/xkbsrv.h      |    3 +-
 nx-X11/programs/Xserver/xkb/Imakefile         |    8 +-
 nx-X11/programs/Xserver/xkb/XKBMisc.c         |    7 +-
 nx-X11/programs/Xserver/xkb/ddxBeep.c         |    1 +
 nx-X11/programs/Xserver/xkb/ddxKillSrv.c      |    5 -
 nx-X11/programs/Xserver/xkb/ddxList.c         |   13 +-
 nx-X11/programs/Xserver/xkb/ddxLoad.c         |    1 -
 nx-X11/programs/Xserver/xkb/ddxPrivate.c      |    5 -
 nx-X11/programs/Xserver/xkb/ddxVT.c           |    5 -
 nx-X11/programs/Xserver/xkb/maprules.c        |   16 +-
 nx-X11/programs/Xserver/xkb/xkb.c             |  294 +++---
 nx-X11/programs/Xserver/xkb/xkbActions.c      |    4 -
 nx-X11/programs/Xserver/xkb/xkbEvents.c       |    4 +
 nx-X11/programs/Xserver/xkb/xkbInit.c         |    8 -
 nx-X11/programs/Xserver/xkb/xkbLEDs.c         |   18 +-
 nx-X11/programs/Xserver/xkb/xkbPrKeyEv.c      |    4 -
 nx-X11/programs/Xserver/xkb/xkbUtils.c        |    4 +-
 nx-X11/programs/Xserver/xkb/xkbfmisc.c        |  456 ++++++++-
 nx-X11/programs/Xserver/xkb/xkbout.c          | 1047 +++++++++++++++++++
 nx-X11/programs/Xserver/xkb/xkbtext.c         | 1325 +++++++++++++++++++++++++
 nx-X11/programs/Xserver/xkb/xkmread.c         |   94 +-
 23 files changed, 2979 insertions(+), 377 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
index 6a14667..c6998e8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
@@ -155,7 +155,7 @@ extern        Status        XkbGetControls(
 #define XKB_CONFIG_FILE_X2GO "/etc/x2go/x2goagent.keyboard"
 #endif
 #ifndef XKB_DFLT_RULES_FILE
-#define XKB_DFLT_RULES_FILE  "xfree86"
+#define XKB_DFLT_RULES_FILE  "base"
 #endif
 #ifndef XKB_ALTS_RULES_FILE
 #define XKB_ALTS_RULES_FILE  "xorg"
diff --git a/nx-X11/programs/Xserver/include/xkbfile.h b/nx-X11/programs/Xserver/include/xkbfile.h
index e99de6c..2b02244 100644
--- a/nx-X11/programs/Xserver/include/xkbfile.h
+++ b/nx-X11/programs/Xserver/include/xkbfile.h
@@ -10,19 +10,19 @@
  fee is hereby granted, provided that the above copyright
  notice appear in all copies and that both that copyright
  notice and this permission notice appear in supporting
- documentation, and that the name of Silicon Graphics not be 
- used in advertising or publicity pertaining to distribution 
+ documentation, and that the name of Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
  of the software without specific prior written permission.
- Silicon Graphics makes no representation about the suitability 
+ Silicon Graphics makes no representation about the suitability
  of this software for any purpose. It is provided "as is"
  without any express or implied warranty.
- 
- SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- GRAPHICS 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 
+ GRAPHICS 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.
 
@@ -83,9 +83,9 @@ typedef void	(*XkbFileAddOnFunc)(
 #define	_XkbErrXReqFailure		25
 #define	_XkbErrBadImplementation	26
 
-extern char *		_XkbErrMessages[];
+extern const char *	_XkbErrMessages[];
 extern unsigned		_XkbErrCode;
-extern char *		_XkbErrLocation;
+extern const char *	_XkbErrLocation;
 extern unsigned		_XkbErrData;
 
 /***====================================================================***/
@@ -233,12 +233,14 @@ extern	Bool	XkbLookupGroupAndLevel(
 
 /***====================================================================***/
 
-
-/***====================================================================***/
+extern	char *	XkbAtomGetString(
+    Display *	/* dpy */,
+    Atom 	/* atm */
+);
 
 extern	Atom	XkbInternAtom(
     Display *	/* dpy */,
-    char *	/* name */,
+    char *      /* name */,
     Bool	/* onlyIfExists */
 );
 
@@ -272,7 +274,7 @@ typedef struct _XkbDrawable {
 	    XkbSectionPtr	section;
 	} u;
 	struct _XkbDrawable *	next;
-} XkbDrawableRec,*XkbDrawablePtr; 
+} XkbDrawableRec,*XkbDrawablePtr;
 
 extern	XkbDrawablePtr
 XkbGetOrderedDrawables(
diff --git a/nx-X11/programs/Xserver/include/xkbsrv.h b/nx-X11/programs/Xserver/include/xkbsrv.h
index 9f9ccc5..a3f8718 100644
--- a/nx-X11/programs/Xserver/include/xkbsrv.h
+++ b/nx-X11/programs/Xserver/include/xkbsrv.h
@@ -267,7 +267,8 @@ extern int	XkbEventBase;
 extern int	XkbDisableLockActions;
 extern char *	XkbBaseDirectory;
 extern char *	XkbBinDirectory;
-extern char *	XkbInitialMap;
+extern int	_XkbClientMajor;
+extern int	_XkbClientMinor;
 extern unsigned	int XkbXIUnsupported;
 
 extern Bool	noXkbExtension;
diff --git a/nx-X11/programs/Xserver/xkb/Imakefile b/nx-X11/programs/Xserver/xkb/Imakefile
index 5acd977..21d631a 100644
--- a/nx-X11/programs/Xserver/xkb/Imakefile
+++ b/nx-X11/programs/Xserver/xkb/Imakefile
@@ -26,13 +26,13 @@ XKB_DDXDEFS = XkbServerDefines
 	    ddxList.o ddxDevBtn.o ddxPrivate.o
      SRCS = xkb.c xkbUtils.c xkbEvents.c xkbAccessX.c xkbSwap.c \
             xkbLEDs.c xkbInit.c xkbActions.c xkbPrKeyEv.c \
-	    xkmread.c xkbfmisc.c xkberrs.c maprules.c \
-	    XKBMisc.c XKBMAlloc.c XKBAlloc.c XKBGAlloc.c \
+	    xkmread.c xkbtext.c xkbfmisc.c xkberrs.c maprules.c \
+	    XKBMisc.c XKBMAlloc.c XKBAlloc.c XKBGAlloc.c xkbout.c \
 	    $(XKBXI_SRCS) $(DDX_SRCS)
      OBJS = xkb.o xkbUtils.o xkbEvents.o xkbAccessX.o xkbSwap.o \
             xkbLEDs.o xkbInit.o xkbActions.o xkbPrKeyEv.o \
-	    xkmread.o xkbfmisc.o xkberrs.o maprules.o \
-	    XKBMisc.o XKBMAlloc.o XKBAlloc.o XKBGAlloc.o \
+	    xkmread.o xkbtext.o xkbfmisc.o xkberrs.o maprules.o \
+	    XKBMisc.o XKBMAlloc.o XKBAlloc.o XKBGAlloc.o xkbout.o \
 	    $(XKBXI_OBJS) $(DDX_OBJS)
    INCLUDES = -I../include -I$(XINCLUDESRC) -I$(EXTINCSRC) -I$(SERVERSRC)/Xext \
 	      -I$(SERVERSRC)/mi $(XF86INCLUDES) \
diff --git a/nx-X11/programs/Xserver/xkb/XKBMisc.c b/nx-X11/programs/Xserver/xkb/XKBMisc.c
index 98f11a2..2c5cf42 100644
--- a/nx-X11/programs/Xserver/xkb/XKBMisc.c
+++ b/nx-X11/programs/Xserver/xkb/XKBMisc.c
@@ -366,8 +366,11 @@ unsigned		changed,tmp;
 	unsigned int	new_vmodmask;
 	changed|= XkbKeyActionsMask;
 	pActs= XkbResizeKeyActions(xkb,key,nSyms);
-	if (!pActs)
+	if (!pActs) {
+            if (nSyms > IBUF_SIZE)
+                free(interps);
 	    return False;
+        }
 	new_vmodmask= 0;
 	for (n=0;n<nSyms;n++) {
 	    if (interps[n]) {
@@ -470,7 +473,7 @@ register int	i;
 int		width,nOldGroups,oldWidth,newTypes[XkbNumKbdGroups];
 
     if ((!xkb) || (!XkbKeycodeInRange(xkb,key)) || (!xkb->map) ||
-	(!xkb->map->types)||((groups&XkbAllGroupsMask)==0)||
+	(!xkb->map->types)||(!newTypesIn)||((groups&XkbAllGroupsMask)==0)||
 	(nGroups>XkbNumKbdGroups)) {
 	return BadMatch;
     }
diff --git a/nx-X11/programs/Xserver/xkb/ddxBeep.c b/nx-X11/programs/Xserver/xkb/ddxBeep.c
index fa4af74..9f55ff3 100644
--- a/nx-X11/programs/Xserver/xkb/ddxBeep.c
+++ b/nx-X11/programs/Xserver/xkb/ddxBeep.c
@@ -38,6 +38,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <xkbsrv.h>
 #include <nx-X11/extensions/XI.h>
 
+
 /*#define FALLING_TONE	1*/
 /*#define RISING_TONE	1*/
 #define FALLING_TONE	10
diff --git a/nx-X11/programs/Xserver/xkb/ddxKillSrv.c b/nx-X11/programs/Xserver/xkb/ddxKillSrv.c
index c581d42..3a8ffdd 100644
--- a/nx-X11/programs/Xserver/xkb/ddxKillSrv.c
+++ b/nx-X11/programs/Xserver/xkb/ddxKillSrv.c
@@ -28,10 +28,6 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <dix-config.h>
 #endif
 
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
 #include <stdio.h>
 #include <nx-X11/X.h>
 #include <nx-X11/Xproto.h>
@@ -40,7 +36,6 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "scrnintstr.h"
 #include "windowstr.h"
 #include <xkbsrv.h>
-#include <nx-X11/extensions/XI.h>
 
 int
 XkbDDXTerminateServer(DeviceIntPtr dev,KeyCode key,XkbAction *act)
diff --git a/nx-X11/programs/Xserver/xkb/ddxList.c b/nx-X11/programs/Xserver/xkb/ddxList.c
index 6023366..e48e28d 100644
--- a/nx-X11/programs/Xserver/xkb/ddxList.c
+++ b/nx-X11/programs/Xserver/xkb/ddxList.c
@@ -164,8 +164,6 @@ char	tmpname[PATH_MAX];
 	if ((list->pattern[what][0]=='*')&&(list->pattern[what][1]=='\0')) {
 	    buf = Xprintf("%s/%s.dir",XkbBaseDirectory,componentDirs[what]);
 	    in= fopen(buf,"r");
-	    free (buf);
-	    buf = NULL;
 	}
 	if (!in) {
 	    haveDir= False;
@@ -181,8 +179,6 @@ char	tmpname[PATH_MAX];
 	if ((list->pattern[what][0]=='*')&&(list->pattern[what][1]=='\0')) {
 	    buf = Xprintf("%s.dir",componentDirs[what]);
 	    in= fopen(buf,"r");
-	    free (buf);
-	    buf = NULL;
 	}
 	if (!in) {
 	    haveDir= False;
@@ -219,6 +215,13 @@ char	tmpname[PATH_MAX];
 	return BadImplementation;
     }
     list->nFound[what]= 0;
+    if (buf) {
+        free(buf);
+        buf = NULL;
+    }
+    buf = malloc(PATH_MAX * sizeof(char));
+    if (!buf)
+        return BadAlloc;
     while ((status==Success)&&((tmp=fgets(buf,PATH_MAX,in))!=NULL)) {
 	unsigned flags;
 	register unsigned int i;
@@ -263,7 +266,7 @@ char	tmpname[PATH_MAX];
 #ifndef WIN32
     if (haveDir)
 	fclose(in);
-    else if ((rval=pclose(in))!=0) {
+    else if ((rval=Pclose(in))!=0) {
 	if (xkbDebugFlags)
 	    ErrorF("xkbcomp returned exit code %d\n",rval);
     }
diff --git a/nx-X11/programs/Xserver/xkb/ddxLoad.c b/nx-X11/programs/Xserver/xkb/ddxLoad.c
index 83db435..f710af2 100644
--- a/nx-X11/programs/Xserver/xkb/ddxLoad.c
+++ b/nx-X11/programs/Xserver/xkb/ddxLoad.c
@@ -565,7 +565,6 @@ char 	*cmd = NULL,file[PATH_MAX],xkm_output_dir[PATH_MAX],*map,*outFile;
         char *xkbbasedir = XkbBaseDirectory;
         char *xkbbindir = XkbBinDirectory;
 #endif
-
 	cmd = Xprintf("\"%s" PATHSEPARATOR "xkbcomp\" -w %d \"-R%s\" -xkm %s%s -em1 %s -emp %s -eml %s keymap/%s \"%s%s.xkm\"",
 		xkbbindir,
 		((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)),
diff --git a/nx-X11/programs/Xserver/xkb/ddxPrivate.c b/nx-X11/programs/Xserver/xkb/ddxPrivate.c
index 0064cab..f602f0a 100644
--- a/nx-X11/programs/Xserver/xkb/ddxPrivate.c
+++ b/nx-X11/programs/Xserver/xkb/ddxPrivate.c
@@ -3,11 +3,6 @@
 #include <dix-config.h>
 #endif
 
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <stdio.h>
 #include <nx-X11/X.h>
 #include "windowstr.h"
 #include <xkbsrv.h>
diff --git a/nx-X11/programs/Xserver/xkb/ddxVT.c b/nx-X11/programs/Xserver/xkb/ddxVT.c
index 6c61de0..f0edddc 100644
--- a/nx-X11/programs/Xserver/xkb/ddxVT.c
+++ b/nx-X11/programs/Xserver/xkb/ddxVT.c
@@ -28,10 +28,6 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <dix-config.h>
 #endif
 
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
 #include <stdio.h>
 #include <nx-X11/X.h>
 #include <nx-X11/Xproto.h>
@@ -40,7 +36,6 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "scrnintstr.h"
 #include "windowstr.h"
 #include <xkbsrv.h>
-#include <nx-X11/extensions/XI.h>
 
 int
 XkbDDXSwitchScreen(DeviceIntPtr dev,KeyCode key,XkbAction *act)
diff --git a/nx-X11/programs/Xserver/xkb/maprules.c b/nx-X11/programs/Xserver/xkb/maprules.c
index c64e1f7..295f1ac 100644
--- a/nx-X11/programs/Xserver/xkb/maprules.c
+++ b/nx-X11/programs/Xserver/xkb/maprules.c
@@ -58,12 +58,6 @@
 #define PR_DEBUG2(s,a,b)
 #endif
 
-#ifdef NEED_STRCASECMP
-extern int _XkbStrCaseCmp(char *s1, char *s2);
-#else
-#define _XkbStrCaseCmp strcasecmp
-#endif
-
 /***====================================================================***/
 
 #define DFLT_LINE_SIZE	128
@@ -1088,20 +1082,20 @@ int			len,headingtype,extra_ndx = 0;
     for ( ; GetInputLine(file,&line,False); line.num_line= 0) {
 	if (line.line[0]=='!') {
 	    tok = strtok(&(line.line[1]), " \t");
-	    if (_XkbStrCaseCmp(tok,"model") == 0)
+	    if (strcasecmp(tok,"model") == 0)
 		headingtype = HEAD_MODEL;
-	    else if (_XkbStrCaseCmp(tok,"layout") == 0)
+	    else if (strcasecmp(tok,"layout") == 0)
 		headingtype = HEAD_LAYOUT;
-	    else if (_XkbStrCaseCmp(tok,"variant") == 0)
+	    else if (strcasecmp(tok,"variant") == 0)
 		headingtype = HEAD_VARIANT;
-	    else if (_XkbStrCaseCmp(tok,"option") == 0)
+	    else if (strcasecmp(tok,"option") == 0)
 		headingtype = HEAD_OPTION;
 	    else {
 		int i;
 		headingtype = HEAD_EXTRA;
 		extra_ndx= -1;
 		for (i=0;(i<rules->num_extra)&&(extra_ndx<0);i++) {
-		    if (!_XkbStrCaseCmp(tok,rules->extra_names[i]))
+		    if (!strcasecmp(tok,rules->extra_names[i]))
 			extra_ndx= i;
 		}
 		if (extra_ndx<0) {
diff --git a/nx-X11/programs/Xserver/xkb/xkb.c b/nx-X11/programs/Xserver/xkb/xkb.c
index 2138497..3de41c0 100644
--- a/nx-X11/programs/Xserver/xkb/xkb.c
+++ b/nx-X11/programs/Xserver/xkb/xkb.c
@@ -47,13 +47,6 @@ static	int	XkbKeyboardErrorCode;
 CARD32	xkbDebugFlags = 0;
 static	CARD32	xkbDebugCtrls = 0;
 
-
-#ifndef XKB_SRV_UNSUPPORTED_XI_FEATURES
-#define	XKB_SRV_UNSUPPORTED_XI_FEATURES	XkbXI_KeyboardsMask
-#endif
-
-unsigned XkbXIUnsupported= XKB_SRV_UNSUPPORTED_XI_FEATURES;
-
 static RESTYPE	RT_XKBCLIENT;
 
 /***====================================================================***/
@@ -168,11 +161,6 @@ ProcXkbUseExtension(ClientPtr client)
     }
     else supported = 1;
 
-#ifdef XKB_SWAPPING_BUSTED
-    if (client->swapped)
-	supported= 0;
-#endif
-
     if ((supported) && (!(client->xkbClientFlags&_XkbClientInitialized))) {
 	client->xkbClientFlags= _XkbClientInitialized;
 	client->vMajor= stuff->wantedMajor;
@@ -2891,7 +2879,6 @@ ProcXkbGetNamedIndicator(ClientPtr client)
     register int		i = 0;
     XkbSrvLedInfoPtr		sli;
     XkbIndicatorMapPtr		map = NULL;
-    Bool			supported;
 
     REQUEST(xkbGetNamedIndicatorReq);
     REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq);
@@ -2906,25 +2893,15 @@ ProcXkbGetNamedIndicator(ClientPtr client)
     if (!sli)
 	return BadAlloc;
 
-    supported= True;
-    if (XkbXIUnsupported&XkbXI_IndicatorsMask) {
-	if ((dev!=(DeviceIntPtr)LookupKeyboardDevice())||
-					((sli->flags&XkbSLI_IsDefault)==0)) {
-	    supported= False;
-	}
-    }
-
-    if (supported) {
-	i= 0;
-	map= NULL;
-	if ((sli->names)&&(sli->maps)) {
-	    for (i=0;i<XkbNumIndicators;i++) {
-		if (stuff->indicator==sli->names[i]) {
-		    map= &sli->maps[i];
-		    break;
-		}
-	    }
-	}
+    i= 0;
+    map= NULL;
+    if ((sli->names)&&(sli->maps)) {
+        for (i=0;i<XkbNumIndicators;i++) {
+            if (stuff->indicator==sli->names[i]) {
+                map= &sli->maps[i];
+                break;
+            }
+        }
     }
 
     rep.type= X_Reply;
@@ -2932,7 +2909,7 @@ ProcXkbGetNamedIndicator(ClientPtr client)
     rep.sequenceNumber = client->sequence;
     rep.deviceID = dev->id;
     rep.indicator= stuff->indicator;
-    if ((map!=NULL)&&(supported)) {
+    if (map!=NULL) {
 	rep.found= 		True;
 	rep.on=			((sli->effectiveState&(1<<i))!=0);
 	rep.realIndicator=	((sli->physIndicators&(1<<i))!=0);
@@ -2960,7 +2937,7 @@ ProcXkbGetNamedIndicator(ClientPtr client)
 	rep.realMods= 		0;
 	rep.virtualMods= 	0;
 	rep.ctrls= 		0;
-	rep.supported= 		supported;
+	rep.supported= 		True;
     }
     if ( client->swapped ) {
 	swapl(&rep.length);
@@ -2971,21 +2948,6 @@ ProcXkbGetNamedIndicator(ClientPtr client)
     }
 
     WriteToClient(client,SIZEOF(xkbGetNamedIndicatorReply), &rep);
-    if (!supported) {
-	xkbExtensionDeviceNotify        edev;
-
-	bzero(&edev,sizeof(xkbExtensionDeviceNotify));
-	edev.reason=            XkbXI_UnsupportedFeatureMask;
-	edev.ledClass=          stuff->ledClass;
-	edev.ledID=             stuff->ledID;
-	edev.ledsDefined=       sli->namesPresent|sli->mapsPresent;
-	edev.ledState=          sli->effectiveState;
-	edev.firstBtn=          0;
-	edev.nBtns=             0;
-	edev.unsupported=       XkbXIUnsupported&XkbXI_IndicatorsMask;
-	edev.supported=         XkbXI_AllFeaturesMask&(~XkbXIUnsupported);
-	XkbSendExtensionDeviceNotify(dev,client,&edev);
-    }
     return client->noClientException;
 }
 
@@ -3020,24 +2982,6 @@ ProcXkbSetNamedIndicator(ClientPtr client)
     if (!sli)
 	return BadAlloc;
 
-    if (XkbXIUnsupported&XkbXI_IndicatorsMask) {
-	if ((dev!=(DeviceIntPtr)LookupKeyboardDevice())||
-					((sli->flags&XkbSLI_IsDefault)==0)) {
-	    bzero(&ed,sizeof(xkbExtensionDeviceNotify));
-	    ed.reason=            XkbXI_UnsupportedFeatureMask;
-	    ed.ledClass=          stuff->ledClass;
-	    ed.ledID=             stuff->ledID;
-	    ed.ledsDefined=       sli->namesPresent|sli->mapsPresent;
-	    ed.ledState=          sli->effectiveState;
-	    ed.firstBtn=          0;
-	    ed.nBtns=             0;
-	    ed.unsupported=       XkbXIUnsupported&XkbXI_IndicatorsMask;
-	    ed.supported=         XkbXI_AllFeaturesMask&(~XkbXIUnsupported);
-	    XkbSendExtensionDeviceNotify(dev,client,&ed);
-	    return client->noClientException;
-	}
-    }
-
     statec= mapc= namec= 0;
     map= NULL;
     if (sli->names && sli->maps) {
@@ -3052,7 +2996,8 @@ ProcXkbSetNamedIndicator(ClientPtr client)
 	if (!stuff->createMap)
 	    return client->noClientException;
 	for (led=0,map=NULL;(led<XkbNumIndicators)&&(map==NULL);led++) {
-	    if ((sli->names[led]==None)&&(!XkbIM_InUse(&sli->maps[led]))) {
+	    if ((sli->names)&&(sli->maps)&&(sli->names[led]==None)&&
+                (!XkbIM_InUse(&sli->maps[led]))) {
 		map= &sli->maps[led];
 		sli->names[led]= stuff->indicator;
 		break;
@@ -3261,118 +3206,121 @@ char *			desc;
     start = desc = (char *)malloc(length);
     if ( !start )
 	return BadAlloc;
-    if (which&XkbKeycodesNameMask) {
-	*((CARD32 *)desc)= xkb->names->keycodes;
-	if (client->swapped) {
+    if (xkb->names) {
+        if (which&XkbKeycodesNameMask) {
+            *((CARD32 *)desc)= xkb->names->keycodes;
+            if (client->swapped) {
 	    swapl((int *)desc);
-	}
-	desc+= 4;
-    }
-    if (which&XkbGeometryNameMask)  {
-	*((CARD32 *)desc)= xkb->names->geometry;
-	if (client->swapped) {
+            }
+            desc+= 4;
+        }
+        if (which&XkbGeometryNameMask)  {
+            *((CARD32 *)desc)= xkb->names->geometry;
+            if (client->swapped) {
 	    swapl((int *)desc);
-	}
-	desc+= 4;
-    }
-    if (which&XkbSymbolsNameMask) {
-	*((CARD32 *)desc)= xkb->names->symbols;
-	if (client->swapped) {
+            }
+            desc+= 4;
+        }
+        if (which&XkbSymbolsNameMask) {
+            *((CARD32 *)desc)= xkb->names->symbols;
+            if (client->swapped) {
 	    swapl((int *)desc);
-	}
-	desc+= 4;
-    }
-    if (which&XkbPhysSymbolsNameMask) {
-	register CARD32 *atm= (CARD32 *)desc;
-	atm[0]= (CARD32)xkb->names->phys_symbols;
-	if (client->swapped) {
+            }
+            desc+= 4;
+        }
+        if (which&XkbPhysSymbolsNameMask) {
+            register CARD32 *atm= (CARD32 *)desc;
+            atm[0]= (CARD32)xkb->names->phys_symbols;
+            if (client->swapped) {
 	    swapl(&atm[0]);
-	}
-	desc+= 4;
-    }
-    if (which&XkbTypesNameMask) {
-	*((CARD32 *)desc)= (CARD32)xkb->names->types;
-	if (client->swapped) {
+            }
+            desc+= 4;
+        }
+        if (which&XkbTypesNameMask) {
+            *((CARD32 *)desc)= (CARD32)xkb->names->types;
+            if (client->swapped) {
 	    swapl((int *)desc);
-	}
-	desc+= 4;
-    }
-    if (which&XkbCompatNameMask) {
-	*((CARD32 *)desc)= (CARD32)xkb->names->compat;
-	if (client->swapped) {
+            }
+            desc+= 4;
+        }
+        if (which&XkbCompatNameMask) {
+            *((CARD32 *)desc)= (CARD32)xkb->names->compat;
+            if (client->swapped) {
 	    swapl((int *)desc);
-	}
-	desc+= 4;
-    }
-    if (which&XkbKeyTypeNamesMask) {
-	register CARD32 *atm= (CARD32 *)desc;
-	register XkbKeyTypePtr type= xkb->map->types;
+            }
+            desc+= 4;
+        }
+        if (which&XkbKeyTypeNamesMask) {
+            register CARD32 *atm= (CARD32 *)desc;
+            register XkbKeyTypePtr type= xkb->map->types;
 
-	for (i=0;i<xkb->map->num_types;i++,atm++,type++) {
-	    *atm= (CARD32)type->name;
-	    if (client->swapped) {
+            for (i=0;i<xkb->map->num_types;i++,atm++,type++) {
+                *atm= (CARD32)type->name;
+                if (client->swapped) {
 		swapl(atm);
-	    }
-	}
-	desc= (char *)atm;
-    }
-    if (which&XkbKTLevelNamesMask) {
-	XkbKeyTypePtr type = xkb->map->types;
-	register CARD32 *atm;
-	for (i=0;i<rep->nTypes;i++,type++) {
-	    *desc++ = type->num_levels;
-	}
-	desc+= XkbPaddedSize(rep->nTypes)-rep->nTypes;
-
-	atm= (CARD32 *)desc;
-	type = xkb->map->types;
-	for (i=0;i<xkb->map->num_types;i++,type++) {
-	    register unsigned l;
-	    if (type->level_names) {
-		for (l=0;l<type->num_levels;l++,atm++) {
-		    *atm= type->level_names[l];
-		    if (client->swapped) {
+                }
+            }
+            desc= (char *)atm;
+        }
+        if (which&XkbKTLevelNamesMask && xkb->map) {
+            XkbKeyTypePtr type = xkb->map->types;
+            register CARD32 *atm;
+            for (i=0;i<rep->nTypes;i++,type++) {
+                *desc++ = type->num_levels;
+            }
+            desc+= XkbPaddedSize(rep->nTypes)-rep->nTypes;
+
+            atm= (CARD32 *)desc;
+            type = xkb->map->types;
+            for (i=0;i<xkb->map->num_types;i++,type++) {
+                register unsigned l;
+                if (type->level_names) {
+                    for (l=0;l<type->num_levels;l++,atm++) {
+                        *atm= type->level_names[l];
+                        if (client->swapped) {
 			swapl(atm);
-		    }
-		}
-		desc+= type->num_levels*4;
-	    }
-	}
-    }
-    if (which&XkbIndicatorNamesMask) {
-	desc= _XkbWriteAtoms(desc,xkb->names->indicators,XkbNumIndicators,
-							 client->swapped);
-    }
-    if (which&XkbVirtualModNamesMask) {
-	desc= _XkbWriteAtoms(desc,xkb->names->vmods,XkbNumVirtualMods,
-							client->swapped);
-    }
-    if (which&XkbGroupNamesMask) {
-	desc= _XkbWriteAtoms(desc,xkb->names->groups,XkbNumKbdGroups,
-							client->swapped);
-    }
-    if (which&XkbKeyNamesMask) {
-	for (i=0;i<rep->nKeys;i++,desc+= sizeof(XkbKeyNameRec)) {
-	    *((XkbKeyNamePtr)desc)= xkb->names->keys[i+rep->firstKey];
-	}
-    }
-    if (which&XkbKeyAliasesMask) {
-	XkbKeyAliasPtr	pAl;
-	pAl= xkb->names->key_aliases;
-	for (i=0;i<rep->nKeyAliases;i++,pAl++,desc+=2*XkbKeyNameLength) {
-	    *((XkbKeyAliasPtr)desc)= *pAl;
-	}
-    }
-    if ((which&XkbRGNamesMask)&&(rep->nRadioGroups>0)) {
-	register CARD32	*atm= (CARD32 *)desc;
-	for (i=0;i<rep->nRadioGroups;i++,atm++) {
-	    *atm= (CARD32)xkb->names->radio_groups[i];
-	    if (client->swapped) {
+                        }
+                    }
+                    desc+= type->num_levels*4;
+                }
+            }
+        }
+        if (which&XkbIndicatorNamesMask) {
+            desc= _XkbWriteAtoms(desc,xkb->names->indicators,XkbNumIndicators,
+                                 client->swapped);
+        }
+        if (which&XkbVirtualModNamesMask) {
+            desc= _XkbWriteAtoms(desc,xkb->names->vmods,XkbNumVirtualMods,
+                                 client->swapped);
+        }
+        if (which&XkbGroupNamesMask) {
+            desc= _XkbWriteAtoms(desc,xkb->names->groups,XkbNumKbdGroups,
+                                 client->swapped);
+        }
+        if (which&XkbKeyNamesMask) {
+            for (i=0;i<rep->nKeys;i++,desc+= sizeof(XkbKeyNameRec)) {
+                *((XkbKeyNamePtr)desc)= xkb->names->keys[i+rep->firstKey];
+            }
+        }
+        if (which&XkbKeyAliasesMask) {
+            XkbKeyAliasPtr	pAl;
+            pAl= xkb->names->key_aliases;
+            for (i=0;i<rep->nKeyAliases;i++,pAl++,desc+=2*XkbKeyNameLength) {
+                *((XkbKeyAliasPtr)desc)= *pAl;
+            }
+        }
+        if ((which&XkbRGNamesMask)&&(rep->nRadioGroups>0)) {
+            register CARD32	*atm= (CARD32 *)desc;
+            for (i=0;i<rep->nRadioGroups;i++,atm++) {
+                *atm= (CARD32)xkb->names->radio_groups[i];
+                if (client->swapped) {
 		swapl(atm);
-	    }
-	}
-	desc+= rep->nRadioGroups*4;
+                }
+            }
+            desc+= rep->nRadioGroups*4;
+        }
     }
+
     if ((desc-start)!=(length)) {
 	ErrorF("BOGUS LENGTH in write names, expected %d, got %ld\n",
 					length, (unsigned long)(desc-start));
@@ -4722,7 +4670,7 @@ char *		wire;
 	if (XkbAddGeomProperty(geom,name,val)==NULL) {
             free(name);
             free(val);
-	    return BadAlloc;
+            return BadAlloc;
         }
         free(name);
         free(val);
@@ -5610,7 +5558,7 @@ char *			str;
 	wanted&= ~XkbXI_ButtonActionsMask;
     if ((!dev->kbdfeed)&&(!dev->leds))
 	wanted&= ~XkbXI_IndicatorsMask;
-    wanted&= ~XkbXIUnsupported;
+    wanted&= ~XkbXI_KeyboardsMask;
 
     nameLen= XkbSizeCountedString(dev->name);
     rep.type = X_Reply;
@@ -5618,8 +5566,8 @@ char *			str;
     rep.sequenceNumber = client->sequence;
     rep.length = nameLen/4;
     rep.present = wanted;
-    rep.supported = XkbXI_AllDeviceFeaturesMask&(~XkbXIUnsupported);
-    rep.unsupported = XkbXIUnsupported;
+    rep.supported = XkbXI_AllDeviceFeaturesMask&(~XkbXI_KeyboardsMask);
+    rep.unsupported = XkbXI_KeyboardsMask;
     rep.firstBtnWanted = rep.nBtnsWanted = 0;
     rep.firstBtnRtrn = rep.nBtnsRtrn = 0;
     if (dev->button)
diff --git a/nx-X11/programs/Xserver/xkb/xkbActions.c b/nx-X11/programs/Xserver/xkb/xkbActions.c
index 2bb41b9..d2dda00 100644
--- a/nx-X11/programs/Xserver/xkb/xkbActions.c
+++ b/nx-X11/programs/Xserver/xkb/xkbActions.c
@@ -996,7 +996,6 @@ _XkbFilterSwitchScreen(	XkbSrvInfoPtr	xkbi,
     return 1;
 }
 
-#ifdef XFree86Server
 static int
 _XkbFilterXF86Private(	XkbSrvInfoPtr	xkbi,
 			XkbFilterPtr	filter,
@@ -1018,7 +1017,6 @@ _XkbFilterXF86Private(	XkbSrvInfoPtr	xkbi,
     }
     return 1;
 }
-#endif
 
 #ifdef XINPUT
 
@@ -1248,12 +1246,10 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
 		    sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act);
 		    break;
 #endif
-#ifdef XFree86Server
 		case XkbSA_XFree86Private:
 		    filter = _XkbNextFreeFilter();
 		    sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act);
 		    break;
-#endif
 	    }
 	}
     }
diff --git a/nx-X11/programs/Xserver/xkb/xkbEvents.c b/nx-X11/programs/Xserver/xkb/xkbEvents.c
index d6408a6..c7a0f9e 100644
--- a/nx-X11/programs/Xserver/xkb/xkbEvents.c
+++ b/nx-X11/programs/Xserver/xkb/xkbEvents.c
@@ -207,6 +207,10 @@ int		i;
 CARD32 		changedControls;
 
     changedControls= 0;
+
+    if (!kbd || !kbd->kbdfeed)
+        return 0;
+    
     if (old->enabled_ctrls!=new->enabled_ctrls)
 	changedControls|= XkbControlsEnabledMask;
     if ((old->repeat_delay!=new->repeat_delay)||
diff --git a/nx-X11/programs/Xserver/xkb/xkbInit.c b/nx-X11/programs/Xserver/xkb/xkbInit.c
index f39e47a..a459065 100644
--- a/nx-X11/programs/Xserver/xkb/xkbInit.c
+++ b/nx-X11/programs/Xserver/xkb/xkbInit.c
@@ -54,13 +54,6 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 #define	CREATE_ATOM(s)	MakeAtom(s,sizeof(s)-1,1)
 
-#if defined(ultrix) || defined(__alpha) || defined(__alpha__)
-#define	LED_COMPOSE	2
-#define LED_CAPS	3
-#define	LED_SCROLL	4
-#define	LED_NUM		5
-#define	PHYS_LEDS	0x1f
-#else
 #ifdef sun
 #define LED_NUM		1
 #define	LED_SCROLL	2
@@ -73,7 +66,6 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #define	LED_SCROLL	3
 #define	PHYS_LEDS	0x07
 #endif
-#endif
 
 #define	MAX_TOC	16
 typedef struct	_SrvXkmInfo {
diff --git a/nx-X11/programs/Xserver/xkb/xkbLEDs.c b/nx-X11/programs/Xserver/xkb/xkbLEDs.c
index 75e8ef3..2383bdd 100644
--- a/nx-X11/programs/Xserver/xkb/xkbLEDs.c
+++ b/nx-X11/programs/Xserver/xkb/xkbLEDs.c
@@ -745,13 +745,13 @@ xkbExtensionDeviceNotify	my_ed;
 	changes->names.changed_indicators|= changed_names;
     }
 
-    ed->reason|=	(XkbXI_IndicatorNamesMask&(~XkbXIUnsupported));
+    ed->reason|=	(XkbXI_IndicatorNamesMask&(~XkbXI_KeyboardsMask));
     ed->ledClass= 	sli->class;
     ed->ledID=		sli->id;
     ed->ledsDefined=	sli->namesPresent|sli->mapsPresent;
     ed->ledState=	sli->effectiveState;
-    ed->unsupported|=	XkbXIUnsupported&XkbXI_IndicatorNamesMask;
-    ed->supported=	XkbXI_AllFeaturesMask&(~XkbXIUnsupported);
+    ed->unsupported=	XkbXI_KeyboardsMask;
+    ed->supported=	XkbXI_AllFeaturesMask&(~XkbXI_KeyboardsMask);
 
     if (changes!=&my_changes)	changes= NULL;
     if (ed!=&my_ed)		ed= NULL;
@@ -823,13 +823,13 @@ xkbExtensionDeviceNotify	my_ed;
 
     XkbCheckIndicatorMaps(dev,sli,changed_maps);
 
-    ed->reason|=	(XkbXI_IndicatorMapsMask&(~XkbXIUnsupported));
+    ed->reason|=	(XkbXI_IndicatorMapsMask&(~XkbXI_KeyboardsMask));
     ed->ledClass= 	sli->class;
     ed->ledID=		sli->id;
     ed->ledsDefined=	sli->namesPresent|sli->mapsPresent;
     ed->ledState=	sli->effectiveState;
-    ed->unsupported|=	XkbXIUnsupported&XkbXI_IndicatorMapsMask;
-    ed->supported=	XkbXI_AllFeaturesMask&(~XkbXIUnsupported);
+    ed->unsupported|=	XkbXI_KeyboardsMask&XkbXI_IndicatorMapsMask;
+    ed->supported=	XkbXI_AllFeaturesMask&(~XkbXI_KeyboardsMask);
 
     XkbUpdateLedAutoState(dev,sli,changed_maps,ed,changes,cause);
 
@@ -904,13 +904,13 @@ Bool				kb_changed;
     if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault))
 	changes->indicators.state_changes|= affected;
     if (affected) {
-	ed->reason|=		(XkbXI_IndicatorStateMask&(~XkbXIUnsupported));
+	ed->reason|=		(XkbXI_IndicatorStateMask&(~XkbXI_KeyboardsMask));
 	ed->ledClass= 		sli->class;
 	ed->ledID=		sli->id;
 	ed->ledsDefined=	sli->namesPresent|sli->mapsPresent;
 	ed->ledState=		sli->effectiveState;
-	ed->unsupported|=	XkbXIUnsupported&XkbXI_IndicatorStateMask;
-	ed->supported=		XkbXI_AllFeaturesMask&(~XkbXIUnsupported);
+	ed->unsupported|=	XkbXI_KeyboardsMask&XkbXI_IndicatorStateMask;
+	ed->supported=		XkbXI_AllFeaturesMask&(~XkbXI_KeyboardsMask);
     }
 
     if (kb_changed) {
diff --git a/nx-X11/programs/Xserver/xkb/xkbPrKeyEv.c b/nx-X11/programs/Xserver/xkb/xkbPrKeyEv.c
index 9c13d99..ede2355 100644
--- a/nx-X11/programs/Xserver/xkb/xkbPrKeyEv.c
+++ b/nx-X11/programs/Xserver/xkb/xkbPrKeyEv.c
@@ -149,11 +149,7 @@ unsigned        ndx;
 		break;
 	    default:
 		ErrorF("unknown key behavior 0x%04x\n",behavior.type);
-#if defined(MetroLink)
-		return;
-#else
 		break;
-#endif
 	}
     }
     XkbHandleActions(keybd,keybd,xE,count);
diff --git a/nx-X11/programs/Xserver/xkb/xkbUtils.c b/nx-X11/programs/Xserver/xkb/xkbUtils.c
index bf88458..c97a54b 100644
--- a/nx-X11/programs/Xserver/xkb/xkbUtils.c
+++ b/nx-X11/programs/Xserver/xkb/xkbUtils.c
@@ -711,11 +711,11 @@ unsigned char	grp;
 
     grp= state->locked_group;
     if (grp>=ctrls->num_groups)
-	state->locked_group= XkbAdjustGroup(grp,ctrls);
+	state->locked_group= XkbAdjustGroup(XkbCharToInt(grp),ctrls);
 
     grp= state->locked_group+state->base_group+state->latched_group;
     if (grp>=ctrls->num_groups)
-	 state->group= XkbAdjustGroup(grp,ctrls);
+	 state->group= XkbAdjustGroup(XkbCharToInt(grp),ctrls);
     else state->group= grp;
     XkbComputeCompatState(xkbi);
     return;
diff --git a/nx-X11/programs/Xserver/xkb/xkbfmisc.c b/nx-X11/programs/Xserver/xkb/xkbfmisc.c
index d2d4a5d..823bb74 100644
--- a/nx-X11/programs/Xserver/xkb/xkbfmisc.c
+++ b/nx-X11/programs/Xserver/xkb/xkbfmisc.c
@@ -46,18 +46,185 @@
 #include "xkbgeom.h"
 #include "xkb.h"
 
+unsigned
+_XkbKSCheckCase(KeySym ks)
+{
+unsigned	set,rtrn;
+
+    set= (ks & (~0xff)) >> 8;
+    rtrn= 0;
+    switch (set) {
+	case 0:		/* latin 1 */
+	    if (((ks>=XK_A)&&(ks<=XK_Z))||
+		((ks>=XK_Agrave)&&(ks<=XK_THORN)&&(ks!=XK_multiply))) {
+		rtrn|= _XkbKSUpper;
+	    }
+	    if (((ks>=XK_a)&&(ks<=XK_z))||
+		((ks>=XK_agrave)&&(ks<=XK_ydiaeresis))) {
+		rtrn|= _XkbKSLower;
+	    }
+	    break;
+	case 1:		/* latin 2 */
+	    if (((ks>=XK_Aogonek)&&(ks<=XK_Zabovedot)&&(ks!=XK_breve))||
+		((ks>=XK_Racute)&&(ks<=XK_Tcedilla))) {
+		rtrn|= _XkbKSUpper;
+	    }
+	    if (((ks>=XK_aogonek)&&(ks<=XK_zabovedot)&&(ks!=XK_caron))||
+		((ks>=XK_racute)&&(ks<=XK_tcedilla))) {
+		rtrn|= _XkbKSLower;
+	    }
+	    break;
+	case 2:		/* latin 3 */
+	    if (((ks>=XK_Hstroke)&&(ks<=XK_Jcircumflex))||
+		((ks>=XK_Cabovedot)&&(ks<=XK_Scircumflex))) {
+		rtrn|= _XkbKSUpper;
+	    }
+	    if (((ks>=XK_hstroke)&&(ks<=XK_jcircumflex))||
+		((ks>=XK_cabovedot)&&(ks<=XK_scircumflex))) {
+		rtrn|= _XkbKSLower;
+	    }
+	    break;
+	case 3:		/* latin 4 */
+	    if (((ks>=XK_Rcedilla)&&(ks<=XK_Tslash))||
+	        (ks==XK_ENG)||
+		((ks>=XK_Amacron)&&(ks<=XK_Umacron))) {
+		rtrn|= _XkbKSUpper;
+	    }
+	    if (((ks>=XK_rcedilla)&&(ks<=XK_tslash))||
+	        (ks==XK_eng)||
+		((ks>=XK_amacron)&&(ks<=XK_umacron))) {
+		rtrn|= _XkbKSLower;
+	    }
+	    break;
+	case 18:		/* latin 8 */
+	    if ((ks==XK_Babovedot)||
+                ((ks>=XK_Dabovedot)&&(ks<=XK_Wacute))||
+		((ks>=XK_Ygrave)&&(ks<=XK_Fabovedot))||
+	        (ks==XK_Mabovedot)||
+	        (ks==XK_Pabovedot)||
+	        (ks==XK_Sabovedot)||
+	        (ks==XK_Wdiaeresis)||
+		((ks>=XK_Wcircumflex)&&(ks<=XK_Ycircumflex))) {
+		rtrn|= _XkbKSUpper;
+	    }
+	    if ((ks==XK_babovedot)||
+	        (ks==XK_dabovedot)||
+	        (ks==XK_fabovedot)||
+	        (ks==XK_mabovedot)||
+                ((ks>=XK_wgrave)&&(ks<=XK_wacute))||
+	        (ks==XK_ygrave)||
+		((ks>=XK_wdiaeresis)&&(ks<=XK_ycircumflex))) {
+		rtrn|= _XkbKSLower;
+	    }
+	    break;
+	case 19:		/* latin 9 */
+	    if ((ks==XK_OE)||(ks==XK_Ydiaeresis)) {
+		rtrn|= _XkbKSUpper;
+	    }
+	    if (ks==XK_oe) {
+		rtrn|= _XkbKSLower;
+	    }
+	    break;
+    }
+    return rtrn;
+}
+
+/***===================================================================***/
+
+Bool
+XkbLookupGroupAndLevel(	XkbDescPtr 	xkb,
+			int 		key,
+			int *		mods_inout,
+			int *		grp_inout,
+			int *		lvl_rtrn)
+{
+int		nG,eG;
+
+    if ((!xkb)||(!XkbKeycodeInRange(xkb,key))||(!grp_inout))
+	return False;
+
+    nG= XkbKeyNumGroups(xkb,key);
+    eG= *grp_inout;
+
+    if ( nG==0 ) {
+	*grp_inout= 0;
+	if (lvl_rtrn!=NULL)
+	    *lvl_rtrn= 0;
+	return False;
+    }
+    else if ( nG==1 ) {
+	eG= 0;
+    }
+    else if ( eG>=nG ) {
+	unsigned gI= XkbKeyGroupInfo(xkb,key);
+	switch (XkbOutOfRangeGroupAction(gI)) {
+	    default:
+		eG %= nG;
+		break;
+	    case XkbClampIntoRange:
+		eG = nG-1;
+		break;
+	    case XkbRedirectIntoRange:
+		eG = XkbOutOfRangeGroupNumber(gI);
+		if (eG>=nG)
+		    eG= 0;
+		break;
+	}
+    }
+    *grp_inout= eG;
+    if (mods_inout!=NULL) {
+	XkbKeyTypePtr	type;
+	int		preserve;
+
+	type = XkbKeyKeyType(xkb,key,eG);
+	if (lvl_rtrn!=NULL)
+	    *lvl_rtrn= 0;
+	preserve= 0;
+	if (type->map) { /* find the shift level */
+	    register int i;
+	    register XkbKTMapEntryPtr entry;
+	    for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
+		if ((entry->active)&&
+			(((*mods_inout)&type->mods.mask)==entry->mods.mask)){
+		    if (lvl_rtrn!=NULL)
+			*lvl_rtrn= entry->level;
+		    if (type->preserve)
+			preserve= type->preserve[i].mask;
+		    break;
+		}
+	    }
+	}
+	(*mods_inout)&= ~(type->mods.mask&(~preserve));
+    }
+    return True;
+}
+
 /***===================================================================***/
 
 static Bool
 XkbWriteSectionFromName(FILE *file,char *sectionName,char *name)
 {
     fprintf(file,"    xkb_%-20s { include \"%s\" };\n",sectionName,name);
-    ErrorF("    xkb_%-20s { include \"%s\" };\n",sectionName,name);
     return True;
 }
 
-#define	NEED_DESC(n) ((!n)||((n)[0]=='+')||((n)[0]=='|')||(strchr((n),'%')))
-#define	COMPLETE(n)  ((n)&&(!NEED_DESC(n)))
+#define NEED_DESC(n) ((!n)||((n)[0]=='+')||((n)[0]=='|')||(strchr((n),'%')))
+#define COMPLETE(n)  ((n)&&(!NEED_DESC(n)))
+
+/* ARGSUSED */
+static void
+_AddIncl(	FILE *		file,
+		XkbFileInfo *	result,
+		Bool 		topLevel,
+		Bool 		showImplicit,
+		int 		index,
+		void *		priv)
+{
+    if ((priv)&&(strcmp((char *)priv,"%")!=0))
+	fprintf(file,"    include \"%s\"\n",(char *)priv);
+    return;
+}
+
 Bool
 XkbWriteXKBKeymapForNames(	FILE *			file,
 				XkbComponentNamesPtr	names,
@@ -66,29 +233,230 @@ XkbWriteXKBKeymapForNames(	FILE *			file,
 				unsigned		want,
 				unsigned		need)
 {
-    if (!names || (!names->keycodes && !names->types && !names->compat &&
-                   !names->symbols && !names->geometry))
-        return False;
-
-    fprintf(file, "xkb_keymap \"%s\" {\n", names->keymap ? names->keymap :
-                                                           "default");
-
-    if (names->keycodes)
-	XkbWriteSectionFromName(file, "keycodes", names->keycodes);
-    if (names->types)
-	XkbWriteSectionFromName(file, "types", names->types);
-    if (names->compat)
-	XkbWriteSectionFromName(file, "compatibility", names->compat);
-    if (names->symbols)
-	XkbWriteSectionFromName(file, "symbols", names->symbols);
-    if (names->geometry)
-	XkbWriteSectionFromName(file, "geometry", names->geometry);
-
-    fprintf(file,"};\n");
+char *		name;
+const char *	tmp;
+unsigned	complete;
+XkbNamesPtr	old_names;
+int		multi_section;
+unsigned	wantNames,wantConfig,wantDflts;
+XkbFileInfo	finfo;
+
+    bzero(&finfo,sizeof(XkbFileInfo));
+
+    complete= 0;
+    if ((name=names->keymap)==NULL)	name= "default";
+    if (COMPLETE(names->keycodes))	complete|= XkmKeyNamesMask;
+    if (COMPLETE(names->types))		complete|= XkmTypesMask;
+    if (COMPLETE(names->compat))	complete|= XkmCompatMapMask;
+    if (COMPLETE(names->symbols))	complete|= XkmSymbolsMask;
+    if (COMPLETE(names->geometry))	complete|= XkmGeometryMask;
+    want|= (complete|need);
+    if (want&XkmSymbolsMask)
+	want|= XkmKeyNamesMask|XkmTypesMask;
+
+    if (want==0)
+	return False;
+
+    if (xkb!=NULL) {
+	 old_names= xkb->names;
+	 finfo.type= 0;
+	 finfo.defined= 0;
+	 finfo.xkb= xkb;
+	 if (!XkbDetermineFileType(&finfo,XkbXKBFile,NULL))
+	    return False;
+    }
+    else old_names= NULL;
 
+    wantConfig= want&(~complete);
+    if (xkb!=NULL) {
+	if (wantConfig&XkmTypesMask) {
+	    if ((!xkb->map) || (xkb->map->num_types<XkbNumRequiredTypes))
+		wantConfig&= ~XkmTypesMask;
+	}
+	if (wantConfig&XkmCompatMapMask) {
+	    if ((!xkb->compat) || (xkb->compat->num_si<1))
+		wantConfig&= ~XkmCompatMapMask;
+	}
+	if (wantConfig&XkmSymbolsMask) {
+	    if ((!xkb->map) || (!xkb->map->key_sym_map))
+		wantConfig&= ~XkmSymbolsMask;
+	}
+	if (wantConfig&XkmIndicatorsMask) {
+	    if (!xkb->indicators)
+		wantConfig&= ~XkmIndicatorsMask;
+	}
+	if (wantConfig&XkmKeyNamesMask) {
+	    if ((!xkb->names)||(!xkb->names->keys))
+		wantConfig&= ~XkmKeyNamesMask;
+	}
+	if ((wantConfig&XkmGeometryMask)&&(!xkb->geom))
+	    wantConfig&= ~XkmGeometryMask;
+    }
+    else {
+	wantConfig= 0;
+    }
+    complete|= wantConfig;
+
+    wantDflts= 0;
+    wantNames= want&(~complete);
+    if ((xkb!=NULL) && (old_names!=NULL)) {
+	if (wantNames&XkmTypesMask) {
+	    if (old_names->types!=None) {
+		tmp= NameForAtom(old_names->types);
+		names->types= Xstrdup(tmp);
+	    }
+	    else {
+		wantDflts|= XkmTypesMask;
+	    }
+	    complete|= XkmTypesMask; 
+	}
+	if (wantNames&XkmCompatMapMask) {
+	    if (old_names->compat!=None) {
+		tmp= NameForAtom(old_names->compat);
+		names->compat= Xstrdup(tmp);
+	    }
+	    else wantDflts|= XkmCompatMapMask;
+	    complete|= XkmCompatMapMask; 
+	}
+	if (wantNames&XkmSymbolsMask) {
+	    if (old_names->symbols==None)
+		return False;
+	    tmp= NameForAtom(old_names->symbols);
+	    names->symbols= Xstrdup(tmp);
+	    complete|= XkmSymbolsMask; 
+	}
+	if (wantNames&XkmKeyNamesMask) {
+	   if (old_names->keycodes!=None) {
+               tmp= NameForAtom(old_names->keycodes);
+		names->keycodes= Xstrdup(tmp);
+	    }
+	    else wantDflts|= XkmKeyNamesMask;
+	    complete|= XkmKeyNamesMask;
+	}
+	if (wantNames&XkmGeometryMask) {
+	    if (old_names->geometry==None)
+		return False;
+	    tmp= NameForAtom(old_names->geometry);
+	    names->geometry= Xstrdup(tmp);
+	    complete|= XkmGeometryMask; 
+	    wantNames&= ~XkmGeometryMask;
+	}
+    }
+    if (complete&XkmCompatMapMask)
+	complete|= XkmIndicatorsMask|XkmVirtualModsMask;
+    else if (complete&(XkmSymbolsMask|XkmTypesMask))
+	complete|= XkmVirtualModsMask;
+    if (need & (~complete))
+	return False;
+    if ((complete&XkmSymbolsMask)&&((XkmKeyNamesMask|XkmTypesMask)&(~complete)))
+	return False;
+
+    multi_section= 1;
+    if (((complete&XkmKeymapRequired)==XkmKeymapRequired)&&
+	((complete&(~XkmKeymapLegal))==0)) {
+	fprintf(file,"xkb_keymap \"%s\" {\n",name);
+    }
+    else if (((complete&XkmSemanticsRequired)==XkmSemanticsRequired)&&
+	((complete&(~XkmSemanticsLegal))==0)) {
+	fprintf(file,"xkb_semantics \"%s\" {\n",name);
+    }
+    else if (((complete&XkmLayoutRequired)==XkmLayoutRequired)&&
+	((complete&(~XkmLayoutLegal))==0)) {
+	fprintf(file,"xkb_layout \"%s\" {\n",name);
+    }
+    else if (XkmSingleSection(complete&(~XkmVirtualModsMask))) {
+	multi_section= 0;
+    }
+    else {
+	return False;
+    }
+
+    wantNames= complete&(~(wantConfig|wantDflts));
+    name= names->keycodes;
+    if (wantConfig&XkmKeyNamesMask)
+	XkbWriteXKBKeycodes(file,&finfo,False,False,_AddIncl,name);
+    else if (wantDflts&XkmKeyNamesMask)
+	fprintf(stderr,"Default symbols not implemented yet!\n");
+    else if (wantNames&XkmKeyNamesMask)
+	XkbWriteSectionFromName(file,"keycodes",name);
+
+    name= names->types;
+    if (wantConfig&XkmTypesMask)
+	XkbWriteXKBKeyTypes(file,&finfo,False,False,_AddIncl,name);
+    else if (wantDflts&XkmTypesMask)
+	fprintf(stderr,"Default types not implemented yet!\n");
+    else if (wantNames&XkmTypesMask)
+	XkbWriteSectionFromName(file,"types",name);
+
+    name= names->compat;
+    if (wantConfig&XkmCompatMapMask)
+	XkbWriteXKBCompatMap(file,&finfo,False,False,_AddIncl,name);
+    else if (wantDflts&XkmCompatMapMask)
+	fprintf(stderr,"Default interps not implemented yet!\n");
+    else if (wantNames&XkmCompatMapMask)
+	XkbWriteSectionFromName(file,"compatibility",name);
+
+    name= names->symbols;
+    if (wantConfig&XkmSymbolsMask)
+	XkbWriteXKBSymbols(file,&finfo,False,False,_AddIncl,name);
+    else if (wantNames&XkmSymbolsMask)
+	XkbWriteSectionFromName(file,"symbols",name);
+
+    name= names->geometry;
+    if (wantConfig&XkmGeometryMask)
+	XkbWriteXKBGeometry(file,&finfo,False,False,_AddIncl,name);
+    else if (wantNames&XkmGeometryMask)
+	XkbWriteSectionFromName(file,"geometry",name);
+
+    if (multi_section)
+	fprintf(file,"};\n");
     return True;
 }
 
+/***====================================================================***/
+
+/*ARGSUSED*/
+Status
+XkbMergeFile(XkbDescPtr xkb,XkbFileInfo finfo)
+{
+    return BadImplementation;
+}
+
+/***====================================================================***/
+
+int
+XkbFindKeycodeByName(XkbDescPtr xkb,char *name,Bool use_aliases)
+{
+register int	i;
+
+    if ((!xkb)||(!xkb->names)||(!xkb->names->keys))
+	return 0;
+    for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+	if (strncmp(xkb->names->keys[i].name,name,XkbKeyNameLength)==0)
+	    return i;
+    }
+    if (!use_aliases)
+	return 0;
+    if (xkb->geom && xkb->geom->key_aliases) {
+	XkbKeyAliasPtr	a;
+	a= xkb->geom->key_aliases;
+	for (i=0;i<xkb->geom->num_key_aliases;i++,a++) {
+	    if (strncmp(name,a->alias,XkbKeyNameLength)==0)
+		return XkbFindKeycodeByName(xkb,a->real,False);
+	}
+    }
+    if (xkb->names && xkb->names->key_aliases) {
+	XkbKeyAliasPtr	a;
+	a= xkb->names->key_aliases;
+	for (i=0;i<xkb->names->num_key_aliases;i++,a++) {
+	    if (strncmp(name,a->alias,XkbKeyNameLength)==0)
+		return XkbFindKeycodeByName(xkb,a->real,False);
+	}
+    }
+    return 0;
+}
+
+
 unsigned
 XkbConvertGetByNameComponents(Bool toXkm,unsigned orig)
 {
@@ -115,6 +483,34 @@ unsigned	rtrn;
     return rtrn;
 }
 
+unsigned
+XkbConvertXkbComponents(Bool toXkm,unsigned orig)
+{
+unsigned	rtrn;
+
+    rtrn= 0;
+    if (toXkm) {
+	if (orig&XkbClientMapMask)	rtrn|= XkmTypesMask|XkmSymbolsMask;
+	if (orig&XkbServerMapMask)	rtrn|= XkmTypesMask|XkmSymbolsMask;
+	if (orig&XkbCompatMapMask)	rtrn|= XkmCompatMapMask;
+	if (orig&XkbIndicatorMapMask)	rtrn|= XkmIndicatorsMask;
+	if (orig&XkbNamesMask)		rtrn|= XkmKeyNamesMask;
+	if (orig&XkbGeometryMask)	rtrn|= XkmGeometryMask;
+    }
+    else {
+	if (orig!=0)			rtrn|= XkbNamesMask;
+	if (orig&XkmTypesMask)		rtrn|= XkbClientMapMask;
+	if (orig&XkmCompatMapMask)
+		rtrn|= XkbCompatMapMask|XkbIndicatorMapMask;
+	if (orig&XkmSymbolsMask)	rtrn|=XkbClientMapMask|XkbServerMapMask;
+	if (orig&XkmIndicatorsMask)	rtrn|= XkbIndicatorMapMask;
+	if (orig&XkmKeyNamesMask)	
+		rtrn|= XkbNamesMask|XkbIndicatorMapMask;
+	if (orig&XkmGeometryMask)	rtrn|= XkbGeometryMask;
+    }
+    return rtrn;
+}
+
 Bool
 XkbDetermineFileType(XkbFileInfoPtr finfo,int format,int *opts_missing)
 {
@@ -245,19 +641,3 @@ XkbNameMatchesPattern(char *name,char *ptrn)
     /* if we get here, the pattern is exhausted (-:just like me:-) */
     return (name[0]=='\0');
 }
-
-#ifdef NEED_STRCASECMP
-_X_HIDDEN int
-_XkbStrCaseCmp(char *str1,char *str2)
-{
-    const u_char *us1 = (const u_char *)str1, *us2 = (const u_char *)str2;
-
-    while (tolower(*us1) == tolower(*us2)) {
-        if (*us1++ == '\0')
-            return (0);
-        us2++;
-    }
-
-    return (tolower(*us1) - tolower(*us2));
-}
-#endif
diff --git a/nx-X11/programs/Xserver/xkb/xkbout.c b/nx-X11/programs/Xserver/xkb/xkbout.c
new file mode 100644
index 0000000..ae821c9
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkbout.c
@@ -0,0 +1,1047 @@
+/************************************************************
+ Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+
+ Permission to use, copy, modify, and distribute this
+ software and its documentation for any purpose and without
+ fee is hereby granted, provided that the above copyright
+ notice appear in all copies and that both that copyright
+ notice and this permission notice appear in supporting
+ documentation, and that the name of Silicon Graphics not be 
+ used in advertising or publicity pertaining to distribution 
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability 
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+ 
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 
+ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 
+ DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 
+ OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
+ THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <nx-X11/Xfuncs.h>
+
+#include <nx-X11/X.h>
+#include <nx-X11/keysym.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "dix.h"
+#include "xkbstr.h"
+#include <xkbsrv.h>
+
+#include "xkbgeom.h"
+#include <xkbfile.h>
+
+#define	VMOD_HIDE_VALUE	0
+#define	VMOD_SHOW_VALUE	1
+#define	VMOD_COMMENT_VALUE 2
+
+static Bool
+WriteXKBVModDecl(FILE *file,Display *dpy,XkbDescPtr xkb,int showValue)
+{
+register int 	i,nMods;
+Atom *		vmodNames;
+
+    if (xkb==NULL)
+	return False;
+    if (xkb->names!=NULL)
+	 vmodNames= xkb->names->vmods;
+    else vmodNames= NULL;
+
+    for (i=nMods=0;i<XkbNumVirtualMods;i++) {
+	if ((vmodNames!=NULL)&&(vmodNames[i]!=None)) {
+	    if (nMods==0)	fprintf(file,"    virtual_modifiers ");
+	    else		fprintf(file,",");
+	    fprintf(file,"%s",XkbAtomText(dpy,vmodNames[i],XkbXKBFile));
+	    if ((showValue!=VMOD_HIDE_VALUE)&&
+		(xkb->server)&&(xkb->server->vmods[i]!=XkbNoModifierMask)) {
+		if (showValue==VMOD_COMMENT_VALUE) {
+		    fprintf(file,"/* = %s */",
+			XkbModMaskText(xkb->server->vmods[i],XkbXKBFile));
+		}
+		else  {
+		    fprintf(file,"= %s",
+			XkbModMaskText(xkb->server->vmods[i],XkbXKBFile));
+		}
+	    }
+	    nMods++;
+	}
+    }
+    if (nMods>0)
+	fprintf(file,";\n\n");
+    return True;
+}
+
+/***====================================================================***/
+
+static Bool
+WriteXKBAction(FILE *file,XkbFileInfo *result,XkbAnyAction *action)
+{
+XkbDescPtr	xkb;
+Display *	dpy;
+
+    xkb= result->xkb;
+    dpy= xkb->dpy;
+    fprintf(file,"%s",XkbActionText(dpy,xkb,(XkbAction *)action,XkbXKBFile));
+    return True;
+}
+
+/***====================================================================***/
+
+Bool
+XkbWriteXKBKeycodes(	FILE *			file,
+			XkbFileInfo *		result,
+			Bool			topLevel,
+			Bool			showImplicit,
+			XkbFileAddOnFunc	addOn,
+			void *			priv)
+{
+Atom			kcName;
+register unsigned 	i;
+XkbDescPtr		xkb;
+Display *		dpy;
+char *			alternate;
+
+    xkb= result->xkb;
+    dpy= xkb->dpy;
+    if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) {
+	_XkbLibError(_XkbErrMissingNames,"XkbWriteXKBKeycodes",0);
+	return False;
+    }
+    kcName= xkb->names->keycodes;
+    if (kcName!=None)
+	 fprintf(file,"xkb_keycodes \"%s\" {\n",
+					XkbAtomText(dpy,kcName,XkbXKBFile));
+    else fprintf(file,"xkb_keycodes {\n");
+    fprintf(file,"    minimum = %d;\n",xkb->min_key_code);
+    fprintf(file,"    maximum = %d;\n",xkb->max_key_code);
+    for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+	if (xkb->names->keys[i].name[0]!='\0') {
+	    if (XkbFindKeycodeByName(xkb,xkb->names->keys[i].name,True)!=i)
+		 alternate= "alternate ";
+	    else alternate= "";
+	    fprintf(file,"    %s%6s = %d;\n",alternate,
+			XkbKeyNameText(xkb->names->keys[i].name,XkbXKBFile),
+			i);
+	}
+    }
+    if (xkb->indicators!=NULL) {
+	for (i=0;i<XkbNumIndicators;i++) {
+	    char *type;
+	    if (xkb->indicators->phys_indicators&(1<<i))
+			type= "    ";
+	    else	type= "    virtual ";
+	    if (xkb->names->indicators[i]!=None) {
+		fprintf(file,"%sindicator %d = \"%s\";\n",type,i+1,
+			XkbAtomText(dpy,xkb->names->indicators[i],XkbXKBFile));
+	    }
+	}
+    }
+    if (xkb->names->key_aliases!=NULL) {
+	XkbKeyAliasPtr	pAl;
+	pAl= xkb->names->key_aliases;
+	for (i=0;i<xkb->names->num_key_aliases;i++,pAl++) {
+	    fprintf(file,"    alias %6s = %6s;\n",
+			XkbKeyNameText(pAl->alias,XkbXKBFile),
+			XkbKeyNameText(pAl->real,XkbXKBFile));
+	}
+    }
+    if (addOn)
+	(*addOn)(file,result,topLevel,showImplicit,XkmKeyNamesIndex,priv);
+    fprintf(file,"};\n\n");
+    return True;
+}
+
+Bool
+XkbWriteXKBKeyTypes(	FILE *			file,
+			XkbFileInfo *		result,
+			Bool			topLevel,
+			Bool			showImplicit,
+			XkbFileAddOnFunc	addOn,
+			void *			priv)
+{
+Display *		dpy;
+register unsigned	i,n;
+XkbKeyTypePtr		type;
+XkbKTMapEntryPtr	entry;
+XkbDescPtr		xkb;
+
+    xkb= result->xkb;
+    dpy= xkb->dpy;
+    if ((!xkb)||(!xkb->map)||(!xkb->map->types)) {
+	_XkbLibError(_XkbErrMissingTypes,"XkbWriteXKBKeyTypes",0);
+	return False;
+    }
+    if (xkb->map->num_types<XkbNumRequiredTypes) {
+	_XkbLibError(_XkbErrMissingReqTypes,"XkbWriteXKBKeyTypes",0);
+	return 0;
+    }
+    if ((xkb->names==NULL)||(xkb->names->types==None))
+	 fprintf(file,"xkb_types {\n\n");
+    else fprintf(file,"xkb_types \"%s\" {\n\n",
+			XkbAtomText(dpy,xkb->names->types,XkbXKBFile));
+    WriteXKBVModDecl(file,dpy,xkb,
+			(showImplicit?VMOD_COMMENT_VALUE:VMOD_HIDE_VALUE));
+
+    type= xkb->map->types;
+    for (i=0;i<xkb->map->num_types;i++,type++) {
+	fprintf(file,"    type \"%s\" {\n",
+		XkbAtomText(dpy,type->name,XkbXKBFile));
+	fprintf(file,"        modifiers= %s;\n",
+	       XkbVModMaskText(dpy,xkb,type->mods.real_mods,type->mods.vmods,
+								XkbXKBFile));
+	entry= type->map;
+	for (n=0;n<type->map_count;n++,entry++) {
+	    char *str;	
+	    str=XkbVModMaskText(dpy,xkb,entry->mods.real_mods,entry->mods.vmods,
+								XkbXKBFile);
+	    fprintf(file,"        map[%s]= Level%d;\n",str,entry->level+1);
+	    if ((type->preserve)&&((type->preserve[n].real_mods)||
+				   (type->preserve[n].vmods))) {
+		fprintf(file,"        preserve[%s]= ",str);
+		fprintf(file,"%s;\n",XkbVModMaskText(dpy,xkb,
+					type->preserve[n].real_mods,
+					type->preserve[n].vmods,
+					XkbXKBFile));
+	    }
+	}
+	if (type->level_names!=NULL) {
+	    Atom *name= type->level_names;
+	    for (n=0;n<type->num_levels;n++,name++) {
+		if ((*name)==None)
+		    continue;
+		fprintf(file,"        level_name[Level%d]= \"%s\";\n",n+1,
+					XkbAtomText(dpy,*name,XkbXKBFile));
+	    }
+	}
+	fprintf(file,"    };\n");
+    }
+    if (addOn)
+	(*addOn)(file,result,topLevel,showImplicit,XkmTypesIndex,priv);
+    fprintf(file,"};\n\n");
+    return True;
+}
+
+static Bool
+WriteXKBIndicatorMap(	FILE *			file,
+			XkbFileInfo *		result,
+			Atom			name,
+			XkbIndicatorMapPtr	led,
+			XkbFileAddOnFunc	addOn,
+			void *			priv)
+{
+XkbDescPtr	xkb;
+
+    xkb= result->xkb;
+    fprintf(file,"    indicator \"%s\" {\n",NameForAtom(name));
+    if (led->flags&XkbIM_NoExplicit)
+	fprintf(file,"        !allowExplicit;\n");
+    if (led->flags&XkbIM_LEDDrivesKB)
+	fprintf(file,"        indicatorDrivesKeyboard;\n");
+    if (led->which_groups!=0) {
+	if (led->which_groups!=XkbIM_UseEffective) {
+	    fprintf(file,"        whichGroupState= %s;\n",
+			XkbIMWhichStateMaskText(led->which_groups,XkbXKBFile));
+	}
+	fprintf(file,"        groups= 0x%02x;\n",led->groups);
+    }
+    if (led->which_mods!=0) {
+	if (led->which_mods!=XkbIM_UseEffective) {
+	    fprintf(file,"        whichModState= %s;\n",
+			XkbIMWhichStateMaskText(led->which_mods,XkbXKBFile));
+	}
+	fprintf(file,"        modifiers= %s;\n",
+			XkbVModMaskText(xkb->dpy,xkb,
+					led->mods.real_mods,led->mods.vmods,
+					XkbXKBFile));
+    }
+    if (led->ctrls!=0) {
+	fprintf(file,"        controls= %s;\n",
+			XkbControlsMaskText(led->ctrls,XkbXKBFile));
+    }
+    if (addOn)
+	(*addOn)(file,result,False,True,XkmIndicatorsIndex,priv);
+    fprintf(file,"    };\n");
+    return True;
+}
+
+Bool
+XkbWriteXKBCompatMap(	FILE *			file,
+			XkbFileInfo *		result,
+			Bool			topLevel,
+			Bool			showImplicit,
+			XkbFileAddOnFunc	addOn,
+			void *			priv)
+{
+Display *		dpy;
+register unsigned	i;
+XkbSymInterpretPtr	interp;
+XkbDescPtr		xkb;
+
+    xkb= result->xkb;
+    dpy= xkb->dpy;
+    if ((!xkb)||(!xkb->compat)||(!xkb->compat->sym_interpret)) {
+	_XkbLibError(_XkbErrMissingCompatMap,"XkbWriteXKBCompatMap",0);
+	return False;
+    }
+    if ((xkb->names==NULL)||(xkb->names->compat==None))
+	 fprintf(file,"xkb_compatibility {\n\n");
+    else fprintf(file,"xkb_compatibility \"%s\" {\n\n",
+			XkbAtomText(dpy,xkb->names->compat,XkbXKBFile));
+    WriteXKBVModDecl(file,dpy,xkb,
+			(showImplicit?VMOD_COMMENT_VALUE:VMOD_HIDE_VALUE));
+
+    fprintf(file,"    interpret.useModMapMods= AnyLevel;\n");
+    fprintf(file,"    interpret.repeat= False;\n");
+    fprintf(file,"    interpret.locking= False;\n");
+    interp= xkb->compat->sym_interpret;
+    for (i=0;i<xkb->compat->num_si;i++,interp++) {
+	fprintf(file,"    interpret %s+%s(%s) {\n",	
+				((interp->sym==NoSymbol)?"Any":
+					XkbKeysymText(interp->sym,XkbXKBFile)),
+				XkbSIMatchText(interp->match,XkbXKBFile),
+				XkbModMaskText(interp->mods,XkbXKBFile));
+	if (interp->virtual_mod!=XkbNoModifier) {
+	    fprintf(file,"        virtualModifier= %s;\n",
+		XkbVModIndexText(dpy,xkb,interp->virtual_mod,XkbXKBFile));
+	}
+	if (interp->match&XkbSI_LevelOneOnly)
+	    fprintf(file,"        useModMapMods=level1;\n");
+	if (interp->flags&XkbSI_LockingKey)
+	    fprintf(file,"        locking= True;\n");
+	if (interp->flags&XkbSI_AutoRepeat)
+	    fprintf(file,"        repeat= True;\n");
+	fprintf(file,"        action= ");
+	WriteXKBAction(file,result,&interp->act);
+	fprintf(file,";\n");
+	fprintf(file,"    };\n");
+    }
+    for (i=0;i<XkbNumKbdGroups;i++) {
+	XkbModsPtr	gc;
+
+	gc= &xkb->compat->groups[i];
+	if ((gc->real_mods==0)&&(gc->vmods==0))
+	    continue;
+	fprintf(file,"    group %d = %s;\n",i+1,XkbVModMaskText(xkb->dpy,xkb,
+							gc->real_mods,gc->vmods,
+							XkbXKBFile));
+    }
+    if (xkb->indicators) {
+	for (i=0;i<XkbNumIndicators;i++) {
+	    XkbIndicatorMapPtr map= &xkb->indicators->maps[i];
+	    if ((map->flags!=0)||(map->which_groups!=0)||(map->groups!=0)||
+		(map->which_mods!=0)||
+		(map->mods.real_mods!=0)||(map->mods.vmods!=0)||
+		(map->ctrls!=0)) {
+		WriteXKBIndicatorMap(file,result,xkb->names->indicators[i],map,
+								addOn,priv);
+	    }
+	}
+    }
+    if (addOn)
+	(*addOn)(file,result,topLevel,showImplicit,XkmCompatMapIndex,priv);
+    fprintf(file,"};\n\n");
+    return True;
+}
+
+Bool
+XkbWriteXKBSymbols(	FILE *			file,
+			XkbFileInfo *		result,
+			Bool			topLevel,
+			Bool			showImplicit,
+			XkbFileAddOnFunc	addOn,
+			void *			priv)
+{
+Display *		dpy;
+register unsigned	i,tmp;
+XkbDescPtr		xkb;
+XkbClientMapPtr		map;
+XkbServerMapPtr		srv;
+Bool			showActions;
+
+    xkb= result->xkb;
+    map= xkb->map;
+    srv= xkb->server;
+    dpy= xkb->dpy;
+    if ((!xkb)||(!map)||(!map->syms)||(!map->key_sym_map)) {
+	_XkbLibError(_XkbErrMissingSymbols,"XkbWriteXKBSymbols",0);
+	return False;
+    }
+    if ((!xkb->names)||(!xkb->names->keys)) {
+	_XkbLibError(_XkbErrMissingNames,"XkbWriteXKBSymbols",0);
+	return False;
+    }
+    if ((xkb->names==NULL)||(xkb->names->symbols==None))
+	 fprintf(file,"xkb_symbols {\n\n");
+    else fprintf(file,"xkb_symbols \"%s\" {\n\n",
+			XkbAtomText(dpy,xkb->names->symbols,XkbXKBFile));
+    for (tmp=i=0;i<XkbNumKbdGroups;i++) {
+	if (xkb->names->groups[i]!=None) {
+	    fprintf(file,"    name[group%d]=\"%s\";\n",i+1,
+			XkbAtomText(dpy,xkb->names->groups[i],XkbXKBFile));
+	    tmp++;
+	}
+    }
+    if (tmp>0)
+	fprintf(file,"\n");
+    for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+	Bool	simple;
+	if ((int)XkbKeyNumSyms(xkb,i)<1)
+	    continue;
+	if (XkbFindKeycodeByName(xkb,xkb->names->keys[i].name,True)!=i)
+	    continue;
+	simple= True;
+	fprintf(file,"    key %6s {",
+			XkbKeyNameText(xkb->names->keys[i].name,XkbXKBFile));
+	if (srv->explicit) {
+	    if (((srv->explicit[i]&XkbExplicitKeyTypesMask)!=0)||
+	   						(showImplicit)) {
+		int 	typeNdx,g;
+		Bool	multi;
+		char *	comment="  ";
+
+		if ((srv->explicit[i]&XkbExplicitKeyTypesMask)==0)
+		    comment= "//";
+		multi= False;
+		typeNdx= XkbKeyKeyTypeIndex(xkb,i,0);
+		for (g=1;(g<XkbKeyNumGroups(xkb,i))&&(!multi);g++) {
+		    if (XkbKeyKeyTypeIndex(xkb,i,g)!=typeNdx)
+			multi= True;
+		}
+		if (multi) {
+		    for (g=0;g<XkbKeyNumGroups(xkb,i);g++) {
+			typeNdx= XkbKeyKeyTypeIndex(xkb,i,g);
+			if (srv->explicit[i]&(1<<g)) {
+			    fprintf(file,"\n%s      type[group%d]= \"%s\",",
+			    	comment,g+1,
+				XkbAtomText(dpy,map->types[typeNdx].name,
+			    	XkbXKBFile));
+			}
+			else if (showImplicit) {
+			    fprintf(file,"\n//      type[group%d]= \"%s\",",g+1,
+				XkbAtomText(dpy,map->types[typeNdx].name,
+			    	XkbXKBFile));
+			}
+		    }
+		}
+		else {
+		    fprintf(file,"\n%s      type= \"%s\",",comment,
+				XkbAtomText(dpy,map->types[typeNdx].name,
+			    	XkbXKBFile));
+		}
+		simple= False;
+	    }
+	    if (((srv->explicit[i]&XkbExplicitAutoRepeatMask)!=0)&&
+		    					  (xkb->ctrls!=NULL)) {
+		if (xkb->ctrls->per_key_repeat[i/8]&(1<<(i%8)))
+		     fprintf(file,"\n        repeat= Yes,");
+		else fprintf(file,"\n        repeat= No,");
+		simple= False;
+	    }
+	    if ((xkb->server!=NULL)&&(xkb->server->vmodmap!=NULL)&&
+					(xkb->server->vmodmap[i]!=0)) {
+		if ((srv->explicit[i]&XkbExplicitVModMapMask)!=0) {
+		    fprintf(file,"\n        virtualMods= %s,",
+				XkbVModMaskText(dpy,xkb,0,
+						xkb->server->vmodmap[i],
+						XkbXKBFile));
+		}
+		else if (showImplicit) {
+		    fprintf(file,"\n//      virtualMods= %s,",
+				XkbVModMaskText(dpy,xkb,0,
+						xkb->server->vmodmap[i],
+						XkbXKBFile));
+		}
+	    }
+	}
+	switch (XkbOutOfRangeGroupAction(XkbKeyGroupInfo(xkb,i))) {
+	    case XkbClampIntoRange:
+		fprintf(file,"\n        groupsClamp,");
+		break;
+	    case XkbRedirectIntoRange:
+		fprintf(file,"\n        groupsRedirect= Group%d,",
+			XkbOutOfRangeGroupNumber(XkbKeyGroupInfo(xkb,i))+1);
+		break;
+	}
+	if (srv->behaviors!=NULL) {
+	    unsigned type;
+	    type= srv->behaviors[i].type&XkbKB_OpMask;
+
+	    if (type!=XkbKB_Default) {
+		simple= False;
+		fprintf(file,"\n        %s,",
+			XkbBehaviorText(xkb,&srv->behaviors[i],XkbXKBFile));
+	    }
+	}
+	if ((srv->explicit==NULL) || showImplicit ||
+	    ((srv->explicit[i]&XkbExplicitInterpretMask)!=0))
+	     showActions= XkbKeyHasActions(xkb,i);
+	else showActions= False;
+	
+	if (((unsigned)XkbKeyNumGroups(xkb,i)>1)||showActions)
+	    simple= False;
+	if (simple) {
+	    KeySym *syms;
+	    unsigned s;
+
+	    syms= XkbKeySymsPtr(xkb,i);
+	    fprintf(file,"         [ ");
+	    for (s=0;s<XkbKeyGroupWidth(xkb,i,XkbGroup1Index);s++) {
+		if (s!=0)
+		    fprintf(file,", ");
+		fprintf(file,"%15s",XkbKeysymText(*syms++,XkbXKBFile));
+	    }
+	    fprintf(file," ] };\n");
+	}
+	else {
+	    unsigned g,s;
+	    KeySym *syms;
+	    XkbAction *acts;
+	    syms= XkbKeySymsPtr(xkb,i);
+	    acts= XkbKeyActionsPtr(xkb,i);
+	    for (g=0;g<XkbKeyNumGroups(xkb,i);g++) {
+		if (g!=0)
+		    fprintf(file,",");
+		fprintf(file,"\n        symbols[Group%d]= [ ",g+1);
+		for (s=0;s<XkbKeyGroupWidth(xkb,i,g);s++) {
+		    if (s!=0)
+			fprintf(file,", ");
+		    fprintf(file,"%15s",XkbKeysymText(syms[s],XkbXKBFile));
+		}
+		fprintf(file," ]");
+		syms+= XkbKeyGroupsWidth(xkb,i);
+		if (showActions) {
+		    fprintf(file,",\n        actions[Group%d]= [ ",g+1);
+		    for (s=0;s<XkbKeyGroupWidth(xkb,i,g);s++) {
+			if (s!=0)
+			    fprintf(file,", ");
+			WriteXKBAction(file,result,(XkbAnyAction *)&acts[s]);
+		    }
+		    fprintf(file," ]");
+		    acts+= XkbKeyGroupsWidth(xkb,i);
+		}
+	    }
+	    fprintf(file,"\n    };\n");
+	}
+    }
+    if (map && map->modmap) {
+	for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+	    if (map->modmap[i]!=0) {
+		register int n,bit;
+		for (bit=1,n=0;n<XkbNumModifiers;n++,bit<<=1) {
+		    if (map->modmap[i]&bit) {
+			char buf[5];
+			memcpy(buf,xkb->names->keys[i].name,4);
+			buf[4]= '\0';
+			fprintf(file,"    modifier_map %s { <%s> };\n",
+					XkbModIndexText(n,XkbXKBFile),buf);
+		    }
+		}
+	    }
+	}
+    }
+    if (addOn)
+	(*addOn)(file,result,topLevel,showImplicit,XkmSymbolsIndex,priv);
+    fprintf(file,"};\n\n");
+    return True;
+}
+
+static Bool
+WriteXKBOutline(	FILE *		file,
+			XkbShapePtr	shape,
+			XkbOutlinePtr	outline,
+			int		lastRadius,
+			int		first,
+			int		indent)
+{
+register int	i;
+XkbPointPtr	pt;
+char *		iStr;
+
+    fprintf(file,"%s",iStr= XkbIndentText(first));
+    if (first!=indent)
+	iStr= XkbIndentText(indent);
+    if (outline->corner_radius!=lastRadius) {
+	fprintf(file,"corner= %s,",
+			XkbGeomFPText(outline->corner_radius,XkbMessage));
+	if (shape!=NULL) {
+	    fprintf(file,"\n%s",iStr);
+	}
+    }
+    if (shape) {
+	if (outline==shape->approx)
+	    fprintf(file,"approx= ");
+	else if (outline==shape->primary)
+	    fprintf(file,"primary= ");
+    }
+    fprintf(file,"{");
+    for (pt=outline->points,i=0;i<outline->num_points;i++,pt++) {
+	if (i==0)		fprintf(file," ");
+	else if ((i%4)==0)	fprintf(file,",\n%s  ",iStr);
+	else			fprintf(file,", ");
+	fprintf(file,"[ %3s, %3s ]",XkbGeomFPText(pt->x,XkbXKBFile),
+				  XkbGeomFPText(pt->y,XkbXKBFile));
+    }
+    fprintf(file," }");
+    return True;
+}
+
+static Bool
+WriteXKBDoodad(	FILE *		file,
+		Display *	dpy,
+		unsigned	indent,
+		XkbGeometryPtr	geom,
+		XkbDoodadPtr	doodad)
+{
+register char *	i_str;
+XkbShapePtr	shape;
+XkbColorPtr	color;
+
+    i_str= XkbIndentText(indent);
+    fprintf(file,"%s%s \"%s\" {\n",i_str,
+				XkbDoodadTypeText(doodad->any.type,XkbMessage),
+				XkbAtomText(dpy,doodad->any.name,XkbMessage));
+    fprintf(file,"%s    top=      %s;\n",i_str,
+				 XkbGeomFPText(doodad->any.top,XkbXKBFile));
+    fprintf(file,"%s    left=     %s;\n",i_str,
+				XkbGeomFPText(doodad->any.left,XkbXKBFile));
+    fprintf(file,"%s    priority= %d;\n",i_str,doodad->any.priority);
+    switch (doodad->any.type) {
+	case XkbOutlineDoodad:
+	case XkbSolidDoodad:
+	    if (doodad->shape.angle!=0) {
+		fprintf(file,"%s    angle=  %s;\n",i_str,
+			     XkbGeomFPText(doodad->shape.angle,XkbXKBFile));
+	    }
+	    if (doodad->shape.color_ndx!=0) {
+		fprintf(file,"%s    color= \"%s\";\n",i_str,
+			     XkbShapeDoodadColor(geom,&doodad->shape)->spec);
+	    }
+	    shape= XkbShapeDoodadShape(geom,&doodad->shape);
+	    fprintf(file,"%s    shape= \"%s\";\n",i_str,
+			    XkbAtomText(dpy,shape->name,XkbXKBFile));
+	    break;
+	case XkbTextDoodad:
+	    if (doodad->text.angle!=0) {
+		fprintf(file,"%s    angle=  %s;\n",i_str,
+			     XkbGeomFPText(doodad->text.angle,XkbXKBFile));
+	    }
+	    if (doodad->text.width!=0) {
+		fprintf(file,"%s    width=  %s;\n",i_str,
+			     XkbGeomFPText(doodad->text.width,XkbXKBFile));
+
+	    }
+	    if (doodad->text.height!=0) {
+		fprintf(file,"%s    height=  %s;\n",i_str,
+			     XkbGeomFPText(doodad->text.height,XkbXKBFile));
+
+	    }
+	    if (doodad->text.color_ndx!=0) {
+		color= XkbTextDoodadColor(geom,&doodad->text);
+		fprintf(file,"%s    color= \"%s\";\n",i_str,
+			     XkbStringText(color->spec,XkbXKBFile));
+	    }
+	    fprintf(file,"%s    XFont= \"%s\";\n",i_str,
+	    		     XkbStringText(doodad->text.font,XkbXKBFile));
+	    fprintf(file,"%s    text=  \"%s\";\n",i_str,
+	    		    XkbStringText(doodad->text.text,XkbXKBFile));
+	    break;
+	case XkbIndicatorDoodad:
+	    shape= XkbIndicatorDoodadShape(geom,&doodad->indicator);
+	    color= XkbIndicatorDoodadOnColor(geom,&doodad->indicator);
+	    fprintf(file,"%s    onColor= \"%s\";\n",i_str,
+	    		    XkbStringText(color->spec,XkbXKBFile));
+	    color= XkbIndicatorDoodadOffColor(geom,&doodad->indicator);
+	    fprintf(file,"%s    offColor= \"%s\";\n",i_str,
+	    		    XkbStringText(color->spec,XkbXKBFile));
+	    fprintf(file,"%s    shape= \"%s\";\n",i_str,
+			     XkbAtomText(dpy,shape->name,XkbXKBFile));
+	    break;
+	case XkbLogoDoodad:
+	    fprintf(file,"%s    logoName= \"%s\";\n",i_str,
+			     XkbStringText(doodad->logo.logo_name,XkbXKBFile));
+	    if (doodad->shape.angle!=0) {
+		fprintf(file,"%s    angle=  %s;\n",i_str,
+			     XkbGeomFPText(doodad->logo.angle,XkbXKBFile));
+	    }
+	    if (doodad->shape.color_ndx!=0) {
+		fprintf(file,"%s    color= \"%s\";\n",i_str,
+			     XkbLogoDoodadColor(geom,&doodad->logo)->spec);
+	    }
+	    shape= XkbLogoDoodadShape(geom,&doodad->logo);
+	    fprintf(file,"%s    shape= \"%s\";\n",i_str,
+			    XkbAtomText(dpy,shape->name,XkbXKBFile));
+	    break;
+    }
+    fprintf(file,"%s};\n",i_str);
+    return True;
+}
+
+/*ARGSUSED*/
+static Bool
+WriteXKBOverlay(	FILE *		file,
+			Display *	dpy,
+			unsigned	indent,
+			XkbGeometryPtr	geom,
+			XkbOverlayPtr	ol)
+{
+register char *		i_str;
+int			r,k,nOut;
+XkbOverlayRowPtr	row;
+XkbOverlayKeyPtr	key;
+
+    i_str= XkbIndentText(indent);
+    if (ol->name!=None) {
+	 fprintf(file,"%soverlay \"%s\" {\n",i_str,
+    					XkbAtomText(dpy,ol->name,XkbMessage));
+    }
+    else fprintf(file,"%soverlay {\n",i_str);
+    for (nOut=r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
+	for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
+	    char *over,*under;
+	    over= XkbKeyNameText(key->over.name,XkbXKBFile);
+	    under= XkbKeyNameText(key->under.name,XkbXKBFile);
+	    if (nOut==0)
+		 fprintf(file,"%s    %6s=%6s",i_str,under,over);
+	    else if ((nOut%4)==0)
+		 fprintf(file,",\n%s    %6s=%6s",i_str,under,over);
+	    else fprintf(file,", %6s=%6s",under,over);
+	    nOut++;
+	}
+    }
+    fprintf(file,"\n%s};\n",i_str);
+    return True;
+}
+
+static Bool
+WriteXKBSection(	FILE *		file,
+			Display *	dpy,
+			XkbSectionPtr 	s,
+			XkbGeometryPtr	geom)
+{
+register int	i;
+XkbRowPtr	row;
+int		dfltKeyColor = 0;
+
+    fprintf(file,"    section \"%s\" {\n",
+				XkbAtomText(dpy,s->name,XkbXKBFile));
+    if (s->rows&&(s->rows->num_keys>0)) {
+	dfltKeyColor= s->rows->keys[0].color_ndx;
+	fprintf(file,"        key.color= \"%s\";\n",
+		XkbStringText(geom->colors[dfltKeyColor].spec,XkbXKBFile));
+    }
+    fprintf(file,"        priority=  %d;\n",s->priority);
+    fprintf(file,"        top=       %s;\n",XkbGeomFPText(s->top,XkbXKBFile));
+    fprintf(file,"        left=      %s;\n",XkbGeomFPText(s->left,XkbXKBFile));
+    fprintf(file,"        width=     %s;\n",XkbGeomFPText(s->width,XkbXKBFile));
+    fprintf(file,"        height=    %s;\n",
+					XkbGeomFPText(s->height,XkbXKBFile));
+    if (s->angle!=0) {
+	fprintf(file,"        angle=  %s;\n",
+					XkbGeomFPText(s->angle,XkbXKBFile));
+    }
+    for (i=0,row=s->rows;i<s->num_rows;i++,row++) {
+	fprintf(file,"        row {\n");
+	fprintf(file,"            top=  %s;\n",
+					XkbGeomFPText(row->top,XkbXKBFile));
+	fprintf(file,"            left= %s;\n",
+					XkbGeomFPText(row->left,XkbXKBFile));
+	if (row->vertical)
+	    fprintf(file,"            vertical;\n");
+	if (row->num_keys>0) {
+	    register int 	k;
+	    register XkbKeyPtr	key;
+	    int			forceNL=0;
+	    int			nThisLine= 0;
+	    fprintf(file,"            keys {\n");
+	    for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
+		XkbShapePtr	shape;
+		if (key->color_ndx!=dfltKeyColor)
+		    forceNL= 1;
+		if (k==0) {
+		     fprintf(file,"                ");
+		     nThisLine= 0;
+		}
+		else if (((nThisLine%2)==1)||(forceNL)) {
+		     fprintf(file,",\n                ");
+		     forceNL= nThisLine= 0;
+		}
+		else {
+		     fprintf(file,", ");
+		     nThisLine++;
+		}
+		shape= XkbKeyShape(geom,key);
+		fprintf(file,"{ %6s, \"%s\", %3s",
+		      XkbKeyNameText(key->name.name,XkbXKBFile),
+		      XkbAtomText(dpy,shape->name,XkbXKBFile),
+		      XkbGeomFPText(key->gap,XkbXKBFile));
+		if (key->color_ndx!=dfltKeyColor) {
+		    fprintf(file,", color=\"%s\"",XkbKeyColor(geom,key)->spec);
+		    forceNL= 1;
+		}
+		fprintf(file," }");
+	    }
+	    fprintf(file,"\n            };\n");
+	}
+	fprintf(file,"        };\n");
+    }
+    if (s->doodads!=NULL) {
+	XkbDoodadPtr	doodad;
+	for (i=0,doodad=s->doodads;i<s->num_doodads;i++,doodad++) {
+	    WriteXKBDoodad(file,dpy,8,geom,doodad);
+	}
+    }
+    if (s->overlays!=NULL) {
+	XkbOverlayPtr	ol;
+	for (i=0,ol=s->overlays;i<s->num_overlays;i++,ol++) {
+	    WriteXKBOverlay(file,dpy,8,geom,ol);
+	}
+    }
+    fprintf(file,"    }; // End of \"%s\" section\n\n",
+				XkbAtomText(dpy,s->name,XkbXKBFile));
+    return True;
+}
+
+Bool
+XkbWriteXKBGeometry(	FILE *			file,
+			XkbFileInfo *		result,
+			Bool			topLevel,
+			Bool			showImplicit,
+			XkbFileAddOnFunc	addOn,
+			void *			priv)
+{
+Display *		dpy;
+register unsigned	i,n;
+XkbDescPtr		xkb;
+XkbGeometryPtr		geom;
+
+    xkb= result->xkb;
+    if ((!xkb)||(!xkb->geom)) {
+	_XkbLibError(_XkbErrMissingGeometry,"XkbWriteXKBGeometry",0);
+ 	return False;
+    }
+    dpy= xkb->dpy;
+    geom= xkb->geom;
+    if (geom->name==None)
+	 fprintf(file,"xkb_geometry {\n\n");
+    else fprintf(file,"xkb_geometry \"%s\" {\n\n",
+				XkbAtomText(dpy,geom->name,XkbXKBFile));
+    fprintf(file,"    width=       %s;\n",
+				XkbGeomFPText(geom->width_mm,XkbXKBFile));
+    fprintf(file,"    height=      %s;\n\n",
+				XkbGeomFPText(geom->height_mm,XkbXKBFile));
+
+    if (geom->key_aliases!=NULL) {
+	XkbKeyAliasPtr	pAl;
+	pAl= geom->key_aliases;
+	for (i=0;i<geom->num_key_aliases;i++,pAl++) {
+	    fprintf(file,"    alias %6s = %6s;\n",
+				XkbKeyNameText(pAl->alias,XkbXKBFile),
+				XkbKeyNameText(pAl->real,XkbXKBFile));
+	}
+	fprintf(file,"\n");
+    }
+
+    if (geom->base_color!=NULL)
+	fprintf(file,"    baseColor=   \"%s\";\n",
+			XkbStringText(geom->base_color->spec,XkbXKBFile));
+    if (geom->label_color!=NULL)
+	fprintf(file,"    labelColor=  \"%s\";\n",
+			XkbStringText(geom->label_color->spec,XkbXKBFile));
+    if (geom->label_font!=NULL)
+	fprintf(file,"    xfont=       \"%s\";\n",
+			XkbStringText(geom->label_font,XkbXKBFile));
+    if ((geom->num_colors>0)&&(showImplicit)) {
+	XkbColorPtr	color;
+	for (color=geom->colors,i=0;i<geom->num_colors;i++,color++) {
+		fprintf(file,"//     color[%d]= \"%s\"\n",i,
+				XkbStringText(color->spec,XkbXKBFile));
+	}
+	fprintf(file,"\n");
+    }
+    if (geom->num_properties>0) {
+	XkbPropertyPtr	prop;
+	for (prop=geom->properties,i=0;i<geom->num_properties;i++,prop++) {
+	    fprintf(file,"    %s= \"%s\";\n",prop->name,
+    				XkbStringText(prop->value,XkbXKBFile));
+	}
+	fprintf(file,"\n");
+    }
+    if (geom->num_shapes>0) {
+	XkbShapePtr	shape;
+	XkbOutlinePtr	outline;
+	int		lastR;
+	for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) {
+	    lastR=0;
+	    fprintf(file,"    shape \"%s\" {",
+				   XkbAtomText(dpy,shape->name,XkbXKBFile));
+	    outline= shape->outlines;
+	    if (shape->num_outlines>1) {
+		for (n=0;n<shape->num_outlines;n++,outline++) {
+		    if (n==0)	fprintf(file,"\n");
+		    else	fprintf(file,",\n");
+		    WriteXKBOutline(file,shape,outline,lastR,8,8);
+		    lastR= outline->corner_radius;
+		}
+		fprintf(file,"\n    };\n");
+	    }
+	    else {
+		WriteXKBOutline(file,NULL,outline,lastR,1,8);
+		fprintf(file," };\n");
+	    }
+	}
+    }
+    if (geom->num_sections>0) {
+	XkbSectionPtr	section;
+	for (section=geom->sections,i=0;i<geom->num_sections;i++,section++){
+	    WriteXKBSection(file,dpy,section,geom);
+	}
+    }
+    if (geom->num_doodads>0) {
+	XkbDoodadPtr	doodad;
+	for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) {
+	    WriteXKBDoodad(file,dpy,4,geom,doodad);
+	}
+    }
+    if (addOn)
+	(*addOn)(file,result,topLevel,showImplicit,XkmGeometryIndex,priv);
+    fprintf(file,"};\n\n");
+    return True;
+}
+
+/*ARGSUSED*/
+Bool
+XkbWriteXKBSemantics(	FILE *			file,
+			XkbFileInfo *		result,
+			Bool			topLevel,
+			Bool			showImplicit,
+			XkbFileAddOnFunc	addOn,
+			void *			priv)
+{
+Bool		ok;
+
+    fprintf(file,"xkb_semantics {\n");
+    ok= XkbWriteXKBKeyTypes(file,result,False,False,addOn,priv);
+    ok= ok&&XkbWriteXKBCompatMap(file,result,False,False,addOn,priv);
+    fprintf(file,"};\n");
+    return ok;
+}
+
+/*ARGSUSED*/
+Bool
+XkbWriteXKBLayout(	FILE *			file,
+			XkbFileInfo *		result,
+			Bool			topLevel,
+			Bool			showImplicit,
+			XkbFileAddOnFunc	addOn,
+			void *			priv)
+{
+Bool		ok;
+XkbDescPtr	xkb;
+
+    xkb= result->xkb;
+    fprintf(file,"xkb_layout {\n");
+    ok= XkbWriteXKBKeycodes(file,result,False,showImplicit,addOn,priv);
+    ok= ok&&XkbWriteXKBKeyTypes(file,result,False,showImplicit,addOn,priv);
+    ok= ok&&XkbWriteXKBSymbols(file,result,False,showImplicit,addOn,priv);
+    if (xkb->geom)
+	ok= ok&&XkbWriteXKBGeometry(file,result,False,showImplicit,addOn,priv);
+    fprintf(file,"};\n");
+    return ok;
+}
+
+/*ARGSUSED*/
+Bool
+XkbWriteXKBKeymap(	FILE *			file,
+			XkbFileInfo *		result,
+			Bool			topLevel,
+			Bool			showImplicit,
+			XkbFileAddOnFunc	addOn,
+			void *			priv)
+{
+Bool		ok;
+XkbDescPtr	xkb;
+
+    xkb= result->xkb;
+    fprintf(file,"xkb_keymap {\n");
+    ok= XkbWriteXKBKeycodes(file,result,False,showImplicit,addOn,priv);
+    ok= ok&&XkbWriteXKBKeyTypes(file,result,False,showImplicit,addOn,priv);
+    ok= ok&&XkbWriteXKBCompatMap(file,result,False,showImplicit,addOn,priv);
+    ok= ok&&XkbWriteXKBSymbols(file,result,False,showImplicit,addOn,priv);
+    if (xkb->geom)
+	ok= ok&&XkbWriteXKBGeometry(file,result,False,showImplicit,addOn,priv);
+    fprintf(file,"};\n");
+    return ok;
+}
+
+Bool
+XkbWriteXKBFile(	FILE *			out,
+			XkbFileInfo *		result,
+			Bool			showImplicit,
+			XkbFileAddOnFunc	addOn,
+			void *			priv)
+{
+Bool	 		ok = False;
+Bool			(*func)(
+    FILE *		/* file */,
+    XkbFileInfo *	/* result */,
+    Bool		/* topLevel */,
+    Bool		/* showImplicit */,
+    XkbFileAddOnFunc	/* addOn */,
+    void *		/* priv */
+) = NULL;
+
+    switch (result->type) {
+	case XkmSemanticsFile:
+	    func= XkbWriteXKBSemantics;
+	    break;
+	case XkmLayoutFile:
+	    func= XkbWriteXKBLayout;
+	    break;
+	case XkmKeymapFile:
+	    func= XkbWriteXKBKeymap;
+	    break;
+	case XkmTypesIndex:
+	    func= XkbWriteXKBKeyTypes;
+	    break;
+	case XkmCompatMapIndex:
+	    func= XkbWriteXKBCompatMap;
+	    break;
+	case XkmSymbolsIndex:
+	    func= XkbWriteXKBSymbols;
+	    break;
+	case XkmKeyNamesIndex:
+	    func= XkbWriteXKBKeycodes;
+	    break;
+	case XkmGeometryFile:
+	case XkmGeometryIndex:
+	    func= XkbWriteXKBGeometry;
+	    break;
+	case XkmVirtualModsIndex:
+	case XkmIndicatorsIndex:
+	    _XkbLibError(_XkbErrBadImplementation,
+	    		XkbConfigText(result->type,XkbMessage),0);
+	    return False;
+    }
+    if (out==NULL) {
+	_XkbLibError(_XkbErrFileCannotOpen,"XkbWriteXkbFile",0);
+	ok= False;
+    }
+    else if (func) {
+	ok= (*func)(out,result,True,showImplicit,addOn,priv);
+    }
+    return ok;
+}
diff --git a/nx-X11/programs/Xserver/xkb/xkbtext.c b/nx-X11/programs/Xserver/xkb/xkbtext.c
new file mode 100644
index 0000000..dc1c712
--- /dev/null
+++ b/nx-X11/programs/Xserver/xkb/xkbtext.c
@@ -0,0 +1,1325 @@
+/************************************************************
+ Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
+
+ Permission to use, copy, modify, and distribute this
+ software and its documentation for any purpose and without
+ fee is hereby granted, provided that the above copyright
+ notice appear in all copies and that both that copyright
+ notice and this permission notice appear in supporting
+ documentation, and that the name of Silicon Graphics not be 
+ used in advertising or publicity pertaining to distribution 
+ of the software without specific prior written permission.
+ Silicon Graphics makes no representation about the suitability 
+ of this software for any purpose. It is provided "as is"
+ without any express or implied warranty.
+ 
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 
+ AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+ GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 
+ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 
+ DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 
+ OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
+ THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#include <nx-X11/Xos.h>
+
+#include <nx-X11/X.h>
+#include <nx-X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "dix.h"
+#include "xkbstr.h"
+#include <xkbsrv.h>
+#include "xkbgeom.h"
+
+/***====================================================================***/
+
+#define	BUFFER_SIZE	512
+
+static char textBuffer[BUFFER_SIZE];
+static int  tbNext= 0;
+
+static char *
+tbGetBuffer(unsigned size)
+{
+char *rtrn;
+
+    if (size>=BUFFER_SIZE)
+	return NULL;
+    if ((BUFFER_SIZE-tbNext)<=size)
+	tbNext= 0;
+    rtrn= &textBuffer[tbNext];
+    tbNext+= size;
+    return rtrn;
+}
+
+/***====================================================================***/
+
+char *
+XkbAtomText(Display *dpy,Atom atm,unsigned format)
+{
+const char	*atmstr;
+char	*rtrn,*tmp;
+
+    atmstr= NameForAtom(atm);
+    if (atmstr!=NULL) {
+	int	len;
+	len= strlen(atmstr)+1;
+	if (len>BUFFER_SIZE)
+	    len= BUFFER_SIZE-2;
+	rtrn= tbGetBuffer(len);
+	strncpy(rtrn,atmstr,len);
+	rtrn[len]= '\0';
+    }
+    else {
+	rtrn= tbGetBuffer(1);
+	rtrn[0]= '\0';
+    }
+    if (format==XkbCFile) {
+	for (tmp=rtrn;*tmp!='\0';tmp++) {
+	    if ((tmp==rtrn)&&(!isalpha(*tmp)))
+		*tmp= '_';
+	    else if (!isalnum(*tmp))
+		*tmp= '_';
+	}
+    }
+    return XkbStringText(rtrn,format);
+}
+
+/***====================================================================***/
+
+char *
+XkbVModIndexText(Display *dpy,XkbDescPtr xkb,unsigned ndx,unsigned format)
+{
+register int len;
+register Atom *vmodNames;
+char *rtrn;
+const char *tmp;
+char  numBuf[20];
+
+    if (xkb && xkb->names)
+	 vmodNames= xkb->names->vmods;
+    else vmodNames= NULL;
+
+    tmp= NULL;
+    if (ndx>=XkbNumVirtualMods)
+	 tmp= "illegal";
+    else if (vmodNames&&(vmodNames[ndx]!=None))
+        tmp= NameForAtom(vmodNames[ndx]);
+    if (tmp==NULL) {
+	sprintf(numBuf,"%d",ndx);
+	tmp = numBuf;
+    }
+
+    len= strlen(tmp)+1;
+    if (format==XkbCFile)
+	len+= 4;
+    if (len>=BUFFER_SIZE)
+	len= BUFFER_SIZE-1;
+    rtrn= tbGetBuffer(len);
+    if (format==XkbCFile) {
+	 strcpy(rtrn,"vmod_");
+	 strncpy(&rtrn[5],tmp,len-4);
+    }
+    else strncpy(rtrn,tmp,len);
+    return rtrn;
+}
+
+char *
+XkbVModMaskText(	Display *	dpy,
+			XkbDescPtr	xkb,
+			unsigned	modMask,
+			unsigned	mask,
+			unsigned	format)
+{
+register int i,bit;
+int	 len;
+char *mm,*rtrn;
+char *str,buf[BUFFER_SIZE];
+
+    if ((modMask==0)&&(mask==0)) {
+	rtrn= tbGetBuffer(5);
+	if (format==XkbCFile)
+	     sprintf(rtrn,"0");
+	else sprintf(rtrn,"none");
+	return rtrn;
+    }
+    if (modMask!=0)
+	 mm= XkbModMaskText(modMask,format);
+    else mm= NULL;
+
+    str= buf;
+    buf[0]= '\0';
+    if (mask) {
+	char *tmp;
+	for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+	    if (mask&bit) {
+		tmp= XkbVModIndexText(dpy,xkb,i,format);
+		len= strlen(tmp)+1+(str==buf?0:1);
+		if (format==XkbCFile)
+		    len+= 4;
+		if ((str-(buf+len))<=BUFFER_SIZE) {
+		    if (str!=buf) {
+			if (format==XkbCFile)	*str++= '|';
+			else			*str++= '+';
+			len--;
+		    }
+		}
+		if (format==XkbCFile)
+		     sprintf(str,"%sMask",tmp);
+		else strcpy(str,tmp);
+		str= &str[len-1];
+	    }
+	}
+	str= buf;
+    }
+    else str= NULL;
+    if (mm)	
+	len= strlen(mm);
+    else	len= 0;
+    if (str)
+	len+= strlen(str)+(mm==NULL?0:1);
+    if (len>=BUFFER_SIZE)
+	len= BUFFER_SIZE-1;
+    rtrn= tbGetBuffer(len+1);
+    rtrn[0]= '\0';
+
+    if (mm!=NULL) {
+	i= strlen(mm);
+	if (i>len)
+	    i= len;
+	strcpy(rtrn,mm);
+    }
+    else {
+	i=0;
+    }
+    if (str!=NULL) {
+	if (mm!=NULL) {
+	    if (format==XkbCFile)	strcat(rtrn,"|");
+	    else			strcat(rtrn,"+");
+	}
+	strncat(rtrn,str,len-i);
+    }
+    rtrn[len]= '\0';
+    return rtrn;
+}
+
+static char *modNames[XkbNumModifiers] = {
+    "Shift", "Lock", "Control", "Mod1", "Mod2", "Mod3", "Mod4", "Mod5"
+};
+
+char *
+XkbModIndexText(unsigned ndx,unsigned format)
+{
+char *	rtrn;
+char	buf[100];
+
+    if (format==XkbCFile) {
+	if (ndx<XkbNumModifiers)
+	     sprintf(buf,"%sMapIndex",modNames[ndx]);
+	else if (ndx==XkbNoModifier)
+	     sprintf(buf,"XkbNoModifier");
+	else sprintf(buf,"0x%02x",ndx);
+    }
+    else {
+	if (ndx<XkbNumModifiers)
+	     strcpy(buf,modNames[ndx]);
+	else if (ndx==XkbNoModifier)
+	     strcpy(buf,"none");
+	else sprintf(buf,"ILLEGAL_%02x",ndx);
+    }
+    rtrn= tbGetBuffer(strlen(buf)+1);
+    strcpy(rtrn,buf);
+    return rtrn;
+}
+
+char *
+XkbModMaskText(unsigned mask,unsigned format)
+{
+register int i,bit;
+char buf[64],*rtrn;
+
+    if ((mask&0xff)==0xff) {
+	if (format==XkbCFile) 		strcpy(buf,"0xff");
+	else				strcpy(buf,"all");
+    }
+    else if ((mask&0xff)==0) {
+	if (format==XkbCFile)		strcpy(buf,"0");
+	else				strcpy(buf,"none");
+    }
+    else {
+	char *str= buf;
+	buf[0]= '\0';
+	for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) {
+	    if (mask&bit) {
+		if (str!=buf) {
+		    if (format==XkbCFile)	*str++= '|';
+		    else			*str++= '+';
+		}
+		strcpy(str,modNames[i]);
+		str= &str[strlen(str)];
+		if (format==XkbCFile) {
+		    strcpy(str,"Mask");
+		    str+= 4;
+		}
+	    }
+	}
+    }
+    rtrn= tbGetBuffer(strlen(buf)+1);
+    strcpy(rtrn,buf);
+    return rtrn;
+}
+
+/***====================================================================***/
+
+/*ARGSUSED*/
+char *
+XkbConfigText(unsigned config,unsigned format)
+{
+static char *buf;
+
+    buf= tbGetBuffer(32);
+    switch (config) {
+	case XkmSemanticsFile:
+	    strcpy(buf,"Semantics");
+	    break;
+	case XkmLayoutFile:
+	    strcpy(buf,"Layout");
+	    break;
+	case XkmKeymapFile:
+	    strcpy(buf,"Keymap");
+	    break;
+	case XkmGeometryFile:
+	case XkmGeometryIndex:
+	    strcpy(buf,"Geometry");
+	    break;
+	case XkmTypesIndex:
+	    strcpy(buf,"Types");
+	    break;
+	case XkmCompatMapIndex:
+	    strcpy(buf,"CompatMap");
+	    break;
+	case XkmSymbolsIndex:
+	    strcpy(buf,"Symbols");
+	    break;
+	case XkmIndicatorsIndex:
+	    strcpy(buf,"Indicators");
+	    break;
+	case XkmKeyNamesIndex:
+	    strcpy(buf,"KeyNames");
+	    break;
+	case XkmVirtualModsIndex:
+	    strcpy(buf,"VirtualMods");
+	    break;
+	default:
+	    sprintf(buf,"unknown(%d)",config);
+	    break;
+    }
+    return buf;
+}
+
+/***====================================================================***/
+
+char *
+XkbKeysymText(KeySym sym,unsigned format)
+{
+static char buf[32],*rtrn;
+
+    if (sym==NoSymbol)
+	 strcpy(rtrn=buf,"NoSymbol");
+    else sprintf(rtrn=buf, "0x%lx", (long)sym);
+    return rtrn;
+}
+
+char *
+XkbKeyNameText(char *name,unsigned format)
+{
+char *buf;
+
+    if (format==XkbCFile) {
+	buf= tbGetBuffer(5);
+	memcpy(buf,name,4);
+	buf[4]= '\0';
+    }
+    else {
+	int len;
+	buf= tbGetBuffer(7);
+	buf[0]= '<';
+	memcpy(&buf[1],name,4);
+	buf[5]= '\0';
+	len= strlen(buf);
+	buf[len++]= '>';
+	buf[len]= '\0';
+    }
+    return buf;
+}
+
+/***====================================================================***/
+
+static char *siMatchText[5] = {
+	"NoneOf", "AnyOfOrNone", "AnyOf", "AllOf", "Exactly"
+};
+
+char *
+XkbSIMatchText(unsigned type,unsigned format)
+{
+static char buf[40];
+char *rtrn;
+
+    switch (type&XkbSI_OpMask) {
+	case XkbSI_NoneOf:	rtrn= siMatchText[0]; break;
+	case XkbSI_AnyOfOrNone:	rtrn= siMatchText[1]; break;
+	case XkbSI_AnyOf:	rtrn= siMatchText[2]; break;
+	case XkbSI_AllOf:	rtrn= siMatchText[3]; break;
+	case XkbSI_Exactly:	rtrn= siMatchText[4]; break;
+	default:		sprintf(buf,"0x%x",type&XkbSI_OpMask);
+				return buf;
+    }
+    if (format==XkbCFile) {
+	if (type&XkbSI_LevelOneOnly)
+	     sprintf(buf,"XkbSI_LevelOneOnly|XkbSI_%s",rtrn);
+	else sprintf(buf,"XkbSI_%s",rtrn);
+	rtrn= buf;
+    }
+    return rtrn;
+}
+
+/***====================================================================***/
+
+static char *imWhichNames[]= {
+	"base",
+	"latched",
+	"locked",
+	"effective",
+	"compat"
+};
+
+char *
+XkbIMWhichStateMaskText(unsigned use_which,unsigned format)
+{
+int		len;
+unsigned	i,bit,tmp;
+char *		buf;
+
+    if (use_which==0) {
+	buf= tbGetBuffer(2);
+	strcpy(buf,"0");
+	return buf;
+    }
+    tmp= use_which&XkbIM_UseAnyMods;
+    for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
+	if (tmp&bit) {
+	    tmp&= ~bit;
+	    len+= strlen(imWhichNames[i])+1;
+	    if (format==XkbCFile)
+		len+= 9;
+	}
+    }
+    buf= tbGetBuffer(len+1);
+    tmp= use_which&XkbIM_UseAnyMods;
+    for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
+	if (tmp&bit) {
+	    tmp&= ~bit;
+	    if (format==XkbCFile) {
+		if (len!=0)
+		    buf[len++]= '|';
+		sprintf(&buf[len],"XkbIM_Use%s",imWhichNames[i]);
+		buf[len+9]= toupper(buf[len+9]);
+	    }
+	    else {
+		if (len!=0)
+		    buf[len++]= '+';
+		sprintf(&buf[len],"%s",imWhichNames[i]);
+	    }
+	    len+= strlen(&buf[len]);
+	}
+    }
+    return buf;
+}
+
+char *
+XkbAccessXDetailText(unsigned state,unsigned format)
+{
+char *buf,*prefix;
+
+    buf= tbGetBuffer(32);
+    if (format==XkbMessage)	prefix= "";
+    else			prefix= "XkbAXN_";
+    switch (state){
+	case XkbAXN_SKPress:	sprintf(buf,"%sSKPress",prefix); break;
+	case XkbAXN_SKAccept:	sprintf(buf,"%sSKAccept",prefix); break;
+	case XkbAXN_SKRelease:	sprintf(buf,"%sSKRelease",prefix); break;
+	case XkbAXN_SKReject:	sprintf(buf,"%sSKReject",prefix); break;
+	case XkbAXN_BKAccept:	sprintf(buf,"%sBKAccept",prefix); break;
+	case XkbAXN_BKReject:	sprintf(buf,"%sBKReject",prefix); break;
+	case XkbAXN_AXKWarning:	sprintf(buf,"%sAXKWarning",prefix); break;
+	default:		sprintf(buf,"ILLEGAL"); break;
+    }
+    return buf;
+}
+
+static char *nknNames[] = {
+	"keycodes", "geometry", "deviceID"
+};
+#define	NUM_NKN	(sizeof(nknNames)/sizeof(char *))
+
+char *
+XkbNKNDetailMaskText(unsigned detail,unsigned format)
+{
+char *buf,*prefix,*suffix;
+register int 		i;
+register unsigned	bit;
+int			len,plen,slen;
+
+
+    if ((detail&XkbAllNewKeyboardEventsMask)==0) {
+	char *tmp = "";
+	if (format==XkbCFile)			tmp= "0";
+	else if (format==XkbMessage)		tmp= "none";
+	buf=  tbGetBuffer(strlen(tmp)+1);
+	strcpy(buf,tmp);
+	return buf;
+    }
+    else if ((detail&XkbAllNewKeyboardEventsMask)==XkbAllNewKeyboardEventsMask){
+	char *	tmp;
+	if (format==XkbCFile)		tmp= "XkbAllNewKeyboardEventsMask";
+	else 				tmp= "all";
+	buf=  tbGetBuffer(strlen(tmp)+1);
+	strcpy(buf,tmp);
+	return buf;
+    }
+    if (format==XkbMessage) {
+	prefix= "";
+	suffix= "";
+	slen= plen= 0;
+    }
+    else {
+	prefix= "XkbNKN_";
+	plen= 7;
+	if (format==XkbCFile)
+	     suffix= "Mask";
+	else suffix= "";
+	slen= strlen(suffix);
+    }
+    for (len=0,i=0,bit=1;i<NUM_NKN;i++,bit<<=1) {
+	if (detail&bit) {
+	    if (len!=0)	len+= 1;	/* room for '+' or '|' */
+	    len+= plen+slen+strlen(nknNames[i]);
+	}
+    }
+    buf= tbGetBuffer(len+1);
+    buf[0]= '\0';
+    for (len=0,i=0,bit=1;i<NUM_NKN;i++,bit<<=1) {
+	if (detail&bit) {
+	    if (len!=0) {
+		if (format==XkbCFile)	buf[len++]= '|';
+		else			buf[len++]= '+';
+	    }
+	    if (plen) {
+		strcpy(&buf[len],prefix);
+		len+= plen;
+	    }
+	    strcpy(&buf[len],nknNames[i]);
+	    len+= strlen(nknNames[i]);
+	    if (slen) {
+		strcpy(&buf[len],suffix);
+		len+= slen;
+	    }
+	}
+    }
+    buf[len++]= '\0';
+    return buf;
+}
+
+static char *ctrlNames[] = {
+	"repeatKeys",
+	"slowKeys",
+	"bounceKeys",
+	"stickyKeys",
+	"mouseKeys",
+	"mouseKeysAccel",
+	"accessXKeys",
+	"accessXTimeout",
+	"accessXFeedback",
+	"audibleBell",
+	"overlay1",
+	"overlay2",
+	"ignoreGroupLock"
+};
+
+char *
+XkbControlsMaskText(unsigned ctrls,unsigned format)
+{
+int		len;
+unsigned	i,bit,tmp;
+char *		buf;
+
+    if (ctrls==0) {
+	buf= tbGetBuffer(5);
+	if (format==XkbCFile)
+	     strcpy(buf,"0");
+	else strcpy(buf,"none");
+	return buf;
+    }
+    tmp= ctrls&XkbAllBooleanCtrlsMask;
+    for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
+	if (tmp&bit) {
+	    tmp&= ~bit;
+	    len+= strlen(ctrlNames[i])+1;
+	    if (format==XkbCFile)
+		len+= 7;
+	}
+    }
+    buf= tbGetBuffer(len+1);
+    tmp= ctrls&XkbAllBooleanCtrlsMask;
+    for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
+	if (tmp&bit) {
+	    tmp&= ~bit;
+	    if (format==XkbCFile) {
+		if (len!=0)
+		    buf[len++]= '|';
+		sprintf(&buf[len],"Xkb%sMask",ctrlNames[i]);
+		buf[len+3]= toupper(buf[len+3]);
+	    }
+	    else {
+		if (len!=0)
+		    buf[len++]= '+';
+		sprintf(&buf[len],"%s",ctrlNames[i]);
+	    }
+	    len+= strlen(&buf[len]);
+	}
+    }
+    return buf;
+}
+
+/***====================================================================***/
+
+char *
+XkbStringText(char *str,unsigned format)
+{
+char *	buf;
+register char *in,*out;
+int	len;
+Bool	ok;
+
+    if (str==NULL) {
+	buf= tbGetBuffer(2);
+	buf[0]='\0';
+	return buf;
+    }
+    else if (format==XkbXKMFile)
+	return str;
+    for (ok= True,len=0,in=str;*in!='\0';in++,len++) {
+	if (!isprint(*in)) {
+	    ok= False;
+	    switch (*in) {
+		case '\n': case '\t': case '\v':
+		case '\b': case '\r': case '\f':
+		    len++;
+		    break;
+		default:
+		    len+= 4;
+		    break;
+	    }
+	}
+    }
+    if (ok)
+	return str;
+    buf= tbGetBuffer(len+1);
+    for (in=str,out=buf;*in!='\0';in++) {
+	if (isprint(*in))
+	    *out++= *in;
+	else {
+	    *out++= '\\';
+	    if (*in=='\n')	*out++= 'n';
+	    else if (*in=='\t')	*out++= 't';
+	    else if (*in=='\v')	*out++= 'v';
+	    else if (*in=='\b')	*out++= 'b';
+	    else if (*in=='\r')	*out++= 'r';
+	    else if (*in=='\f')	*out++= 'f';
+	    else if ((*in=='\033')&&(format==XkbXKMFile)) {
+		*out++= 'e';
+	    }
+	    else {
+		*out++= '0';
+		sprintf(out,"%o",*in);
+		while (*out!='\0')
+		    out++;
+	    }
+	}
+    }
+    *out++= '\0';
+    return buf;
+}
+
+/***====================================================================***/
+
+char *
+XkbGeomFPText(int val,unsigned format)
+{
+int	whole,frac;
+char *	buf;
+
+    buf= tbGetBuffer(12);
+    if (format==XkbCFile) {
+	sprintf(buf,"%d",val);
+    }
+    else {
+	whole= val/XkbGeomPtsPerMM;
+	frac= val%XkbGeomPtsPerMM;
+	if (frac!=0)
+	     sprintf(buf,"%d.%d",whole,frac);
+	else sprintf(buf,"%d",whole);
+    }
+    return buf;
+}
+
+char *
+XkbDoodadTypeText(unsigned type,unsigned format)
+{
+char *	buf;
+    if (format==XkbCFile) {
+	buf= tbGetBuffer(24);
+	if (type==XkbOutlineDoodad)	   strcpy(buf,"XkbOutlineDoodad");
+	else if (type==XkbSolidDoodad)	   strcpy(buf,"XkbSolidDoodad");
+	else if (type==XkbTextDoodad)	   strcpy(buf,"XkbTextDoodad");
+	else if (type==XkbIndicatorDoodad) strcpy(buf,"XkbIndicatorDoodad");
+	else if (type==XkbLogoDoodad)	   strcpy(buf,"XkbLogoDoodad");
+	else				   sprintf(buf,"UnknownDoodad%d",type);
+    }
+    else {
+	buf= tbGetBuffer(12);
+	if (type==XkbOutlineDoodad)	   strcpy(buf,"outline");
+	else if (type==XkbSolidDoodad)	   strcpy(buf,"solid");
+	else if (type==XkbTextDoodad)	   strcpy(buf,"text");
+	else if (type==XkbIndicatorDoodad) strcpy(buf,"indicator");
+	else if (type==XkbLogoDoodad)	   strcpy(buf,"logo");
+	else				   sprintf(buf,"unknown%d",type);
+    }
+    return buf;
+}
+
+static char *actionTypeNames[XkbSA_NumActions]= {
+    "NoAction", 
+    "SetMods",      "LatchMods",    "LockMods", 
+    "SetGroup",     "LatchGroup",   "LockGroup",
+    "MovePtr",
+    "PtrBtn",       "LockPtrBtn",
+    "SetPtrDflt",
+    "ISOLock",
+    "Terminate",    "SwitchScreen", 
+    "SetControls",  "LockControls",
+    "ActionMessage",
+    "RedirectKey",
+    "DeviceBtn",    "LockDeviceBtn"
+};
+
+char *
+XkbActionTypeText(unsigned type,unsigned format)
+{
+static char buf[32];
+char *rtrn;
+
+    if (type<=XkbSA_LastAction) {
+	rtrn= actionTypeNames[type];
+	if (format==XkbCFile) {
+	    sprintf(buf,"XkbSA_%s",rtrn);
+	    return buf;
+	}
+	return rtrn;
+    }
+    sprintf(buf,"Private");
+    return buf;
+}
+
+/***====================================================================***/
+
+static int
+TryCopyStr(char *to,char *from,int *pLeft)
+{
+register int len;
+    if (*pLeft>0) {
+	len= strlen(from);
+	if (len<((*pLeft)-3)) {
+	    strcat(to,from);
+	    *pLeft-= len;
+	    return True;
+	}
+    }
+    *pLeft= -1;
+    return False;
+}
+
+/*ARGSUSED*/
+static Bool
+CopyNoActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int*sz)
+{
+    return True;
+}
+
+static Bool
+CopyModActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
+								int* sz)
+{
+XkbModAction *	act;
+unsigned	tmp;
+
+    act= &action->mods;
+    tmp= XkbModActionVMods(act);
+    TryCopyStr(buf,"modifiers=",sz);
+    if (act->flags&XkbSA_UseModMapMods)
+	  TryCopyStr(buf,"modMapMods",sz);
+    else if (act->real_mods || tmp) {
+	 TryCopyStr(buf,
+		     XkbVModMaskText(dpy,xkb,act->real_mods,tmp,XkbXKBFile),
+		     sz);
+    }
+    else TryCopyStr(buf,"none",sz);
+    if (act->type==XkbSA_LockMods)
+	return True;
+    if (act->flags&XkbSA_ClearLocks)
+	TryCopyStr(buf,",clearLocks",sz);
+    if (act->flags&XkbSA_LatchToLock)
+	TryCopyStr(buf,",latchToLock",sz);
+    return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopyGroupActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
+								int *sz)
+{
+XkbGroupAction *	act;
+char			tbuf[32];
+
+    act= &action->group;
+    TryCopyStr(buf,"group=",sz);
+    if (act->flags&XkbSA_GroupAbsolute)
+	 sprintf(tbuf,"%d",XkbSAGroup(act)+1);
+    else if (XkbSAGroup(act)<0)
+	 sprintf(tbuf,"%d",XkbSAGroup(act));
+    else sprintf(tbuf,"+%d",XkbSAGroup(act));
+    TryCopyStr(buf,tbuf,sz);
+    if (act->type==XkbSA_LockGroup)
+	return True;
+    if (act->flags&XkbSA_ClearLocks)
+	TryCopyStr(buf,",clearLocks",sz);
+    if (act->flags&XkbSA_LatchToLock)
+	TryCopyStr(buf,",latchToLock",sz);
+    return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopyMovePtrArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
+{
+XkbPtrAction *	act;
+int		x,y;
+char		tbuf[32];
+
+    act= &action->ptr;
+    x= XkbPtrActionX(act);
+    y= XkbPtrActionY(act);
+    if ((act->flags&XkbSA_MoveAbsoluteX)||(x<0))
+	 sprintf(tbuf,"x=%d",x);
+    else sprintf(tbuf,"x=+%d",x);
+    TryCopyStr(buf,tbuf,sz);
+
+    if ((act->flags&XkbSA_MoveAbsoluteY)||(y<0))
+	 sprintf(tbuf,",y=%d",y);
+    else sprintf(tbuf,",y=+%d",y);
+    TryCopyStr(buf,tbuf,sz);
+    if (act->flags&XkbSA_NoAcceleration)
+	TryCopyStr(buf,",!accel",sz);
+    return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopyPtrBtnArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
+{
+XkbPtrBtnAction *	act;
+char			tbuf[32];
+
+    act= &action->btn;
+    TryCopyStr(buf,"button=",sz);
+    if ((act->button>0)&&(act->button<6)) {
+	 sprintf(tbuf,"%d",act->button);
+	 TryCopyStr(buf,tbuf,sz);
+    }
+    else TryCopyStr(buf,"default",sz);
+    if (act->count>0) {
+	sprintf(tbuf,",count=%d",act->count);
+	TryCopyStr(buf,tbuf,sz);
+    }
+    if (action->type==XkbSA_LockPtrBtn) {
+	switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) {
+	    case XkbSA_LockNoLock:
+		sprintf(tbuf,",affect=unlock"); break;
+	    case XkbSA_LockNoUnlock:
+		sprintf(tbuf,",affect=lock"); break;
+	    case XkbSA_LockNoUnlock|XkbSA_LockNoLock:
+		sprintf(tbuf,",affect=neither"); break;
+	    default:
+		sprintf(tbuf,",affect=both"); break;
+	}
+	TryCopyStr(buf,tbuf,sz);
+    }
+    return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopySetPtrDfltArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
+								int *sz)
+{
+XkbPtrDfltAction *	act;
+char			tbuf[32];
+
+    act= &action->dflt;
+    if (act->affect==XkbSA_AffectDfltBtn) {
+	TryCopyStr(buf,"affect=button,button=",sz);
+	if ((act->flags&XkbSA_DfltBtnAbsolute)||(XkbSAPtrDfltValue(act)<0))
+	     sprintf(tbuf,"%d",XkbSAPtrDfltValue(act));
+	else sprintf(tbuf,"+%d",XkbSAPtrDfltValue(act));
+	TryCopyStr(buf,tbuf,sz);
+    }
+    return True;
+}
+
+static Bool
+CopyISOLockArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
+{
+XkbISOAction *	act;
+char		tbuf[64];
+
+    act= &action->iso;
+    if (act->flags&XkbSA_ISODfltIsGroup) {
+	TryCopyStr(tbuf,"group=",sz);
+	if (act->flags&XkbSA_GroupAbsolute)
+	     sprintf(tbuf,"%d",XkbSAGroup(act)+1);
+	else if (XkbSAGroup(act)<0)
+	     sprintf(tbuf,"%d",XkbSAGroup(act));
+	else sprintf(tbuf,"+%d",XkbSAGroup(act));
+	TryCopyStr(buf,tbuf,sz);
+    }
+    else {
+	unsigned tmp;
+	tmp= XkbModActionVMods(act);
+	TryCopyStr(buf,"modifiers=",sz);
+	if (act->flags&XkbSA_UseModMapMods)
+	     TryCopyStr(buf,"modMapMods",sz);
+	else if (act->real_mods || tmp) {
+	    if (act->real_mods) {
+		TryCopyStr(buf,XkbModMaskText(act->real_mods,XkbXKBFile),sz);
+		if (tmp)
+		    TryCopyStr(buf,"+",sz);
+	    }
+	    if (tmp)
+		TryCopyStr(buf,XkbVModMaskText(dpy,xkb,0,tmp,XkbXKBFile),sz);
+	}
+	else TryCopyStr(buf,"none",sz);
+    }
+    TryCopyStr(buf,",affect=",sz);
+    if ((act->affect&XkbSA_ISOAffectMask)==0)
+	TryCopyStr(buf,"all",sz);
+    else {
+	int nOut= 0;
+	if ((act->affect&XkbSA_ISONoAffectMods)==0) {
+	    TryCopyStr(buf,"mods",sz);
+	    nOut++;
+	}
+	if ((act->affect&XkbSA_ISONoAffectGroup)==0) {
+	    sprintf(tbuf,"%sgroups",(nOut>0?"+":""));
+	    TryCopyStr(buf,tbuf,sz);
+	    nOut++;
+	}
+	if ((act->affect&XkbSA_ISONoAffectPtr)==0) {
+	    sprintf(tbuf,"%spointer",(nOut>0?"+":""));
+	    TryCopyStr(buf,tbuf,sz);
+	    nOut++;
+	}
+	if ((act->affect&XkbSA_ISONoAffectCtrls)==0) {
+	    sprintf(tbuf,"%scontrols",(nOut>0?"+":""));
+	    TryCopyStr(buf,tbuf,sz);
+	    nOut++;
+	}
+    }
+    return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopySwitchScreenArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
+								int *sz)
+{
+XkbSwitchScreenAction *	act;
+char			tbuf[32];
+
+    act= &action->screen;
+    if ((act->flags&XkbSA_SwitchAbsolute)||(XkbSAScreen(act)<0))
+	 sprintf(tbuf,"screen=%d",XkbSAScreen(act));
+    else sprintf(tbuf,"screen=+%d",XkbSAScreen(act));
+    TryCopyStr(buf,tbuf,sz);
+    if (act->flags&XkbSA_SwitchApplication)
+	 TryCopyStr(buf,",!same",sz);
+    else TryCopyStr(buf,",same",sz);
+    return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopySetLockControlsArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,
+							char *buf,int *sz)
+{
+XkbCtrlsAction *	act;
+unsigned		tmp;
+char			tbuf[32];
+
+    act= &action->ctrls;
+    tmp= XkbActionCtrls(act);
+    TryCopyStr(buf,"controls=",sz);
+    if (tmp==0)
+	TryCopyStr(buf,"none",sz);
+    else if ((tmp&XkbAllBooleanCtrlsMask)==XkbAllBooleanCtrlsMask)
+	TryCopyStr(buf,"all",sz);
+    else {
+	int nOut= 0;
+	if (tmp&XkbRepeatKeysMask) {
+	    sprintf(tbuf,"%sRepeatKeys",(nOut>0?"+":""));
+	    TryCopyStr(buf,tbuf,sz);
+	    nOut++;
+	}
+	if (tmp&XkbSlowKeysMask) {
+	    sprintf(tbuf,"%sSlowKeys",(nOut>0?"+":""));
+	    TryCopyStr(buf,tbuf,sz);
+	    nOut++;
+	}
+	if (tmp&XkbBounceKeysMask) {
+	    sprintf(tbuf,"%sBounceKeys",(nOut>0?"+":""));
+	    TryCopyStr(buf,tbuf,sz);
+	    nOut++;
+	}
+	if (tmp&XkbStickyKeysMask) {
+	    sprintf(tbuf,"%sStickyKeys",(nOut>0?"+":""));
+	    TryCopyStr(buf,tbuf,sz);
+	    nOut++;
+	}
+	if (tmp&XkbMouseKeysMask) {
+	    sprintf(tbuf,"%sMouseKeys",(nOut>0?"+":""));
+	    TryCopyStr(buf,tbuf,sz);
+	    nOut++;
+	}
+	if (tmp&XkbMouseKeysAccelMask) {
+	    sprintf(tbuf,"%sMouseKeysAccel",(nOut>0?"+":""));
+	    TryCopyStr(buf,tbuf,sz);
+	    nOut++;
+	}
+	if (tmp&XkbAccessXKeysMask) {
+	    sprintf(tbuf,"%sAccessXKeys",(nOut>0?"+":""));
+	    TryCopyStr(buf,tbuf,sz);
+	    nOut++;
+	}
+	if (tmp&XkbAccessXTimeoutMask) {
+	    sprintf(tbuf,"%sAccessXTimeout",(nOut>0?"+":""));
+	    TryCopyStr(buf,tbuf,sz);
+	    nOut++;
+	}
+	if (tmp&XkbAccessXFeedbackMask) {
+	    sprintf(tbuf,"%sAccessXFeedback",(nOut>0?"+":""));
+	    TryCopyStr(buf,tbuf,sz);
+	    nOut++;
+	}
+	if (tmp&XkbAudibleBellMask) {
+	    sprintf(tbuf,"%sAudibleBell",(nOut>0?"+":""));
+	    TryCopyStr(buf,tbuf,sz);
+	    nOut++;
+	}
+	if (tmp&XkbOverlay1Mask) {
+	    sprintf(tbuf,"%sOverlay1",(nOut>0?"+":""));
+	    TryCopyStr(buf,tbuf,sz);
+	    nOut++;
+	}
+	if (tmp&XkbOverlay2Mask) {
+	    sprintf(tbuf,"%sOverlay2",(nOut>0?"+":""));
+	    TryCopyStr(buf,tbuf,sz);
+	    nOut++;
+	}
+	if (tmp&XkbIgnoreGroupLockMask) {
+	    sprintf(tbuf,"%sIgnoreGroupLock",(nOut>0?"+":""));
+	    TryCopyStr(buf,tbuf,sz);
+	    nOut++;
+	}
+    }
+    return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopyActionMessageArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
+								int *sz)
+{
+XkbMessageAction *	act;
+unsigned		all;
+char			tbuf[32];
+
+    act= &action->msg;
+    all= XkbSA_MessageOnPress|XkbSA_MessageOnRelease;
+    TryCopyStr(buf,"report=",sz);
+    if ((act->flags&all)==0)
+	TryCopyStr(buf,"none",sz);
+    else if ((act->flags&all)==all)
+	TryCopyStr(buf,"all",sz);
+    else if (act->flags&XkbSA_MessageOnPress)
+	 TryCopyStr(buf,"KeyPress",sz);
+    else TryCopyStr(buf,"KeyRelease",sz);
+    sprintf(tbuf,",data[0]=0x%02x",act->message[0]); TryCopyStr(buf,tbuf,sz);
+    sprintf(tbuf,",data[1]=0x%02x",act->message[1]); TryCopyStr(buf,tbuf,sz);
+    sprintf(tbuf,",data[2]=0x%02x",act->message[2]); TryCopyStr(buf,tbuf,sz);
+    sprintf(tbuf,",data[3]=0x%02x",act->message[3]); TryCopyStr(buf,tbuf,sz);
+    sprintf(tbuf,",data[4]=0x%02x",act->message[4]); TryCopyStr(buf,tbuf,sz);
+    sprintf(tbuf,",data[5]=0x%02x",act->message[5]); TryCopyStr(buf,tbuf,sz);
+    return True;
+}
+
+static Bool
+CopyRedirectKeyArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
+								int *sz)
+{
+XkbRedirectKeyAction *	act;
+char			tbuf[32],*tmp;
+unsigned		kc;
+unsigned		vmods,vmods_mask;
+
+    act= &action->redirect;
+    kc= act->new_key;
+    vmods= XkbSARedirectVMods(act);
+    vmods_mask= XkbSARedirectVModsMask(act);
+    if (xkb && xkb->names && xkb->names->keys && (kc<=xkb->max_key_code) &&
+				(xkb->names->keys[kc].name[0]!='\0')) {
+	char *kn;
+	kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile);
+	sprintf(tbuf,"key=%s",kn);
+    }
+    else sprintf(tbuf,"key=%d",kc);
+    TryCopyStr(buf,tbuf,sz);
+    if ((act->mods_mask==0)&&(vmods_mask==0))
+	return True;
+    if ((act->mods_mask==XkbAllModifiersMask)&&
+	(vmods_mask==XkbAllVirtualModsMask)) {
+	tmp= XkbVModMaskText(dpy,xkb,act->mods,vmods,XkbXKBFile);
+	TryCopyStr(buf,",mods=",sz);
+	TryCopyStr(buf,tmp,sz);
+    }
+    else {
+	if ((act->mods_mask&act->mods)||(vmods_mask&vmods)) {
+	    tmp= XkbVModMaskText(dpy,xkb,act->mods_mask&act->mods,
+					 vmods_mask&vmods,XkbXKBFile);
+	    TryCopyStr(buf,",mods= ",sz);
+	    TryCopyStr(buf,tmp,sz);
+	}
+	if ((act->mods_mask&(~act->mods))||(vmods_mask&(~vmods))) {
+	    tmp= XkbVModMaskText(dpy,xkb,act->mods_mask&(~act->mods),
+					 vmods_mask&(~vmods),XkbXKBFile);
+	    TryCopyStr(buf,",clearMods= ",sz);
+	    TryCopyStr(buf,tmp,sz);
+	}
+    }
+    return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopyDeviceBtnArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
+								int *sz)
+{
+XkbDeviceBtnAction *	act;
+char			tbuf[32];
+
+    act= &action->devbtn;
+    sprintf(tbuf,"device= %d",act->device); TryCopyStr(buf,tbuf,sz);
+    TryCopyStr(buf,",button=",sz);
+    sprintf(tbuf,"%d",act->button);
+    TryCopyStr(buf,tbuf,sz);
+    if (act->count>0) {
+	sprintf(tbuf,",count=%d",act->count);
+	TryCopyStr(buf,tbuf,sz);
+    }
+    if (action->type==XkbSA_LockDeviceBtn) {
+	switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) {
+	    case XkbSA_LockNoLock:
+		sprintf(tbuf,",affect=unlock"); break;
+	    case XkbSA_LockNoUnlock:
+		sprintf(tbuf,",affect=lock"); break;
+	    case XkbSA_LockNoUnlock|XkbSA_LockNoLock:
+		sprintf(tbuf,",affect=neither"); break;
+	    default:
+		sprintf(tbuf,",affect=both"); break;
+	}
+	TryCopyStr(buf,tbuf,sz);
+    }
+    return True;
+}
+
+/*ARGSUSED*/
+static Bool
+CopyOtherArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
+{
+XkbAnyAction *	act;
+char		tbuf[32];
+
+    act= &action->any;
+    sprintf(tbuf,"type=0x%02x",act->type); TryCopyStr(buf,tbuf,sz);
+    sprintf(tbuf,",data[0]=0x%02x",act->data[0]); TryCopyStr(buf,tbuf,sz);
+    sprintf(tbuf,",data[1]=0x%02x",act->data[1]); TryCopyStr(buf,tbuf,sz);
+    sprintf(tbuf,",data[2]=0x%02x",act->data[2]); TryCopyStr(buf,tbuf,sz);
+    sprintf(tbuf,",data[3]=0x%02x",act->data[3]); TryCopyStr(buf,tbuf,sz);
+    sprintf(tbuf,",data[4]=0x%02x",act->data[4]); TryCopyStr(buf,tbuf,sz);
+    sprintf(tbuf,",data[5]=0x%02x",act->data[5]); TryCopyStr(buf,tbuf,sz);
+    sprintf(tbuf,",data[6]=0x%02x",act->data[6]); TryCopyStr(buf,tbuf,sz);
+    return True;
+}
+
+typedef	Bool	(*actionCopy)(
+	Display *	/* dpy */,
+	XkbDescPtr 	/* xkb */,
+	XkbAction *	/* action */,
+	char *		/* buf */,
+	int*		/* sz */
+);
+static actionCopy	copyActionArgs[XkbSA_NumActions] = {
+	CopyNoActionArgs		/* NoAction	*/,
+	CopyModActionArgs		/* SetMods	*/,
+	CopyModActionArgs		/* LatchMods	*/,
+	CopyModActionArgs		/* LockMods	*/,
+	CopyGroupActionArgs		/* SetGroup	*/,
+	CopyGroupActionArgs		/* LatchGroup	*/,
+	CopyGroupActionArgs		/* LockGroup	*/,
+	CopyMovePtrArgs			/* MovePtr	*/,
+	CopyPtrBtnArgs			/* PtrBtn	*/,
+	CopyPtrBtnArgs			/* LockPtrBtn	*/,
+	CopySetPtrDfltArgs		/* SetPtrDflt	*/,
+	CopyISOLockArgs			/* ISOLock	*/,
+	CopyNoActionArgs		/* Terminate	*/,
+	CopySwitchScreenArgs		/* SwitchScreen	*/,
+	CopySetLockControlsArgs		/* SetControls	*/,
+	CopySetLockControlsArgs		/* LockControls	*/,
+	CopyActionMessageArgs		/* ActionMessage*/,
+	CopyRedirectKeyArgs		/* RedirectKey	*/,
+	CopyDeviceBtnArgs		/* DeviceBtn	*/,
+	CopyDeviceBtnArgs		/* LockDeviceBtn*/
+};
+
+#define	ACTION_SZ	256
+
+char *
+XkbActionText(Display *dpy,XkbDescPtr xkb,XkbAction *action,unsigned format)
+{
+char	buf[ACTION_SZ],*tmp;
+int	sz;
+
+    if (format==XkbCFile) {
+	sprintf(buf,
+	    "{ %20s, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x } }",
+	    XkbActionTypeText(action->type,XkbCFile),
+	    action->any.data[0],action->any.data[1],action->any.data[2],
+	    action->any.data[3],action->any.data[4],action->any.data[5],
+	    action->any.data[6]);
+    }
+    else {
+	sprintf(buf,"%s(",XkbActionTypeText(action->type,XkbXKBFile));
+	sz= ACTION_SZ-strlen(buf)+2; /* room for close paren and NULL */
+	if (action->type<(unsigned)XkbSA_NumActions)
+	     (*copyActionArgs[action->type])(dpy,xkb,action,buf,&sz);
+	else CopyOtherArgs(dpy,xkb,action,buf,&sz);
+	TryCopyStr(buf,")",&sz);
+    }
+    tmp= tbGetBuffer(strlen(buf)+1);
+    if (tmp!=NULL)
+	strcpy(tmp,buf);
+    return tmp;
+}
+
+char *
+XkbBehaviorText(XkbDescPtr xkb,XkbBehavior *behavior,unsigned format)
+{
+char	buf[256],*tmp;
+
+    if (format==XkbCFile) {
+	if (behavior->type==XkbKB_Default)
+	     sprintf(buf,"{   0,    0 }");
+	else sprintf(buf,"{ %3d, 0x%02x }",behavior->type,behavior->data);
+    }
+    else {
+	unsigned 	type,permanent;
+	type= behavior->type&XkbKB_OpMask;
+	permanent=((behavior->type&XkbKB_Permanent)!=0);
+
+	if (type==XkbKB_Lock) {
+	    sprintf(buf,"lock= %s",(permanent?"Permanent":"True"));
+	}
+	else if (type==XkbKB_RadioGroup) {
+	    int 	g;
+	    char	*tmp;
+	    g= ((behavior->data)&(~XkbKB_RGAllowNone))+1;
+	    if (XkbKB_RGAllowNone&behavior->data) {
+		sprintf(buf,"allowNone,");
+		tmp= &buf[strlen(buf)];
+	    }
+	    else tmp= buf;
+	    if (permanent)
+		 sprintf(tmp,"permanentRadioGroup= %d",g);
+	    else sprintf(tmp,"radioGroup= %d",g);
+	}
+	else if ((type==XkbKB_Overlay1)||(type==XkbKB_Overlay2)) {
+	    int ndx,kc;
+	    char *kn;
+
+	    ndx= ((type==XkbKB_Overlay1)?1:2);
+	    kc= behavior->data;
+	    if ((xkb)&&(xkb->names)&&(xkb->names->keys))
+		kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile);
+	    else {
+		static char tbuf[8];
+		sprintf(tbuf,"%d",kc);
+		kn= tbuf;
+	    }
+	    if (permanent)
+		 sprintf(buf,"permanentOverlay%d= %s",ndx,kn);
+	    else sprintf(buf,"overlay%d= %s",ndx,kn);
+	}
+    }
+    tmp= tbGetBuffer(strlen(buf)+1);
+    if (tmp!=NULL)
+	strcpy(tmp,buf);
+    return tmp;
+}
+
+/***====================================================================***/
+
+char *
+XkbIndentText(unsigned size)
+{
+static char buf[32];
+register int i;
+
+    if (size>31)
+	size= 31;
+
+    for (i=0;i<size;i++) {
+	buf[i]= ' ';
+    }
+    buf[size]= '\0';
+    return buf;
+}
diff --git a/nx-X11/programs/Xserver/xkb/xkmread.c b/nx-X11/programs/Xserver/xkb/xkmread.c
index e81835c..4871f3a 100644
--- a/nx-X11/programs/Xserver/xkb/xkmread.c
+++ b/nx-X11/programs/Xserver/xkb/xkmread.c
@@ -152,89 +152,6 @@ int	count,nRead=0;
     return nRead;
 }
 
-unsigned
-_XkbKSCheckCase(KeySym ks)
-{
-unsigned	set,rtrn;
-
-    set= (ks & (~0xff)) >> 8;
-    rtrn= 0;
-    switch (set) {
-	case 0:		/* latin 1 */
-	    if (((ks>=XK_A)&&(ks<=XK_Z))||
-		((ks>=XK_Agrave)&&(ks<=XK_THORN)&&(ks!=XK_multiply))) {
-		rtrn|= _XkbKSUpper;
-	    }
-	    if (((ks>=XK_a)&&(ks<=XK_z))||
-		((ks>=XK_agrave)&&(ks<=XK_ydiaeresis))) {
-		rtrn|= _XkbKSLower;
-	    }
-	    break;
-	case 1:		/* latin 2 */
-	    if (((ks>=XK_Aogonek)&&(ks<=XK_Zabovedot)&&(ks!=XK_breve))||
-		((ks>=XK_Racute)&&(ks<=XK_Tcedilla))) {
-		rtrn|= _XkbKSUpper;
-	    }
-	    if (((ks>=XK_aogonek)&&(ks<=XK_zabovedot)&&(ks!=XK_caron))||
-		((ks>=XK_racute)&&(ks<=XK_tcedilla))) {
-		rtrn|= _XkbKSLower;
-	    }
-	    break;
-	case 2:		/* latin 3 */
-	    if (((ks>=XK_Hstroke)&&(ks<=XK_Jcircumflex))||
-		((ks>=XK_Cabovedot)&&(ks<=XK_Scircumflex))) {
-		rtrn|= _XkbKSUpper;
-	    }
-	    if (((ks>=XK_hstroke)&&(ks<=XK_jcircumflex))||
-		((ks>=XK_cabovedot)&&(ks<=XK_scircumflex))) {
-		rtrn|= _XkbKSLower;
-	    }
-	    break;
-	case 3:		/* latin 4 */
-	    if (((ks>=XK_Rcedilla)&&(ks<=XK_Tslash))||
-	        (ks==XK_ENG)||
-		((ks>=XK_Amacron)&&(ks<=XK_Umacron))) {
-		rtrn|= _XkbKSUpper;
-	    }
-	    if (((ks>=XK_rcedilla)&&(ks<=XK_tslash))||
-	        (ks==XK_eng)||
-		((ks>=XK_amacron)&&(ks<=XK_umacron))) {
-		rtrn|= _XkbKSLower;
-	    }
-	    break;
-	case 18:		/* latin 8 */
-	    if ((ks==XK_Babovedot)||
-                ((ks>=XK_Dabovedot)&&(ks<=XK_Wacute))||
-		((ks>=XK_Ygrave)&&(ks<=XK_Fabovedot))||
-	        (ks==XK_Mabovedot)||
-	        (ks==XK_Pabovedot)||
-	        (ks==XK_Sabovedot)||
-	        (ks==XK_Wdiaeresis)||
-		((ks>=XK_Wcircumflex)&&(ks<=XK_Ycircumflex))) {
-		rtrn|= _XkbKSUpper;
-	    }
-	    if ((ks==XK_babovedot)||
-	        (ks==XK_dabovedot)||
-	        (ks==XK_fabovedot)||
-	        (ks==XK_mabovedot)||
-                ((ks>=XK_wgrave)&&(ks<=XK_wacute))||
-	        (ks==XK_ygrave)||
-		((ks>=XK_wdiaeresis)&&(ks<=XK_ycircumflex))) {
-		rtrn|= _XkbKSLower;
-	    }
-	    break;
-	case 19:		/* latin 9 */
-	    if ((ks==XK_OE)||(ks==XK_Ydiaeresis)) {
-		rtrn|= _XkbKSUpper;
-	    }
-	    if (ks==XK_oe) {
-		rtrn|= _XkbKSLower;
-	    }
-	    break;
-    }
-    return rtrn;
-}
-
 /***====================================================================***/
 
 static int
@@ -1226,10 +1143,14 @@ int			nRead;
 		*loaded_rtrn|= XkmGeometryMask;
 	    break;
 	default:
+	    _XkbLibError(_XkbErrBadImplementation,
+	    			XkbConfigText(tmpTOC.type,XkbMessage),0);
 	    nRead= 0;
 	    break;
     }
     if (nRead!=tmpTOC.size) {
+	_XkbLibError(_XkbErrBadLength,XkbConfigText(tmpTOC.type,XkbMessage),
+						nRead-tmpTOC.size);
 	return 0;
     }
     return (nRead>=0);
@@ -1264,6 +1185,8 @@ char 		name[100];
 		return Xstrdup(name);
 	    break;
 	default:
+	    _XkbLibError(_XkbErrBadImplementation,
+				XkbConfigText(tmpTOC.type,XkbMessage),0);
 	    break;
     }
     return NULL;
@@ -1329,6 +1252,8 @@ unsigned		which= need|want;
 		tmp= ReadXkmGeometry(file,result);
 		break;
 	    default:
+		_XkbLibError(_XkbErrBadImplementation,
+				XkbConfigText(tmpTOC.type,XkbMessage),0);
 		tmp= 0;
 		break;
 	}
@@ -1338,7 +1263,8 @@ unsigned		which= need|want;
 	    result->defined|= (1<<toc[i].type);
 	}
 	if (nRead!=tmpTOC.size) {
-            return 0;
+	    _XkbLibError(_XkbErrBadLength,XkbConfigText(tmpTOC.type,XkbMessage),
+	    						nRead-tmpTOC.size);
 	}
     }
     return which;

--
Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/nx-libs.git


More information about the x2go-commits mailing list