xkbtext.c revision 6747b715
105b261ecSmrg/************************************************************
205b261ecSmrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
305b261ecSmrg
405b261ecSmrg Permission to use, copy, modify, and distribute this
505b261ecSmrg software and its documentation for any purpose and without
605b261ecSmrg fee is hereby granted, provided that the above copyright
705b261ecSmrg notice appear in all copies and that both that copyright
805b261ecSmrg notice and this permission notice appear in supporting
905b261ecSmrg documentation, and that the name of Silicon Graphics not be
1005b261ecSmrg used in advertising or publicity pertaining to distribution
1105b261ecSmrg of the software without specific prior written permission.
1205b261ecSmrg Silicon Graphics makes no representation about the suitability
1305b261ecSmrg of this software for any purpose. It is provided "as is"
1405b261ecSmrg without any express or implied warranty.
1505b261ecSmrg
1605b261ecSmrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
1705b261ecSmrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1805b261ecSmrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
1905b261ecSmrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
2005b261ecSmrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
2105b261ecSmrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
2205b261ecSmrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
2305b261ecSmrg THE USE OR PERFORMANCE OF THIS SOFTWARE.
2405b261ecSmrg
2505b261ecSmrg ********************************************************/
2605b261ecSmrg
2705b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
2805b261ecSmrg#include <dix-config.h>
2905b261ecSmrg#endif
3005b261ecSmrg
3105b261ecSmrg#include <stdio.h>
3205b261ecSmrg#include <ctype.h>
3305b261ecSmrg#include <stdlib.h>
3405b261ecSmrg
3505b261ecSmrg#include <X11/Xos.h>
3605b261ecSmrg
3705b261ecSmrg#include <X11/X.h>
3805b261ecSmrg#include <X11/Xproto.h>
396747b715Smrg#include <X11/extensions/XKMformat.h>
4005b261ecSmrg#include "misc.h"
4105b261ecSmrg#include "inputstr.h"
4205b261ecSmrg#include "dix.h"
434642e01fSmrg#include "xkbstr.h"
4405b261ecSmrg#define XKBSRV_NEED_FILE_FUNCS	1
4505b261ecSmrg#include <xkbsrv.h>
464642e01fSmrg#include "xkbgeom.h"
4705b261ecSmrg
4805b261ecSmrg/***====================================================================***/
4905b261ecSmrg
5005b261ecSmrg#define	BUFFER_SIZE	512
5105b261ecSmrg
5205b261ecSmrgstatic char textBuffer[BUFFER_SIZE];
5305b261ecSmrgstatic int  tbNext= 0;
5405b261ecSmrg
5505b261ecSmrgstatic char *
5605b261ecSmrgtbGetBuffer(unsigned size)
5705b261ecSmrg{
5805b261ecSmrgchar *rtrn;
5905b261ecSmrg
6005b261ecSmrg    if (size>=BUFFER_SIZE)
6105b261ecSmrg	return NULL;
6205b261ecSmrg    if ((BUFFER_SIZE-tbNext)<=size)
6305b261ecSmrg	tbNext= 0;
6405b261ecSmrg    rtrn= &textBuffer[tbNext];
6505b261ecSmrg    tbNext+= size;
6605b261ecSmrg    return rtrn;
6705b261ecSmrg}
6805b261ecSmrg
6905b261ecSmrg/***====================================================================***/
7005b261ecSmrg
7105b261ecSmrgchar *
724642e01fSmrgXkbAtomText(Atom atm,unsigned format)
7305b261ecSmrg{
746747b715Smrgconst char	*atmstr;
7505b261ecSmrgchar	*rtrn,*tmp;
7605b261ecSmrg
776747b715Smrg    atmstr = NameForAtom(atm);
786747b715Smrg    if (atmstr != NULL) {
7905b261ecSmrg	int	len;
806747b715Smrg	len= strlen(atmstr)+1;
8105b261ecSmrg	if (len>BUFFER_SIZE)
8205b261ecSmrg	    len= BUFFER_SIZE-2;
8305b261ecSmrg	rtrn= tbGetBuffer(len);
846747b715Smrg	strncpy(rtrn,atmstr,len);
8505b261ecSmrg	rtrn[len]= '\0';
8605b261ecSmrg    }
8705b261ecSmrg    else {
8805b261ecSmrg	rtrn= tbGetBuffer(1);
8905b261ecSmrg	rtrn[0]= '\0';
9005b261ecSmrg    }
9105b261ecSmrg    if (format==XkbCFile) {
9205b261ecSmrg	for (tmp=rtrn;*tmp!='\0';tmp++) {
9305b261ecSmrg	    if ((tmp==rtrn)&&(!isalpha(*tmp)))
9405b261ecSmrg		*tmp= '_';
9505b261ecSmrg	    else if (!isalnum(*tmp))
9605b261ecSmrg		*tmp= '_';
9705b261ecSmrg	}
9805b261ecSmrg    }
9905b261ecSmrg    return XkbStringText(rtrn,format);
10005b261ecSmrg}
10105b261ecSmrg
10205b261ecSmrg/***====================================================================***/
10305b261ecSmrg
10405b261ecSmrgchar *
1054642e01fSmrgXkbVModIndexText(XkbDescPtr xkb,unsigned ndx,unsigned format)
10605b261ecSmrg{
10705b261ecSmrgregister int len;
10805b261ecSmrgregister Atom *vmodNames;
1096747b715Smrgchar *rtrn;
1106747b715Smrgconst char *tmp;
11105b261ecSmrgchar  numBuf[20];
11205b261ecSmrg
11305b261ecSmrg    if (xkb && xkb->names)
11405b261ecSmrg	 vmodNames= xkb->names->vmods;
11505b261ecSmrg    else vmodNames= NULL;
11605b261ecSmrg
11705b261ecSmrg    tmp= NULL;
11805b261ecSmrg    if (ndx>=XkbNumVirtualMods)
11905b261ecSmrg	 tmp= "illegal";
12005b261ecSmrg    else if (vmodNames&&(vmodNames[ndx]!=None))
1216747b715Smrg	 tmp= NameForAtom(vmodNames[ndx]);
1226747b715Smrg    if (tmp==NULL) {
1236747b715Smrg	sprintf(numBuf,"%d",ndx);
1246747b715Smrg	tmp = numBuf;
1256747b715Smrg    }
12605b261ecSmrg
12705b261ecSmrg    len= strlen(tmp)+1;
12805b261ecSmrg    if (format==XkbCFile)
12905b261ecSmrg	len+= 4;
13005b261ecSmrg    if (len>=BUFFER_SIZE)
13105b261ecSmrg	len= BUFFER_SIZE-1;
13205b261ecSmrg    rtrn= tbGetBuffer(len);
13305b261ecSmrg    if (format==XkbCFile) {
13405b261ecSmrg	 strcpy(rtrn,"vmod_");
13505b261ecSmrg	 strncpy(&rtrn[5],tmp,len-4);
13605b261ecSmrg    }
13705b261ecSmrg    else strncpy(rtrn,tmp,len);
13805b261ecSmrg    return rtrn;
13905b261ecSmrg}
14005b261ecSmrg
14105b261ecSmrgchar *
1424642e01fSmrgXkbVModMaskText(        XkbDescPtr	xkb,
14305b261ecSmrg			unsigned	modMask,
14405b261ecSmrg			unsigned	mask,
14505b261ecSmrg			unsigned	format)
14605b261ecSmrg{
14705b261ecSmrgregister int i,bit;
14805b261ecSmrgint	 len;
14905b261ecSmrgchar *mm,*rtrn;
15005b261ecSmrgchar *str,buf[BUFFER_SIZE];
15105b261ecSmrg
15205b261ecSmrg    if ((modMask==0)&&(mask==0)) {
15305b261ecSmrg	rtrn= tbGetBuffer(5);
15405b261ecSmrg	if (format==XkbCFile)
15505b261ecSmrg	     sprintf(rtrn,"0");
15605b261ecSmrg	else sprintf(rtrn,"none");
15705b261ecSmrg	return rtrn;
15805b261ecSmrg    }
15905b261ecSmrg    if (modMask!=0)
16005b261ecSmrg	 mm= XkbModMaskText(modMask,format);
16105b261ecSmrg    else mm= NULL;
16205b261ecSmrg
16305b261ecSmrg    str= buf;
16405b261ecSmrg    buf[0]= '\0';
16505b261ecSmrg    if (mask) {
16605b261ecSmrg	char *tmp;
16705b261ecSmrg	for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
16805b261ecSmrg	    if (mask&bit) {
1694642e01fSmrg		tmp= XkbVModIndexText(xkb,i,format);
17005b261ecSmrg		len= strlen(tmp)+1+(str==buf?0:1);
17105b261ecSmrg		if (format==XkbCFile)
17205b261ecSmrg		    len+= 4;
17305b261ecSmrg		if ((str-(buf+len))<=BUFFER_SIZE) {
17405b261ecSmrg		    if (str!=buf) {
17505b261ecSmrg			if (format==XkbCFile)	*str++= '|';
17605b261ecSmrg			else			*str++= '+';
17705b261ecSmrg			len--;
17805b261ecSmrg		    }
17905b261ecSmrg		}
18005b261ecSmrg		if (format==XkbCFile)
18105b261ecSmrg		     sprintf(str,"%sMask",tmp);
18205b261ecSmrg		else strcpy(str,tmp);
18305b261ecSmrg		str= &str[len-1];
18405b261ecSmrg	    }
18505b261ecSmrg	}
18605b261ecSmrg	str= buf;
18705b261ecSmrg    }
18805b261ecSmrg    else str= NULL;
18905b261ecSmrg    if (mm)
19005b261ecSmrg	len= strlen(mm);
19105b261ecSmrg    else	len= 0;
19205b261ecSmrg    if (str)
19305b261ecSmrg	len+= strlen(str)+(mm==NULL?0:1);
19405b261ecSmrg    if (len>=BUFFER_SIZE)
19505b261ecSmrg	len= BUFFER_SIZE-1;
19605b261ecSmrg    rtrn= tbGetBuffer(len+1);
19705b261ecSmrg    rtrn[0]= '\0';
19805b261ecSmrg
19905b261ecSmrg    if (mm!=NULL) {
20005b261ecSmrg	i= strlen(mm);
20105b261ecSmrg	if (i>len)
20205b261ecSmrg	    i= len;
20305b261ecSmrg	strcpy(rtrn,mm);
20405b261ecSmrg    }
20505b261ecSmrg    else {
20605b261ecSmrg	i=0;
20705b261ecSmrg    }
20805b261ecSmrg    if (str!=NULL) {
20905b261ecSmrg	if (mm!=NULL) {
21005b261ecSmrg	    if (format==XkbCFile)	strcat(rtrn,"|");
21105b261ecSmrg	    else			strcat(rtrn,"+");
21205b261ecSmrg	}
21305b261ecSmrg	strncat(rtrn,str,len-i);
21405b261ecSmrg    }
21505b261ecSmrg    rtrn[len]= '\0';
21605b261ecSmrg    return rtrn;
21705b261ecSmrg}
21805b261ecSmrg
21905b261ecSmrgstatic char *modNames[XkbNumModifiers] = {
22005b261ecSmrg    "Shift", "Lock", "Control", "Mod1", "Mod2", "Mod3", "Mod4", "Mod5"
22105b261ecSmrg};
22205b261ecSmrg
22305b261ecSmrgchar *
22405b261ecSmrgXkbModIndexText(unsigned ndx,unsigned format)
22505b261ecSmrg{
22605b261ecSmrgchar *	rtrn;
22705b261ecSmrgchar	buf[100];
22805b261ecSmrg
22905b261ecSmrg    if (format==XkbCFile) {
23005b261ecSmrg	if (ndx<XkbNumModifiers)
23105b261ecSmrg	     sprintf(buf,"%sMapIndex",modNames[ndx]);
23205b261ecSmrg	else if (ndx==XkbNoModifier)
23305b261ecSmrg	     sprintf(buf,"XkbNoModifier");
23405b261ecSmrg	else sprintf(buf,"0x%02x",ndx);
23505b261ecSmrg    }
23605b261ecSmrg    else {
23705b261ecSmrg	if (ndx<XkbNumModifiers)
23805b261ecSmrg	     strcpy(buf,modNames[ndx]);
23905b261ecSmrg	else if (ndx==XkbNoModifier)
24005b261ecSmrg	     strcpy(buf,"none");
24105b261ecSmrg	else sprintf(buf,"ILLEGAL_%02x",ndx);
24205b261ecSmrg    }
24305b261ecSmrg    rtrn= tbGetBuffer(strlen(buf)+1);
24405b261ecSmrg    strcpy(rtrn,buf);
24505b261ecSmrg    return rtrn;
24605b261ecSmrg}
24705b261ecSmrg
24805b261ecSmrgchar *
24905b261ecSmrgXkbModMaskText(unsigned mask,unsigned format)
25005b261ecSmrg{
25105b261ecSmrgregister int i,bit;
25205b261ecSmrgchar buf[64],*rtrn;
25305b261ecSmrg
25405b261ecSmrg    if ((mask&0xff)==0xff) {
25505b261ecSmrg	if (format==XkbCFile) 		strcpy(buf,"0xff");
25605b261ecSmrg	else				strcpy(buf,"all");
25705b261ecSmrg    }
25805b261ecSmrg    else if ((mask&0xff)==0) {
25905b261ecSmrg	if (format==XkbCFile)		strcpy(buf,"0");
26005b261ecSmrg	else				strcpy(buf,"none");
26105b261ecSmrg    }
26205b261ecSmrg    else {
26305b261ecSmrg	char *str= buf;
26405b261ecSmrg	buf[0]= '\0';
26505b261ecSmrg	for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) {
26605b261ecSmrg	    if (mask&bit) {
26705b261ecSmrg		if (str!=buf) {
26805b261ecSmrg		    if (format==XkbCFile)	*str++= '|';
26905b261ecSmrg		    else			*str++= '+';
27005b261ecSmrg		}
27105b261ecSmrg		strcpy(str,modNames[i]);
27205b261ecSmrg		str= &str[strlen(str)];
27305b261ecSmrg		if (format==XkbCFile) {
27405b261ecSmrg		    strcpy(str,"Mask");
27505b261ecSmrg		    str+= 4;
27605b261ecSmrg		}
27705b261ecSmrg	    }
27805b261ecSmrg	}
27905b261ecSmrg    }
28005b261ecSmrg    rtrn= tbGetBuffer(strlen(buf)+1);
28105b261ecSmrg    strcpy(rtrn,buf);
28205b261ecSmrg    return rtrn;
28305b261ecSmrg}
28405b261ecSmrg
28505b261ecSmrg/***====================================================================***/
28605b261ecSmrg
28705b261ecSmrg/*ARGSUSED*/
28805b261ecSmrgchar *
28905b261ecSmrgXkbConfigText(unsigned config,unsigned format)
29005b261ecSmrg{
29105b261ecSmrgstatic char *buf;
29205b261ecSmrg
29305b261ecSmrg    buf= tbGetBuffer(32);
29405b261ecSmrg    switch (config) {
29505b261ecSmrg	case XkmSemanticsFile:
29605b261ecSmrg	    strcpy(buf,"Semantics");
29705b261ecSmrg	    break;
29805b261ecSmrg	case XkmLayoutFile:
29905b261ecSmrg	    strcpy(buf,"Layout");
30005b261ecSmrg	    break;
30105b261ecSmrg	case XkmKeymapFile:
30205b261ecSmrg	    strcpy(buf,"Keymap");
30305b261ecSmrg	    break;
30405b261ecSmrg	case XkmGeometryFile:
30505b261ecSmrg	case XkmGeometryIndex:
30605b261ecSmrg	    strcpy(buf,"Geometry");
30705b261ecSmrg	    break;
30805b261ecSmrg	case XkmTypesIndex:
30905b261ecSmrg	    strcpy(buf,"Types");
31005b261ecSmrg	    break;
31105b261ecSmrg	case XkmCompatMapIndex:
31205b261ecSmrg	    strcpy(buf,"CompatMap");
31305b261ecSmrg	    break;
31405b261ecSmrg	case XkmSymbolsIndex:
31505b261ecSmrg	    strcpy(buf,"Symbols");
31605b261ecSmrg	    break;
31705b261ecSmrg	case XkmIndicatorsIndex:
31805b261ecSmrg	    strcpy(buf,"Indicators");
31905b261ecSmrg	    break;
32005b261ecSmrg	case XkmKeyNamesIndex:
32105b261ecSmrg	    strcpy(buf,"KeyNames");
32205b261ecSmrg	    break;
32305b261ecSmrg	case XkmVirtualModsIndex:
32405b261ecSmrg	    strcpy(buf,"VirtualMods");
32505b261ecSmrg	    break;
32605b261ecSmrg	default:
32705b261ecSmrg	    sprintf(buf,"unknown(%d)",config);
32805b261ecSmrg	    break;
32905b261ecSmrg    }
33005b261ecSmrg    return buf;
33105b261ecSmrg}
33205b261ecSmrg
33305b261ecSmrg/***====================================================================***/
33405b261ecSmrg
33505b261ecSmrgchar *
33605b261ecSmrgXkbKeysymText(KeySym sym,unsigned format)
33705b261ecSmrg{
33805b261ecSmrgstatic char buf[32],*rtrn;
33905b261ecSmrg
34005b261ecSmrg    if (sym==NoSymbol)
34105b261ecSmrg	 strcpy(rtrn=buf,"NoSymbol");
34205b261ecSmrg    else sprintf(rtrn=buf, "0x%lx", (long)sym);
34305b261ecSmrg    return rtrn;
34405b261ecSmrg}
34505b261ecSmrg
34605b261ecSmrgchar *
34705b261ecSmrgXkbKeyNameText(char *name,unsigned format)
34805b261ecSmrg{
34905b261ecSmrgchar *buf;
35005b261ecSmrg
35105b261ecSmrg    if (format==XkbCFile) {
35205b261ecSmrg	buf= tbGetBuffer(5);
35305b261ecSmrg	memcpy(buf,name,4);
35405b261ecSmrg	buf[4]= '\0';
35505b261ecSmrg    }
35605b261ecSmrg    else {
35705b261ecSmrg	int len;
35805b261ecSmrg	buf= tbGetBuffer(7);
35905b261ecSmrg	buf[0]= '<';
36005b261ecSmrg	memcpy(&buf[1],name,4);
36105b261ecSmrg	buf[5]= '\0';
36205b261ecSmrg	len= strlen(buf);
36305b261ecSmrg	buf[len++]= '>';
36405b261ecSmrg	buf[len]= '\0';
36505b261ecSmrg    }
36605b261ecSmrg    return buf;
36705b261ecSmrg}
36805b261ecSmrg
36905b261ecSmrg/***====================================================================***/
37005b261ecSmrg
37105b261ecSmrgstatic char *siMatchText[5] = {
37205b261ecSmrg	"NoneOf", "AnyOfOrNone", "AnyOf", "AllOf", "Exactly"
37305b261ecSmrg};
37405b261ecSmrg
37505b261ecSmrgchar *
37605b261ecSmrgXkbSIMatchText(unsigned type,unsigned format)
37705b261ecSmrg{
37805b261ecSmrgstatic char buf[40];
37905b261ecSmrgchar *rtrn;
38005b261ecSmrg
38105b261ecSmrg    switch (type&XkbSI_OpMask) {
38205b261ecSmrg	case XkbSI_NoneOf:	rtrn= siMatchText[0]; break;
38305b261ecSmrg	case XkbSI_AnyOfOrNone:	rtrn= siMatchText[1]; break;
38405b261ecSmrg	case XkbSI_AnyOf:	rtrn= siMatchText[2]; break;
38505b261ecSmrg	case XkbSI_AllOf:	rtrn= siMatchText[3]; break;
38605b261ecSmrg	case XkbSI_Exactly:	rtrn= siMatchText[4]; break;
38705b261ecSmrg	default:		sprintf(buf,"0x%x",type&XkbSI_OpMask);
38805b261ecSmrg				return buf;
38905b261ecSmrg    }
39005b261ecSmrg    if (format==XkbCFile) {
39105b261ecSmrg	if (type&XkbSI_LevelOneOnly)
39205b261ecSmrg	     sprintf(buf,"XkbSI_LevelOneOnly|XkbSI_%s",rtrn);
39305b261ecSmrg	else sprintf(buf,"XkbSI_%s",rtrn);
39405b261ecSmrg	rtrn= buf;
39505b261ecSmrg    }
39605b261ecSmrg    return rtrn;
39705b261ecSmrg}
39805b261ecSmrg
39905b261ecSmrg/***====================================================================***/
40005b261ecSmrg
40105b261ecSmrgstatic char *imWhichNames[]= {
40205b261ecSmrg	"base",
40305b261ecSmrg	"latched",
40405b261ecSmrg	"locked",
40505b261ecSmrg	"effective",
40605b261ecSmrg	"compat"
40705b261ecSmrg};
40805b261ecSmrg
40905b261ecSmrgchar *
41005b261ecSmrgXkbIMWhichStateMaskText(unsigned use_which,unsigned format)
41105b261ecSmrg{
41205b261ecSmrgint		len;
41305b261ecSmrgunsigned	i,bit,tmp;
41405b261ecSmrgchar *		buf;
41505b261ecSmrg
41605b261ecSmrg    if (use_which==0) {
41705b261ecSmrg	buf= tbGetBuffer(2);
41805b261ecSmrg	strcpy(buf,"0");
41905b261ecSmrg	return buf;
42005b261ecSmrg    }
42105b261ecSmrg    tmp= use_which&XkbIM_UseAnyMods;
42205b261ecSmrg    for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
42305b261ecSmrg	if (tmp&bit) {
42405b261ecSmrg	    tmp&= ~bit;
42505b261ecSmrg	    len+= strlen(imWhichNames[i])+1;
42605b261ecSmrg	    if (format==XkbCFile)
42705b261ecSmrg		len+= 9;
42805b261ecSmrg	}
42905b261ecSmrg    }
43005b261ecSmrg    buf= tbGetBuffer(len+1);
43105b261ecSmrg    tmp= use_which&XkbIM_UseAnyMods;
43205b261ecSmrg    for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
43305b261ecSmrg	if (tmp&bit) {
43405b261ecSmrg	    tmp&= ~bit;
43505b261ecSmrg	    if (format==XkbCFile) {
43605b261ecSmrg		if (len!=0)
43705b261ecSmrg		    buf[len++]= '|';
43805b261ecSmrg		sprintf(&buf[len],"XkbIM_Use%s",imWhichNames[i]);
43905b261ecSmrg		buf[len+9]= toupper(buf[len+9]);
44005b261ecSmrg	    }
44105b261ecSmrg	    else {
44205b261ecSmrg		if (len!=0)
44305b261ecSmrg		    buf[len++]= '+';
44405b261ecSmrg		sprintf(&buf[len],"%s",imWhichNames[i]);
44505b261ecSmrg	    }
44605b261ecSmrg	    len+= strlen(&buf[len]);
44705b261ecSmrg	}
44805b261ecSmrg    }
44905b261ecSmrg    return buf;
45005b261ecSmrg}
45105b261ecSmrg
45205b261ecSmrgstatic char *ctrlNames[] = {
45305b261ecSmrg	"repeatKeys",
45405b261ecSmrg	"slowKeys",
45505b261ecSmrg	"bounceKeys",
45605b261ecSmrg	"stickyKeys",
45705b261ecSmrg	"mouseKeys",
45805b261ecSmrg	"mouseKeysAccel",
45905b261ecSmrg	"accessXKeys",
46005b261ecSmrg	"accessXTimeout",
46105b261ecSmrg	"accessXFeedback",
46205b261ecSmrg	"audibleBell",
46305b261ecSmrg	"overlay1",
46405b261ecSmrg	"overlay2",
46505b261ecSmrg	"ignoreGroupLock"
46605b261ecSmrg};
46705b261ecSmrg
46805b261ecSmrgchar *
46905b261ecSmrgXkbControlsMaskText(unsigned ctrls,unsigned format)
47005b261ecSmrg{
47105b261ecSmrgint		len;
47205b261ecSmrgunsigned	i,bit,tmp;
47305b261ecSmrgchar *		buf;
47405b261ecSmrg
47505b261ecSmrg    if (ctrls==0) {
47605b261ecSmrg	buf= tbGetBuffer(5);
47705b261ecSmrg	if (format==XkbCFile)
47805b261ecSmrg	     strcpy(buf,"0");
47905b261ecSmrg	else strcpy(buf,"none");
48005b261ecSmrg	return buf;
48105b261ecSmrg    }
48205b261ecSmrg    tmp= ctrls&XkbAllBooleanCtrlsMask;
48305b261ecSmrg    for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
48405b261ecSmrg	if (tmp&bit) {
48505b261ecSmrg	    tmp&= ~bit;
48605b261ecSmrg	    len+= strlen(ctrlNames[i])+1;
48705b261ecSmrg	    if (format==XkbCFile)
48805b261ecSmrg		len+= 7;
48905b261ecSmrg	}
49005b261ecSmrg    }
49105b261ecSmrg    buf= tbGetBuffer(len+1);
49205b261ecSmrg    tmp= ctrls&XkbAllBooleanCtrlsMask;
49305b261ecSmrg    for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
49405b261ecSmrg	if (tmp&bit) {
49505b261ecSmrg	    tmp&= ~bit;
49605b261ecSmrg	    if (format==XkbCFile) {
49705b261ecSmrg		if (len!=0)
49805b261ecSmrg		    buf[len++]= '|';
49905b261ecSmrg		sprintf(&buf[len],"Xkb%sMask",ctrlNames[i]);
50005b261ecSmrg		buf[len+3]= toupper(buf[len+3]);
50105b261ecSmrg	    }
50205b261ecSmrg	    else {
50305b261ecSmrg		if (len!=0)
50405b261ecSmrg		    buf[len++]= '+';
50505b261ecSmrg		sprintf(&buf[len],"%s",ctrlNames[i]);
50605b261ecSmrg	    }
50705b261ecSmrg	    len+= strlen(&buf[len]);
50805b261ecSmrg	}
50905b261ecSmrg    }
51005b261ecSmrg    return buf;
51105b261ecSmrg}
51205b261ecSmrg
51305b261ecSmrg/***====================================================================***/
51405b261ecSmrg
51505b261ecSmrgchar *
51605b261ecSmrgXkbStringText(char *str,unsigned format)
51705b261ecSmrg{
51805b261ecSmrgchar *	buf;
51905b261ecSmrgregister char *in,*out;
52005b261ecSmrgint	len;
52105b261ecSmrgBool	ok;
52205b261ecSmrg
52305b261ecSmrg    if (str==NULL) {
52405b261ecSmrg	buf= tbGetBuffer(2);
52505b261ecSmrg	buf[0]='\0';
52605b261ecSmrg	return buf;
52705b261ecSmrg    }
52805b261ecSmrg    else if (format==XkbXKMFile)
52905b261ecSmrg	return str;
5306747b715Smrg    for (ok= TRUE,len=0,in=str;*in!='\0';in++,len++) {
53105b261ecSmrg	if (!isprint(*in)) {
5326747b715Smrg	    ok= FALSE;
53305b261ecSmrg	    switch (*in) {
53405b261ecSmrg		case '\n': case '\t': case '\v':
53505b261ecSmrg		case '\b': case '\r': case '\f':
53605b261ecSmrg		    len++;
53705b261ecSmrg		    break;
53805b261ecSmrg		default:
53905b261ecSmrg		    len+= 4;
54005b261ecSmrg		    break;
54105b261ecSmrg	    }
54205b261ecSmrg	}
54305b261ecSmrg    }
54405b261ecSmrg    if (ok)
54505b261ecSmrg	return str;
54605b261ecSmrg    buf= tbGetBuffer(len+1);
54705b261ecSmrg    for (in=str,out=buf;*in!='\0';in++) {
54805b261ecSmrg	if (isprint(*in))
54905b261ecSmrg	    *out++= *in;
55005b261ecSmrg	else {
55105b261ecSmrg	    *out++= '\\';
55205b261ecSmrg	    if (*in=='\n')	*out++= 'n';
55305b261ecSmrg	    else if (*in=='\t')	*out++= 't';
55405b261ecSmrg	    else if (*in=='\v')	*out++= 'v';
55505b261ecSmrg	    else if (*in=='\b')	*out++= 'b';
55605b261ecSmrg	    else if (*in=='\r')	*out++= 'r';
55705b261ecSmrg	    else if (*in=='\f')	*out++= 'f';
55805b261ecSmrg	    else if ((*in=='\033')&&(format==XkbXKMFile)) {
55905b261ecSmrg		*out++= 'e';
56005b261ecSmrg	    }
56105b261ecSmrg	    else {
56205b261ecSmrg		*out++= '0';
56305b261ecSmrg		sprintf(out,"%o",*in);
56405b261ecSmrg		while (*out!='\0')
56505b261ecSmrg		    out++;
56605b261ecSmrg	    }
56705b261ecSmrg	}
56805b261ecSmrg    }
56905b261ecSmrg    *out++= '\0';
57005b261ecSmrg    return buf;
57105b261ecSmrg}
57205b261ecSmrg
57305b261ecSmrg/***====================================================================***/
57405b261ecSmrg
57505b261ecSmrgchar *
57605b261ecSmrgXkbGeomFPText(int val,unsigned format)
57705b261ecSmrg{
57805b261ecSmrgint	whole,frac;
57905b261ecSmrgchar *	buf;
58005b261ecSmrg
58105b261ecSmrg    buf= tbGetBuffer(12);
58205b261ecSmrg    if (format==XkbCFile) {
58305b261ecSmrg	sprintf(buf,"%d",val);
58405b261ecSmrg    }
58505b261ecSmrg    else {
58605b261ecSmrg	whole= val/XkbGeomPtsPerMM;
58705b261ecSmrg	frac= val%XkbGeomPtsPerMM;
58805b261ecSmrg	if (frac!=0)
58905b261ecSmrg	     sprintf(buf,"%d.%d",whole,frac);
59005b261ecSmrg	else sprintf(buf,"%d",whole);
59105b261ecSmrg    }
59205b261ecSmrg    return buf;
59305b261ecSmrg}
59405b261ecSmrg
59505b261ecSmrgchar *
59605b261ecSmrgXkbDoodadTypeText(unsigned type,unsigned format)
59705b261ecSmrg{
59805b261ecSmrgchar *	buf;
59905b261ecSmrg    if (format==XkbCFile) {
60005b261ecSmrg	buf= tbGetBuffer(24);
60105b261ecSmrg	if (type==XkbOutlineDoodad)	   strcpy(buf,"XkbOutlineDoodad");
60205b261ecSmrg	else if (type==XkbSolidDoodad)	   strcpy(buf,"XkbSolidDoodad");
60305b261ecSmrg	else if (type==XkbTextDoodad)	   strcpy(buf,"XkbTextDoodad");
60405b261ecSmrg	else if (type==XkbIndicatorDoodad) strcpy(buf,"XkbIndicatorDoodad");
60505b261ecSmrg	else if (type==XkbLogoDoodad)	   strcpy(buf,"XkbLogoDoodad");
60605b261ecSmrg	else				   sprintf(buf,"UnknownDoodad%d",type);
60705b261ecSmrg    }
60805b261ecSmrg    else {
60905b261ecSmrg	buf= tbGetBuffer(12);
61005b261ecSmrg	if (type==XkbOutlineDoodad)	   strcpy(buf,"outline");
61105b261ecSmrg	else if (type==XkbSolidDoodad)	   strcpy(buf,"solid");
61205b261ecSmrg	else if (type==XkbTextDoodad)	   strcpy(buf,"text");
61305b261ecSmrg	else if (type==XkbIndicatorDoodad) strcpy(buf,"indicator");
61405b261ecSmrg	else if (type==XkbLogoDoodad)	   strcpy(buf,"logo");
61505b261ecSmrg	else				   sprintf(buf,"unknown%d",type);
61605b261ecSmrg    }
61705b261ecSmrg    return buf;
61805b261ecSmrg}
61905b261ecSmrg
62005b261ecSmrgstatic char *actionTypeNames[XkbSA_NumActions]= {
62105b261ecSmrg    "NoAction",
62205b261ecSmrg    "SetMods",      "LatchMods",    "LockMods",
62305b261ecSmrg    "SetGroup",     "LatchGroup",   "LockGroup",
62405b261ecSmrg    "MovePtr",
62505b261ecSmrg    "PtrBtn",       "LockPtrBtn",
62605b261ecSmrg    "SetPtrDflt",
62705b261ecSmrg    "ISOLock",
62805b261ecSmrg    "Terminate",    "SwitchScreen",
62905b261ecSmrg    "SetControls",  "LockControls",
63005b261ecSmrg    "ActionMessage",
63105b261ecSmrg    "RedirectKey",
63205b261ecSmrg    "DeviceBtn",    "LockDeviceBtn"
63305b261ecSmrg};
63405b261ecSmrg
63505b261ecSmrgchar *
63605b261ecSmrgXkbActionTypeText(unsigned type,unsigned format)
63705b261ecSmrg{
63805b261ecSmrgstatic char buf[32];
63905b261ecSmrgchar *rtrn;
64005b261ecSmrg
64105b261ecSmrg    if (type<=XkbSA_LastAction) {
64205b261ecSmrg	rtrn= actionTypeNames[type];
64305b261ecSmrg	if (format==XkbCFile) {
64405b261ecSmrg	    sprintf(buf,"XkbSA_%s",rtrn);
64505b261ecSmrg	    return buf;
64605b261ecSmrg	}
64705b261ecSmrg	return rtrn;
64805b261ecSmrg    }
64905b261ecSmrg    sprintf(buf,"Private");
65005b261ecSmrg    return buf;
65105b261ecSmrg}
65205b261ecSmrg
65305b261ecSmrg/***====================================================================***/
65405b261ecSmrg
65505b261ecSmrgstatic int
65605b261ecSmrgTryCopyStr(char *to,char *from,int *pLeft)
65705b261ecSmrg{
65805b261ecSmrgregister int len;
65905b261ecSmrg    if (*pLeft>0) {
66005b261ecSmrg	len= strlen(from);
66105b261ecSmrg	if (len<((*pLeft)-3)) {
66205b261ecSmrg	    strcat(to,from);
66305b261ecSmrg	    *pLeft-= len;
6646747b715Smrg	    return TRUE;
66505b261ecSmrg	}
66605b261ecSmrg    }
66705b261ecSmrg    *pLeft= -1;
6686747b715Smrg    return FALSE;
66905b261ecSmrg}
67005b261ecSmrg
67105b261ecSmrg/*ARGSUSED*/
67205b261ecSmrgstatic Bool
6734642e01fSmrgCopyNoActionArgs(XkbDescPtr xkb,XkbAction *action,char *buf,int*sz)
67405b261ecSmrg{
6756747b715Smrg    return TRUE;
67605b261ecSmrg}
67705b261ecSmrg
67805b261ecSmrgstatic Bool
6794642e01fSmrgCopyModActionArgs(XkbDescPtr xkb,XkbAction *action,char *buf,
68005b261ecSmrg								int* sz)
68105b261ecSmrg{
68205b261ecSmrgXkbModAction *	act;
68305b261ecSmrgunsigned	tmp;
68405b261ecSmrg
68505b261ecSmrg    act= &action->mods;
68605b261ecSmrg    tmp= XkbModActionVMods(act);
68705b261ecSmrg    TryCopyStr(buf,"modifiers=",sz);
68805b261ecSmrg    if (act->flags&XkbSA_UseModMapMods)
68905b261ecSmrg	  TryCopyStr(buf,"modMapMods",sz);
69005b261ecSmrg    else if (act->real_mods || tmp) {
69105b261ecSmrg	 TryCopyStr(buf,
6924642e01fSmrg		     XkbVModMaskText(xkb,act->real_mods,tmp,XkbXKBFile),
69305b261ecSmrg		     sz);
69405b261ecSmrg    }
69505b261ecSmrg    else TryCopyStr(buf,"none",sz);
69605b261ecSmrg    if (act->type==XkbSA_LockMods)
6976747b715Smrg	return TRUE;
69805b261ecSmrg    if (act->flags&XkbSA_ClearLocks)
69905b261ecSmrg	TryCopyStr(buf,",clearLocks",sz);
70005b261ecSmrg    if (act->flags&XkbSA_LatchToLock)
70105b261ecSmrg	TryCopyStr(buf,",latchToLock",sz);
7026747b715Smrg    return TRUE;
70305b261ecSmrg}
70405b261ecSmrg
70505b261ecSmrg/*ARGSUSED*/
70605b261ecSmrgstatic Bool
7074642e01fSmrgCopyGroupActionArgs(XkbDescPtr xkb,XkbAction *action,char *buf,
70805b261ecSmrg								int *sz)
70905b261ecSmrg{
71005b261ecSmrgXkbGroupAction *	act;
71105b261ecSmrgchar			tbuf[32];
71205b261ecSmrg
71305b261ecSmrg    act= &action->group;
71405b261ecSmrg    TryCopyStr(buf,"group=",sz);
71505b261ecSmrg    if (act->flags&XkbSA_GroupAbsolute)
71605b261ecSmrg	 sprintf(tbuf,"%d",XkbSAGroup(act)+1);
71705b261ecSmrg    else if (XkbSAGroup(act)<0)
71805b261ecSmrg	 sprintf(tbuf,"%d",XkbSAGroup(act));
71905b261ecSmrg    else sprintf(tbuf,"+%d",XkbSAGroup(act));
72005b261ecSmrg    TryCopyStr(buf,tbuf,sz);
72105b261ecSmrg    if (act->type==XkbSA_LockGroup)
7226747b715Smrg	return TRUE;
72305b261ecSmrg    if (act->flags&XkbSA_ClearLocks)
72405b261ecSmrg	TryCopyStr(buf,",clearLocks",sz);
72505b261ecSmrg    if (act->flags&XkbSA_LatchToLock)
72605b261ecSmrg	TryCopyStr(buf,",latchToLock",sz);
7276747b715Smrg    return TRUE;
72805b261ecSmrg}
72905b261ecSmrg
73005b261ecSmrg/*ARGSUSED*/
73105b261ecSmrgstatic Bool
7324642e01fSmrgCopyMovePtrArgs(XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
73305b261ecSmrg{
73405b261ecSmrgXkbPtrAction *	act;
73505b261ecSmrgint		x,y;
73605b261ecSmrgchar		tbuf[32];
73705b261ecSmrg
73805b261ecSmrg    act= &action->ptr;
73905b261ecSmrg    x= XkbPtrActionX(act);
74005b261ecSmrg    y= XkbPtrActionY(act);
74105b261ecSmrg    if ((act->flags&XkbSA_MoveAbsoluteX)||(x<0))
74205b261ecSmrg	 sprintf(tbuf,"x=%d",x);
74305b261ecSmrg    else sprintf(tbuf,"x=+%d",x);
74405b261ecSmrg    TryCopyStr(buf,tbuf,sz);
74505b261ecSmrg
74605b261ecSmrg    if ((act->flags&XkbSA_MoveAbsoluteY)||(y<0))
74705b261ecSmrg	 sprintf(tbuf,",y=%d",y);
74805b261ecSmrg    else sprintf(tbuf,",y=+%d",y);
74905b261ecSmrg    TryCopyStr(buf,tbuf,sz);
75005b261ecSmrg    if (act->flags&XkbSA_NoAcceleration)
75105b261ecSmrg	TryCopyStr(buf,",!accel",sz);
7526747b715Smrg    return TRUE;
75305b261ecSmrg}
75405b261ecSmrg
75505b261ecSmrg/*ARGSUSED*/
75605b261ecSmrgstatic Bool
7574642e01fSmrgCopyPtrBtnArgs(XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
75805b261ecSmrg{
75905b261ecSmrgXkbPtrBtnAction *	act;
76005b261ecSmrgchar			tbuf[32];
76105b261ecSmrg
76205b261ecSmrg    act= &action->btn;
76305b261ecSmrg    TryCopyStr(buf,"button=",sz);
76405b261ecSmrg    if ((act->button>0)&&(act->button<6)) {
76505b261ecSmrg	 sprintf(tbuf,"%d",act->button);
76605b261ecSmrg	 TryCopyStr(buf,tbuf,sz);
76705b261ecSmrg    }
76805b261ecSmrg    else TryCopyStr(buf,"default",sz);
76905b261ecSmrg    if (act->count>0) {
77005b261ecSmrg	sprintf(tbuf,",count=%d",act->count);
77105b261ecSmrg	TryCopyStr(buf,tbuf,sz);
77205b261ecSmrg    }
77305b261ecSmrg    if (action->type==XkbSA_LockPtrBtn) {
77405b261ecSmrg	switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) {
77505b261ecSmrg	    case XkbSA_LockNoLock:
77605b261ecSmrg		sprintf(tbuf,",affect=unlock"); break;
77705b261ecSmrg	    case XkbSA_LockNoUnlock:
77805b261ecSmrg		sprintf(tbuf,",affect=lock"); break;
77905b261ecSmrg	    case XkbSA_LockNoUnlock|XkbSA_LockNoLock:
78005b261ecSmrg		sprintf(tbuf,",affect=neither"); break;
78105b261ecSmrg	    default:
78205b261ecSmrg		sprintf(tbuf,",affect=both"); break;
78305b261ecSmrg	}
78405b261ecSmrg	TryCopyStr(buf,tbuf,sz);
78505b261ecSmrg    }
7866747b715Smrg    return TRUE;
78705b261ecSmrg}
78805b261ecSmrg
78905b261ecSmrg/*ARGSUSED*/
79005b261ecSmrgstatic Bool
7914642e01fSmrgCopySetPtrDfltArgs(XkbDescPtr xkb,XkbAction *action,char *buf,
79205b261ecSmrg								int *sz)
79305b261ecSmrg{
79405b261ecSmrgXkbPtrDfltAction *	act;
79505b261ecSmrgchar			tbuf[32];
79605b261ecSmrg
79705b261ecSmrg    act= &action->dflt;
79805b261ecSmrg    if (act->affect==XkbSA_AffectDfltBtn) {
79905b261ecSmrg	TryCopyStr(buf,"affect=button,button=",sz);
80005b261ecSmrg	if ((act->flags&XkbSA_DfltBtnAbsolute)||(XkbSAPtrDfltValue(act)<0))
80105b261ecSmrg	     sprintf(tbuf,"%d",XkbSAPtrDfltValue(act));
80205b261ecSmrg	else sprintf(tbuf,"+%d",XkbSAPtrDfltValue(act));
80305b261ecSmrg	TryCopyStr(buf,tbuf,sz);
80405b261ecSmrg    }
8056747b715Smrg    return TRUE;
80605b261ecSmrg}
80705b261ecSmrg
80805b261ecSmrgstatic Bool
8094642e01fSmrgCopyISOLockArgs(XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
81005b261ecSmrg{
81105b261ecSmrgXkbISOAction *	act;
81205b261ecSmrgchar		tbuf[64];
81305b261ecSmrg
81405b261ecSmrg    act= &action->iso;
81505b261ecSmrg    if (act->flags&XkbSA_ISODfltIsGroup) {
81605b261ecSmrg	TryCopyStr(tbuf,"group=",sz);
81705b261ecSmrg	if (act->flags&XkbSA_GroupAbsolute)
81805b261ecSmrg	     sprintf(tbuf,"%d",XkbSAGroup(act)+1);
81905b261ecSmrg	else if (XkbSAGroup(act)<0)
82005b261ecSmrg	     sprintf(tbuf,"%d",XkbSAGroup(act));
82105b261ecSmrg	else sprintf(tbuf,"+%d",XkbSAGroup(act));
82205b261ecSmrg	TryCopyStr(buf,tbuf,sz);
82305b261ecSmrg    }
82405b261ecSmrg    else {
82505b261ecSmrg	unsigned tmp;
82605b261ecSmrg	tmp= XkbModActionVMods(act);
82705b261ecSmrg	TryCopyStr(buf,"modifiers=",sz);
82805b261ecSmrg	if (act->flags&XkbSA_UseModMapMods)
82905b261ecSmrg	     TryCopyStr(buf,"modMapMods",sz);
83005b261ecSmrg	else if (act->real_mods || tmp) {
83105b261ecSmrg	    if (act->real_mods) {
83205b261ecSmrg		TryCopyStr(buf,XkbModMaskText(act->real_mods,XkbXKBFile),sz);
83305b261ecSmrg		if (tmp)
83405b261ecSmrg		    TryCopyStr(buf,"+",sz);
83505b261ecSmrg	    }
83605b261ecSmrg	    if (tmp)
8374642e01fSmrg		TryCopyStr(buf,XkbVModMaskText(xkb,0,tmp,XkbXKBFile),sz);
83805b261ecSmrg	}
83905b261ecSmrg	else TryCopyStr(buf,"none",sz);
84005b261ecSmrg    }
84105b261ecSmrg    TryCopyStr(buf,",affect=",sz);
84205b261ecSmrg    if ((act->affect&XkbSA_ISOAffectMask)==0)
84305b261ecSmrg	TryCopyStr(buf,"all",sz);
84405b261ecSmrg    else {
84505b261ecSmrg	int nOut= 0;
84605b261ecSmrg	if ((act->affect&XkbSA_ISONoAffectMods)==0) {
84705b261ecSmrg	    TryCopyStr(buf,"mods",sz);
84805b261ecSmrg	    nOut++;
84905b261ecSmrg	}
85005b261ecSmrg	if ((act->affect&XkbSA_ISONoAffectGroup)==0) {
85105b261ecSmrg	    sprintf(tbuf,"%sgroups",(nOut>0?"+":""));
85205b261ecSmrg	    TryCopyStr(buf,tbuf,sz);
85305b261ecSmrg	    nOut++;
85405b261ecSmrg	}
85505b261ecSmrg	if ((act->affect&XkbSA_ISONoAffectPtr)==0) {
85605b261ecSmrg	    sprintf(tbuf,"%spointer",(nOut>0?"+":""));
85705b261ecSmrg	    TryCopyStr(buf,tbuf,sz);
85805b261ecSmrg	    nOut++;
85905b261ecSmrg	}
86005b261ecSmrg	if ((act->affect&XkbSA_ISONoAffectCtrls)==0) {
86105b261ecSmrg	    sprintf(tbuf,"%scontrols",(nOut>0?"+":""));
86205b261ecSmrg	    TryCopyStr(buf,tbuf,sz);
86305b261ecSmrg	    nOut++;
86405b261ecSmrg	}
86505b261ecSmrg    }
8666747b715Smrg    return TRUE;
86705b261ecSmrg}
86805b261ecSmrg
86905b261ecSmrg/*ARGSUSED*/
87005b261ecSmrgstatic Bool
8714642e01fSmrgCopySwitchScreenArgs(XkbDescPtr xkb,XkbAction *action,char *buf,
87205b261ecSmrg								int *sz)
87305b261ecSmrg{
87405b261ecSmrgXkbSwitchScreenAction *	act;
87505b261ecSmrgchar			tbuf[32];
87605b261ecSmrg
87705b261ecSmrg    act= &action->screen;
87805b261ecSmrg    if ((act->flags&XkbSA_SwitchAbsolute)||(XkbSAScreen(act)<0))
87905b261ecSmrg	 sprintf(tbuf,"screen=%d",XkbSAScreen(act));
88005b261ecSmrg    else sprintf(tbuf,"screen=+%d",XkbSAScreen(act));
88105b261ecSmrg    TryCopyStr(buf,tbuf,sz);
88205b261ecSmrg    if (act->flags&XkbSA_SwitchApplication)
88305b261ecSmrg	 TryCopyStr(buf,",!same",sz);
88405b261ecSmrg    else TryCopyStr(buf,",same",sz);
8856747b715Smrg    return TRUE;
88605b261ecSmrg}
88705b261ecSmrg
88805b261ecSmrg/*ARGSUSED*/
88905b261ecSmrgstatic Bool
8904642e01fSmrgCopySetLockControlsArgs(XkbDescPtr xkb,XkbAction *action,
89105b261ecSmrg							char *buf,int *sz)
89205b261ecSmrg{
89305b261ecSmrgXkbCtrlsAction *	act;
89405b261ecSmrgunsigned		tmp;
89505b261ecSmrgchar			tbuf[32];
89605b261ecSmrg
89705b261ecSmrg    act= &action->ctrls;
89805b261ecSmrg    tmp= XkbActionCtrls(act);
89905b261ecSmrg    TryCopyStr(buf,"controls=",sz);
90005b261ecSmrg    if (tmp==0)
90105b261ecSmrg	TryCopyStr(buf,"none",sz);
90205b261ecSmrg    else if ((tmp&XkbAllBooleanCtrlsMask)==XkbAllBooleanCtrlsMask)
90305b261ecSmrg	TryCopyStr(buf,"all",sz);
90405b261ecSmrg    else {
90505b261ecSmrg	int nOut= 0;
90605b261ecSmrg	if (tmp&XkbRepeatKeysMask) {
90705b261ecSmrg	    sprintf(tbuf,"%sRepeatKeys",(nOut>0?"+":""));
90805b261ecSmrg	    TryCopyStr(buf,tbuf,sz);
90905b261ecSmrg	    nOut++;
91005b261ecSmrg	}
91105b261ecSmrg	if (tmp&XkbSlowKeysMask) {
91205b261ecSmrg	    sprintf(tbuf,"%sSlowKeys",(nOut>0?"+":""));
91305b261ecSmrg	    TryCopyStr(buf,tbuf,sz);
91405b261ecSmrg	    nOut++;
91505b261ecSmrg	}
91605b261ecSmrg	if (tmp&XkbBounceKeysMask) {
91705b261ecSmrg	    sprintf(tbuf,"%sBounceKeys",(nOut>0?"+":""));
91805b261ecSmrg	    TryCopyStr(buf,tbuf,sz);
91905b261ecSmrg	    nOut++;
92005b261ecSmrg	}
92105b261ecSmrg	if (tmp&XkbStickyKeysMask) {
92205b261ecSmrg	    sprintf(tbuf,"%sStickyKeys",(nOut>0?"+":""));
92305b261ecSmrg	    TryCopyStr(buf,tbuf,sz);
92405b261ecSmrg	    nOut++;
92505b261ecSmrg	}
92605b261ecSmrg	if (tmp&XkbMouseKeysMask) {
92705b261ecSmrg	    sprintf(tbuf,"%sMouseKeys",(nOut>0?"+":""));
92805b261ecSmrg	    TryCopyStr(buf,tbuf,sz);
92905b261ecSmrg	    nOut++;
93005b261ecSmrg	}
93105b261ecSmrg	if (tmp&XkbMouseKeysAccelMask) {
93205b261ecSmrg	    sprintf(tbuf,"%sMouseKeysAccel",(nOut>0?"+":""));
93305b261ecSmrg	    TryCopyStr(buf,tbuf,sz);
93405b261ecSmrg	    nOut++;
93505b261ecSmrg	}
93605b261ecSmrg	if (tmp&XkbAccessXKeysMask) {
93705b261ecSmrg	    sprintf(tbuf,"%sAccessXKeys",(nOut>0?"+":""));
93805b261ecSmrg	    TryCopyStr(buf,tbuf,sz);
93905b261ecSmrg	    nOut++;
94005b261ecSmrg	}
94105b261ecSmrg	if (tmp&XkbAccessXTimeoutMask) {
94205b261ecSmrg	    sprintf(tbuf,"%sAccessXTimeout",(nOut>0?"+":""));
94305b261ecSmrg	    TryCopyStr(buf,tbuf,sz);
94405b261ecSmrg	    nOut++;
94505b261ecSmrg	}
94605b261ecSmrg	if (tmp&XkbAccessXFeedbackMask) {
94705b261ecSmrg	    sprintf(tbuf,"%sAccessXFeedback",(nOut>0?"+":""));
94805b261ecSmrg	    TryCopyStr(buf,tbuf,sz);
94905b261ecSmrg	    nOut++;
95005b261ecSmrg	}
95105b261ecSmrg	if (tmp&XkbAudibleBellMask) {
95205b261ecSmrg	    sprintf(tbuf,"%sAudibleBell",(nOut>0?"+":""));
95305b261ecSmrg	    TryCopyStr(buf,tbuf,sz);
95405b261ecSmrg	    nOut++;
95505b261ecSmrg	}
95605b261ecSmrg	if (tmp&XkbOverlay1Mask) {
95705b261ecSmrg	    sprintf(tbuf,"%sOverlay1",(nOut>0?"+":""));
95805b261ecSmrg	    TryCopyStr(buf,tbuf,sz);
95905b261ecSmrg	    nOut++;
96005b261ecSmrg	}
96105b261ecSmrg	if (tmp&XkbOverlay2Mask) {
96205b261ecSmrg	    sprintf(tbuf,"%sOverlay2",(nOut>0?"+":""));
96305b261ecSmrg	    TryCopyStr(buf,tbuf,sz);
96405b261ecSmrg	    nOut++;
96505b261ecSmrg	}
96605b261ecSmrg	if (tmp&XkbIgnoreGroupLockMask) {
96705b261ecSmrg	    sprintf(tbuf,"%sIgnoreGroupLock",(nOut>0?"+":""));
96805b261ecSmrg	    TryCopyStr(buf,tbuf,sz);
96905b261ecSmrg	    nOut++;
97005b261ecSmrg	}
97105b261ecSmrg    }
9726747b715Smrg    return TRUE;
97305b261ecSmrg}
97405b261ecSmrg
97505b261ecSmrg/*ARGSUSED*/
97605b261ecSmrgstatic Bool
9774642e01fSmrgCopyActionMessageArgs(XkbDescPtr xkb,XkbAction *action,char *buf,
97805b261ecSmrg								int *sz)
97905b261ecSmrg{
98005b261ecSmrgXkbMessageAction *	act;
98105b261ecSmrgunsigned		all;
98205b261ecSmrgchar			tbuf[32];
98305b261ecSmrg
98405b261ecSmrg    act= &action->msg;
98505b261ecSmrg    all= XkbSA_MessageOnPress|XkbSA_MessageOnRelease;
98605b261ecSmrg    TryCopyStr(buf,"report=",sz);
98705b261ecSmrg    if ((act->flags&all)==0)
98805b261ecSmrg	TryCopyStr(buf,"none",sz);
98905b261ecSmrg    else if ((act->flags&all)==all)
99005b261ecSmrg	TryCopyStr(buf,"all",sz);
99105b261ecSmrg    else if (act->flags&XkbSA_MessageOnPress)
99205b261ecSmrg	 TryCopyStr(buf,"KeyPress",sz);
99305b261ecSmrg    else TryCopyStr(buf,"KeyRelease",sz);
99405b261ecSmrg    sprintf(tbuf,",data[0]=0x%02x",act->message[0]); TryCopyStr(buf,tbuf,sz);
99505b261ecSmrg    sprintf(tbuf,",data[1]=0x%02x",act->message[1]); TryCopyStr(buf,tbuf,sz);
99605b261ecSmrg    sprintf(tbuf,",data[2]=0x%02x",act->message[2]); TryCopyStr(buf,tbuf,sz);
99705b261ecSmrg    sprintf(tbuf,",data[3]=0x%02x",act->message[3]); TryCopyStr(buf,tbuf,sz);
99805b261ecSmrg    sprintf(tbuf,",data[4]=0x%02x",act->message[4]); TryCopyStr(buf,tbuf,sz);
99905b261ecSmrg    sprintf(tbuf,",data[5]=0x%02x",act->message[5]); TryCopyStr(buf,tbuf,sz);
10006747b715Smrg    return TRUE;
100105b261ecSmrg}
100205b261ecSmrg
100305b261ecSmrgstatic Bool
10044642e01fSmrgCopyRedirectKeyArgs(XkbDescPtr xkb,XkbAction *action,char *buf,
100505b261ecSmrg								int *sz)
100605b261ecSmrg{
100705b261ecSmrgXkbRedirectKeyAction *	act;
100805b261ecSmrgchar			tbuf[32],*tmp;
100905b261ecSmrgunsigned		kc;
101005b261ecSmrgunsigned		vmods,vmods_mask;
101105b261ecSmrg
101205b261ecSmrg    act= &action->redirect;
101305b261ecSmrg    kc= act->new_key;
101405b261ecSmrg    vmods= XkbSARedirectVMods(act);
101505b261ecSmrg    vmods_mask= XkbSARedirectVModsMask(act);
101605b261ecSmrg    if (xkb && xkb->names && xkb->names->keys && (kc<=xkb->max_key_code) &&
101705b261ecSmrg				(xkb->names->keys[kc].name[0]!='\0')) {
101805b261ecSmrg	char *kn;
101905b261ecSmrg	kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile);
102005b261ecSmrg	sprintf(tbuf,"key=%s",kn);
102105b261ecSmrg    }
102205b261ecSmrg    else sprintf(tbuf,"key=%d",kc);
102305b261ecSmrg    TryCopyStr(buf,tbuf,sz);
102405b261ecSmrg    if ((act->mods_mask==0)&&(vmods_mask==0))
10256747b715Smrg	return TRUE;
102605b261ecSmrg    if ((act->mods_mask==XkbAllModifiersMask)&&
102705b261ecSmrg	(vmods_mask==XkbAllVirtualModsMask)) {
10284642e01fSmrg	tmp= XkbVModMaskText(xkb,act->mods,vmods,XkbXKBFile);
102905b261ecSmrg	TryCopyStr(buf,",mods=",sz);
103005b261ecSmrg	TryCopyStr(buf,tmp,sz);
103105b261ecSmrg    }
103205b261ecSmrg    else {
103305b261ecSmrg	if ((act->mods_mask&act->mods)||(vmods_mask&vmods)) {
10344642e01fSmrg	    tmp= XkbVModMaskText(xkb,act->mods_mask&act->mods,
103505b261ecSmrg					 vmods_mask&vmods,XkbXKBFile);
103605b261ecSmrg	    TryCopyStr(buf,",mods= ",sz);
103705b261ecSmrg	    TryCopyStr(buf,tmp,sz);
103805b261ecSmrg	}
103905b261ecSmrg	if ((act->mods_mask&(~act->mods))||(vmods_mask&(~vmods))) {
10404642e01fSmrg	    tmp= XkbVModMaskText(xkb,act->mods_mask&(~act->mods),
104105b261ecSmrg					 vmods_mask&(~vmods),XkbXKBFile);
104205b261ecSmrg	    TryCopyStr(buf,",clearMods= ",sz);
104305b261ecSmrg	    TryCopyStr(buf,tmp,sz);
104405b261ecSmrg	}
104505b261ecSmrg    }
10466747b715Smrg    return TRUE;
104705b261ecSmrg}
104805b261ecSmrg
104905b261ecSmrg/*ARGSUSED*/
105005b261ecSmrgstatic Bool
10514642e01fSmrgCopyDeviceBtnArgs(XkbDescPtr xkb,XkbAction *action,char *buf,
105205b261ecSmrg								int *sz)
105305b261ecSmrg{
105405b261ecSmrgXkbDeviceBtnAction *	act;
105505b261ecSmrgchar			tbuf[32];
105605b261ecSmrg
105705b261ecSmrg    act= &action->devbtn;
105805b261ecSmrg    sprintf(tbuf,"device= %d",act->device); TryCopyStr(buf,tbuf,sz);
105905b261ecSmrg    TryCopyStr(buf,",button=",sz);
106005b261ecSmrg    sprintf(tbuf,"%d",act->button);
106105b261ecSmrg    TryCopyStr(buf,tbuf,sz);
106205b261ecSmrg    if (act->count>0) {
106305b261ecSmrg	sprintf(tbuf,",count=%d",act->count);
106405b261ecSmrg	TryCopyStr(buf,tbuf,sz);
106505b261ecSmrg    }
106605b261ecSmrg    if (action->type==XkbSA_LockDeviceBtn) {
106705b261ecSmrg	switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) {
106805b261ecSmrg	    case XkbSA_LockNoLock:
106905b261ecSmrg		sprintf(tbuf,",affect=unlock"); break;
107005b261ecSmrg	    case XkbSA_LockNoUnlock:
107105b261ecSmrg		sprintf(tbuf,",affect=lock"); break;
107205b261ecSmrg	    case XkbSA_LockNoUnlock|XkbSA_LockNoLock:
107305b261ecSmrg		sprintf(tbuf,",affect=neither"); break;
107405b261ecSmrg	    default:
107505b261ecSmrg		sprintf(tbuf,",affect=both"); break;
107605b261ecSmrg	}
107705b261ecSmrg	TryCopyStr(buf,tbuf,sz);
107805b261ecSmrg    }
10796747b715Smrg    return TRUE;
108005b261ecSmrg}
108105b261ecSmrg
108205b261ecSmrg/*ARGSUSED*/
108305b261ecSmrgstatic Bool
10844642e01fSmrgCopyOtherArgs(XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
108505b261ecSmrg{
108605b261ecSmrgXkbAnyAction *	act;
108705b261ecSmrgchar		tbuf[32];
108805b261ecSmrg
108905b261ecSmrg    act= &action->any;
109005b261ecSmrg    sprintf(tbuf,"type=0x%02x",act->type); TryCopyStr(buf,tbuf,sz);
109105b261ecSmrg    sprintf(tbuf,",data[0]=0x%02x",act->data[0]); TryCopyStr(buf,tbuf,sz);
109205b261ecSmrg    sprintf(tbuf,",data[1]=0x%02x",act->data[1]); TryCopyStr(buf,tbuf,sz);
109305b261ecSmrg    sprintf(tbuf,",data[2]=0x%02x",act->data[2]); TryCopyStr(buf,tbuf,sz);
109405b261ecSmrg    sprintf(tbuf,",data[3]=0x%02x",act->data[3]); TryCopyStr(buf,tbuf,sz);
109505b261ecSmrg    sprintf(tbuf,",data[4]=0x%02x",act->data[4]); TryCopyStr(buf,tbuf,sz);
109605b261ecSmrg    sprintf(tbuf,",data[5]=0x%02x",act->data[5]); TryCopyStr(buf,tbuf,sz);
109705b261ecSmrg    sprintf(tbuf,",data[6]=0x%02x",act->data[6]); TryCopyStr(buf,tbuf,sz);
10986747b715Smrg    return TRUE;
109905b261ecSmrg}
110005b261ecSmrg
110105b261ecSmrgtypedef	Bool	(*actionCopy)(
110205b261ecSmrg	XkbDescPtr 	/* xkb */,
110305b261ecSmrg	XkbAction *	/* action */,
110405b261ecSmrg	char *		/* buf */,
110505b261ecSmrg	int*		/* sz */
110605b261ecSmrg);
110705b261ecSmrgstatic actionCopy	copyActionArgs[XkbSA_NumActions] = {
110805b261ecSmrg	CopyNoActionArgs		/* NoAction	*/,
110905b261ecSmrg	CopyModActionArgs		/* SetMods	*/,
111005b261ecSmrg	CopyModActionArgs		/* LatchMods	*/,
111105b261ecSmrg	CopyModActionArgs		/* LockMods	*/,
111205b261ecSmrg	CopyGroupActionArgs		/* SetGroup	*/,
111305b261ecSmrg	CopyGroupActionArgs		/* LatchGroup	*/,
111405b261ecSmrg	CopyGroupActionArgs		/* LockGroup	*/,
111505b261ecSmrg	CopyMovePtrArgs			/* MovePtr	*/,
111605b261ecSmrg	CopyPtrBtnArgs			/* PtrBtn	*/,
111705b261ecSmrg	CopyPtrBtnArgs			/* LockPtrBtn	*/,
111805b261ecSmrg	CopySetPtrDfltArgs		/* SetPtrDflt	*/,
111905b261ecSmrg	CopyISOLockArgs			/* ISOLock	*/,
112005b261ecSmrg	CopyNoActionArgs		/* Terminate	*/,
112105b261ecSmrg	CopySwitchScreenArgs		/* SwitchScreen	*/,
112205b261ecSmrg	CopySetLockControlsArgs		/* SetControls	*/,
112305b261ecSmrg	CopySetLockControlsArgs		/* LockControls	*/,
112405b261ecSmrg	CopyActionMessageArgs		/* ActionMessage*/,
112505b261ecSmrg	CopyRedirectKeyArgs		/* RedirectKey	*/,
112605b261ecSmrg	CopyDeviceBtnArgs		/* DeviceBtn	*/,
112705b261ecSmrg	CopyDeviceBtnArgs		/* LockDeviceBtn*/
112805b261ecSmrg};
112905b261ecSmrg
113005b261ecSmrg#define	ACTION_SZ	256
113105b261ecSmrg
113205b261ecSmrgchar *
11334642e01fSmrgXkbActionText(XkbDescPtr xkb,XkbAction *action,unsigned format)
113405b261ecSmrg{
113505b261ecSmrgchar	buf[ACTION_SZ],*tmp;
113605b261ecSmrgint	sz;
113705b261ecSmrg
113805b261ecSmrg    if (format==XkbCFile) {
113905b261ecSmrg	sprintf(buf,
114005b261ecSmrg	    "{ %20s, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x } }",
114105b261ecSmrg	    XkbActionTypeText(action->type,XkbCFile),
114205b261ecSmrg	    action->any.data[0],action->any.data[1],action->any.data[2],
114305b261ecSmrg	    action->any.data[3],action->any.data[4],action->any.data[5],
114405b261ecSmrg	    action->any.data[6]);
114505b261ecSmrg    }
114605b261ecSmrg    else {
114705b261ecSmrg	sprintf(buf,"%s(",XkbActionTypeText(action->type,XkbXKBFile));
114805b261ecSmrg	sz= ACTION_SZ-strlen(buf)+2; /* room for close paren and NULL */
114905b261ecSmrg	if (action->type<(unsigned)XkbSA_NumActions)
11504642e01fSmrg	     (*copyActionArgs[action->type])(xkb,action,buf,&sz);
11514642e01fSmrg	else CopyOtherArgs(xkb,action,buf,&sz);
115205b261ecSmrg	TryCopyStr(buf,")",&sz);
115305b261ecSmrg    }
115405b261ecSmrg    tmp= tbGetBuffer(strlen(buf)+1);
115505b261ecSmrg    if (tmp!=NULL)
115605b261ecSmrg	strcpy(tmp,buf);
115705b261ecSmrg    return tmp;
115805b261ecSmrg}
115905b261ecSmrg
116005b261ecSmrgchar *
116105b261ecSmrgXkbBehaviorText(XkbDescPtr xkb,XkbBehavior *behavior,unsigned format)
116205b261ecSmrg{
116305b261ecSmrgchar	buf[256],*tmp;
116405b261ecSmrg
116505b261ecSmrg    if (format==XkbCFile) {
116605b261ecSmrg	if (behavior->type==XkbKB_Default)
116705b261ecSmrg	     sprintf(buf,"{   0,    0 }");
116805b261ecSmrg	else sprintf(buf,"{ %3d, 0x%02x }",behavior->type,behavior->data);
116905b261ecSmrg    }
117005b261ecSmrg    else {
117105b261ecSmrg	unsigned 	type,permanent;
117205b261ecSmrg	type= behavior->type&XkbKB_OpMask;
117305b261ecSmrg	permanent=((behavior->type&XkbKB_Permanent)!=0);
117405b261ecSmrg
117505b261ecSmrg	if (type==XkbKB_Lock) {
11766747b715Smrg	    sprintf(buf,"lock= %s",(permanent?"Permanent":"TRUE"));
117705b261ecSmrg	}
117805b261ecSmrg	else if (type==XkbKB_RadioGroup) {
117905b261ecSmrg	    int 	g;
118005b261ecSmrg	    char	*tmp;
118105b261ecSmrg	    g= ((behavior->data)&(~XkbKB_RGAllowNone))+1;
118205b261ecSmrg	    if (XkbKB_RGAllowNone&behavior->data) {
118305b261ecSmrg		sprintf(buf,"allowNone,");
118405b261ecSmrg		tmp= &buf[strlen(buf)];
118505b261ecSmrg	    }
118605b261ecSmrg	    else tmp= buf;
118705b261ecSmrg	    if (permanent)
118805b261ecSmrg		 sprintf(tmp,"permanentRadioGroup= %d",g);
118905b261ecSmrg	    else sprintf(tmp,"radioGroup= %d",g);
119005b261ecSmrg	}
119105b261ecSmrg	else if ((type==XkbKB_Overlay1)||(type==XkbKB_Overlay2)) {
119205b261ecSmrg	    int ndx,kc;
119305b261ecSmrg	    char *kn;
119405b261ecSmrg
119505b261ecSmrg	    ndx= ((type==XkbKB_Overlay1)?1:2);
119605b261ecSmrg	    kc= behavior->data;
119705b261ecSmrg	    if ((xkb)&&(xkb->names)&&(xkb->names->keys))
119805b261ecSmrg		kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile);
119905b261ecSmrg	    else {
120005b261ecSmrg		static char tbuf[8];
120105b261ecSmrg		sprintf(tbuf,"%d",kc);
120205b261ecSmrg		kn= tbuf;
120305b261ecSmrg	    }
120405b261ecSmrg	    if (permanent)
120505b261ecSmrg		 sprintf(buf,"permanentOverlay%d= %s",ndx,kn);
120605b261ecSmrg	    else sprintf(buf,"overlay%d= %s",ndx,kn);
120705b261ecSmrg	}
120805b261ecSmrg    }
120905b261ecSmrg    tmp= tbGetBuffer(strlen(buf)+1);
121005b261ecSmrg    if (tmp!=NULL)
121105b261ecSmrg	strcpy(tmp,buf);
121205b261ecSmrg    return tmp;
121305b261ecSmrg}
121405b261ecSmrg
121505b261ecSmrg/***====================================================================***/
121605b261ecSmrg
121705b261ecSmrgchar *
121805b261ecSmrgXkbIndentText(unsigned size)
121905b261ecSmrg{
122005b261ecSmrgstatic char buf[32];
122105b261ecSmrgregister int i;
122205b261ecSmrg
122305b261ecSmrg    if (size>31)
122405b261ecSmrg	size= 31;
122505b261ecSmrg
122605b261ecSmrg    for (i=0;i<size;i++) {
122705b261ecSmrg	buf[i]= ' ';
122805b261ecSmrg    }
122905b261ecSmrg    buf[size]= '\0';
123005b261ecSmrg    return buf;
123105b261ecSmrg}
1232