1230 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1230 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			C
		
	
	
	
/************************************************************
 | 
						|
 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
 | 
						|
 | 
						|
 Permission to use, copy, modify, and distribute this
 | 
						|
 software and its documentation for any purpose and without
 | 
						|
 fee is hereby granted, provided that the above copyright
 | 
						|
 notice appear in all copies and that both that copyright
 | 
						|
 notice and this permission notice appear in supporting
 | 
						|
 documentation, and that the name of Silicon Graphics not be 
 | 
						|
 used in advertising or publicity pertaining to distribution 
 | 
						|
 of the software without specific prior written permission.
 | 
						|
 Silicon Graphics makes no representation about the suitability 
 | 
						|
 of this software for any purpose. It is provided "as is"
 | 
						|
 without any express or implied warranty.
 | 
						|
 
 | 
						|
 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 
 | 
						|
 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 
 | 
						|
 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
 | 
						|
 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 
 | 
						|
 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 
 | 
						|
 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 
 | 
						|
 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
 | 
						|
 THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
						|
 | 
						|
 ********************************************************/
 | 
						|
 | 
						|
#ifdef HAVE_DIX_CONFIG_H
 | 
						|
#include <dix-config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include <ctype.h>
 | 
						|
#include <stdlib.h>
 | 
						|
 | 
						|
#include <X11/Xos.h>
 | 
						|
 | 
						|
#include <X11/X.h>
 | 
						|
#define	NEED_EVENTS
 | 
						|
#include <X11/Xproto.h>
 | 
						|
#include "misc.h"
 | 
						|
#include "inputstr.h"
 | 
						|
#include "dix.h"
 | 
						|
#include <X11/extensions/XKBstr.h>
 | 
						|
#define XKBSRV_NEED_FILE_FUNCS	1
 | 
						|
#include <xkbsrv.h>
 | 
						|
#include <X11/extensions/XKBgeom.h>
 | 
						|
 | 
						|
/***====================================================================***/
 | 
						|
 | 
						|
#define	BUFFER_SIZE	512
 | 
						|
 | 
						|
static char textBuffer[BUFFER_SIZE];
 | 
						|
static int  tbNext= 0;
 | 
						|
 | 
						|
static char *
 | 
						|
tbGetBuffer(unsigned size)
 | 
						|
{
 | 
						|
char *rtrn;
 | 
						|
 | 
						|
    if (size>=BUFFER_SIZE)
 | 
						|
	return NULL;
 | 
						|
    if ((BUFFER_SIZE-tbNext)<=size)
 | 
						|
	tbNext= 0;
 | 
						|
    rtrn= &textBuffer[tbNext];
 | 
						|
    tbNext+= size;
 | 
						|
    return rtrn;
 | 
						|
}
 | 
						|
 | 
						|
/***====================================================================***/
 | 
						|
 | 
						|
char *
 | 
						|
XkbAtomText(Display *dpy,Atom atm,unsigned format)
 | 
						|
{
 | 
						|
char	*rtrn,*tmp;
 | 
						|
 | 
						|
    tmp= XkbAtomGetString(dpy,atm);
 | 
						|
    if (tmp!=NULL) {
 | 
						|
	int	len;
 | 
						|
	len= strlen(tmp)+1;
 | 
						|
	if (len>BUFFER_SIZE)
 | 
						|
	    len= BUFFER_SIZE-2;
 | 
						|
	rtrn= tbGetBuffer(len);
 | 
						|
	strncpy(rtrn,tmp,len);
 | 
						|
	rtrn[len]= '\0';
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	rtrn= tbGetBuffer(1);
 | 
						|
	rtrn[0]= '\0';
 | 
						|
    }
 | 
						|
    if (format==XkbCFile) {
 | 
						|
	for (tmp=rtrn;*tmp!='\0';tmp++) {
 | 
						|
	    if ((tmp==rtrn)&&(!isalpha(*tmp)))
 | 
						|
		*tmp= '_';
 | 
						|
	    else if (!isalnum(*tmp))
 | 
						|
		*tmp= '_';
 | 
						|
	}
 | 
						|
    }
 | 
						|
    return XkbStringText(rtrn,format);
 | 
						|
}
 | 
						|
 | 
						|
/***====================================================================***/
 | 
						|
 | 
						|
char *
 | 
						|
XkbVModIndexText(Display *dpy,XkbDescPtr xkb,unsigned ndx,unsigned format)
 | 
						|
{
 | 
						|
register int len;
 | 
						|
register Atom *vmodNames;
 | 
						|
char *rtrn,*tmp;
 | 
						|
char  numBuf[20];
 | 
						|
 | 
						|
    if (xkb && xkb->names)
 | 
						|
	 vmodNames= xkb->names->vmods;
 | 
						|
    else vmodNames= NULL;
 | 
						|
 | 
						|
    tmp= NULL;
 | 
						|
    if (ndx>=XkbNumVirtualMods)
 | 
						|
	 tmp= "illegal";
 | 
						|
    else if (vmodNames&&(vmodNames[ndx]!=None))
 | 
						|
	 tmp= XkbAtomGetString(dpy,vmodNames[ndx]);
 | 
						|
    if (tmp==NULL)
 | 
						|
	sprintf(tmp=numBuf,"%d",ndx);
 | 
						|
 | 
						|
    len= strlen(tmp)+1;
 | 
						|
    if (format==XkbCFile)
 | 
						|
	len+= 4;
 | 
						|
    if (len>=BUFFER_SIZE)
 | 
						|
	len= BUFFER_SIZE-1;
 | 
						|
    rtrn= tbGetBuffer(len);
 | 
						|
    if (format==XkbCFile) {
 | 
						|
	 strcpy(rtrn,"vmod_");
 | 
						|
	 strncpy(&rtrn[5],tmp,len-4);
 | 
						|
    }
 | 
						|
    else strncpy(rtrn,tmp,len);
 | 
						|
    return rtrn;
 | 
						|
}
 | 
						|
 | 
						|
char *
 | 
						|
XkbVModMaskText(	Display *	dpy,
 | 
						|
			XkbDescPtr	xkb,
 | 
						|
			unsigned	modMask,
 | 
						|
			unsigned	mask,
 | 
						|
			unsigned	format)
 | 
						|
{
 | 
						|
register int i,bit;
 | 
						|
int	 len;
 | 
						|
char *mm,*rtrn;
 | 
						|
char *str,buf[BUFFER_SIZE];
 | 
						|
 | 
						|
    if ((modMask==0)&&(mask==0)) {
 | 
						|
	rtrn= tbGetBuffer(5);
 | 
						|
	if (format==XkbCFile)
 | 
						|
	     sprintf(rtrn,"0");
 | 
						|
	else sprintf(rtrn,"none");
 | 
						|
	return rtrn;
 | 
						|
    }
 | 
						|
    if (modMask!=0)
 | 
						|
	 mm= XkbModMaskText(modMask,format);
 | 
						|
    else mm= NULL;
 | 
						|
 | 
						|
    str= buf;
 | 
						|
    buf[0]= '\0';
 | 
						|
    if (mask) {
 | 
						|
	char *tmp;
 | 
						|
	for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
 | 
						|
	    if (mask&bit) {
 | 
						|
		tmp= XkbVModIndexText(dpy,xkb,i,format);
 | 
						|
		len= strlen(tmp)+1+(str==buf?0:1);
 | 
						|
		if (format==XkbCFile)
 | 
						|
		    len+= 4;
 | 
						|
		if ((str-(buf+len))<=BUFFER_SIZE) {
 | 
						|
		    if (str!=buf) {
 | 
						|
			if (format==XkbCFile)	*str++= '|';
 | 
						|
			else			*str++= '+';
 | 
						|
			len--;
 | 
						|
		    }
 | 
						|
		}
 | 
						|
		if (format==XkbCFile)
 | 
						|
		     sprintf(str,"%sMask",tmp);
 | 
						|
		else strcpy(str,tmp);
 | 
						|
		str= &str[len-1];
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	str= buf;
 | 
						|
    }
 | 
						|
    else str= NULL;
 | 
						|
    if (mm)	
 | 
						|
	len= strlen(mm);
 | 
						|
    else	len= 0;
 | 
						|
    if (str)
 | 
						|
	len+= strlen(str)+(mm==NULL?0:1);
 | 
						|
    if (len>=BUFFER_SIZE)
 | 
						|
	len= BUFFER_SIZE-1;
 | 
						|
    rtrn= tbGetBuffer(len+1);
 | 
						|
    rtrn[0]= '\0';
 | 
						|
 | 
						|
    if (mm!=NULL) {
 | 
						|
	i= strlen(mm);
 | 
						|
	if (i>len)
 | 
						|
	    i= len;
 | 
						|
	strcpy(rtrn,mm);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	i=0;
 | 
						|
    }
 | 
						|
    if (str!=NULL) {
 | 
						|
	if (mm!=NULL) {
 | 
						|
	    if (format==XkbCFile)	strcat(rtrn,"|");
 | 
						|
	    else			strcat(rtrn,"+");
 | 
						|
	}
 | 
						|
	strncat(rtrn,str,len-i);
 | 
						|
    }
 | 
						|
    rtrn[len]= '\0';
 | 
						|
    return rtrn;
 | 
						|
}
 | 
						|
 | 
						|
static char *modNames[XkbNumModifiers] = {
 | 
						|
    "Shift", "Lock", "Control", "Mod1", "Mod2", "Mod3", "Mod4", "Mod5"
 | 
						|
};
 | 
						|
 | 
						|
char *
 | 
						|
XkbModIndexText(unsigned ndx,unsigned format)
 | 
						|
{
 | 
						|
char *	rtrn;
 | 
						|
char	buf[100];
 | 
						|
 | 
						|
    if (format==XkbCFile) {
 | 
						|
	if (ndx<XkbNumModifiers)
 | 
						|
	     sprintf(buf,"%sMapIndex",modNames[ndx]);
 | 
						|
	else if (ndx==XkbNoModifier)
 | 
						|
	     sprintf(buf,"XkbNoModifier");
 | 
						|
	else sprintf(buf,"0x%02x",ndx);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	if (ndx<XkbNumModifiers)
 | 
						|
	     strcpy(buf,modNames[ndx]);
 | 
						|
	else if (ndx==XkbNoModifier)
 | 
						|
	     strcpy(buf,"none");
 | 
						|
	else sprintf(buf,"ILLEGAL_%02x",ndx);
 | 
						|
    }
 | 
						|
    rtrn= tbGetBuffer(strlen(buf)+1);
 | 
						|
    strcpy(rtrn,buf);
 | 
						|
    return rtrn;
 | 
						|
}
 | 
						|
 | 
						|
char *
 | 
						|
XkbModMaskText(unsigned mask,unsigned format)
 | 
						|
{
 | 
						|
register int i,bit;
 | 
						|
char buf[64],*rtrn;
 | 
						|
 | 
						|
    if ((mask&0xff)==0xff) {
 | 
						|
	if (format==XkbCFile) 		strcpy(buf,"0xff");
 | 
						|
	else				strcpy(buf,"all");
 | 
						|
    }
 | 
						|
    else if ((mask&0xff)==0) {
 | 
						|
	if (format==XkbCFile)		strcpy(buf,"0");
 | 
						|
	else				strcpy(buf,"none");
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	char *str= buf;
 | 
						|
	buf[0]= '\0';
 | 
						|
	for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) {
 | 
						|
	    if (mask&bit) {
 | 
						|
		if (str!=buf) {
 | 
						|
		    if (format==XkbCFile)	*str++= '|';
 | 
						|
		    else			*str++= '+';
 | 
						|
		}
 | 
						|
		strcpy(str,modNames[i]);
 | 
						|
		str= &str[strlen(str)];
 | 
						|
		if (format==XkbCFile) {
 | 
						|
		    strcpy(str,"Mask");
 | 
						|
		    str+= 4;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
    rtrn= tbGetBuffer(strlen(buf)+1);
 | 
						|
    strcpy(rtrn,buf);
 | 
						|
    return rtrn;
 | 
						|
}
 | 
						|
 | 
						|
/***====================================================================***/
 | 
						|
 | 
						|
/*ARGSUSED*/
 | 
						|
char *
 | 
						|
XkbConfigText(unsigned config,unsigned format)
 | 
						|
{
 | 
						|
static char *buf;
 | 
						|
 | 
						|
    buf= tbGetBuffer(32);
 | 
						|
    switch (config) {
 | 
						|
	case XkmSemanticsFile:
 | 
						|
	    strcpy(buf,"Semantics");
 | 
						|
	    break;
 | 
						|
	case XkmLayoutFile:
 | 
						|
	    strcpy(buf,"Layout");
 | 
						|
	    break;
 | 
						|
	case XkmKeymapFile:
 | 
						|
	    strcpy(buf,"Keymap");
 | 
						|
	    break;
 | 
						|
	case XkmGeometryFile:
 | 
						|
	case XkmGeometryIndex:
 | 
						|
	    strcpy(buf,"Geometry");
 | 
						|
	    break;
 | 
						|
	case XkmTypesIndex:
 | 
						|
	    strcpy(buf,"Types");
 | 
						|
	    break;
 | 
						|
	case XkmCompatMapIndex:
 | 
						|
	    strcpy(buf,"CompatMap");
 | 
						|
	    break;
 | 
						|
	case XkmSymbolsIndex:
 | 
						|
	    strcpy(buf,"Symbols");
 | 
						|
	    break;
 | 
						|
	case XkmIndicatorsIndex:
 | 
						|
	    strcpy(buf,"Indicators");
 | 
						|
	    break;
 | 
						|
	case XkmKeyNamesIndex:
 | 
						|
	    strcpy(buf,"KeyNames");
 | 
						|
	    break;
 | 
						|
	case XkmVirtualModsIndex:
 | 
						|
	    strcpy(buf,"VirtualMods");
 | 
						|
	    break;
 | 
						|
	default:
 | 
						|
	    sprintf(buf,"unknown(%d)",config);
 | 
						|
	    break;
 | 
						|
    }
 | 
						|
    return buf;
 | 
						|
}
 | 
						|
 | 
						|
/***====================================================================***/
 | 
						|
 | 
						|
char *
 | 
						|
XkbKeysymText(KeySym sym,unsigned format)
 | 
						|
{
 | 
						|
static char buf[32],*rtrn;
 | 
						|
 | 
						|
    if (sym==NoSymbol)
 | 
						|
	 strcpy(rtrn=buf,"NoSymbol");
 | 
						|
    else sprintf(rtrn=buf, "0x%lx", (long)sym);
 | 
						|
    return rtrn;
 | 
						|
}
 | 
						|
 | 
						|
char *
 | 
						|
XkbKeyNameText(char *name,unsigned format)
 | 
						|
{
 | 
						|
char *buf;
 | 
						|
 | 
						|
    if (format==XkbCFile) {
 | 
						|
	buf= tbGetBuffer(5);
 | 
						|
	memcpy(buf,name,4);
 | 
						|
	buf[4]= '\0';
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	int len;
 | 
						|
	buf= tbGetBuffer(7);
 | 
						|
	buf[0]= '<';
 | 
						|
	memcpy(&buf[1],name,4);
 | 
						|
	buf[5]= '\0';
 | 
						|
	len= strlen(buf);
 | 
						|
	buf[len++]= '>';
 | 
						|
	buf[len]= '\0';
 | 
						|
    }
 | 
						|
    return buf;
 | 
						|
}
 | 
						|
 | 
						|
/***====================================================================***/
 | 
						|
 | 
						|
static char *siMatchText[5] = {
 | 
						|
	"NoneOf", "AnyOfOrNone", "AnyOf", "AllOf", "Exactly"
 | 
						|
};
 | 
						|
 | 
						|
char *
 | 
						|
XkbSIMatchText(unsigned type,unsigned format)
 | 
						|
{
 | 
						|
static char buf[40];
 | 
						|
char *rtrn;
 | 
						|
 | 
						|
    switch (type&XkbSI_OpMask) {
 | 
						|
	case XkbSI_NoneOf:	rtrn= siMatchText[0]; break;
 | 
						|
	case XkbSI_AnyOfOrNone:	rtrn= siMatchText[1]; break;
 | 
						|
	case XkbSI_AnyOf:	rtrn= siMatchText[2]; break;
 | 
						|
	case XkbSI_AllOf:	rtrn= siMatchText[3]; break;
 | 
						|
	case XkbSI_Exactly:	rtrn= siMatchText[4]; break;
 | 
						|
	default:		sprintf(buf,"0x%x",type&XkbSI_OpMask);
 | 
						|
				return buf;
 | 
						|
    }
 | 
						|
    if (format==XkbCFile) {
 | 
						|
	if (type&XkbSI_LevelOneOnly)
 | 
						|
	     sprintf(buf,"XkbSI_LevelOneOnly|XkbSI_%s",rtrn);
 | 
						|
	else sprintf(buf,"XkbSI_%s",rtrn);
 | 
						|
	rtrn= buf;
 | 
						|
    }
 | 
						|
    return rtrn;
 | 
						|
}
 | 
						|
 | 
						|
/***====================================================================***/
 | 
						|
 | 
						|
static char *imWhichNames[]= {
 | 
						|
	"base",
 | 
						|
	"latched",
 | 
						|
	"locked",
 | 
						|
	"effective",
 | 
						|
	"compat"
 | 
						|
};
 | 
						|
 | 
						|
char *
 | 
						|
XkbIMWhichStateMaskText(unsigned use_which,unsigned format)
 | 
						|
{
 | 
						|
int		len;
 | 
						|
unsigned	i,bit,tmp;
 | 
						|
char *		buf;
 | 
						|
 | 
						|
    if (use_which==0) {
 | 
						|
	buf= tbGetBuffer(2);
 | 
						|
	strcpy(buf,"0");
 | 
						|
	return buf;
 | 
						|
    }
 | 
						|
    tmp= use_which&XkbIM_UseAnyMods;
 | 
						|
    for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
 | 
						|
	if (tmp&bit) {
 | 
						|
	    tmp&= ~bit;
 | 
						|
	    len+= strlen(imWhichNames[i])+1;
 | 
						|
	    if (format==XkbCFile)
 | 
						|
		len+= 9;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    buf= tbGetBuffer(len+1);
 | 
						|
    tmp= use_which&XkbIM_UseAnyMods;
 | 
						|
    for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
 | 
						|
	if (tmp&bit) {
 | 
						|
	    tmp&= ~bit;
 | 
						|
	    if (format==XkbCFile) {
 | 
						|
		if (len!=0)
 | 
						|
		    buf[len++]= '|';
 | 
						|
		sprintf(&buf[len],"XkbIM_Use%s",imWhichNames[i]);
 | 
						|
		buf[len+9]= toupper(buf[len+9]);
 | 
						|
	    }
 | 
						|
	    else {
 | 
						|
		if (len!=0)
 | 
						|
		    buf[len++]= '+';
 | 
						|
		sprintf(&buf[len],"%s",imWhichNames[i]);
 | 
						|
	    }
 | 
						|
	    len+= strlen(&buf[len]);
 | 
						|
	}
 | 
						|
    }
 | 
						|
    return buf;
 | 
						|
}
 | 
						|
 | 
						|
static char *ctrlNames[] = {
 | 
						|
	"repeatKeys",
 | 
						|
	"slowKeys",
 | 
						|
	"bounceKeys",
 | 
						|
	"stickyKeys",
 | 
						|
	"mouseKeys",
 | 
						|
	"mouseKeysAccel",
 | 
						|
	"accessXKeys",
 | 
						|
	"accessXTimeout",
 | 
						|
	"accessXFeedback",
 | 
						|
	"audibleBell",
 | 
						|
	"overlay1",
 | 
						|
	"overlay2",
 | 
						|
	"ignoreGroupLock"
 | 
						|
};
 | 
						|
 | 
						|
char *
 | 
						|
XkbControlsMaskText(unsigned ctrls,unsigned format)
 | 
						|
{
 | 
						|
int		len;
 | 
						|
unsigned	i,bit,tmp;
 | 
						|
char *		buf;
 | 
						|
 | 
						|
    if (ctrls==0) {
 | 
						|
	buf= tbGetBuffer(5);
 | 
						|
	if (format==XkbCFile)
 | 
						|
	     strcpy(buf,"0");
 | 
						|
	else strcpy(buf,"none");
 | 
						|
	return buf;
 | 
						|
    }
 | 
						|
    tmp= ctrls&XkbAllBooleanCtrlsMask;
 | 
						|
    for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
 | 
						|
	if (tmp&bit) {
 | 
						|
	    tmp&= ~bit;
 | 
						|
	    len+= strlen(ctrlNames[i])+1;
 | 
						|
	    if (format==XkbCFile)
 | 
						|
		len+= 7;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    buf= tbGetBuffer(len+1);
 | 
						|
    tmp= ctrls&XkbAllBooleanCtrlsMask;
 | 
						|
    for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) {
 | 
						|
	if (tmp&bit) {
 | 
						|
	    tmp&= ~bit;
 | 
						|
	    if (format==XkbCFile) {
 | 
						|
		if (len!=0)
 | 
						|
		    buf[len++]= '|';
 | 
						|
		sprintf(&buf[len],"Xkb%sMask",ctrlNames[i]);
 | 
						|
		buf[len+3]= toupper(buf[len+3]);
 | 
						|
	    }
 | 
						|
	    else {
 | 
						|
		if (len!=0)
 | 
						|
		    buf[len++]= '+';
 | 
						|
		sprintf(&buf[len],"%s",ctrlNames[i]);
 | 
						|
	    }
 | 
						|
	    len+= strlen(&buf[len]);
 | 
						|
	}
 | 
						|
    }
 | 
						|
    return buf;
 | 
						|
}
 | 
						|
 | 
						|
/***====================================================================***/
 | 
						|
 | 
						|
char *
 | 
						|
XkbStringText(char *str,unsigned format)
 | 
						|
{
 | 
						|
char *	buf;
 | 
						|
register char *in,*out;
 | 
						|
int	len;
 | 
						|
Bool	ok;
 | 
						|
 | 
						|
    if (str==NULL) {
 | 
						|
	buf= tbGetBuffer(2);
 | 
						|
	buf[0]='\0';
 | 
						|
	return buf;
 | 
						|
    }
 | 
						|
    else if (format==XkbXKMFile)
 | 
						|
	return str;
 | 
						|
    for (ok= True,len=0,in=str;*in!='\0';in++,len++) {
 | 
						|
	if (!isprint(*in)) {
 | 
						|
	    ok= False;
 | 
						|
	    switch (*in) {
 | 
						|
		case '\n': case '\t': case '\v':
 | 
						|
		case '\b': case '\r': case '\f':
 | 
						|
		    len++;
 | 
						|
		    break;
 | 
						|
		default:
 | 
						|
		    len+= 4;
 | 
						|
		    break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
    if (ok)
 | 
						|
	return str;
 | 
						|
    buf= tbGetBuffer(len+1);
 | 
						|
    for (in=str,out=buf;*in!='\0';in++) {
 | 
						|
	if (isprint(*in))
 | 
						|
	    *out++= *in;
 | 
						|
	else {
 | 
						|
	    *out++= '\\';
 | 
						|
	    if (*in=='\n')	*out++= 'n';
 | 
						|
	    else if (*in=='\t')	*out++= 't';
 | 
						|
	    else if (*in=='\v')	*out++= 'v';
 | 
						|
	    else if (*in=='\b')	*out++= 'b';
 | 
						|
	    else if (*in=='\r')	*out++= 'r';
 | 
						|
	    else if (*in=='\f')	*out++= 'f';
 | 
						|
	    else if ((*in=='\033')&&(format==XkbXKMFile)) {
 | 
						|
		*out++= 'e';
 | 
						|
	    }
 | 
						|
	    else {
 | 
						|
		*out++= '0';
 | 
						|
		sprintf(out,"%o",*in);
 | 
						|
		while (*out!='\0')
 | 
						|
		    out++;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
    *out++= '\0';
 | 
						|
    return buf;
 | 
						|
}
 | 
						|
 | 
						|
/***====================================================================***/
 | 
						|
 | 
						|
char *
 | 
						|
XkbGeomFPText(int val,unsigned format)
 | 
						|
{
 | 
						|
int	whole,frac;
 | 
						|
char *	buf;
 | 
						|
 | 
						|
    buf= tbGetBuffer(12);
 | 
						|
    if (format==XkbCFile) {
 | 
						|
	sprintf(buf,"%d",val);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	whole= val/XkbGeomPtsPerMM;
 | 
						|
	frac= val%XkbGeomPtsPerMM;
 | 
						|
	if (frac!=0)
 | 
						|
	     sprintf(buf,"%d.%d",whole,frac);
 | 
						|
	else sprintf(buf,"%d",whole);
 | 
						|
    }
 | 
						|
    return buf;
 | 
						|
}
 | 
						|
 | 
						|
char *
 | 
						|
XkbDoodadTypeText(unsigned type,unsigned format)
 | 
						|
{
 | 
						|
char *	buf;
 | 
						|
    if (format==XkbCFile) {
 | 
						|
	buf= tbGetBuffer(24);
 | 
						|
	if (type==XkbOutlineDoodad)	   strcpy(buf,"XkbOutlineDoodad");
 | 
						|
	else if (type==XkbSolidDoodad)	   strcpy(buf,"XkbSolidDoodad");
 | 
						|
	else if (type==XkbTextDoodad)	   strcpy(buf,"XkbTextDoodad");
 | 
						|
	else if (type==XkbIndicatorDoodad) strcpy(buf,"XkbIndicatorDoodad");
 | 
						|
	else if (type==XkbLogoDoodad)	   strcpy(buf,"XkbLogoDoodad");
 | 
						|
	else				   sprintf(buf,"UnknownDoodad%d",type);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	buf= tbGetBuffer(12);
 | 
						|
	if (type==XkbOutlineDoodad)	   strcpy(buf,"outline");
 | 
						|
	else if (type==XkbSolidDoodad)	   strcpy(buf,"solid");
 | 
						|
	else if (type==XkbTextDoodad)	   strcpy(buf,"text");
 | 
						|
	else if (type==XkbIndicatorDoodad) strcpy(buf,"indicator");
 | 
						|
	else if (type==XkbLogoDoodad)	   strcpy(buf,"logo");
 | 
						|
	else				   sprintf(buf,"unknown%d",type);
 | 
						|
    }
 | 
						|
    return buf;
 | 
						|
}
 | 
						|
 | 
						|
static char *actionTypeNames[XkbSA_NumActions]= {
 | 
						|
    "NoAction", 
 | 
						|
    "SetMods",      "LatchMods",    "LockMods", 
 | 
						|
    "SetGroup",     "LatchGroup",   "LockGroup",
 | 
						|
    "MovePtr",
 | 
						|
    "PtrBtn",       "LockPtrBtn",
 | 
						|
    "SetPtrDflt",
 | 
						|
    "ISOLock",
 | 
						|
    "Terminate",    "SwitchScreen", 
 | 
						|
    "SetControls",  "LockControls",
 | 
						|
    "ActionMessage",
 | 
						|
    "RedirectKey",
 | 
						|
    "DeviceBtn",    "LockDeviceBtn"
 | 
						|
};
 | 
						|
 | 
						|
char *
 | 
						|
XkbActionTypeText(unsigned type,unsigned format)
 | 
						|
{
 | 
						|
static char buf[32];
 | 
						|
char *rtrn;
 | 
						|
 | 
						|
    if (type<=XkbSA_LastAction) {
 | 
						|
	rtrn= actionTypeNames[type];
 | 
						|
	if (format==XkbCFile) {
 | 
						|
	    sprintf(buf,"XkbSA_%s",rtrn);
 | 
						|
	    return buf;
 | 
						|
	}
 | 
						|
	return rtrn;
 | 
						|
    }
 | 
						|
    sprintf(buf,"Private");
 | 
						|
    return buf;
 | 
						|
}
 | 
						|
 | 
						|
/***====================================================================***/
 | 
						|
 | 
						|
static int
 | 
						|
TryCopyStr(char *to,char *from,int *pLeft)
 | 
						|
{
 | 
						|
register int len;
 | 
						|
    if (*pLeft>0) {
 | 
						|
	len= strlen(from);
 | 
						|
	if (len<((*pLeft)-3)) {
 | 
						|
	    strcat(to,from);
 | 
						|
	    *pLeft-= len;
 | 
						|
	    return True;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    *pLeft= -1;
 | 
						|
    return False;
 | 
						|
}
 | 
						|
 | 
						|
/*ARGSUSED*/
 | 
						|
static Bool
 | 
						|
CopyNoActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int*sz)
 | 
						|
{
 | 
						|
    return True;
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
CopyModActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
 | 
						|
								int* sz)
 | 
						|
{
 | 
						|
XkbModAction *	act;
 | 
						|
unsigned	tmp;
 | 
						|
 | 
						|
    act= &action->mods;
 | 
						|
    tmp= XkbModActionVMods(act);
 | 
						|
    TryCopyStr(buf,"modifiers=",sz);
 | 
						|
    if (act->flags&XkbSA_UseModMapMods)
 | 
						|
	  TryCopyStr(buf,"modMapMods",sz);
 | 
						|
    else if (act->real_mods || tmp) {
 | 
						|
	 TryCopyStr(buf,
 | 
						|
		     XkbVModMaskText(dpy,xkb,act->real_mods,tmp,XkbXKBFile),
 | 
						|
		     sz);
 | 
						|
    }
 | 
						|
    else TryCopyStr(buf,"none",sz);
 | 
						|
    if (act->type==XkbSA_LockMods)
 | 
						|
	return True;
 | 
						|
    if (act->flags&XkbSA_ClearLocks)
 | 
						|
	TryCopyStr(buf,",clearLocks",sz);
 | 
						|
    if (act->flags&XkbSA_LatchToLock)
 | 
						|
	TryCopyStr(buf,",latchToLock",sz);
 | 
						|
    return True;
 | 
						|
}
 | 
						|
 | 
						|
/*ARGSUSED*/
 | 
						|
static Bool
 | 
						|
CopyGroupActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
 | 
						|
								int *sz)
 | 
						|
{
 | 
						|
XkbGroupAction *	act;
 | 
						|
char			tbuf[32];
 | 
						|
 | 
						|
    act= &action->group;
 | 
						|
    TryCopyStr(buf,"group=",sz);
 | 
						|
    if (act->flags&XkbSA_GroupAbsolute)
 | 
						|
	 sprintf(tbuf,"%d",XkbSAGroup(act)+1);
 | 
						|
    else if (XkbSAGroup(act)<0)
 | 
						|
	 sprintf(tbuf,"%d",XkbSAGroup(act));
 | 
						|
    else sprintf(tbuf,"+%d",XkbSAGroup(act));
 | 
						|
    TryCopyStr(buf,tbuf,sz);
 | 
						|
    if (act->type==XkbSA_LockGroup)
 | 
						|
	return True;
 | 
						|
    if (act->flags&XkbSA_ClearLocks)
 | 
						|
	TryCopyStr(buf,",clearLocks",sz);
 | 
						|
    if (act->flags&XkbSA_LatchToLock)
 | 
						|
	TryCopyStr(buf,",latchToLock",sz);
 | 
						|
    return True;
 | 
						|
}
 | 
						|
 | 
						|
/*ARGSUSED*/
 | 
						|
static Bool
 | 
						|
CopyMovePtrArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
 | 
						|
{
 | 
						|
XkbPtrAction *	act;
 | 
						|
int		x,y;
 | 
						|
char		tbuf[32];
 | 
						|
 | 
						|
    act= &action->ptr;
 | 
						|
    x= XkbPtrActionX(act);
 | 
						|
    y= XkbPtrActionY(act);
 | 
						|
    if ((act->flags&XkbSA_MoveAbsoluteX)||(x<0))
 | 
						|
	 sprintf(tbuf,"x=%d",x);
 | 
						|
    else sprintf(tbuf,"x=+%d",x);
 | 
						|
    TryCopyStr(buf,tbuf,sz);
 | 
						|
 | 
						|
    if ((act->flags&XkbSA_MoveAbsoluteY)||(y<0))
 | 
						|
	 sprintf(tbuf,",y=%d",y);
 | 
						|
    else sprintf(tbuf,",y=+%d",y);
 | 
						|
    TryCopyStr(buf,tbuf,sz);
 | 
						|
    if (act->flags&XkbSA_NoAcceleration)
 | 
						|
	TryCopyStr(buf,",!accel",sz);
 | 
						|
    return True;
 | 
						|
}
 | 
						|
 | 
						|
/*ARGSUSED*/
 | 
						|
static Bool
 | 
						|
CopyPtrBtnArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
 | 
						|
{
 | 
						|
XkbPtrBtnAction *	act;
 | 
						|
char			tbuf[32];
 | 
						|
 | 
						|
    act= &action->btn;
 | 
						|
    TryCopyStr(buf,"button=",sz);
 | 
						|
    if ((act->button>0)&&(act->button<6)) {
 | 
						|
	 sprintf(tbuf,"%d",act->button);
 | 
						|
	 TryCopyStr(buf,tbuf,sz);
 | 
						|
    }
 | 
						|
    else TryCopyStr(buf,"default",sz);
 | 
						|
    if (act->count>0) {
 | 
						|
	sprintf(tbuf,",count=%d",act->count);
 | 
						|
	TryCopyStr(buf,tbuf,sz);
 | 
						|
    }
 | 
						|
    if (action->type==XkbSA_LockPtrBtn) {
 | 
						|
	switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) {
 | 
						|
	    case XkbSA_LockNoLock:
 | 
						|
		sprintf(tbuf,",affect=unlock"); break;
 | 
						|
	    case XkbSA_LockNoUnlock:
 | 
						|
		sprintf(tbuf,",affect=lock"); break;
 | 
						|
	    case XkbSA_LockNoUnlock|XkbSA_LockNoLock:
 | 
						|
		sprintf(tbuf,",affect=neither"); break;
 | 
						|
	    default:
 | 
						|
		sprintf(tbuf,",affect=both"); break;
 | 
						|
	}
 | 
						|
	TryCopyStr(buf,tbuf,sz);
 | 
						|
    }
 | 
						|
    return True;
 | 
						|
}
 | 
						|
 | 
						|
/*ARGSUSED*/
 | 
						|
static Bool
 | 
						|
CopySetPtrDfltArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
 | 
						|
								int *sz)
 | 
						|
{
 | 
						|
XkbPtrDfltAction *	act;
 | 
						|
char			tbuf[32];
 | 
						|
 | 
						|
    act= &action->dflt;
 | 
						|
    if (act->affect==XkbSA_AffectDfltBtn) {
 | 
						|
	TryCopyStr(buf,"affect=button,button=",sz);
 | 
						|
	if ((act->flags&XkbSA_DfltBtnAbsolute)||(XkbSAPtrDfltValue(act)<0))
 | 
						|
	     sprintf(tbuf,"%d",XkbSAPtrDfltValue(act));
 | 
						|
	else sprintf(tbuf,"+%d",XkbSAPtrDfltValue(act));
 | 
						|
	TryCopyStr(buf,tbuf,sz);
 | 
						|
    }
 | 
						|
    return True;
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
CopyISOLockArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
 | 
						|
{
 | 
						|
XkbISOAction *	act;
 | 
						|
char		tbuf[64];
 | 
						|
 | 
						|
    act= &action->iso;
 | 
						|
    if (act->flags&XkbSA_ISODfltIsGroup) {
 | 
						|
	TryCopyStr(tbuf,"group=",sz);
 | 
						|
	if (act->flags&XkbSA_GroupAbsolute)
 | 
						|
	     sprintf(tbuf,"%d",XkbSAGroup(act)+1);
 | 
						|
	else if (XkbSAGroup(act)<0)
 | 
						|
	     sprintf(tbuf,"%d",XkbSAGroup(act));
 | 
						|
	else sprintf(tbuf,"+%d",XkbSAGroup(act));
 | 
						|
	TryCopyStr(buf,tbuf,sz);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	unsigned tmp;
 | 
						|
	tmp= XkbModActionVMods(act);
 | 
						|
	TryCopyStr(buf,"modifiers=",sz);
 | 
						|
	if (act->flags&XkbSA_UseModMapMods)
 | 
						|
	     TryCopyStr(buf,"modMapMods",sz);
 | 
						|
	else if (act->real_mods || tmp) {
 | 
						|
	    if (act->real_mods) {
 | 
						|
		TryCopyStr(buf,XkbModMaskText(act->real_mods,XkbXKBFile),sz);
 | 
						|
		if (tmp)
 | 
						|
		    TryCopyStr(buf,"+",sz);
 | 
						|
	    }
 | 
						|
	    if (tmp)
 | 
						|
		TryCopyStr(buf,XkbVModMaskText(dpy,xkb,0,tmp,XkbXKBFile),sz);
 | 
						|
	}
 | 
						|
	else TryCopyStr(buf,"none",sz);
 | 
						|
    }
 | 
						|
    TryCopyStr(buf,",affect=",sz);
 | 
						|
    if ((act->affect&XkbSA_ISOAffectMask)==0)
 | 
						|
	TryCopyStr(buf,"all",sz);
 | 
						|
    else {
 | 
						|
	int nOut= 0;
 | 
						|
	if ((act->affect&XkbSA_ISONoAffectMods)==0) {
 | 
						|
	    TryCopyStr(buf,"mods",sz);
 | 
						|
	    nOut++;
 | 
						|
	}
 | 
						|
	if ((act->affect&XkbSA_ISONoAffectGroup)==0) {
 | 
						|
	    sprintf(tbuf,"%sgroups",(nOut>0?"+":""));
 | 
						|
	    TryCopyStr(buf,tbuf,sz);
 | 
						|
	    nOut++;
 | 
						|
	}
 | 
						|
	if ((act->affect&XkbSA_ISONoAffectPtr)==0) {
 | 
						|
	    sprintf(tbuf,"%spointer",(nOut>0?"+":""));
 | 
						|
	    TryCopyStr(buf,tbuf,sz);
 | 
						|
	    nOut++;
 | 
						|
	}
 | 
						|
	if ((act->affect&XkbSA_ISONoAffectCtrls)==0) {
 | 
						|
	    sprintf(tbuf,"%scontrols",(nOut>0?"+":""));
 | 
						|
	    TryCopyStr(buf,tbuf,sz);
 | 
						|
	    nOut++;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    return True;
 | 
						|
}
 | 
						|
 | 
						|
/*ARGSUSED*/
 | 
						|
static Bool
 | 
						|
CopySwitchScreenArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
 | 
						|
								int *sz)
 | 
						|
{
 | 
						|
XkbSwitchScreenAction *	act;
 | 
						|
char			tbuf[32];
 | 
						|
 | 
						|
    act= &action->screen;
 | 
						|
    if ((act->flags&XkbSA_SwitchAbsolute)||(XkbSAScreen(act)<0))
 | 
						|
	 sprintf(tbuf,"screen=%d",XkbSAScreen(act));
 | 
						|
    else sprintf(tbuf,"screen=+%d",XkbSAScreen(act));
 | 
						|
    TryCopyStr(buf,tbuf,sz);
 | 
						|
    if (act->flags&XkbSA_SwitchApplication)
 | 
						|
	 TryCopyStr(buf,",!same",sz);
 | 
						|
    else TryCopyStr(buf,",same",sz);
 | 
						|
    return True;
 | 
						|
}
 | 
						|
 | 
						|
/*ARGSUSED*/
 | 
						|
static Bool
 | 
						|
CopySetLockControlsArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,
 | 
						|
							char *buf,int *sz)
 | 
						|
{
 | 
						|
XkbCtrlsAction *	act;
 | 
						|
unsigned		tmp;
 | 
						|
char			tbuf[32];
 | 
						|
 | 
						|
    act= &action->ctrls;
 | 
						|
    tmp= XkbActionCtrls(act);
 | 
						|
    TryCopyStr(buf,"controls=",sz);
 | 
						|
    if (tmp==0)
 | 
						|
	TryCopyStr(buf,"none",sz);
 | 
						|
    else if ((tmp&XkbAllBooleanCtrlsMask)==XkbAllBooleanCtrlsMask)
 | 
						|
	TryCopyStr(buf,"all",sz);
 | 
						|
    else {
 | 
						|
	int nOut= 0;
 | 
						|
	if (tmp&XkbRepeatKeysMask) {
 | 
						|
	    sprintf(tbuf,"%sRepeatKeys",(nOut>0?"+":""));
 | 
						|
	    TryCopyStr(buf,tbuf,sz);
 | 
						|
	    nOut++;
 | 
						|
	}
 | 
						|
	if (tmp&XkbSlowKeysMask) {
 | 
						|
	    sprintf(tbuf,"%sSlowKeys",(nOut>0?"+":""));
 | 
						|
	    TryCopyStr(buf,tbuf,sz);
 | 
						|
	    nOut++;
 | 
						|
	}
 | 
						|
	if (tmp&XkbBounceKeysMask) {
 | 
						|
	    sprintf(tbuf,"%sBounceKeys",(nOut>0?"+":""));
 | 
						|
	    TryCopyStr(buf,tbuf,sz);
 | 
						|
	    nOut++;
 | 
						|
	}
 | 
						|
	if (tmp&XkbStickyKeysMask) {
 | 
						|
	    sprintf(tbuf,"%sStickyKeys",(nOut>0?"+":""));
 | 
						|
	    TryCopyStr(buf,tbuf,sz);
 | 
						|
	    nOut++;
 | 
						|
	}
 | 
						|
	if (tmp&XkbMouseKeysMask) {
 | 
						|
	    sprintf(tbuf,"%sMouseKeys",(nOut>0?"+":""));
 | 
						|
	    TryCopyStr(buf,tbuf,sz);
 | 
						|
	    nOut++;
 | 
						|
	}
 | 
						|
	if (tmp&XkbMouseKeysAccelMask) {
 | 
						|
	    sprintf(tbuf,"%sMouseKeysAccel",(nOut>0?"+":""));
 | 
						|
	    TryCopyStr(buf,tbuf,sz);
 | 
						|
	    nOut++;
 | 
						|
	}
 | 
						|
	if (tmp&XkbAccessXKeysMask) {
 | 
						|
	    sprintf(tbuf,"%sAccessXKeys",(nOut>0?"+":""));
 | 
						|
	    TryCopyStr(buf,tbuf,sz);
 | 
						|
	    nOut++;
 | 
						|
	}
 | 
						|
	if (tmp&XkbAccessXTimeoutMask) {
 | 
						|
	    sprintf(tbuf,"%sAccessXTimeout",(nOut>0?"+":""));
 | 
						|
	    TryCopyStr(buf,tbuf,sz);
 | 
						|
	    nOut++;
 | 
						|
	}
 | 
						|
	if (tmp&XkbAccessXFeedbackMask) {
 | 
						|
	    sprintf(tbuf,"%sAccessXFeedback",(nOut>0?"+":""));
 | 
						|
	    TryCopyStr(buf,tbuf,sz);
 | 
						|
	    nOut++;
 | 
						|
	}
 | 
						|
	if (tmp&XkbAudibleBellMask) {
 | 
						|
	    sprintf(tbuf,"%sAudibleBell",(nOut>0?"+":""));
 | 
						|
	    TryCopyStr(buf,tbuf,sz);
 | 
						|
	    nOut++;
 | 
						|
	}
 | 
						|
	if (tmp&XkbOverlay1Mask) {
 | 
						|
	    sprintf(tbuf,"%sOverlay1",(nOut>0?"+":""));
 | 
						|
	    TryCopyStr(buf,tbuf,sz);
 | 
						|
	    nOut++;
 | 
						|
	}
 | 
						|
	if (tmp&XkbOverlay2Mask) {
 | 
						|
	    sprintf(tbuf,"%sOverlay2",(nOut>0?"+":""));
 | 
						|
	    TryCopyStr(buf,tbuf,sz);
 | 
						|
	    nOut++;
 | 
						|
	}
 | 
						|
	if (tmp&XkbIgnoreGroupLockMask) {
 | 
						|
	    sprintf(tbuf,"%sIgnoreGroupLock",(nOut>0?"+":""));
 | 
						|
	    TryCopyStr(buf,tbuf,sz);
 | 
						|
	    nOut++;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    return True;
 | 
						|
}
 | 
						|
 | 
						|
/*ARGSUSED*/
 | 
						|
static Bool
 | 
						|
CopyActionMessageArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
 | 
						|
								int *sz)
 | 
						|
{
 | 
						|
XkbMessageAction *	act;
 | 
						|
unsigned		all;
 | 
						|
char			tbuf[32];
 | 
						|
 | 
						|
    act= &action->msg;
 | 
						|
    all= XkbSA_MessageOnPress|XkbSA_MessageOnRelease;
 | 
						|
    TryCopyStr(buf,"report=",sz);
 | 
						|
    if ((act->flags&all)==0)
 | 
						|
	TryCopyStr(buf,"none",sz);
 | 
						|
    else if ((act->flags&all)==all)
 | 
						|
	TryCopyStr(buf,"all",sz);
 | 
						|
    else if (act->flags&XkbSA_MessageOnPress)
 | 
						|
	 TryCopyStr(buf,"KeyPress",sz);
 | 
						|
    else TryCopyStr(buf,"KeyRelease",sz);
 | 
						|
    sprintf(tbuf,",data[0]=0x%02x",act->message[0]); TryCopyStr(buf,tbuf,sz);
 | 
						|
    sprintf(tbuf,",data[1]=0x%02x",act->message[1]); TryCopyStr(buf,tbuf,sz);
 | 
						|
    sprintf(tbuf,",data[2]=0x%02x",act->message[2]); TryCopyStr(buf,tbuf,sz);
 | 
						|
    sprintf(tbuf,",data[3]=0x%02x",act->message[3]); TryCopyStr(buf,tbuf,sz);
 | 
						|
    sprintf(tbuf,",data[4]=0x%02x",act->message[4]); TryCopyStr(buf,tbuf,sz);
 | 
						|
    sprintf(tbuf,",data[5]=0x%02x",act->message[5]); TryCopyStr(buf,tbuf,sz);
 | 
						|
    return True;
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
CopyRedirectKeyArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
 | 
						|
								int *sz)
 | 
						|
{
 | 
						|
XkbRedirectKeyAction *	act;
 | 
						|
char			tbuf[32],*tmp;
 | 
						|
unsigned		kc;
 | 
						|
unsigned		vmods,vmods_mask;
 | 
						|
 | 
						|
    act= &action->redirect;
 | 
						|
    kc= act->new_key;
 | 
						|
    vmods= XkbSARedirectVMods(act);
 | 
						|
    vmods_mask= XkbSARedirectVModsMask(act);
 | 
						|
    if (xkb && xkb->names && xkb->names->keys && (kc<=xkb->max_key_code) &&
 | 
						|
				(xkb->names->keys[kc].name[0]!='\0')) {
 | 
						|
	char *kn;
 | 
						|
	kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile);
 | 
						|
	sprintf(tbuf,"key=%s",kn);
 | 
						|
    }
 | 
						|
    else sprintf(tbuf,"key=%d",kc);
 | 
						|
    TryCopyStr(buf,tbuf,sz);
 | 
						|
    if ((act->mods_mask==0)&&(vmods_mask==0))
 | 
						|
	return True;
 | 
						|
    if ((act->mods_mask==XkbAllModifiersMask)&&
 | 
						|
	(vmods_mask==XkbAllVirtualModsMask)) {
 | 
						|
	tmp= XkbVModMaskText(dpy,xkb,act->mods,vmods,XkbXKBFile);
 | 
						|
	TryCopyStr(buf,",mods=",sz);
 | 
						|
	TryCopyStr(buf,tmp,sz);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	if ((act->mods_mask&act->mods)||(vmods_mask&vmods)) {
 | 
						|
	    tmp= XkbVModMaskText(dpy,xkb,act->mods_mask&act->mods,
 | 
						|
					 vmods_mask&vmods,XkbXKBFile);
 | 
						|
	    TryCopyStr(buf,",mods= ",sz);
 | 
						|
	    TryCopyStr(buf,tmp,sz);
 | 
						|
	}
 | 
						|
	if ((act->mods_mask&(~act->mods))||(vmods_mask&(~vmods))) {
 | 
						|
	    tmp= XkbVModMaskText(dpy,xkb,act->mods_mask&(~act->mods),
 | 
						|
					 vmods_mask&(~vmods),XkbXKBFile);
 | 
						|
	    TryCopyStr(buf,",clearMods= ",sz);
 | 
						|
	    TryCopyStr(buf,tmp,sz);
 | 
						|
	}
 | 
						|
    }
 | 
						|
    return True;
 | 
						|
}
 | 
						|
 | 
						|
/*ARGSUSED*/
 | 
						|
static Bool
 | 
						|
CopyDeviceBtnArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,
 | 
						|
								int *sz)
 | 
						|
{
 | 
						|
XkbDeviceBtnAction *	act;
 | 
						|
char			tbuf[32];
 | 
						|
 | 
						|
    act= &action->devbtn;
 | 
						|
    sprintf(tbuf,"device= %d",act->device); TryCopyStr(buf,tbuf,sz);
 | 
						|
    TryCopyStr(buf,",button=",sz);
 | 
						|
    sprintf(tbuf,"%d",act->button);
 | 
						|
    TryCopyStr(buf,tbuf,sz);
 | 
						|
    if (act->count>0) {
 | 
						|
	sprintf(tbuf,",count=%d",act->count);
 | 
						|
	TryCopyStr(buf,tbuf,sz);
 | 
						|
    }
 | 
						|
    if (action->type==XkbSA_LockDeviceBtn) {
 | 
						|
	switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) {
 | 
						|
	    case XkbSA_LockNoLock:
 | 
						|
		sprintf(tbuf,",affect=unlock"); break;
 | 
						|
	    case XkbSA_LockNoUnlock:
 | 
						|
		sprintf(tbuf,",affect=lock"); break;
 | 
						|
	    case XkbSA_LockNoUnlock|XkbSA_LockNoLock:
 | 
						|
		sprintf(tbuf,",affect=neither"); break;
 | 
						|
	    default:
 | 
						|
		sprintf(tbuf,",affect=both"); break;
 | 
						|
	}
 | 
						|
	TryCopyStr(buf,tbuf,sz);
 | 
						|
    }
 | 
						|
    return True;
 | 
						|
}
 | 
						|
 | 
						|
/*ARGSUSED*/
 | 
						|
static Bool
 | 
						|
CopyOtherArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz)
 | 
						|
{
 | 
						|
XkbAnyAction *	act;
 | 
						|
char		tbuf[32];
 | 
						|
 | 
						|
    act= &action->any;
 | 
						|
    sprintf(tbuf,"type=0x%02x",act->type); TryCopyStr(buf,tbuf,sz);
 | 
						|
    sprintf(tbuf,",data[0]=0x%02x",act->data[0]); TryCopyStr(buf,tbuf,sz);
 | 
						|
    sprintf(tbuf,",data[1]=0x%02x",act->data[1]); TryCopyStr(buf,tbuf,sz);
 | 
						|
    sprintf(tbuf,",data[2]=0x%02x",act->data[2]); TryCopyStr(buf,tbuf,sz);
 | 
						|
    sprintf(tbuf,",data[3]=0x%02x",act->data[3]); TryCopyStr(buf,tbuf,sz);
 | 
						|
    sprintf(tbuf,",data[4]=0x%02x",act->data[4]); TryCopyStr(buf,tbuf,sz);
 | 
						|
    sprintf(tbuf,",data[5]=0x%02x",act->data[5]); TryCopyStr(buf,tbuf,sz);
 | 
						|
    sprintf(tbuf,",data[6]=0x%02x",act->data[6]); TryCopyStr(buf,tbuf,sz);
 | 
						|
    return True;
 | 
						|
}
 | 
						|
 | 
						|
typedef	Bool	(*actionCopy)(
 | 
						|
	Display *	/* dpy */,
 | 
						|
	XkbDescPtr 	/* xkb */,
 | 
						|
	XkbAction *	/* action */,
 | 
						|
	char *		/* buf */,
 | 
						|
	int*		/* sz */
 | 
						|
);
 | 
						|
static actionCopy	copyActionArgs[XkbSA_NumActions] = {
 | 
						|
	CopyNoActionArgs		/* NoAction	*/,
 | 
						|
	CopyModActionArgs		/* SetMods	*/,
 | 
						|
	CopyModActionArgs		/* LatchMods	*/,
 | 
						|
	CopyModActionArgs		/* LockMods	*/,
 | 
						|
	CopyGroupActionArgs		/* SetGroup	*/,
 | 
						|
	CopyGroupActionArgs		/* LatchGroup	*/,
 | 
						|
	CopyGroupActionArgs		/* LockGroup	*/,
 | 
						|
	CopyMovePtrArgs			/* MovePtr	*/,
 | 
						|
	CopyPtrBtnArgs			/* PtrBtn	*/,
 | 
						|
	CopyPtrBtnArgs			/* LockPtrBtn	*/,
 | 
						|
	CopySetPtrDfltArgs		/* SetPtrDflt	*/,
 | 
						|
	CopyISOLockArgs			/* ISOLock	*/,
 | 
						|
	CopyNoActionArgs		/* Terminate	*/,
 | 
						|
	CopySwitchScreenArgs		/* SwitchScreen	*/,
 | 
						|
	CopySetLockControlsArgs		/* SetControls	*/,
 | 
						|
	CopySetLockControlsArgs		/* LockControls	*/,
 | 
						|
	CopyActionMessageArgs		/* ActionMessage*/,
 | 
						|
	CopyRedirectKeyArgs		/* RedirectKey	*/,
 | 
						|
	CopyDeviceBtnArgs		/* DeviceBtn	*/,
 | 
						|
	CopyDeviceBtnArgs		/* LockDeviceBtn*/
 | 
						|
};
 | 
						|
 | 
						|
#define	ACTION_SZ	256
 | 
						|
 | 
						|
char *
 | 
						|
XkbActionText(Display *dpy,XkbDescPtr xkb,XkbAction *action,unsigned format)
 | 
						|
{
 | 
						|
char	buf[ACTION_SZ],*tmp;
 | 
						|
int	sz;
 | 
						|
 | 
						|
    if (format==XkbCFile) {
 | 
						|
	sprintf(buf,
 | 
						|
	    "{ %20s, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x } }",
 | 
						|
	    XkbActionTypeText(action->type,XkbCFile),
 | 
						|
	    action->any.data[0],action->any.data[1],action->any.data[2],
 | 
						|
	    action->any.data[3],action->any.data[4],action->any.data[5],
 | 
						|
	    action->any.data[6]);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	sprintf(buf,"%s(",XkbActionTypeText(action->type,XkbXKBFile));
 | 
						|
	sz= ACTION_SZ-strlen(buf)+2; /* room for close paren and NULL */
 | 
						|
	if (action->type<(unsigned)XkbSA_NumActions)
 | 
						|
	     (*copyActionArgs[action->type])(dpy,xkb,action,buf,&sz);
 | 
						|
	else CopyOtherArgs(dpy,xkb,action,buf,&sz);
 | 
						|
	TryCopyStr(buf,")",&sz);
 | 
						|
    }
 | 
						|
    tmp= tbGetBuffer(strlen(buf)+1);
 | 
						|
    if (tmp!=NULL)
 | 
						|
	strcpy(tmp,buf);
 | 
						|
    return tmp;
 | 
						|
}
 | 
						|
 | 
						|
char *
 | 
						|
XkbBehaviorText(XkbDescPtr xkb,XkbBehavior *behavior,unsigned format)
 | 
						|
{
 | 
						|
char	buf[256],*tmp;
 | 
						|
 | 
						|
    if (format==XkbCFile) {
 | 
						|
	if (behavior->type==XkbKB_Default)
 | 
						|
	     sprintf(buf,"{   0,    0 }");
 | 
						|
	else sprintf(buf,"{ %3d, 0x%02x }",behavior->type,behavior->data);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
	unsigned 	type,permanent;
 | 
						|
	type= behavior->type&XkbKB_OpMask;
 | 
						|
	permanent=((behavior->type&XkbKB_Permanent)!=0);
 | 
						|
 | 
						|
	if (type==XkbKB_Lock) {
 | 
						|
	    sprintf(buf,"lock= %s",(permanent?"Permanent":"True"));
 | 
						|
	}
 | 
						|
	else if (type==XkbKB_RadioGroup) {
 | 
						|
	    int 	g;
 | 
						|
	    char	*tmp;
 | 
						|
	    g= ((behavior->data)&(~XkbKB_RGAllowNone))+1;
 | 
						|
	    if (XkbKB_RGAllowNone&behavior->data) {
 | 
						|
		sprintf(buf,"allowNone,");
 | 
						|
		tmp= &buf[strlen(buf)];
 | 
						|
	    }
 | 
						|
	    else tmp= buf;
 | 
						|
	    if (permanent)
 | 
						|
		 sprintf(tmp,"permanentRadioGroup= %d",g);
 | 
						|
	    else sprintf(tmp,"radioGroup= %d",g);
 | 
						|
	}
 | 
						|
	else if ((type==XkbKB_Overlay1)||(type==XkbKB_Overlay2)) {
 | 
						|
	    int ndx,kc;
 | 
						|
	    char *kn;
 | 
						|
 | 
						|
	    ndx= ((type==XkbKB_Overlay1)?1:2);
 | 
						|
	    kc= behavior->data;
 | 
						|
	    if ((xkb)&&(xkb->names)&&(xkb->names->keys))
 | 
						|
		kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile);
 | 
						|
	    else {
 | 
						|
		static char tbuf[8];
 | 
						|
		sprintf(tbuf,"%d",kc);
 | 
						|
		kn= tbuf;
 | 
						|
	    }
 | 
						|
	    if (permanent)
 | 
						|
		 sprintf(buf,"permanentOverlay%d= %s",ndx,kn);
 | 
						|
	    else sprintf(buf,"overlay%d= %s",ndx,kn);
 | 
						|
	}
 | 
						|
    }
 | 
						|
    tmp= tbGetBuffer(strlen(buf)+1);
 | 
						|
    if (tmp!=NULL)
 | 
						|
	strcpy(tmp,buf);
 | 
						|
    return tmp;
 | 
						|
}
 | 
						|
 | 
						|
/***====================================================================***/
 | 
						|
 | 
						|
char *
 | 
						|
XkbIndentText(unsigned size)
 | 
						|
{
 | 
						|
static char buf[32];
 | 
						|
register int i;
 | 
						|
 | 
						|
    if (size>31)
 | 
						|
	size= 31;
 | 
						|
 | 
						|
    for (i=0;i<size;i++) {
 | 
						|
	buf[i]= ' ';
 | 
						|
    }
 | 
						|
    buf[size]= '\0';
 | 
						|
    return buf;
 | 
						|
}
 |