xkbtext.c revision 4cd6a3ae
18c9fbc29Smrg/************************************************************
28c9fbc29Smrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
38c9fbc29Smrg
48c9fbc29Smrg Permission to use, copy, modify, and distribute this
58c9fbc29Smrg software and its documentation for any purpose and without
68c9fbc29Smrg fee is hereby granted, provided that the above copyright
78c9fbc29Smrg notice appear in all copies and that both that copyright
88c9fbc29Smrg notice and this permission notice appear in supporting
94cd6a3aeSmrg documentation, and that the name of Silicon Graphics not be
104cd6a3aeSmrg used in advertising or publicity pertaining to distribution
118c9fbc29Smrg of the software without specific prior written permission.
124cd6a3aeSmrg Silicon Graphics makes no representation about the suitability
138c9fbc29Smrg of this software for any purpose. It is provided "as is"
148c9fbc29Smrg without any express or implied warranty.
154cd6a3aeSmrg
164cd6a3aeSmrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
174cd6a3aeSmrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
188c9fbc29Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
194cd6a3aeSmrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
204cd6a3aeSmrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
214cd6a3aeSmrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
228c9fbc29Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
238c9fbc29Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE.
248c9fbc29Smrg
258c9fbc29Smrg ********************************************************/
268c9fbc29Smrg
278c9fbc29Smrg#ifdef HAVE_DIX_CONFIG_H
288c9fbc29Smrg#include <dix-config.h>
298c9fbc29Smrg#elif defined(HAVE_CONFIG_H)
308c9fbc29Smrg#include <config.h>
318c9fbc29Smrg#endif
328c9fbc29Smrg
338c9fbc29Smrg#include <stdio.h>
348c9fbc29Smrg#include <ctype.h>
358c9fbc29Smrg#include <stdlib.h>
368c9fbc29Smrg
378c9fbc29Smrg#include <X11/Xos.h>
388c9fbc29Smrg
398c9fbc29Smrg#ifndef XKB_IN_SERVER
408c9fbc29Smrg
418c9fbc29Smrg#include <X11/Xlib.h>
428c9fbc29Smrg#include <X11/XKBlib.h>
438c9fbc29Smrg#include <X11/extensions/XKBgeom.h>
448c9fbc29Smrg
458c9fbc29Smrg#include "XKMformat.h"
468c9fbc29Smrg#include "XKBfileInt.h"
478c9fbc29Smrg
488c9fbc29Smrg#else
498c9fbc29Smrg
508c9fbc29Smrg#include <X11/X.h>
518c9fbc29Smrg#include <X11/Xproto.h>
528c9fbc29Smrg#include "misc.h"
538c9fbc29Smrg#include "inputstr.h"
548c9fbc29Smrg#include "dix.h"
558c9fbc29Smrg#include <X11/extensions/XKBstr.h>
568c9fbc29Smrg#define XKBSRV_NEED_FILE_FUNCS	1
578c9fbc29Smrg#include <X11/extensions/XKBsrv.h>
588c9fbc29Smrg#include <X11/extensions/XKBgeom.h>
598c9fbc29Smrg
608c9fbc29Smrg#endif
618c9fbc29Smrg
628c9fbc29Smrg/***====================================================================***/
638c9fbc29Smrg
648c9fbc29Smrg#define	BUFFER_SIZE	512
658c9fbc29Smrg
668c9fbc29Smrgstatic char textBuffer[BUFFER_SIZE];
678c9fbc29Smrgstatic int  tbNext= 0;
688c9fbc29Smrg
698c9fbc29Smrgstatic char *
708c9fbc29SmrgtbGetBuffer(unsigned size)
718c9fbc29Smrg{
728c9fbc29Smrgchar *rtrn;
738c9fbc29Smrg
748c9fbc29Smrg    if (size>=BUFFER_SIZE)
758c9fbc29Smrg	return NULL;
768c9fbc29Smrg    if ((BUFFER_SIZE-tbNext)<=size)
778c9fbc29Smrg	tbNext= 0;
788c9fbc29Smrg    rtrn= &textBuffer[tbNext];
798c9fbc29Smrg    tbNext+= size;
808c9fbc29Smrg    return rtrn;
818c9fbc29Smrg}
828c9fbc29Smrg
838c9fbc29Smrg/***====================================================================***/
848c9fbc29Smrg
858c9fbc29Smrgchar *
868c9fbc29SmrgXkbAtomText(Display *dpy,Atom atm,unsigned format)
878c9fbc29Smrg{
888c9fbc29Smrgchar	*rtrn,*tmp;
898c9fbc29Smrg
908c9fbc29Smrg    tmp= XkbAtomGetString(dpy,atm);
918c9fbc29Smrg    if (tmp!=NULL) {
928c9fbc29Smrg	int	len;
938c9fbc29Smrg	len= strlen(tmp)+1;
948c9fbc29Smrg	if (len>BUFFER_SIZE)
958c9fbc29Smrg	    len= BUFFER_SIZE-2;
968c9fbc29Smrg	rtrn= tbGetBuffer(len);
978c9fbc29Smrg	strncpy(rtrn,tmp,len);
988c9fbc29Smrg	rtrn[len]= '\0';
998c9fbc29Smrg        _XkbFree(tmp);
1008c9fbc29Smrg    }
1018c9fbc29Smrg    else {
1028c9fbc29Smrg	rtrn= tbGetBuffer(1);
1038c9fbc29Smrg	rtrn[0]= '\0';
1048c9fbc29Smrg    }
1058c9fbc29Smrg    if (format==XkbCFile) {
1068c9fbc29Smrg	for (tmp=rtrn;*tmp!='\0';tmp++) {
1078c9fbc29Smrg	    if ((tmp==rtrn)&&(!isalpha(*tmp)))
1088c9fbc29Smrg		*tmp= '_';
1098c9fbc29Smrg	    else if (!isalnum(*tmp))
1108c9fbc29Smrg		*tmp= '_';
1118c9fbc29Smrg	}
1128c9fbc29Smrg    }
1138c9fbc29Smrg    return XkbStringText(rtrn,format);
1148c9fbc29Smrg}
1158c9fbc29Smrg
1168c9fbc29Smrg/***====================================================================***/
1178c9fbc29Smrg
1188c9fbc29Smrgchar *
1198c9fbc29SmrgXkbVModIndexText(Display *dpy,XkbDescPtr xkb,unsigned ndx,unsigned format)
1208c9fbc29Smrg{
1218c9fbc29Smrgregister int len;
1228c9fbc29Smrgregister Atom *vmodNames;
1238c9fbc29Smrgchar *rtrn,*tmp;
1248c9fbc29Smrg
1258c9fbc29Smrg    if (xkb && xkb->names)
1268c9fbc29Smrg	 vmodNames= xkb->names->vmods;
1278c9fbc29Smrg    else vmodNames= NULL;
1288c9fbc29Smrg
1298c9fbc29Smrg    tmp= NULL;
1308c9fbc29Smrg    if (ndx>=XkbNumVirtualMods)
1318c9fbc29Smrg	 tmp= strdup("illegal");
1328c9fbc29Smrg    else if (vmodNames&&(vmodNames[ndx]!=None))
1338c9fbc29Smrg	 tmp= XkbAtomGetString(dpy,vmodNames[ndx]);
1348c9fbc29Smrg    if (tmp==NULL) {
1358c9fbc29Smrg        tmp= (char *)_XkbAlloc(20 * sizeof(char));
1368c9fbc29Smrg	snprintf(tmp,20,"%d",ndx);
1378c9fbc29Smrg    }
1388c9fbc29Smrg
1398c9fbc29Smrg    len= strlen(tmp)+1;
1408c9fbc29Smrg    if (format==XkbCFile)
1418c9fbc29Smrg	len+= 4;
1428c9fbc29Smrg    if (len>=BUFFER_SIZE)
1438c9fbc29Smrg	len= BUFFER_SIZE-1;
1448c9fbc29Smrg    rtrn= tbGetBuffer(len);
1458c9fbc29Smrg    if (format==XkbCFile) {
1468c9fbc29Smrg         snprintf(rtrn, len, "vmod_%s", tmp);
1478c9fbc29Smrg    }
1488c9fbc29Smrg    else strncpy(rtrn,tmp,len);
1498c9fbc29Smrg    _XkbFree(tmp);
1508c9fbc29Smrg    return rtrn;
1518c9fbc29Smrg}
1528c9fbc29Smrg
1538c9fbc29Smrgchar *
1548c9fbc29SmrgXkbVModMaskText(	Display *	dpy,
1558c9fbc29Smrg			XkbDescPtr	xkb,
1568c9fbc29Smrg			unsigned	modMask,
1578c9fbc29Smrg			unsigned	mask,
1588c9fbc29Smrg			unsigned	format)
1598c9fbc29Smrg{
1608c9fbc29Smrgregister int i,bit;
1618c9fbc29Smrgint	 len;
1628c9fbc29Smrgchar *mm,*rtrn;
1638c9fbc29Smrgchar *str,buf[BUFFER_SIZE];
1648c9fbc29Smrg
1658c9fbc29Smrg    if ((modMask==0)&&(mask==0)) {
1668c9fbc29Smrg	rtrn= tbGetBuffer(5);
1678c9fbc29Smrg	if (format==XkbCFile)
1688c9fbc29Smrg	     sprintf(rtrn,"0");
1698c9fbc29Smrg	else sprintf(rtrn,"none");
1708c9fbc29Smrg	return rtrn;
1718c9fbc29Smrg    }
1728c9fbc29Smrg    if (modMask!=0)
1738c9fbc29Smrg	 mm= XkbModMaskText(modMask,format);
1748c9fbc29Smrg    else mm= NULL;
1758c9fbc29Smrg
1768c9fbc29Smrg    str= buf;
1778c9fbc29Smrg    buf[0]= '\0';
1788c9fbc29Smrg    if (mask) {
1798c9fbc29Smrg	char *tmp;
1808c9fbc29Smrg	for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
1818c9fbc29Smrg	    if (mask&bit) {
1828c9fbc29Smrg		tmp= XkbVModIndexText(dpy,xkb,i,format);
1838c9fbc29Smrg		len= strlen(tmp)+1+(str==buf?0:1);
1848c9fbc29Smrg		if (format==XkbCFile)
1858c9fbc29Smrg		    len+= 4;
1868c9fbc29Smrg		if ((str-(buf+len))<=BUFFER_SIZE) {
1878c9fbc29Smrg		    if (str!=buf) {
1888c9fbc29Smrg			if (format==XkbCFile)	*str++= '|';
1898c9fbc29Smrg			else			*str++= '+';
1908c9fbc29Smrg			len--;
1918c9fbc29Smrg		    }
1928c9fbc29Smrg		}
1938c9fbc29Smrg		if (format==XkbCFile)
1948c9fbc29Smrg		     sprintf(str,"%sMask",tmp);
1958c9fbc29Smrg		else strcpy(str,tmp);
1968c9fbc29Smrg		str= &str[len-1];
1978c9fbc29Smrg	    }
1988c9fbc29Smrg	}
1998c9fbc29Smrg	str= buf;
2008c9fbc29Smrg    }
2018c9fbc29Smrg    else str= NULL;
2024cd6a3aeSmrg    if (mm)
2038c9fbc29Smrg	len= strlen(mm);
2048c9fbc29Smrg    else	len= 0;
2058c9fbc29Smrg    if (str)
2068c9fbc29Smrg	len+= strlen(str)+(mm==NULL?0:1);
2078c9fbc29Smrg    if (len>=BUFFER_SIZE)
2088c9fbc29Smrg	len= BUFFER_SIZE-1;
2098c9fbc29Smrg    rtrn= tbGetBuffer(len+1);
2108c9fbc29Smrg    rtrn[0]= '\0';
2118c9fbc29Smrg
2128c9fbc29Smrg    if (mm!=NULL) {
2138c9fbc29Smrg	i= strlen(mm);
2148c9fbc29Smrg	if (i>len)
2158c9fbc29Smrg	    i= len;
2168c9fbc29Smrg	strcpy(rtrn,mm);
2178c9fbc29Smrg    }
2188c9fbc29Smrg    else {
2198c9fbc29Smrg	i=0;
2208c9fbc29Smrg    }
2218c9fbc29Smrg    if (str!=NULL) {
2228c9fbc29Smrg	if (mm!=NULL) {
2238c9fbc29Smrg	    if (format==XkbCFile)	strcat(rtrn,"|");
2248c9fbc29Smrg	    else			strcat(rtrn,"+");
2258c9fbc29Smrg	}
2268c9fbc29Smrg	strncat(rtrn,str,len-i);
2278c9fbc29Smrg    }
2288c9fbc29Smrg    rtrn[len]= '\0';
2298c9fbc29Smrg    return rtrn;
2308c9fbc29Smrg}
2318c9fbc29Smrg
2324cd6a3aeSmrgstatic const char *modNames[XkbNumModifiers] = {
2338c9fbc29Smrg    "Shift", "Lock", "Control", "Mod1", "Mod2", "Mod3", "Mod4", "Mod5"
2348c9fbc29Smrg};
2358c9fbc29Smrg
2368c9fbc29Smrgchar *
2378c9fbc29SmrgXkbModIndexText(unsigned ndx,unsigned format)
2388c9fbc29Smrg{
2398c9fbc29Smrgchar *	rtrn;
2408c9fbc29Smrgchar	buf[100];
2418c9fbc29Smrg
2428c9fbc29Smrg    if (format==XkbCFile) {
2438c9fbc29Smrg	if (ndx<XkbNumModifiers)
2448c9fbc29Smrg	     sprintf(buf,"%sMapIndex",modNames[ndx]);
2458c9fbc29Smrg	else if (ndx==XkbNoModifier)
2468c9fbc29Smrg	     sprintf(buf,"XkbNoModifier");
2478c9fbc29Smrg	else sprintf(buf,"0x%02x",ndx);
2488c9fbc29Smrg    }
2498c9fbc29Smrg    else {
2508c9fbc29Smrg	if (ndx<XkbNumModifiers)
2518c9fbc29Smrg	     strcpy(buf,modNames[ndx]);
2528c9fbc29Smrg	else if (ndx==XkbNoModifier)
2538c9fbc29Smrg	     strcpy(buf,"none");
2548c9fbc29Smrg	else sprintf(buf,"ILLEGAL_%02x",ndx);
2558c9fbc29Smrg    }
2568c9fbc29Smrg    rtrn= tbGetBuffer(strlen(buf)+1);
2578c9fbc29Smrg    strcpy(rtrn,buf);
2588c9fbc29Smrg    return rtrn;
2598c9fbc29Smrg}
2608c9fbc29Smrg
2618c9fbc29Smrgchar *
2628c9fbc29SmrgXkbModMaskText(unsigned mask,unsigned format)
2638c9fbc29Smrg{
2648c9fbc29Smrgregister int i,bit;
2658c9fbc29Smrgchar buf[64],*rtrn;
2668c9fbc29Smrg
2678c9fbc29Smrg    if ((mask&0xff)==0xff) {
2688c9fbc29Smrg	if (format==XkbCFile) 		strcpy(buf,"0xff");
2698c9fbc29Smrg	else				strcpy(buf,"all");
2708c9fbc29Smrg    }
2718c9fbc29Smrg    else if ((mask&0xff)==0) {
2728c9fbc29Smrg	if (format==XkbCFile)		strcpy(buf,"0");
2738c9fbc29Smrg	else				strcpy(buf,"none");
2748c9fbc29Smrg    }
2758c9fbc29Smrg    else {
2768c9fbc29Smrg	char *str= buf;
2778c9fbc29Smrg	buf[0]= '\0';
2788c9fbc29Smrg	for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) {
2798c9fbc29Smrg	    if (mask&bit) {
2808c9fbc29Smrg		if (str!=buf) {
2818c9fbc29Smrg		    if (format==XkbCFile)	*str++= '|';
2828c9fbc29Smrg		    else			*str++= '+';
2838c9fbc29Smrg		}
2848c9fbc29Smrg		strcpy(str,modNames[i]);
2858c9fbc29Smrg		str= &str[strlen(str)];
2868c9fbc29Smrg		if (format==XkbCFile) {
2878c9fbc29Smrg		    strcpy(str,"Mask");
2888c9fbc29Smrg		    str+= 4;
2898c9fbc29Smrg		}
2908c9fbc29Smrg	    }
2918c9fbc29Smrg	}
2928c9fbc29Smrg    }
2938c9fbc29Smrg    rtrn= tbGetBuffer(strlen(buf)+1);
2948c9fbc29Smrg    strcpy(rtrn,buf);
2958c9fbc29Smrg    return rtrn;
2968c9fbc29Smrg}
2978c9fbc29Smrg
2988c9fbc29Smrg/***====================================================================***/
2998c9fbc29Smrg
3008c9fbc29Smrg/*ARGSUSED*/
3018c9fbc29Smrgchar *
3028c9fbc29SmrgXkbConfigText(unsigned config,unsigned format)
3038c9fbc29Smrg{
3048c9fbc29Smrgstatic char *buf;
3058c9fbc29Smrg
3068c9fbc29Smrg    buf= tbGetBuffer(32);
3078c9fbc29Smrg    switch (config) {
3088c9fbc29Smrg	case XkmSemanticsFile:
3098c9fbc29Smrg	    strcpy(buf,"Semantics");
3108c9fbc29Smrg	    break;
3118c9fbc29Smrg	case XkmLayoutFile:
3128c9fbc29Smrg	    strcpy(buf,"Layout");
3138c9fbc29Smrg	    break;
3148c9fbc29Smrg	case XkmKeymapFile:
3158c9fbc29Smrg	    strcpy(buf,"Keymap");
3168c9fbc29Smrg	    break;
3178c9fbc29Smrg	case XkmGeometryFile:
3188c9fbc29Smrg	case XkmGeometryIndex:
3198c9fbc29Smrg	    strcpy(buf,"Geometry");
3208c9fbc29Smrg	    break;
3218c9fbc29Smrg	case XkmTypesIndex:
3228c9fbc29Smrg	    strcpy(buf,"Types");
3238c9fbc29Smrg	    break;
3248c9fbc29Smrg	case XkmCompatMapIndex:
3258c9fbc29Smrg	    strcpy(buf,"CompatMap");
3268c9fbc29Smrg	    break;
3278c9fbc29Smrg	case XkmSymbolsIndex:
3288c9fbc29Smrg	    strcpy(buf,"Symbols");
3298c9fbc29Smrg	    break;
3308c9fbc29Smrg	case XkmIndicatorsIndex:
3318c9fbc29Smrg	    strcpy(buf,"Indicators");
3328c9fbc29Smrg	    break;
3338c9fbc29Smrg	case XkmKeyNamesIndex:
3348c9fbc29Smrg	    strcpy(buf,"KeyNames");
3358c9fbc29Smrg	    break;
3368c9fbc29Smrg	case XkmVirtualModsIndex:
3378c9fbc29Smrg	    strcpy(buf,"VirtualMods");
3388c9fbc29Smrg	    break;
3398c9fbc29Smrg	default:
3408c9fbc29Smrg	    sprintf(buf,"unknown(%d)",config);
3418c9fbc29Smrg	    break;
3428c9fbc29Smrg    }
3438c9fbc29Smrg    return buf;
3448c9fbc29Smrg}
3458c9fbc29Smrg
3468c9fbc29Smrg/***====================================================================***/
3478c9fbc29Smrg
3488c9fbc29Smrgchar *
3498c9fbc29SmrgXkbKeysymText(KeySym sym,unsigned format)
3508c9fbc29Smrg{
3518c9fbc29Smrgstatic char buf[32],*rtrn;
3528c9fbc29Smrg
3538c9fbc29Smrg#ifndef XKB_IN_SERVER
3548c9fbc29Smrg    if (sym==NoSymbol)
3558c9fbc29Smrg	strcpy(rtrn=buf,"NoSymbol");
3568c9fbc29Smrg    else if ((rtrn=XKeysymToString(sym))==NULL)
3578c9fbc29Smrg	sprintf(rtrn=buf, "0x%lx", (long)sym);
3588c9fbc29Smrg    else if (format==XkbCFile) {
3598c9fbc29Smrg	sprintf(buf,"XK_%s",rtrn);
3608c9fbc29Smrg	rtrn= buf;
3618c9fbc29Smrg    }
3628c9fbc29Smrg    return rtrn;
3638c9fbc29Smrg#else /* def XKB_IN_SERVER */
3648c9fbc29Smrg    if (sym==NoSymbol)
3658c9fbc29Smrg	 strcpy(rtrn=buf,"NoSymbol");
3668c9fbc29Smrg    else sprintf(rtrn=buf, "0x%lx", (long)sym);
3678c9fbc29Smrg    return rtrn;
3688c9fbc29Smrg#endif /* XKB_IN_SERVER */
3698c9fbc29Smrg}
3708c9fbc29Smrg
3718c9fbc29Smrgchar *
3728c9fbc29SmrgXkbKeyNameText(char *name,unsigned format)
3738c9fbc29Smrg{
3748c9fbc29Smrgchar *buf;
3758c9fbc29Smrg
3768c9fbc29Smrg    if (format==XkbCFile) {
3778c9fbc29Smrg	buf= tbGetBuffer(5);
3788c9fbc29Smrg	memcpy(buf,name,4);
3798c9fbc29Smrg	buf[4]= '\0';
3808c9fbc29Smrg    }
3818c9fbc29Smrg    else {
3828c9fbc29Smrg	int len;
3838c9fbc29Smrg	buf= tbGetBuffer(7);
3848c9fbc29Smrg	buf[0]= '<';
3858c9fbc29Smrg	memcpy(&buf[1],name,4);
3868c9fbc29Smrg	buf[5]= '\0';
3878c9fbc29Smrg	len= strlen(buf);
3888c9fbc29Smrg	buf[len++]= '>';
3898c9fbc29Smrg	buf[len]= '\0';
3908c9fbc29Smrg    }
3918c9fbc29Smrg    return buf;
3928c9fbc29Smrg}
3938c9fbc29Smrg
3948c9fbc29Smrg/***====================================================================***/
3958c9fbc29Smrg
3968c9fbc29Smrgstatic char *siMatchText[5] = {
3978c9fbc29Smrg	"NoneOf", "AnyOfOrNone", "AnyOf", "AllOf", "Exactly"
3988c9fbc29Smrg};
3998c9fbc29Smrg
4008c9fbc29Smrgchar *
4018c9fbc29SmrgXkbSIMatchText(unsigned type,unsigned format)
4028c9fbc29Smrg{
4038c9fbc29Smrgstatic char buf[40];
4048c9fbc29Smrgchar *rtrn;
4058c9fbc29Smrg
4068c9fbc29Smrg    switch (type&XkbSI_OpMask) {
4078c9fbc29Smrg	case XkbSI_NoneOf:	rtrn= siMatchText[0]; break;
4088c9fbc29Smrg	case XkbSI_AnyOfOrNone:	rtrn= siMatchText[1]; break;
4098c9fbc29Smrg	case XkbSI_AnyOf:	rtrn= siMatchText[2]; break;
4108c9fbc29Smrg	case XkbSI_AllOf:	rtrn= siMatchText[3]; break;
4118c9fbc29Smrg	case XkbSI_Exactly:	rtrn= siMatchText[4]; break;
4128c9fbc29Smrg	default:		sprintf(buf,"0x%x",type&XkbSI_OpMask);
4138c9fbc29Smrg				return buf;
4148c9fbc29Smrg    }
4158c9fbc29Smrg    if (format==XkbCFile) {
4168c9fbc29Smrg	if (type&XkbSI_LevelOneOnly)
4178c9fbc29Smrg	     sprintf(buf,"XkbSI_LevelOneOnly|XkbSI_%s",rtrn);
4188c9fbc29Smrg	else sprintf(buf,"XkbSI_%s",rtrn);
4198c9fbc29Smrg	rtrn= buf;
4208c9fbc29Smrg    }
4218c9fbc29Smrg    return rtrn;
4228c9fbc29Smrg}
4238c9fbc29Smrg
4248c9fbc29Smrg/***====================================================================***/
4258c9fbc29Smrg
4264cd6a3aeSmrgstatic const char *imWhichNames[]= {
4278c9fbc29Smrg	"base",
4288c9fbc29Smrg	"latched",
4298c9fbc29Smrg	"locked",
4308c9fbc29Smrg	"effective",
4318c9fbc29Smrg	"compat"
4328c9fbc29Smrg};
4338c9fbc29Smrg
4348c9fbc29Smrgchar *
4358c9fbc29SmrgXkbIMWhichStateMaskText(unsigned use_which,unsigned format)
4368c9fbc29Smrg{
4378c9fbc29Smrgint		len;
4388c9fbc29Smrgunsigned	i,bit,tmp;
4398c9fbc29Smrgchar *		buf;
4408c9fbc29Smrg
4418c9fbc29Smrg    if (use_which==0) {
4428c9fbc29Smrg	buf= tbGetBuffer(2);
4438c9fbc29Smrg	strcpy(buf,"0");
4448c9fbc29Smrg	return buf;
4458c9fbc29Smrg    }
4468c9fbc29Smrg    tmp= use_which&XkbIM_UseAnyMods;
4478c9fbc29Smrg    for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
4488c9fbc29Smrg	if (tmp&bit) {
4498c9fbc29Smrg	    tmp&= ~bit;
4508c9fbc29Smrg	    len+= strlen(imWhichNames[i])+1;
4518c9fbc29Smrg	    if (format==XkbCFile)
4528c9fbc29Smrg		len+= 9;
4538c9fbc29Smrg	}
4548c9fbc29Smrg    }
4558c9fbc29Smrg    buf= tbGetBuffer(len+1);
4568c9fbc29Smrg    tmp= use_which&XkbIM_UseAnyMods;
4578c9fbc29Smrg    for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
4588c9fbc29Smrg	if (tmp&bit) {
4598c9fbc29Smrg	    tmp&= ~bit;
4608c9fbc29Smrg	    if (format==XkbCFile) {
4618c9fbc29Smrg		if (len!=0)
4628c9fbc29Smrg		    buf[len++]= '|';
4638c9fbc29Smrg		sprintf(&buf[len],"XkbIM_Use%s",imWhichNames[i]);
4648c9fbc29Smrg		buf[len+9]= toupper(buf[len+9]);
4658c9fbc29Smrg	    }
4668c9fbc29Smrg	    else {
4678c9fbc29Smrg		if (len!=0)
4688c9fbc29Smrg		    buf[len++]= '+';
4698c9fbc29Smrg		sprintf(&buf[len],"%s",imWhichNames[i]);
4708c9fbc29Smrg	    }
4718c9fbc29Smrg	    len+= strlen(&buf[len]);
4728c9fbc29Smrg	}
4738c9fbc29Smrg    }
4748c9fbc29Smrg    return buf;
4758c9fbc29Smrg}
4768c9fbc29Smrg
4778c9fbc29Smrgchar *
4788c9fbc29SmrgXkbAccessXDetailText(unsigned state,unsigned format)
4798c9fbc29Smrg{
4804cd6a3aeSmrgchar *buf;
4814cd6a3aeSmrgconst char *prefix;
4828c9fbc29Smrg
4838c9fbc29Smrg    buf= tbGetBuffer(32);
4848c9fbc29Smrg    if (format==XkbMessage)	prefix= "";
4858c9fbc29Smrg    else			prefix= "XkbAXN_";
4868c9fbc29Smrg    switch (state){
4878c9fbc29Smrg	case XkbAXN_SKPress:	sprintf(buf,"%sSKPress",prefix); break;
4888c9fbc29Smrg	case XkbAXN_SKAccept:	sprintf(buf,"%sSKAccept",prefix); break;
4898c9fbc29Smrg	case XkbAXN_SKRelease:	sprintf(buf,"%sSKRelease",prefix); break;
4908c9fbc29Smrg	case XkbAXN_SKReject:	sprintf(buf,"%sSKReject",prefix); break;
4918c9fbc29Smrg	case XkbAXN_BKAccept:	sprintf(buf,"%sBKAccept",prefix); break;
4928c9fbc29Smrg	case XkbAXN_BKReject:	sprintf(buf,"%sBKReject",prefix); break;
4938c9fbc29Smrg	case XkbAXN_AXKWarning:	sprintf(buf,"%sAXKWarning",prefix); break;
4948c9fbc29Smrg	default:		sprintf(buf,"ILLEGAL"); break;
4958c9fbc29Smrg    }
4968c9fbc29Smrg    return buf;
4978c9fbc29Smrg}
4988c9fbc29Smrg
4994cd6a3aeSmrgstatic const char *nknNames[] = {
5008c9fbc29Smrg	"keycodes", "geometry", "deviceID"
5018c9fbc29Smrg};
5028c9fbc29Smrg#define	NUM_NKN	(sizeof(nknNames)/sizeof(char *))
5038c9fbc29Smrg
5048c9fbc29Smrgchar *
5058c9fbc29SmrgXkbNKNDetailMaskText(unsigned detail,unsigned format)
5068c9fbc29Smrg{
5074cd6a3aeSmrgchar *buf;
5084cd6a3aeSmrgconst char *prefix,*suffix;
5098c9fbc29Smrgregister int 		i;
5108c9fbc29Smrgregister unsigned	bit;
5118c9fbc29Smrgint			len,plen,slen;
5128c9fbc29Smrg
5138c9fbc29Smrg
5148c9fbc29Smrg    if ((detail&XkbAllNewKeyboardEventsMask)==0) {
5154cd6a3aeSmrg	const char *tmp = "";
5168c9fbc29Smrg	if (format==XkbCFile)			tmp= "0";
5178c9fbc29Smrg	else if (format==XkbMessage)		tmp= "none";
5188c9fbc29Smrg	buf=  tbGetBuffer(strlen(tmp)+1);
5198c9fbc29Smrg	strcpy(buf,tmp);
5208c9fbc29Smrg	return buf;
5218c9fbc29Smrg    }
5228c9fbc29Smrg    else if ((detail&XkbAllNewKeyboardEventsMask)==XkbAllNewKeyboardEventsMask){
5234cd6a3aeSmrg	const char *	tmp;
5248c9fbc29Smrg	if (format==XkbCFile)		tmp= "XkbAllNewKeyboardEventsMask";
5258c9fbc29Smrg	else 				tmp= "all";
5268c9fbc29Smrg	buf=  tbGetBuffer(strlen(tmp)+1);
5278c9fbc29Smrg	strcpy(buf,tmp);
5288c9fbc29Smrg	return buf;
5298c9fbc29Smrg    }
5308c9fbc29Smrg    if (format==XkbMessage) {
5318c9fbc29Smrg	prefix= "";
5328c9fbc29Smrg	suffix= "";
5338c9fbc29Smrg	slen= plen= 0;
5348c9fbc29Smrg    }
5358c9fbc29Smrg    else {
5368c9fbc29Smrg	prefix= "XkbNKN_";
5378c9fbc29Smrg	plen= 7;
5388c9fbc29Smrg	if (format==XkbCFile)
5398c9fbc29Smrg	     suffix= "Mask";
5408c9fbc29Smrg	else suffix= "";
5418c9fbc29Smrg	slen= strlen(suffix);
5428c9fbc29Smrg    }
5438c9fbc29Smrg    for (len=0,i=0,bit=1;i<NUM_NKN;i++,bit<<=1) {
5448c9fbc29Smrg	if (detail&bit) {
5458c9fbc29Smrg	    if (len!=0)	len+= 1;	/* room for '+' or '|' */
5468c9fbc29Smrg	    len+= plen+slen+strlen(nknNames[i]);
5478c9fbc29Smrg	}
5488c9fbc29Smrg    }
5498c9fbc29Smrg    buf= tbGetBuffer(len+1);
5508c9fbc29Smrg    buf[0]= '\0';
5518c9fbc29Smrg    for (len=0,i=0,bit=1;i<NUM_NKN;i++,bit<<=1) {
5528c9fbc29Smrg	if (detail&bit) {
5538c9fbc29Smrg	    if (len!=0) {
5548c9fbc29Smrg		if (format==XkbCFile)	buf[len++]= '|';
5558c9fbc29Smrg		else			buf[len++]= '+';
5568c9fbc29Smrg	    }
5578c9fbc29Smrg	    if (plen) {
5588c9fbc29Smrg		strcpy(&buf[len],prefix);
5598c9fbc29Smrg		len+= plen;
5608c9fbc29Smrg	    }
5618c9fbc29Smrg	    strcpy(&buf[len],nknNames[i]);
5628c9fbc29Smrg	    len+= strlen(nknNames[i]);
5638c9fbc29Smrg	    if (slen) {
5648c9fbc29Smrg		strcpy(&buf[len],suffix);
5658c9fbc29Smrg		len+= slen;
5668c9fbc29Smrg	    }
5678c9fbc29Smrg	}
5688c9fbc29Smrg    }
5698c9fbc29Smrg    buf[len++]= '\0';
5708c9fbc29Smrg    return buf;
5718c9fbc29Smrg}
5728c9fbc29Smrg
5734cd6a3aeSmrgstatic const char *ctrlNames[] = {
5748c9fbc29Smrg	"repeatKeys",
5758c9fbc29Smrg	"slowKeys",
5768c9fbc29Smrg	"bounceKeys",
5778c9fbc29Smrg	"stickyKeys",
5788c9fbc29Smrg	"mouseKeys",
5798c9fbc29Smrg	"mouseKeysAccel",
5808c9fbc29Smrg	"accessXKeys",
5818c9fbc29Smrg	"accessXTimeout",
5828c9fbc29Smrg	"accessXFeedback",
5838c9fbc29Smrg	"audibleBell",
5848c9fbc29Smrg	"overlay1",
5858c9fbc29Smrg	"overlay2",
5868c9fbc29Smrg	"ignoreGroupLock"
5878c9fbc29Smrg};
5888c9fbc29Smrg
5898c9fbc29Smrgchar *
5908c9fbc29SmrgXkbControlsMaskText(unsigned ctrls,unsigned format)
5918c9fbc29Smrg{
5928c9fbc29Smrgint		len;
5938c9fbc29Smrgunsigned	i,bit,tmp;
5948c9fbc29Smrgchar *		buf;
5958c9fbc29Smrg
5968c9fbc29Smrg    if (ctrls==0) {
5978c9fbc29Smrg	buf= tbGetBuffer(5);
5988c9fbc29Smrg	if (format==XkbCFile)
5998c9fbc29Smrg	     strcpy(buf,"0");
6008c9fbc29Smrg	else strcpy(buf,"none");
6018c9fbc29Smrg	return buf;
6028c9fbc29Smrg    }
6038c9fbc29Smrg    tmp= ctrls&XkbAllBooleanCtrlsMask;
6048c9fbc29Smrg    for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
6058c9fbc29Smrg	if (tmp&bit) {
6068c9fbc29Smrg	    tmp&= ~bit;
6078c9fbc29Smrg	    len+= strlen(ctrlNames[i])+1;
6088c9fbc29Smrg	    if (format==XkbCFile)
6098c9fbc29Smrg		len+= 7;
6108c9fbc29Smrg	}
6118c9fbc29Smrg    }
6128c9fbc29Smrg    buf= tbGetBuffer(len+1);
6138c9fbc29Smrg    tmp= ctrls&XkbAllBooleanCtrlsMask;
6148c9fbc29Smrg    for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
6158c9fbc29Smrg	if (tmp&bit) {
6168c9fbc29Smrg	    tmp&= ~bit;
6178c9fbc29Smrg	    if (format==XkbCFile) {
6188c9fbc29Smrg		if (len!=0)
6198c9fbc29Smrg		    buf[len++]= '|';
6208c9fbc29Smrg		sprintf(&buf[len],"Xkb%sMask",ctrlNames[i]);
6218c9fbc29Smrg		buf[len+3]= toupper(buf[len+3]);
6228c9fbc29Smrg	    }
6238c9fbc29Smrg	    else {
6248c9fbc29Smrg		if (len!=0)
6258c9fbc29Smrg		    buf[len++]= '+';
6268c9fbc29Smrg		sprintf(&buf[len],"%s",ctrlNames[i]);
6278c9fbc29Smrg	    }
6288c9fbc29Smrg	    len+= strlen(&buf[len]);
6298c9fbc29Smrg	}
6308c9fbc29Smrg    }
6318c9fbc29Smrg    return buf;
6328c9fbc29Smrg}
6338c9fbc29Smrg
6348c9fbc29Smrg/***====================================================================***/
6358c9fbc29Smrg
6368c9fbc29Smrgchar *
6378c9fbc29SmrgXkbStringText(char *str,unsigned format)
6388c9fbc29Smrg{
6398c9fbc29Smrgchar *	buf;
6408c9fbc29Smrgregister char *in,*out;
6418c9fbc29Smrgint	len;
6428c9fbc29SmrgBool	ok;
6438c9fbc29Smrg
6448c9fbc29Smrg    if (str==NULL) {
6458c9fbc29Smrg	buf= tbGetBuffer(2);
6468c9fbc29Smrg	buf[0]='\0';
6478c9fbc29Smrg	return buf;
6488c9fbc29Smrg    }
6498c9fbc29Smrg    else if (format==XkbXKMFile)
6508c9fbc29Smrg	return str;
6518c9fbc29Smrg    for (ok= True,len=0,in=str;*in!='\0';in++,len++) {
6528c9fbc29Smrg	if (!isprint(*in)) {
6538c9fbc29Smrg	    ok= False;
6548c9fbc29Smrg	    switch (*in) {
6558c9fbc29Smrg		case '\n': case '\t': case '\v':
6568c9fbc29Smrg		case '\b': case '\r': case '\f':
6578c9fbc29Smrg		    len++;
6588c9fbc29Smrg		    break;
6598c9fbc29Smrg		default:
6608c9fbc29Smrg		    len+= 4;
6618c9fbc29Smrg		    break;
6628c9fbc29Smrg	    }
6638c9fbc29Smrg	}
6648c9fbc29Smrg    }
6658c9fbc29Smrg    if (ok)
6668c9fbc29Smrg	return str;
6678c9fbc29Smrg    buf= tbGetBuffer(len+1);
6688c9fbc29Smrg    for (in=str,out=buf;*in!='\0';in++) {
6698c9fbc29Smrg	if (isprint(*in))
6708c9fbc29Smrg	    *out++= *in;
6718c9fbc29Smrg	else {
6728c9fbc29Smrg	    *out++= '\\';
6738c9fbc29Smrg	    if (*in=='\n')	*out++= 'n';
6748c9fbc29Smrg	    else if (*in=='\t')	*out++= 't';
6758c9fbc29Smrg	    else if (*in=='\v')	*out++= 'v';
6768c9fbc29Smrg	    else if (*in=='\b')	*out++= 'b';
6778c9fbc29Smrg	    else if (*in=='\r')	*out++= 'r';
6788c9fbc29Smrg	    else if (*in=='\f')	*out++= 'f';
6798c9fbc29Smrg	    else if ((*in=='\033')&&(format==XkbXKMFile)) {
6808c9fbc29Smrg		*out++= 'e';
6818c9fbc29Smrg	    }
6828c9fbc29Smrg	    else {
6838c9fbc29Smrg		*out++= '0';
6848c9fbc29Smrg		sprintf(out,"%o",*in);
6858c9fbc29Smrg		while (*out!='\0')
6868c9fbc29Smrg		    out++;
6878c9fbc29Smrg	    }
6888c9fbc29Smrg	}
6898c9fbc29Smrg    }
6908c9fbc29Smrg    *out++= '\0';
6918c9fbc29Smrg    return buf;
6928c9fbc29Smrg}
6938c9fbc29Smrg
6948c9fbc29Smrg/***====================================================================***/
6958c9fbc29Smrg
6968c9fbc29Smrgchar *
6978c9fbc29SmrgXkbGeomFPText(int val,unsigned format)
6988c9fbc29Smrg{
6998c9fbc29Smrgint	whole,frac;
7008c9fbc29Smrgchar *	buf;
7018c9fbc29Smrg
7028c9fbc29Smrg    buf= tbGetBuffer(12);
7038c9fbc29Smrg    if (format==XkbCFile) {
7048c9fbc29Smrg	sprintf(buf,"%d",val);
7058c9fbc29Smrg    }
7068c9fbc29Smrg    else {
7078c9fbc29Smrg	whole= val/XkbGeomPtsPerMM;
7088c9fbc29Smrg	frac= val%XkbGeomPtsPerMM;
7098c9fbc29Smrg	if (frac!=0)
7108c9fbc29Smrg	     sprintf(buf,"%d.%d",whole,frac);
7118c9fbc29Smrg	else sprintf(buf,"%d",whole);
7128c9fbc29Smrg    }
7138c9fbc29Smrg    return buf;
7148c9fbc29Smrg}
7158c9fbc29Smrg
7168c9fbc29Smrgchar *
7178c9fbc29SmrgXkbDoodadTypeText(unsigned type,unsigned format)
7188c9fbc29Smrg{
7198c9fbc29Smrgchar *	buf;
7208c9fbc29Smrg    if (format==XkbCFile) {
7218c9fbc29Smrg	buf= tbGetBuffer(24);
7228c9fbc29Smrg	if (type==XkbOutlineDoodad)	   strcpy(buf,"XkbOutlineDoodad");
7238c9fbc29Smrg	else if (type==XkbSolidDoodad)	   strcpy(buf,"XkbSolidDoodad");
7248c9fbc29Smrg	else if (type==XkbTextDoodad)	   strcpy(buf,"XkbTextDoodad");
7258c9fbc29Smrg	else if (type==XkbIndicatorDoodad) strcpy(buf,"XkbIndicatorDoodad");
7268c9fbc29Smrg	else if (type==XkbLogoDoodad)	   strcpy(buf,"XkbLogoDoodad");
7278c9fbc29Smrg	else				   sprintf(buf,"UnknownDoodad%d",type);
7288c9fbc29Smrg    }
7298c9fbc29Smrg    else {
7308c9fbc29Smrg	buf= tbGetBuffer(12);
7318c9fbc29Smrg	if (type==XkbOutlineDoodad)	   strcpy(buf,"outline");
7328c9fbc29Smrg	else if (type==XkbSolidDoodad)	   strcpy(buf,"solid");
7338c9fbc29Smrg	else if (type==XkbTextDoodad)	   strcpy(buf,"text");
7348c9fbc29Smrg	else if (type==XkbIndicatorDoodad) strcpy(buf,"indicator");
7358c9fbc29Smrg	else if (type==XkbLogoDoodad)	   strcpy(buf,"logo");
7368c9fbc29Smrg	else				   sprintf(buf,"unknown%d",type);
7378c9fbc29Smrg    }
7388c9fbc29Smrg    return buf;
7398c9fbc29Smrg}
7408c9fbc29Smrg
7418c9fbc29Smrgstatic char *actionTypeNames[XkbSA_NumActions]= {
7424cd6a3aeSmrg    "NoAction",
7434cd6a3aeSmrg    "SetMods",      "LatchMods",    "LockMods",
7448c9fbc29Smrg    "SetGroup",     "LatchGroup",   "LockGroup",
7458c9fbc29Smrg    "MovePtr",
7468c9fbc29Smrg    "PtrBtn",       "LockPtrBtn",
7478c9fbc29Smrg    "SetPtrDflt",
7488c9fbc29Smrg    "ISOLock",
7494cd6a3aeSmrg    "Terminate",    "SwitchScreen",
7508c9fbc29Smrg    "SetControls",  "LockControls",
7518c9fbc29Smrg    "ActionMessage",
7528c9fbc29Smrg    "RedirectKey",
7538c9fbc29Smrg    "DeviceBtn",    "LockDeviceBtn"
7548c9fbc29Smrg};
7558c9fbc29Smrg
7568c9fbc29Smrgchar *
7578c9fbc29SmrgXkbActionTypeText(unsigned type,unsigned format)
7588c9fbc29Smrg{
7598c9fbc29Smrgstatic char buf[32];
7608c9fbc29Smrgchar *rtrn;
7618c9fbc29Smrg
7628c9fbc29Smrg    if (type<=XkbSA_LastAction) {
7638c9fbc29Smrg	rtrn= actionTypeNames[type];
7648c9fbc29Smrg	if (format==XkbCFile) {
7658c9fbc29Smrg	    sprintf(buf,"XkbSA_%s",rtrn);
7668c9fbc29Smrg	    return buf;
7678c9fbc29Smrg	}
7688c9fbc29Smrg	return rtrn;
7698c9fbc29Smrg    }
7708c9fbc29Smrg    sprintf(buf,"Private");
7718c9fbc29Smrg    return buf;
7728c9fbc29Smrg}
7738c9fbc29Smrg
7748c9fbc29Smrg/***====================================================================***/
7758c9fbc29Smrg
7768c9fbc29Smrgstatic int
7774cd6a3aeSmrgTryCopyStr(char *to,const char *from,int *pLeft)
7788c9fbc29Smrg{
7798c9fbc29Smrgregister int len;
7808c9fbc29Smrg    if (*pLeft>0) {
7818c9fbc29Smrg	len= strlen(from);
7828c9fbc29Smrg	if (len<((*pLeft)-3)) {
7838c9fbc29Smrg	    strcat(to,from);
7848c9fbc29Smrg	    *pLeft-= len;
7858c9fbc29Smrg	    return True;
7868c9fbc29Smrg	}
7878c9fbc29Smrg    }
7888c9fbc29Smrg    *pLeft= -1;
7898c9fbc29Smrg    return False;
7908c9fbc29Smrg}
7918c9fbc29Smrg
7928c9fbc29Smrg/*ARGSUSED*/
7938c9fbc29Smrgstatic Bool
7948c9fbc29SmrgCopyNoActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int*sz)
7958c9fbc29Smrg{
7968c9fbc29Smrg    return True;
7978c9fbc29Smrg}
7988c9fbc29Smrg
7998c9fbc29Smrgstatic Bool
8008c9fbc29SmrgCopyModActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
8018c9fbc29Smrg								int* sz)
8028c9fbc29Smrg{
8038c9fbc29SmrgXkbModAction *	act;
8048c9fbc29Smrgunsigned	tmp;
8058c9fbc29Smrg
8068c9fbc29Smrg    act= &action->mods;
8078c9fbc29Smrg    tmp= XkbModActionVMods(act);
8088c9fbc29Smrg    TryCopyStr(buf,"modifiers=",sz);
8098c9fbc29Smrg    if (act->flags&XkbSA_UseModMapMods)
8108c9fbc29Smrg	  TryCopyStr(buf,"modMapMods",sz);
8118c9fbc29Smrg    else if (act->real_mods || tmp) {
8128c9fbc29Smrg	 TryCopyStr(buf,
8138c9fbc29Smrg		     XkbVModMaskText(dpy,xkb,act->real_mods,tmp,XkbXKBFile),
8148c9fbc29Smrg		     sz);
8158c9fbc29Smrg    }
8168c9fbc29Smrg    else TryCopyStr(buf,"none",sz);
8178c9fbc29Smrg    if (act->type==XkbSA_LockMods)
8188c9fbc29Smrg	return True;
8198c9fbc29Smrg    if (act->flags&XkbSA_ClearLocks)
8208c9fbc29Smrg	TryCopyStr(buf,",clearLocks",sz);
8218c9fbc29Smrg    if (act->flags&XkbSA_LatchToLock)
8228c9fbc29Smrg	TryCopyStr(buf,",latchToLock",sz);
8238c9fbc29Smrg    return True;
8248c9fbc29Smrg}
8258c9fbc29Smrg
8268c9fbc29Smrg/*ARGSUSED*/
8278c9fbc29Smrgstatic Bool
8288c9fbc29SmrgCopyGroupActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
8298c9fbc29Smrg								int *sz)
8308c9fbc29Smrg{
8318c9fbc29SmrgXkbGroupAction *	act;
8328c9fbc29Smrgchar			tbuf[32];
8338c9fbc29Smrg
8348c9fbc29Smrg    act= &action->group;
8358c9fbc29Smrg    TryCopyStr(buf,"group=",sz);
8368c9fbc29Smrg    if (act->flags&XkbSA_GroupAbsolute)
8378c9fbc29Smrg	 sprintf(tbuf,"%d",XkbSAGroup(act)+1);
8388c9fbc29Smrg    else if (XkbSAGroup(act)<0)
8398c9fbc29Smrg	 sprintf(tbuf,"%d",XkbSAGroup(act));
8408c9fbc29Smrg    else sprintf(tbuf,"+%d",XkbSAGroup(act));
8418c9fbc29Smrg    TryCopyStr(buf,tbuf,sz);
8428c9fbc29Smrg    if (act->type==XkbSA_LockGroup)
8438c9fbc29Smrg	return True;
8448c9fbc29Smrg    if (act->flags&XkbSA_ClearLocks)
8458c9fbc29Smrg	TryCopyStr(buf,",clearLocks",sz);
8468c9fbc29Smrg    if (act->flags&XkbSA_LatchToLock)
8478c9fbc29Smrg	TryCopyStr(buf,",latchToLock",sz);
8488c9fbc29Smrg    return True;
8498c9fbc29Smrg}
8508c9fbc29Smrg
8518c9fbc29Smrg/*ARGSUSED*/
8528c9fbc29Smrgstatic Bool
8538c9fbc29SmrgCopyMovePtrArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
8548c9fbc29Smrg{
8558c9fbc29SmrgXkbPtrAction *	act;
8568c9fbc29Smrgint		x,y;
8578c9fbc29Smrgchar		tbuf[32];
8588c9fbc29Smrg
8598c9fbc29Smrg    act= &action->ptr;
8608c9fbc29Smrg    x= XkbPtrActionX(act);
8618c9fbc29Smrg    y= XkbPtrActionY(act);
8628c9fbc29Smrg    if ((act->flags&XkbSA_MoveAbsoluteX)||(x<0))
8638c9fbc29Smrg	 sprintf(tbuf,"x=%d",x);
8648c9fbc29Smrg    else sprintf(tbuf,"x=+%d",x);
8658c9fbc29Smrg    TryCopyStr(buf,tbuf,sz);
8668c9fbc29Smrg
8678c9fbc29Smrg    if ((act->flags&XkbSA_MoveAbsoluteY)||(y<0))
8688c9fbc29Smrg	 sprintf(tbuf,",y=%d",y);
8698c9fbc29Smrg    else sprintf(tbuf,",y=+%d",y);
8708c9fbc29Smrg    TryCopyStr(buf,tbuf,sz);
8718c9fbc29Smrg    if (act->flags&XkbSA_NoAcceleration)
8728c9fbc29Smrg	TryCopyStr(buf,",!accel",sz);
8738c9fbc29Smrg    return True;
8748c9fbc29Smrg}
8758c9fbc29Smrg
8768c9fbc29Smrg/*ARGSUSED*/
8778c9fbc29Smrgstatic Bool
8788c9fbc29SmrgCopyPtrBtnArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
8798c9fbc29Smrg{
8808c9fbc29SmrgXkbPtrBtnAction *	act;
8818c9fbc29Smrgchar			tbuf[32];
8828c9fbc29Smrg
8838c9fbc29Smrg    act= &action->btn;
8848c9fbc29Smrg    TryCopyStr(buf,"button=",sz);
8858c9fbc29Smrg    if ((act->button>0)&&(act->button<6)) {
8868c9fbc29Smrg	 sprintf(tbuf,"%d",act->button);
8878c9fbc29Smrg	 TryCopyStr(buf,tbuf,sz);
8888c9fbc29Smrg    }
8898c9fbc29Smrg    else TryCopyStr(buf,"default",sz);
8908c9fbc29Smrg    if (act->count>0) {
8918c9fbc29Smrg	sprintf(tbuf,",count=%d",act->count);
8928c9fbc29Smrg	TryCopyStr(buf,tbuf,sz);
8938c9fbc29Smrg    }
8948c9fbc29Smrg    if (action->type==XkbSA_LockPtrBtn) {
8958c9fbc29Smrg	switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) {
8968c9fbc29Smrg	    case XkbSA_LockNoLock:
8978c9fbc29Smrg		sprintf(tbuf,",affect=unlock"); break;
8988c9fbc29Smrg	    case XkbSA_LockNoUnlock:
8998c9fbc29Smrg		sprintf(tbuf,",affect=lock"); break;
9008c9fbc29Smrg	    case XkbSA_LockNoUnlock|XkbSA_LockNoLock:
9018c9fbc29Smrg		sprintf(tbuf,",affect=neither"); break;
9028c9fbc29Smrg	    default:
9038c9fbc29Smrg		sprintf(tbuf,",affect=both"); break;
9048c9fbc29Smrg	}
9058c9fbc29Smrg	TryCopyStr(buf,tbuf,sz);
9068c9fbc29Smrg    }
9078c9fbc29Smrg    return True;
9088c9fbc29Smrg}
9098c9fbc29Smrg
9108c9fbc29Smrg/*ARGSUSED*/
9118c9fbc29Smrgstatic Bool
9128c9fbc29SmrgCopySetPtrDfltArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
9138c9fbc29Smrg								int *sz)
9148c9fbc29Smrg{
9158c9fbc29SmrgXkbPtrDfltAction *	act;
9168c9fbc29Smrgchar			tbuf[32];
9178c9fbc29Smrg
9188c9fbc29Smrg    act= &action->dflt;
9198c9fbc29Smrg    if (act->affect==XkbSA_AffectDfltBtn) {
9208c9fbc29Smrg	TryCopyStr(buf,"affect=button,button=",sz);
9218c9fbc29Smrg	if ((act->flags&XkbSA_DfltBtnAbsolute)||(XkbSAPtrDfltValue(act)<0))
9228c9fbc29Smrg	     sprintf(tbuf,"%d",XkbSAPtrDfltValue(act));
9238c9fbc29Smrg	else sprintf(tbuf,"+%d",XkbSAPtrDfltValue(act));
9248c9fbc29Smrg	TryCopyStr(buf,tbuf,sz);
9258c9fbc29Smrg    }
9268c9fbc29Smrg    return True;
9278c9fbc29Smrg}
9288c9fbc29Smrg
9298c9fbc29Smrgstatic Bool
9308c9fbc29SmrgCopyISOLockArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
9318c9fbc29Smrg{
9328c9fbc29SmrgXkbISOAction *	act;
9338c9fbc29Smrgchar		tbuf[64];
9348c9fbc29Smrg
9358c9fbc29Smrg    act= &action->iso;
9368c9fbc29Smrg    if (act->flags&XkbSA_ISODfltIsGroup) {
9378c9fbc29Smrg	TryCopyStr(tbuf,"group=",sz);
9388c9fbc29Smrg	if (act->flags&XkbSA_GroupAbsolute)
9398c9fbc29Smrg	     sprintf(tbuf,"%d",XkbSAGroup(act)+1);
9408c9fbc29Smrg	else if (XkbSAGroup(act)<0)
9418c9fbc29Smrg	     sprintf(tbuf,"%d",XkbSAGroup(act));
9428c9fbc29Smrg	else sprintf(tbuf,"+%d",XkbSAGroup(act));
9438c9fbc29Smrg	TryCopyStr(buf,tbuf,sz);
9448c9fbc29Smrg    }
9458c9fbc29Smrg    else {
9468c9fbc29Smrg	unsigned tmp;
9478c9fbc29Smrg	tmp= XkbModActionVMods(act);
9488c9fbc29Smrg	TryCopyStr(buf,"modifiers=",sz);
9498c9fbc29Smrg	if (act->flags&XkbSA_UseModMapMods)
9508c9fbc29Smrg	     TryCopyStr(buf,"modMapMods",sz);
9518c9fbc29Smrg	else if (act->real_mods || tmp) {
9528c9fbc29Smrg	    if (act->real_mods) {
9538c9fbc29Smrg		TryCopyStr(buf,XkbModMaskText(act->real_mods,XkbXKBFile),sz);
9548c9fbc29Smrg		if (tmp)
9558c9fbc29Smrg		    TryCopyStr(buf,"+",sz);
9568c9fbc29Smrg	    }
9578c9fbc29Smrg	    if (tmp)
9588c9fbc29Smrg		TryCopyStr(buf,XkbVModMaskText(dpy,xkb,0,tmp,XkbXKBFile),sz);
9598c9fbc29Smrg	}
9608c9fbc29Smrg	else TryCopyStr(buf,"none",sz);
9618c9fbc29Smrg    }
9628c9fbc29Smrg    TryCopyStr(buf,",affect=",sz);
9638c9fbc29Smrg    if ((act->affect&XkbSA_ISOAffectMask)==0)
9648c9fbc29Smrg	TryCopyStr(buf,"all",sz);
9658c9fbc29Smrg    else {
9668c9fbc29Smrg	int nOut= 0;
9678c9fbc29Smrg	if ((act->affect&XkbSA_ISONoAffectMods)==0) {
9688c9fbc29Smrg	    TryCopyStr(buf,"mods",sz);
9698c9fbc29Smrg	    nOut++;
9708c9fbc29Smrg	}
9718c9fbc29Smrg	if ((act->affect&XkbSA_ISONoAffectGroup)==0) {
9728c9fbc29Smrg	    sprintf(tbuf,"%sgroups",(nOut>0?"+":""));
9738c9fbc29Smrg	    TryCopyStr(buf,tbuf,sz);
9748c9fbc29Smrg	    nOut++;
9758c9fbc29Smrg	}
9768c9fbc29Smrg	if ((act->affect&XkbSA_ISONoAffectPtr)==0) {
9778c9fbc29Smrg	    sprintf(tbuf,"%spointer",(nOut>0?"+":""));
9788c9fbc29Smrg	    TryCopyStr(buf,tbuf,sz);
9798c9fbc29Smrg	    nOut++;
9808c9fbc29Smrg	}
9818c9fbc29Smrg	if ((act->affect&XkbSA_ISONoAffectCtrls)==0) {
9828c9fbc29Smrg	    sprintf(tbuf,"%scontrols",(nOut>0?"+":""));
9838c9fbc29Smrg	    TryCopyStr(buf,tbuf,sz);
9848c9fbc29Smrg	    nOut++;
9858c9fbc29Smrg	}
9868c9fbc29Smrg    }
9878c9fbc29Smrg    return True;
9888c9fbc29Smrg}
9898c9fbc29Smrg
9908c9fbc29Smrg/*ARGSUSED*/
9918c9fbc29Smrgstatic Bool
9928c9fbc29SmrgCopySwitchScreenArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
9938c9fbc29Smrg								int *sz)
9948c9fbc29Smrg{
9958c9fbc29SmrgXkbSwitchScreenAction *	act;
9968c9fbc29Smrgchar			tbuf[32];
9978c9fbc29Smrg
9988c9fbc29Smrg    act= &action->screen;
9998c9fbc29Smrg    if ((act->flags&XkbSA_SwitchAbsolute)||(XkbSAScreen(act)<0))
10008c9fbc29Smrg	 sprintf(tbuf,"screen=%d",XkbSAScreen(act));
10018c9fbc29Smrg    else sprintf(tbuf,"screen=+%d",XkbSAScreen(act));
10028c9fbc29Smrg    TryCopyStr(buf,tbuf,sz);
10038c9fbc29Smrg    if (act->flags&XkbSA_SwitchApplication)
10048c9fbc29Smrg	 TryCopyStr(buf,",!same",sz);
10058c9fbc29Smrg    else TryCopyStr(buf,",same",sz);
10068c9fbc29Smrg    return True;
10078c9fbc29Smrg}
10088c9fbc29Smrg
10098c9fbc29Smrg/*ARGSUSED*/
10108c9fbc29Smrgstatic Bool
10118c9fbc29SmrgCopySetLockControlsArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,
10128c9fbc29Smrg							char *buf,int *sz)
10138c9fbc29Smrg{
10148c9fbc29SmrgXkbCtrlsAction *	act;
10158c9fbc29Smrgunsigned		tmp;
10168c9fbc29Smrgchar			tbuf[32];
10178c9fbc29Smrg
10188c9fbc29Smrg    act= &action->ctrls;
10198c9fbc29Smrg    tmp= XkbActionCtrls(act);
10208c9fbc29Smrg    TryCopyStr(buf,"controls=",sz);
10218c9fbc29Smrg    if (tmp==0)
10228c9fbc29Smrg	TryCopyStr(buf,"none",sz);
10238c9fbc29Smrg    else if ((tmp&XkbAllBooleanCtrlsMask)==XkbAllBooleanCtrlsMask)
10248c9fbc29Smrg	TryCopyStr(buf,"all",sz);
10258c9fbc29Smrg    else {
10268c9fbc29Smrg	int nOut= 0;
10278c9fbc29Smrg	if (tmp&XkbRepeatKeysMask) {
10288c9fbc29Smrg	    sprintf(tbuf,"%sRepeatKeys",(nOut>0?"+":""));
10298c9fbc29Smrg	    TryCopyStr(buf,tbuf,sz);
10308c9fbc29Smrg	    nOut++;
10318c9fbc29Smrg	}
10328c9fbc29Smrg	if (tmp&XkbSlowKeysMask) {
10338c9fbc29Smrg	    sprintf(tbuf,"%sSlowKeys",(nOut>0?"+":""));
10348c9fbc29Smrg	    TryCopyStr(buf,tbuf,sz);
10358c9fbc29Smrg	    nOut++;
10368c9fbc29Smrg	}
10378c9fbc29Smrg	if (tmp&XkbBounceKeysMask) {
10388c9fbc29Smrg	    sprintf(tbuf,"%sBounceKeys",(nOut>0?"+":""));
10398c9fbc29Smrg	    TryCopyStr(buf,tbuf,sz);
10408c9fbc29Smrg	    nOut++;
10418c9fbc29Smrg	}
10428c9fbc29Smrg	if (tmp&XkbStickyKeysMask) {
10438c9fbc29Smrg	    sprintf(tbuf,"%sStickyKeys",(nOut>0?"+":""));
10448c9fbc29Smrg	    TryCopyStr(buf,tbuf,sz);
10458c9fbc29Smrg	    nOut++;
10468c9fbc29Smrg	}
10478c9fbc29Smrg	if (tmp&XkbMouseKeysMask) {
10488c9fbc29Smrg	    sprintf(tbuf,"%sMouseKeys",(nOut>0?"+":""));
10498c9fbc29Smrg	    TryCopyStr(buf,tbuf,sz);
10508c9fbc29Smrg	    nOut++;
10518c9fbc29Smrg	}
10528c9fbc29Smrg	if (tmp&XkbMouseKeysAccelMask) {
10538c9fbc29Smrg	    sprintf(tbuf,"%sMouseKeysAccel",(nOut>0?"+":""));
10548c9fbc29Smrg	    TryCopyStr(buf,tbuf,sz);
10558c9fbc29Smrg	    nOut++;
10568c9fbc29Smrg	}
10578c9fbc29Smrg	if (tmp&XkbAccessXKeysMask) {
10588c9fbc29Smrg	    sprintf(tbuf,"%sAccessXKeys",(nOut>0?"+":""));
10598c9fbc29Smrg	    TryCopyStr(buf,tbuf,sz);
10608c9fbc29Smrg	    nOut++;
10618c9fbc29Smrg	}
10628c9fbc29Smrg	if (tmp&XkbAccessXTimeoutMask) {
10638c9fbc29Smrg	    sprintf(tbuf,"%sAccessXTimeout",(nOut>0?"+":""));
10648c9fbc29Smrg	    TryCopyStr(buf,tbuf,sz);
10658c9fbc29Smrg	    nOut++;
10668c9fbc29Smrg	}
10678c9fbc29Smrg	if (tmp&XkbAccessXFeedbackMask) {
10688c9fbc29Smrg	    sprintf(tbuf,"%sAccessXFeedback",(nOut>0?"+":""));
10698c9fbc29Smrg	    TryCopyStr(buf,tbuf,sz);
10708c9fbc29Smrg	    nOut++;
10718c9fbc29Smrg	}
10728c9fbc29Smrg	if (tmp&XkbAudibleBellMask) {
10738c9fbc29Smrg	    sprintf(tbuf,"%sAudibleBell",(nOut>0?"+":""));
10748c9fbc29Smrg	    TryCopyStr(buf,tbuf,sz);
10758c9fbc29Smrg	    nOut++;
10768c9fbc29Smrg	}
10778c9fbc29Smrg	if (tmp&XkbOverlay1Mask) {
10788c9fbc29Smrg	    sprintf(tbuf,"%sOverlay1",(nOut>0?"+":""));
10798c9fbc29Smrg	    TryCopyStr(buf,tbuf,sz);
10808c9fbc29Smrg	    nOut++;
10818c9fbc29Smrg	}
10828c9fbc29Smrg	if (tmp&XkbOverlay2Mask) {
10838c9fbc29Smrg	    sprintf(tbuf,"%sOverlay2",(nOut>0?"+":""));
10848c9fbc29Smrg	    TryCopyStr(buf,tbuf,sz);
10858c9fbc29Smrg	    nOut++;
10868c9fbc29Smrg	}
10878c9fbc29Smrg	if (tmp&XkbIgnoreGroupLockMask) {
10888c9fbc29Smrg	    sprintf(tbuf,"%sIgnoreGroupLock",(nOut>0?"+":""));
10898c9fbc29Smrg	    TryCopyStr(buf,tbuf,sz);
10908c9fbc29Smrg	    nOut++;
10918c9fbc29Smrg	}
10928c9fbc29Smrg    }
10938c9fbc29Smrg    return True;
10948c9fbc29Smrg}
10958c9fbc29Smrg
10968c9fbc29Smrg/*ARGSUSED*/
10978c9fbc29Smrgstatic Bool
10988c9fbc29SmrgCopyActionMessageArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
10998c9fbc29Smrg								int *sz)
11008c9fbc29Smrg{
11018c9fbc29SmrgXkbMessageAction *	act;
11028c9fbc29Smrgunsigned		all;
11038c9fbc29Smrgchar			tbuf[32];
11048c9fbc29Smrg
11058c9fbc29Smrg    act= &action->msg;
11068c9fbc29Smrg    all= XkbSA_MessageOnPress|XkbSA_MessageOnRelease;
11078c9fbc29Smrg    TryCopyStr(buf,"report=",sz);
11088c9fbc29Smrg    if ((act->flags&all)==0)
11098c9fbc29Smrg	TryCopyStr(buf,"none",sz);
11108c9fbc29Smrg    else if ((act->flags&all)==all)
11118c9fbc29Smrg	TryCopyStr(buf,"all",sz);
11128c9fbc29Smrg    else if (act->flags&XkbSA_MessageOnPress)
11138c9fbc29Smrg	 TryCopyStr(buf,"KeyPress",sz);
11148c9fbc29Smrg    else TryCopyStr(buf,"KeyRelease",sz);
11158c9fbc29Smrg    sprintf(tbuf,",data[0]=0x%02x",act->message[0]); TryCopyStr(buf,tbuf,sz);
11168c9fbc29Smrg    sprintf(tbuf,",data[1]=0x%02x",act->message[1]); TryCopyStr(buf,tbuf,sz);
11178c9fbc29Smrg    sprintf(tbuf,",data[2]=0x%02x",act->message[2]); TryCopyStr(buf,tbuf,sz);
11188c9fbc29Smrg    sprintf(tbuf,",data[3]=0x%02x",act->message[3]); TryCopyStr(buf,tbuf,sz);
11198c9fbc29Smrg    sprintf(tbuf,",data[4]=0x%02x",act->message[4]); TryCopyStr(buf,tbuf,sz);
11208c9fbc29Smrg    sprintf(tbuf,",data[5]=0x%02x",act->message[5]); TryCopyStr(buf,tbuf,sz);
11218c9fbc29Smrg    return True;
11228c9fbc29Smrg}
11238c9fbc29Smrg
11248c9fbc29Smrgstatic Bool
11258c9fbc29SmrgCopyRedirectKeyArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
11268c9fbc29Smrg								int *sz)
11278c9fbc29Smrg{
11288c9fbc29SmrgXkbRedirectKeyAction *	act;
11298c9fbc29Smrgchar			tbuf[32],*tmp;
11308c9fbc29Smrgunsigned		kc;
11318c9fbc29Smrgunsigned		vmods,vmods_mask;
11328c9fbc29Smrg
11338c9fbc29Smrg    act= &action->redirect;
11348c9fbc29Smrg    kc= act->new_key;
11358c9fbc29Smrg    vmods= XkbSARedirectVMods(act);
11368c9fbc29Smrg    vmods_mask= XkbSARedirectVModsMask(act);
11378c9fbc29Smrg    if (xkb && xkb->names && xkb->names->keys && (kc<=xkb->max_key_code) &&
11388c9fbc29Smrg				(xkb->names->keys[kc].name[0]!='\0')) {
11398c9fbc29Smrg	char *kn;
11408c9fbc29Smrg	kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile);
11418c9fbc29Smrg	sprintf(tbuf,"key=%s",kn);
11428c9fbc29Smrg    }
11438c9fbc29Smrg    else sprintf(tbuf,"key=%d",kc);
11448c9fbc29Smrg    TryCopyStr(buf,tbuf,sz);
11458c9fbc29Smrg    if ((act->mods_mask==0)&&(vmods_mask==0))
11468c9fbc29Smrg	return True;
11478c9fbc29Smrg    if ((act->mods_mask==XkbAllModifiersMask)&&
11488c9fbc29Smrg	(vmods_mask==XkbAllVirtualModsMask)) {
11498c9fbc29Smrg	tmp= XkbVModMaskText(dpy,xkb,act->mods,vmods,XkbXKBFile);
11508c9fbc29Smrg	TryCopyStr(buf,",mods=",sz);
11518c9fbc29Smrg	TryCopyStr(buf,tmp,sz);
11528c9fbc29Smrg    }
11538c9fbc29Smrg    else {
11548c9fbc29Smrg	if ((act->mods_mask&act->mods)||(vmods_mask&vmods)) {
11558c9fbc29Smrg	    tmp= XkbVModMaskText(dpy,xkb,act->mods_mask&act->mods,
11568c9fbc29Smrg					 vmods_mask&vmods,XkbXKBFile);
11578c9fbc29Smrg	    TryCopyStr(buf,",mods= ",sz);
11588c9fbc29Smrg	    TryCopyStr(buf,tmp,sz);
11598c9fbc29Smrg	}
11608c9fbc29Smrg	if ((act->mods_mask&(~act->mods))||(vmods_mask&(~vmods))) {
11618c9fbc29Smrg	    tmp= XkbVModMaskText(dpy,xkb,act->mods_mask&(~act->mods),
11628c9fbc29Smrg					 vmods_mask&(~vmods),XkbXKBFile);
11638c9fbc29Smrg	    TryCopyStr(buf,",clearMods= ",sz);
11648c9fbc29Smrg	    TryCopyStr(buf,tmp,sz);
11658c9fbc29Smrg	}
11668c9fbc29Smrg    }
11678c9fbc29Smrg    return True;
11688c9fbc29Smrg}
11698c9fbc29Smrg
11708c9fbc29Smrg/*ARGSUSED*/
11718c9fbc29Smrgstatic Bool
11728c9fbc29SmrgCopyDeviceBtnArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
11738c9fbc29Smrg								int *sz)
11748c9fbc29Smrg{
11758c9fbc29SmrgXkbDeviceBtnAction *	act;
11768c9fbc29Smrgchar			tbuf[32];
11778c9fbc29Smrg
11788c9fbc29Smrg    act= &action->devbtn;
11798c9fbc29Smrg    sprintf(tbuf,"device= %d",act->device); TryCopyStr(buf,tbuf,sz);
11808c9fbc29Smrg    TryCopyStr(buf,",button=",sz);
11818c9fbc29Smrg    sprintf(tbuf,"%d",act->button);
11828c9fbc29Smrg    TryCopyStr(buf,tbuf,sz);
11838c9fbc29Smrg    if (act->count>0) {
11848c9fbc29Smrg	sprintf(tbuf,",count=%d",act->count);
11858c9fbc29Smrg	TryCopyStr(buf,tbuf,sz);
11868c9fbc29Smrg    }
11878c9fbc29Smrg    if (action->type==XkbSA_LockDeviceBtn) {
11888c9fbc29Smrg	switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) {
11898c9fbc29Smrg	    case XkbSA_LockNoLock:
11908c9fbc29Smrg		sprintf(tbuf,",affect=unlock"); break;
11918c9fbc29Smrg	    case XkbSA_LockNoUnlock:
11928c9fbc29Smrg		sprintf(tbuf,",affect=lock"); break;
11938c9fbc29Smrg	    case XkbSA_LockNoUnlock|XkbSA_LockNoLock:
11948c9fbc29Smrg		sprintf(tbuf,",affect=neither"); break;
11958c9fbc29Smrg	    default:
11968c9fbc29Smrg		sprintf(tbuf,",affect=both"); break;
11978c9fbc29Smrg	}
11988c9fbc29Smrg	TryCopyStr(buf,tbuf,sz);
11998c9fbc29Smrg    }
12008c9fbc29Smrg    return True;
12018c9fbc29Smrg}
12028c9fbc29Smrg
12038c9fbc29Smrg/*ARGSUSED*/
12048c9fbc29Smrgstatic Bool
12058c9fbc29SmrgCopyOtherArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
12068c9fbc29Smrg{
12078c9fbc29SmrgXkbAnyAction *	act;
12088c9fbc29Smrgchar		tbuf[32];
12098c9fbc29Smrg
12108c9fbc29Smrg    act= &action->any;
12118c9fbc29Smrg    sprintf(tbuf,"type=0x%02x",act->type); TryCopyStr(buf,tbuf,sz);
12128c9fbc29Smrg    sprintf(tbuf,",data[0]=0x%02x",act->data[0]); TryCopyStr(buf,tbuf,sz);
12138c9fbc29Smrg    sprintf(tbuf,",data[1]=0x%02x",act->data[1]); TryCopyStr(buf,tbuf,sz);
12148c9fbc29Smrg    sprintf(tbuf,",data[2]=0x%02x",act->data[2]); TryCopyStr(buf,tbuf,sz);
12158c9fbc29Smrg    sprintf(tbuf,",data[3]=0x%02x",act->data[3]); TryCopyStr(buf,tbuf,sz);
12168c9fbc29Smrg    sprintf(tbuf,",data[4]=0x%02x",act->data[4]); TryCopyStr(buf,tbuf,sz);
12178c9fbc29Smrg    sprintf(tbuf,",data[5]=0x%02x",act->data[5]); TryCopyStr(buf,tbuf,sz);
12188c9fbc29Smrg    sprintf(tbuf,",data[6]=0x%02x",act->data[6]); TryCopyStr(buf,tbuf,sz);
12198c9fbc29Smrg    return True;
12208c9fbc29Smrg}
12218c9fbc29Smrg
12228c9fbc29Smrgtypedef	Bool	(*actionCopy)(
12238c9fbc29Smrg	Display *	/* dpy */,
12248c9fbc29Smrg	XkbDescPtr 	/* xkb */,
12258c9fbc29Smrg	XkbAction *	/* action */,
12268c9fbc29Smrg	char *		/* buf */,
12278c9fbc29Smrg	int*		/* sz */
12288c9fbc29Smrg);
12298c9fbc29Smrgstatic actionCopy	copyActionArgs[XkbSA_NumActions] = {
12308c9fbc29Smrg	CopyNoActionArgs		/* NoAction	*/,
12318c9fbc29Smrg	CopyModActionArgs		/* SetMods	*/,
12328c9fbc29Smrg	CopyModActionArgs		/* LatchMods	*/,
12338c9fbc29Smrg	CopyModActionArgs		/* LockMods	*/,
12348c9fbc29Smrg	CopyGroupActionArgs		/* SetGroup	*/,
12358c9fbc29Smrg	CopyGroupActionArgs		/* LatchGroup	*/,
12368c9fbc29Smrg	CopyGroupActionArgs		/* LockGroup	*/,
12378c9fbc29Smrg	CopyMovePtrArgs			/* MovePtr	*/,
12388c9fbc29Smrg	CopyPtrBtnArgs			/* PtrBtn	*/,
12398c9fbc29Smrg	CopyPtrBtnArgs			/* LockPtrBtn	*/,
12408c9fbc29Smrg	CopySetPtrDfltArgs		/* SetPtrDflt	*/,
12418c9fbc29Smrg	CopyISOLockArgs			/* ISOLock	*/,
12428c9fbc29Smrg	CopyNoActionArgs		/* Terminate	*/,
12438c9fbc29Smrg	CopySwitchScreenArgs		/* SwitchScreen	*/,
12448c9fbc29Smrg	CopySetLockControlsArgs		/* SetControls	*/,
12458c9fbc29Smrg	CopySetLockControlsArgs		/* LockControls	*/,
12468c9fbc29Smrg	CopyActionMessageArgs		/* ActionMessage*/,
12478c9fbc29Smrg	CopyRedirectKeyArgs		/* RedirectKey	*/,
12488c9fbc29Smrg	CopyDeviceBtnArgs		/* DeviceBtn	*/,
12498c9fbc29Smrg	CopyDeviceBtnArgs		/* LockDeviceBtn*/
12508c9fbc29Smrg};
12518c9fbc29Smrg
12528c9fbc29Smrg#define	ACTION_SZ	256
12538c9fbc29Smrg
12548c9fbc29Smrgchar *
12558c9fbc29SmrgXkbActionText(Display *dpy,XkbDescPtr xkb,XkbAction *action,unsigned format)
12568c9fbc29Smrg{
12578c9fbc29Smrgchar	buf[ACTION_SZ],*tmp;
12588c9fbc29Smrgint	sz;
12598c9fbc29Smrg
12608c9fbc29Smrg    if (format==XkbCFile) {
12618c9fbc29Smrg	sprintf(buf,
12628c9fbc29Smrg	    "{ %20s, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x } }",
12638c9fbc29Smrg	    XkbActionTypeText(action->type,XkbCFile),
12648c9fbc29Smrg	    action->any.data[0],action->any.data[1],action->any.data[2],
12658c9fbc29Smrg	    action->any.data[3],action->any.data[4],action->any.data[5],
12668c9fbc29Smrg	    action->any.data[6]);
12678c9fbc29Smrg    }
12688c9fbc29Smrg    else {
12698c9fbc29Smrg	sprintf(buf,"%s(",XkbActionTypeText(action->type,XkbXKBFile));
12708c9fbc29Smrg	sz= ACTION_SZ-strlen(buf)+2; /* room for close paren and NULL */
12718c9fbc29Smrg	if (action->type<(unsigned)XkbSA_NumActions)
12728c9fbc29Smrg	     (*copyActionArgs[action->type])(dpy,xkb,action,buf,&sz);
12738c9fbc29Smrg	else CopyOtherArgs(dpy,xkb,action,buf,&sz);
12748c9fbc29Smrg	TryCopyStr(buf,")",&sz);
12758c9fbc29Smrg    }
12768c9fbc29Smrg    tmp= tbGetBuffer(strlen(buf)+1);
12778c9fbc29Smrg    if (tmp!=NULL)
12788c9fbc29Smrg	strcpy(tmp,buf);
12798c9fbc29Smrg    return tmp;
12808c9fbc29Smrg}
12818c9fbc29Smrg
12828c9fbc29Smrgchar *
12838c9fbc29SmrgXkbBehaviorText(XkbDescPtr xkb,XkbBehavior *behavior,unsigned format)
12848c9fbc29Smrg{
12858c9fbc29Smrgchar	buf[256],*tmp;
12868c9fbc29Smrg
12878c9fbc29Smrg    if (format==XkbCFile) {
12888c9fbc29Smrg	if (behavior->type==XkbKB_Default)
12898c9fbc29Smrg	     sprintf(buf,"{   0,    0 }");
12908c9fbc29Smrg	else sprintf(buf,"{ %3d, 0x%02x }",behavior->type,behavior->data);
12918c9fbc29Smrg    }
12928c9fbc29Smrg    else {
12938c9fbc29Smrg	unsigned 	type,permanent;
12948c9fbc29Smrg	type= behavior->type&XkbKB_OpMask;
12958c9fbc29Smrg	permanent=((behavior->type&XkbKB_Permanent)!=0);
12968c9fbc29Smrg
12978c9fbc29Smrg	if (type==XkbKB_Lock) {
12988c9fbc29Smrg	    sprintf(buf,"lock= %s",(permanent?"Permanent":"True"));
12998c9fbc29Smrg	}
13008c9fbc29Smrg	else if (type==XkbKB_RadioGroup) {
13018c9fbc29Smrg	    int 	g;
13028c9fbc29Smrg	    char	*tmp;
13038c9fbc29Smrg	    g= ((behavior->data)&(~XkbKB_RGAllowNone))+1;
13048c9fbc29Smrg	    if (XkbKB_RGAllowNone&behavior->data) {
13058c9fbc29Smrg		sprintf(buf,"allowNone,");
13068c9fbc29Smrg		tmp= &buf[strlen(buf)];
13078c9fbc29Smrg	    }
13088c9fbc29Smrg	    else tmp= buf;
13098c9fbc29Smrg	    if (permanent)
13108c9fbc29Smrg		 sprintf(tmp,"permanentRadioGroup= %d",g);
13118c9fbc29Smrg	    else sprintf(tmp,"radioGroup= %d",g);
13128c9fbc29Smrg	}
13138c9fbc29Smrg	else if ((type==XkbKB_Overlay1)||(type==XkbKB_Overlay2)) {
13148c9fbc29Smrg	    int ndx,kc;
13158c9fbc29Smrg	    char *kn;
13168c9fbc29Smrg
13178c9fbc29Smrg	    ndx= ((type==XkbKB_Overlay1)?1:2);
13188c9fbc29Smrg	    kc= behavior->data;
13198c9fbc29Smrg	    if ((xkb)&&(xkb->names)&&(xkb->names->keys))
13208c9fbc29Smrg		kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile);
13218c9fbc29Smrg	    else {
13228c9fbc29Smrg		static char tbuf[8];
13238c9fbc29Smrg		sprintf(tbuf,"%d",kc);
13248c9fbc29Smrg		kn= tbuf;
13258c9fbc29Smrg	    }
13268c9fbc29Smrg	    if (permanent)
13278c9fbc29Smrg		 sprintf(buf,"permanentOverlay%d= %s",ndx,kn);
13288c9fbc29Smrg	    else sprintf(buf,"overlay%d= %s",ndx,kn);
13298c9fbc29Smrg	}
13308c9fbc29Smrg    }
13318c9fbc29Smrg    tmp= tbGetBuffer(strlen(buf)+1);
13328c9fbc29Smrg    if (tmp!=NULL)
13338c9fbc29Smrg	strcpy(tmp,buf);
13348c9fbc29Smrg    return tmp;
13358c9fbc29Smrg}
13368c9fbc29Smrg
13378c9fbc29Smrg/***====================================================================***/
13388c9fbc29Smrg
13398c9fbc29Smrgchar *
13408c9fbc29SmrgXkbIndentText(unsigned size)
13418c9fbc29Smrg{
13428c9fbc29Smrgstatic char buf[32];
13438c9fbc29Smrgregister int i;
13448c9fbc29Smrg
13458c9fbc29Smrg    if (size>31)
13468c9fbc29Smrg	size= 31;
13478c9fbc29Smrg
13488c9fbc29Smrg    for (i=0;i<size;i++) {
13498c9fbc29Smrg	buf[i]= ' ';
13508c9fbc29Smrg    }
13518c9fbc29Smrg    buf[size]= '\0';
13528c9fbc29Smrg    return buf;
13538c9fbc29Smrg}
13548c9fbc29Smrg
13558c9fbc29Smrg#ifndef XKB_IN_SERVER
13568c9fbc29Smrg
13578c9fbc29Smrg/***====================================================================***/
13588c9fbc29Smrg
13598c9fbc29Smrg#define	PIXEL_MAX	65535
13608c9fbc29Smrg
13618c9fbc29SmrgBool
13628c9fbc29SmrgXkbLookupCanonicalRGBColor(char *def,XColor *color)
13638c9fbc29Smrg{
13648c9fbc29Smrgint     tmp;
13658c9fbc29Smrg
13668c9fbc29Smrg    if (_XkbStrCaseEqual(def,"black")) {
13678c9fbc29Smrg	color->red= color->green= color->blue= 0;
13688c9fbc29Smrg	return True;
13698c9fbc29Smrg    }
13708c9fbc29Smrg    else if (_XkbStrCaseEqual(def,"white")) {
13718c9fbc29Smrg	color->red= color->green= color->blue= PIXEL_MAX;
13728c9fbc29Smrg	return True;
13738c9fbc29Smrg    }
13748c9fbc29Smrg    else if ((sscanf(def,"grey%d",&tmp)==1)||
13758c9fbc29Smrg        (sscanf(def,"gray%d",&tmp)==1)||
13768c9fbc29Smrg        (sscanf(def,"Grey%d",&tmp)==1)||
13778c9fbc29Smrg        (sscanf(def,"Gray%d",&tmp)==1)) {
13788c9fbc29Smrg	if ((tmp>0)&&(tmp<=100)) {
13798c9fbc29Smrg	    tmp= (PIXEL_MAX*tmp)/100;
13808c9fbc29Smrg	    color->red= color->green= color->blue= tmp;
13818c9fbc29Smrg	    return True;
13828c9fbc29Smrg	}
13838c9fbc29Smrg    }
13848c9fbc29Smrg    else if ((tmp=(_XkbStrCaseEqual(def,"red")*100))||
13858c9fbc29Smrg             (sscanf(def,"red%d",&tmp)==1)) {
13868c9fbc29Smrg	if ((tmp>0)&&(tmp<=100)) {
13878c9fbc29Smrg	    tmp= (PIXEL_MAX*tmp)/100;
13888c9fbc29Smrg	    color->red= tmp;
13898c9fbc29Smrg	    color->green= color->blue= 0;
13908c9fbc29Smrg	    return True;
13918c9fbc29Smrg	}
13928c9fbc29Smrg    }
13938c9fbc29Smrg    else if ((tmp=(_XkbStrCaseEqual(def,"green")*100))||
13948c9fbc29Smrg             (sscanf(def,"green%d",&tmp)==1)) {
13958c9fbc29Smrg	if ((tmp>0)&&(tmp<=100)) {
13968c9fbc29Smrg	    tmp= (PIXEL_MAX*tmp)/100;
13978c9fbc29Smrg	    color->green= tmp;
13988c9fbc29Smrg	    color->red= color->blue= 0;
13998c9fbc29Smrg	    return True;
14008c9fbc29Smrg	}
14018c9fbc29Smrg    }
14028c9fbc29Smrg    else if ((tmp=(_XkbStrCaseEqual(def,"blue")*100))||
14038c9fbc29Smrg             (sscanf(def,"blue%d",&tmp)==1)) {
14048c9fbc29Smrg	if ((tmp>0)&&(tmp<=100)) {
14058c9fbc29Smrg	    tmp= (PIXEL_MAX*tmp)/100;
14068c9fbc29Smrg	    color->blue= tmp;
14078c9fbc29Smrg	    color->red= color->green= 0;
14088c9fbc29Smrg	    return True;
14098c9fbc29Smrg	}
14108c9fbc29Smrg    }
14118c9fbc29Smrg    else if ((tmp=(_XkbStrCaseEqual(def,"magenta")*100))||
14128c9fbc29Smrg             (sscanf(def,"magenta%d",&tmp)==1)) {
14138c9fbc29Smrg	if ((tmp>0)&&(tmp<=100)) {
14148c9fbc29Smrg	    tmp= (PIXEL_MAX*tmp)/100;
14158c9fbc29Smrg	    color->green= 0;
14168c9fbc29Smrg	    color->red= color->blue= tmp;
14178c9fbc29Smrg	    return True;
14188c9fbc29Smrg	}
14198c9fbc29Smrg    }
14208c9fbc29Smrg    else if ((tmp=(_XkbStrCaseEqual(def,"cyan")*100))||
14218c9fbc29Smrg             (sscanf(def,"cyan%d",&tmp)==1)) {
14228c9fbc29Smrg	if ((tmp>0)&&(tmp<=100)) {
14238c9fbc29Smrg	    tmp= (PIXEL_MAX*tmp)/100;
14248c9fbc29Smrg	    color->red= 0;
14258c9fbc29Smrg	    color->green= color->blue= tmp;
14268c9fbc29Smrg	    return True;
14278c9fbc29Smrg	}
14288c9fbc29Smrg    }
14298c9fbc29Smrg    else if ((tmp=(_XkbStrCaseEqual(def,"yellow")*100))||
14308c9fbc29Smrg             (sscanf(def,"yellow%d",&tmp)==1)) {
14318c9fbc29Smrg	if ((tmp>0)&&(tmp<=100)) {
14328c9fbc29Smrg	    tmp= (PIXEL_MAX*tmp)/100;
14338c9fbc29Smrg	    color->blue= 0;
14348c9fbc29Smrg	    color->red= color->green= tmp;
14358c9fbc29Smrg	    return True;
14368c9fbc29Smrg	}
14378c9fbc29Smrg    }
14388c9fbc29Smrg    return False;
14398c9fbc29Smrg}
14408c9fbc29Smrg
14418c9fbc29Smrg#endif
1442