diff options
author | Kevin E Martin <kem@freedesktop.org> | 2006-07-28 17:16:32 -0400 |
---|---|---|
committer | Kevin E Martin <kem@freedesktop.org> | 2006-07-28 17:16:32 -0400 |
commit | 654619d76c779606f2315782fc01d1410399fa3b (patch) | |
tree | b9d845c0a7284a4e2bf00d9e1d8e02f3a8c08446 /xkb | |
parent | 79016d4036786b091a9b9d1133a6cdfedd6c277d (diff) |
Revert xkb changes that broke XkbGetKeyboard()
Diffstat (limited to 'xkb')
-rw-r--r-- | xkb/Makefile.am | 4 | ||||
-rw-r--r-- | xkb/xkbfmisc.c | 437 | ||||
-rw-r--r-- | xkb/xkbout.c | 1051 | ||||
-rw-r--r-- | xkb/xkbtext.c | 1325 | ||||
-rw-r--r-- | xkb/xkmread.c | 94 |
5 files changed, 2806 insertions, 105 deletions
diff --git a/xkb/Makefile.am b/xkb/Makefile.am index 5763ce8be..996d52761 100644 --- a/xkb/Makefile.am +++ b/xkb/Makefile.am @@ -30,8 +30,10 @@ DIX_SRCS = \ XKBFILE_SRCS = \ maprules.c \ xkmread.c \ + xkbtext.c \ xkbfmisc.c \ - xkberrs.c + xkberrs.c \ + xkbout.c X11_SRCS = \ XKBMisc.c \ diff --git a/xkb/xkbfmisc.c b/xkb/xkbfmisc.c index 2bec21b3f..4130bd998 100644 --- a/xkb/xkbfmisc.c +++ b/xkb/xkbfmisc.c @@ -48,16 +48,185 @@ #include <X11/extensions/XKBgeom.h> #include "xkb.h" +unsigned +_XkbKSCheckCase(KeySym ks) +{ +unsigned set,rtrn; + + set= (ks & (~0xff)) >> 8; + rtrn= 0; + switch (set) { + case 0: /* latin 1 */ + if (((ks>=XK_A)&&(ks<=XK_Z))|| + ((ks>=XK_Agrave)&&(ks<=XK_THORN)&&(ks!=XK_multiply))) { + rtrn|= _XkbKSUpper; + } + if (((ks>=XK_a)&&(ks<=XK_z))|| + ((ks>=XK_agrave)&&(ks<=XK_ydiaeresis))) { + rtrn|= _XkbKSLower; + } + break; + case 1: /* latin 2 */ + if (((ks>=XK_Aogonek)&&(ks<=XK_Zabovedot)&&(ks!=XK_breve))|| + ((ks>=XK_Racute)&&(ks<=XK_Tcedilla))) { + rtrn|= _XkbKSUpper; + } + if (((ks>=XK_aogonek)&&(ks<=XK_zabovedot)&&(ks!=XK_caron))|| + ((ks>=XK_racute)&&(ks<=XK_tcedilla))) { + rtrn|= _XkbKSLower; + } + break; + case 2: /* latin 3 */ + if (((ks>=XK_Hstroke)&&(ks<=XK_Jcircumflex))|| + ((ks>=XK_Cabovedot)&&(ks<=XK_Scircumflex))) { + rtrn|= _XkbKSUpper; + } + if (((ks>=XK_hstroke)&&(ks<=XK_jcircumflex))|| + ((ks>=XK_cabovedot)&&(ks<=XK_scircumflex))) { + rtrn|= _XkbKSLower; + } + break; + case 3: /* latin 4 */ + if (((ks>=XK_Rcedilla)&&(ks<=XK_Tslash))|| + (ks==XK_ENG)|| + ((ks>=XK_Amacron)&&(ks<=XK_Umacron))) { + rtrn|= _XkbKSUpper; + } + if (((ks>=XK_rcedilla)&&(ks<=XK_tslash))|| + (ks==XK_eng)|| + ((ks>=XK_amacron)&&(ks<=XK_umacron))) { + rtrn|= _XkbKSLower; + } + break; + case 18: /* latin 8 */ + if ((ks==XK_Babovedot)|| + ((ks>=XK_Dabovedot)&&(ks<=XK_Wacute))|| + ((ks>=XK_Ygrave)&&(ks<=XK_Fabovedot))|| + (ks==XK_Mabovedot)|| + (ks==XK_Pabovedot)|| + (ks==XK_Sabovedot)|| + (ks==XK_Wdiaeresis)|| + ((ks>=XK_Wcircumflex)&&(ks<=XK_Ycircumflex))) { + rtrn|= _XkbKSUpper; + } + if ((ks==XK_babovedot)|| + (ks==XK_dabovedot)|| + (ks==XK_fabovedot)|| + (ks==XK_mabovedot)|| + ((ks>=XK_wgrave)&&(ks<=XK_wacute))|| + (ks==XK_ygrave)|| + ((ks>=XK_wdiaeresis)&&(ks<=XK_ycircumflex))) { + rtrn|= _XkbKSLower; + } + break; + case 19: /* latin 9 */ + if ((ks==XK_OE)||(ks==XK_Ydiaeresis)) { + rtrn|= _XkbKSUpper; + } + if (ks==XK_oe) { + rtrn|= _XkbKSLower; + } + break; + } + return rtrn; +} + +/***===================================================================***/ + +Bool +XkbLookupGroupAndLevel( XkbDescPtr xkb, + int key, + int * mods_inout, + int * grp_inout, + int * lvl_rtrn) +{ +int nG,eG; + + if ((!xkb)||(!XkbKeycodeInRange(xkb,key))||(!grp_inout)) + return False; + + nG= XkbKeyNumGroups(xkb,key); + eG= *grp_inout; + + if ( nG==0 ) { + *grp_inout= 0; + if (lvl_rtrn!=NULL) + *lvl_rtrn= 0; + return False; + } + else if ( nG==1 ) { + eG= 0; + } + else if ( eG>=nG ) { + unsigned gI= XkbKeyGroupInfo(xkb,key); + switch (XkbOutOfRangeGroupAction(gI)) { + default: + eG %= nG; + break; + case XkbClampIntoRange: + eG = nG-1; + break; + case XkbRedirectIntoRange: + eG = XkbOutOfRangeGroupNumber(gI); + if (eG>=nG) + eG= 0; + break; + } + } + *grp_inout= eG; + if (mods_inout!=NULL) { + XkbKeyTypePtr type; + int preserve; + + type = XkbKeyKeyType(xkb,key,eG); + if (lvl_rtrn!=NULL) + *lvl_rtrn= 0; + preserve= 0; + if (type->map) { /* find the shift level */ + register int i; + register XkbKTMapEntryPtr entry; + for (i=0,entry=type->map;i<type->map_count;i++,entry++) { + if ((entry->active)&& + (((*mods_inout)&type->mods.mask)==entry->mods.mask)){ + if (lvl_rtrn!=NULL) + *lvl_rtrn= entry->level; + if (type->preserve) + preserve= type->preserve[i].mask; + break; + } + } + } + (*mods_inout)&= ~(type->mods.mask&(~preserve)); + } + return True; +} + /***===================================================================***/ static Bool XkbWriteSectionFromName(FILE *file,char *sectionName,char *name) { fprintf(file," xkb_%-20s { include \"%s\" };\n",sectionName,name); - ErrorF(" xkb_%-20s { include \"%s\" };\n",sectionName,name); return True; } +#define NEED_DESC(n) ((!n)||((n)[0]=='+')||((n)[0]=='|')||(strchr((n),'%'))) +#define COMPLETE(n) ((n)&&(!NEED_DESC(n))) + +/* ARGSUSED */ +static void +_AddIncl( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + int index, + void * priv) +{ + if ((priv)&&(strcmp((char *)priv,"%")!=0)) + fprintf(file," include \"%s\"\n",(char *)priv); + return; +} + Bool XkbWriteXKBKeymapForNames( FILE * file, XkbComponentNamesPtr names, @@ -66,29 +235,229 @@ XkbWriteXKBKeymapForNames( FILE * file, unsigned want, unsigned need) { - if (!names || (!names->keycodes && !names->types && !names->compat && - !names->symbols && !names->geometry)) - return False; - - fprintf(file, "xkb_keymap \"%s\" {\n", names->keymap ? names->keymap : - "default"); - - if (names->keycodes) - XkbWriteSectionFromName(file, "keycodes", names->keycodes); - if (names->types) - XkbWriteSectionFromName(file, "types", names->types); - if (names->compat) - XkbWriteSectionFromName(file, "compatibility", names->compat); - if (names->symbols) - XkbWriteSectionFromName(file, "symbols", names->symbols); - if (names->geometry) - XkbWriteSectionFromName(file, "geometry", names->geometry); - - fprintf(file,"};\n"); +char * name,*tmp; +unsigned complete; +XkbNamesPtr old_names; +int multi_section; +unsigned wantNames,wantConfig,wantDflts; +XkbFileInfo finfo; + + bzero(&finfo,sizeof(XkbFileInfo)); + + complete= 0; + if ((name=names->keymap)==NULL) name= "default"; + if (COMPLETE(names->keycodes)) complete|= XkmKeyNamesMask; + if (COMPLETE(names->types)) complete|= XkmTypesMask; + if (COMPLETE(names->compat)) complete|= XkmCompatMapMask; + if (COMPLETE(names->symbols)) complete|= XkmSymbolsMask; + if (COMPLETE(names->geometry)) complete|= XkmGeometryMask; + want|= (complete|need); + if (want&XkmSymbolsMask) + want|= XkmKeyNamesMask|XkmTypesMask; + + if (want==0) + return False; + + if (xkb!=NULL) { + old_names= xkb->names; + finfo.type= 0; + finfo.defined= 0; + finfo.xkb= xkb; + if (!XkbDetermineFileType(&finfo,XkbXKBFile,NULL)) + return False; + } + else old_names= NULL; + + wantConfig= want&(~complete); + if (xkb!=NULL) { + if (wantConfig&XkmTypesMask) { + if ((!xkb->map) || (xkb->map->num_types<XkbNumRequiredTypes)) + wantConfig&= ~XkmTypesMask; + } + if (wantConfig&XkmCompatMapMask) { + if ((!xkb->compat) || (xkb->compat->num_si<1)) + wantConfig&= ~XkmCompatMapMask; + } + if (wantConfig&XkmSymbolsMask) { + if ((!xkb->map) || (!xkb->map->key_sym_map)) + wantConfig&= ~XkmSymbolsMask; + } + if (wantConfig&XkmIndicatorsMask) { + if (!xkb->indicators) + wantConfig&= ~XkmIndicatorsMask; + } + if (wantConfig&XkmKeyNamesMask) { + if ((!xkb->names)||(!xkb->names->keys)) + wantConfig&= ~XkmKeyNamesMask; + } + if ((wantConfig&XkmGeometryMask)&&(!xkb->geom)) + wantConfig&= ~XkmGeometryMask; + } + else { + wantConfig= 0; + } + complete|= wantConfig; + + wantDflts= 0; + wantNames= want&(~complete); + if ((xkb!=NULL) && (old_names!=NULL)) { + if (wantNames&XkmTypesMask) { + if (old_names->types!=None) { + tmp= XkbAtomGetString(dpy,old_names->types); + names->types= _XkbDupString(tmp); + } + else { + wantDflts|= XkmTypesMask; + } + complete|= XkmTypesMask; + } + if (wantNames&XkmCompatMapMask) { + if (old_names->compat!=None) { + tmp= XkbAtomGetString(dpy,old_names->compat); + names->compat= _XkbDupString(tmp); + } + else wantDflts|= XkmCompatMapMask; + complete|= XkmCompatMapMask; + } + if (wantNames&XkmSymbolsMask) { + if (old_names->symbols==None) + return False; + tmp= XkbAtomGetString(dpy,old_names->symbols); + names->symbols= _XkbDupString(tmp); + complete|= XkmSymbolsMask; + } + if (wantNames&XkmKeyNamesMask) { + if (old_names->keycodes!=None) { + tmp= XkbAtomGetString(dpy,old_names->keycodes); + names->keycodes= _XkbDupString(tmp); + } + else wantDflts|= XkmKeyNamesMask; + complete|= XkmKeyNamesMask; + } + if (wantNames&XkmGeometryMask) { + if (old_names->geometry==None) + return False; + tmp= XkbAtomGetString(dpy,old_names->geometry); + names->geometry= _XkbDupString(tmp); + complete|= XkmGeometryMask; + wantNames&= ~XkmGeometryMask; + } + } + if (complete&XkmCompatMapMask) + complete|= XkmIndicatorsMask|XkmVirtualModsMask; + else if (complete&(XkmSymbolsMask|XkmTypesMask)) + complete|= XkmVirtualModsMask; + if (need & (~complete)) + return False; + if ((complete&XkmSymbolsMask)&&((XkmKeyNamesMask|XkmTypesMask)&(~complete))) + return False; + + multi_section= 1; + if (((complete&XkmKeymapRequired)==XkmKeymapRequired)&& + ((complete&(~XkmKeymapLegal))==0)) { + fprintf(file,"xkb_keymap \"%s\" {\n",name); + } + else if (((complete&XkmSemanticsRequired)==XkmSemanticsRequired)&& + ((complete&(~XkmSemanticsLegal))==0)) { + fprintf(file,"xkb_semantics \"%s\" {\n",name); + } + else if (((complete&XkmLayoutRequired)==XkmLayoutRequired)&& + ((complete&(~XkmLayoutLegal))==0)) { + fprintf(file,"xkb_layout \"%s\" {\n",name); + } + else if (XkmSingleSection(complete&(~XkmVirtualModsMask))) { + multi_section= 0; + } + else { + return False; + } + + wantNames= complete&(~(wantConfig|wantDflts)); + name= names->keycodes; + if (wantConfig&XkmKeyNamesMask) + XkbWriteXKBKeycodes(file,&finfo,False,False,_AddIncl,name); + else if (wantDflts&XkmKeyNamesMask) + fprintf(stderr,"Default symbols not implemented yet!\n"); + else if (wantNames&XkmKeyNamesMask) + XkbWriteSectionFromName(file,"keycodes",name); + + name= names->types; + if (wantConfig&XkmTypesMask) + XkbWriteXKBKeyTypes(file,&finfo,False,False,_AddIncl,name); + else if (wantDflts&XkmTypesMask) + fprintf(stderr,"Default types not implemented yet!\n"); + else if (wantNames&XkmTypesMask) + XkbWriteSectionFromName(file,"types",name); + + name= names->compat; + if (wantConfig&XkmCompatMapMask) + XkbWriteXKBCompatMap(file,&finfo,False,False,_AddIncl,name); + else if (wantDflts&XkmCompatMapMask) + fprintf(stderr,"Default interps not implemented yet!\n"); + else if (wantNames&XkmCompatMapMask) + XkbWriteSectionFromName(file,"compatibility",name); + name= names->symbols; + if (wantConfig&XkmSymbolsMask) + XkbWriteXKBSymbols(file,&finfo,False,False,_AddIncl,name); + else if (wantNames&XkmSymbolsMask) + XkbWriteSectionFromName(file,"symbols",name); + + name= names->geometry; + if (wantConfig&XkmGeometryMask) + XkbWriteXKBGeometry(file,&finfo,False,False,_AddIncl,name); + else if (wantNames&XkmGeometryMask) + XkbWriteSectionFromName(file,"geometry",name); + + if (multi_section) + fprintf(file,"};\n"); return True; } +/***====================================================================***/ + +/*ARGSUSED*/ +Status +XkbMergeFile(XkbDescPtr xkb,XkbFileInfo finfo) +{ + return BadImplementation; +} + +/***====================================================================***/ + +int +XkbFindKeycodeByName(XkbDescPtr xkb,char *name,Bool use_aliases) +{ +register int i; + + if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) + return 0; + for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + if (strncmp(xkb->names->keys[i].name,name,XkbKeyNameLength)==0) + return i; + } + if (!use_aliases) + return 0; + if (xkb->geom && xkb->geom->key_aliases) { + XkbKeyAliasPtr a; + a= xkb->geom->key_aliases; + for (i=0;i<xkb->geom->num_key_aliases;i++,a++) { + if (strncmp(name,a->alias,XkbKeyNameLength)==0) + return XkbFindKeycodeByName(xkb,a->real,False); + } + } + if (xkb->names && xkb->names->key_aliases) { + XkbKeyAliasPtr a; + a= xkb->names->key_aliases; + for (i=0;i<xkb->names->num_key_aliases;i++,a++) { + if (strncmp(name,a->alias,XkbKeyNameLength)==0) + return XkbFindKeycodeByName(xkb,a->real,False); + } + } + return 0; +} + + unsigned XkbConvertGetByNameComponents(Bool toXkm,unsigned orig) { @@ -115,6 +484,34 @@ unsigned rtrn; return rtrn; } +unsigned +XkbConvertXkbComponents(Bool toXkm,unsigned orig) +{ +unsigned rtrn; + + rtrn= 0; + if (toXkm) { + if (orig&XkbClientMapMask) rtrn|= XkmTypesMask|XkmSymbolsMask; + if (orig&XkbServerMapMask) rtrn|= XkmTypesMask|XkmSymbolsMask; + if (orig&XkbCompatMapMask) rtrn|= XkmCompatMapMask; + if (orig&XkbIndicatorMapMask) rtrn|= XkmIndicatorsMask; + if (orig&XkbNamesMask) rtrn|= XkmKeyNamesMask; + if (orig&XkbGeometryMask) rtrn|= XkmGeometryMask; + } + else { + if (orig!=0) rtrn|= XkbNamesMask; + if (orig&XkmTypesMask) rtrn|= XkbClientMapMask; + if (orig&XkmCompatMapMask) + rtrn|= XkbCompatMapMask|XkbIndicatorMapMask; + if (orig&XkmSymbolsMask) rtrn|=XkbClientMapMask|XkbServerMapMask; + if (orig&XkmIndicatorsMask) rtrn|= XkbIndicatorMapMask; + if (orig&XkmKeyNamesMask) + rtrn|= XkbNamesMask|XkbIndicatorMapMask; + if (orig&XkmGeometryMask) rtrn|= XkbGeometryMask; + } + return rtrn; +} + Bool XkbDetermineFileType(XkbFileInfoPtr finfo,int format,int *opts_missing) { diff --git a/xkb/xkbout.c b/xkb/xkbout.c new file mode 100644 index 000000000..31cd4fae4 --- /dev/null +++ b/xkb/xkbout.c @@ -0,0 +1,1051 @@ +/* $Xorg: xkbout.c,v 1.3 2000/08/17 19:46:44 cpqbld Exp $ */ +/************************************************************ + 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. + + ********************************************************/ +/* $XFree86: xc/lib/xkbfile/xkbout.c,v 3.9 2001/10/28 03:32:47 tsi Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> +#include <X11/Xfuncs.h> + +#include <X11/X.h> +#define NEED_EVENTS +#include <X11/keysym.h> +#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 <X11/extensions/XKBsrv.h> + +#include <X11/extensions/XKBgeom.h> +#include <X11/extensions/XKBfile.h> + +#define VMOD_HIDE_VALUE 0 +#define VMOD_SHOW_VALUE 1 +#define VMOD_COMMENT_VALUE 2 + +static Bool +WriteXKBVModDecl(FILE *file,Display *dpy,XkbDescPtr xkb,int showValue) +{ +register int i,nMods; +Atom * vmodNames; + + if (xkb==NULL) + return False; + if (xkb->names!=NULL) + vmodNames= xkb->names->vmods; + else vmodNames= NULL; + + for (i=nMods=0;i<XkbNumVirtualMods;i++) { + if ((vmodNames!=NULL)&&(vmodNames[i]!=None)) { + if (nMods==0) fprintf(file," virtual_modifiers "); + else fprintf(file,","); + fprintf(file,"%s",XkbAtomText(dpy,vmodNames[i],XkbXKBFile)); + if ((showValue!=VMOD_HIDE_VALUE)&& + (xkb->server)&&(xkb->server->vmods[i]!=XkbNoModifierMask)) { + if (showValue==VMOD_COMMENT_VALUE) { + fprintf(file,"/* = %s */", + XkbModMaskText(xkb->server->vmods[i],XkbXKBFile)); + } + else { + fprintf(file,"= %s", + XkbModMaskText(xkb->server->vmods[i],XkbXKBFile)); + } + } + nMods++; + } + } + if (nMods>0) + fprintf(file,";\n\n"); + return True; +} + +/***====================================================================***/ + +static Bool +WriteXKBAction(FILE *file,XkbFileInfo *result,XkbAnyAction *action) +{ +XkbDescPtr xkb; +Display * dpy; + + xkb= result->xkb; + dpy= xkb->dpy; + fprintf(file,"%s",XkbActionText(dpy,xkb,(XkbAction *)action,XkbXKBFile)); + return True; +} + +/***====================================================================***/ + +Bool +XkbWriteXKBKeycodes( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Atom kcName; +register unsigned i; +XkbDescPtr xkb; +Display * dpy; +char * alternate; + + xkb= result->xkb; + dpy= xkb->dpy; + if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) { + _XkbLibError(_XkbErrMissingNames,"XkbWriteXKBKeycodes",0); + return False; + } + kcName= xkb->names->keycodes; + if (kcName!=None) + fprintf(file,"xkb_keycodes \"%s\" {\n", + XkbAtomText(dpy,kcName,XkbXKBFile)); + else fprintf(file,"xkb_keycodes {\n"); + fprintf(file," minimum = %d;\n",xkb->min_key_code); + fprintf(file," maximum = %d;\n",xkb->max_key_code); + for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + if (xkb->names->keys[i].name[0]!='\0') { + if (XkbFindKeycodeByName(xkb,xkb->names->keys[i].name,True)!=i) + alternate= "alternate "; + else alternate= ""; + fprintf(file," %s%6s = %d;\n",alternate, + XkbKeyNameText(xkb->names->keys[i].name,XkbXKBFile), + i); + } + } + if (xkb->indicators!=NULL) { + for (i=0;i<XkbNumIndicators;i++) { + char *type; + if (xkb->indicators->phys_indicators&(1<<i)) + type= " "; + else type= " virtual "; + if (xkb->names->indicators[i]!=None) { + fprintf(file,"%sindicator %d = \"%s\";\n",type,i+1, + XkbAtomText(dpy,xkb->names->indicators[i],XkbXKBFile)); + } + } + } + if (xkb->names->key_aliases!=NULL) { + XkbKeyAliasPtr pAl; + pAl= xkb->names->key_aliases; + for (i=0;i<xkb->names->num_key_aliases;i++,pAl++) { + fprintf(file," alias %6s = %6s;\n", + XkbKeyNameText(pAl->alias,XkbXKBFile), + XkbKeyNameText(pAl->real,XkbXKBFile)); + } + } + if (addOn) + (*addOn)(file,result,topLevel,showImplicit,XkmKeyNamesIndex,priv); + fprintf(file,"};\n\n"); + return True; +} + +Bool +XkbWriteXKBKeyTypes( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Display * dpy; +register unsigned i,n; +XkbKeyTypePtr type; +XkbKTMapEntryPtr entry; +XkbDescPtr xkb; + + xkb= result->xkb; + dpy= xkb->dpy; + if ((!xkb)||(!xkb->map)||(!xkb->map->types)) { + _XkbLibError(_XkbErrMissingTypes,"XkbWriteXKBKeyTypes",0); + return False; + } + if (xkb->map->num_types<XkbNumRequiredTypes) { + _XkbLibError(_XkbErrMissingReqTypes,"XkbWriteXKBKeyTypes",0); + return 0; + } + if ((xkb->names==NULL)||(xkb->names->types==None)) + fprintf(file,"xkb_types {\n\n"); + else fprintf(file,"xkb_types \"%s\" {\n\n", + XkbAtomText(dpy,xkb->names->types,XkbXKBFile)); + WriteXKBVModDecl(file,dpy,xkb, + (showImplicit?VMOD_COMMENT_VALUE:VMOD_HIDE_VALUE)); + + type= xkb->map->types; + for (i=0;i<xkb->map->num_types;i++,type++) { + fprintf(file," type \"%s\" {\n", + XkbAtomText(dpy,type->name,XkbXKBFile)); + fprintf(file," modifiers= %s;\n", + XkbVModMaskText(dpy,xkb,type->mods.real_mods,type->mods.vmods, + XkbXKBFile)); + entry= type->map; + for (n=0;n<type->map_count;n++,entry++) { + char *str; + str=XkbVModMaskText(dpy,xkb,entry->mods.real_mods,entry->mods.vmods, + XkbXKBFile); + fprintf(file," map[%s]= Level%d;\n",str,entry->level+1); + if ((type->preserve)&&((type->preserve[n].real_mods)|| + (type->preserve[n].vmods))) { + fprintf(file," preserve[%s]= ",str); + fprintf(file,"%s;\n",XkbVModMaskText(dpy,xkb, + type->preserve[n].real_mods, + type->preserve[n].vmods, + XkbXKBFile)); + } + } + if (type->level_names!=NULL) { + Atom *name= type->level_names; + for (n=0;n<type->num_levels;n++,name++) { + if ((*name)==None) + continue; + fprintf(file," level_name[Level%d]= \"%s\";\n",n+1, + XkbAtomText(dpy,*name,XkbXKBFile)); + } + } + fprintf(file," };\n"); + } + if (addOn) + (*addOn)(file,result,topLevel,showImplicit,XkmTypesIndex,priv); + fprintf(file,"};\n\n"); + return True; +} + +static Bool +WriteXKBIndicatorMap( FILE * file, + XkbFileInfo * result, + Atom name, + XkbIndicatorMapPtr led, + XkbFileAddOnFunc addOn, + void * priv) +{ +XkbDescPtr xkb; + + xkb= result->xkb; + fprintf(file," indicator \"%s\" {\n",XkbAtomGetString(xkb->dpy,name)); + if (led->flags&XkbIM_NoExplicit) + fprintf(file," !allowExplicit;\n"); + if (led->flags&XkbIM_LEDDrivesKB) + fprintf(file," indicatorDrivesKeyboard;\n"); + if (led->which_groups!=0) { + if (led->which_groups!=XkbIM_UseEffective) { + fprintf(file," whichGroupState= %s;\n", + XkbIMWhichStateMaskText(led->which_groups,XkbXKBFile)); + } + fprintf(file," groups= 0x%02x;\n",led->groups); + } + if (led->which_mods!=0) { + if (led->which_mods!=XkbIM_UseEffective) { + fprintf(file," whichModState= %s;\n", + XkbIMWhichStateMaskText(led->which_mods,XkbXKBFile)); + } + fprintf(file," modifiers= %s;\n", + XkbVModMaskText(xkb->dpy,xkb, + led->mods.real_mods,led->mods.vmods, + XkbXKBFile)); + } + if (led->ctrls!=0) { + fprintf(file," controls= %s;\n", + XkbControlsMaskText(led->ctrls,XkbXKBFile)); + } + if (addOn) + (*addOn)(file,result,False,True,XkmIndicatorsIndex,priv); + fprintf(file," };\n"); + return True; +} + +Bool +XkbWriteXKBCompatMap( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Display * dpy; +register unsigned i; +XkbSymInterpretPtr interp; +XkbDescPtr xkb; + + xkb= result->xkb; + dpy= xkb->dpy; + if ((!xkb)||(!xkb->compat)||(!xkb->compat->sym_interpret)) { + _XkbLibError(_XkbErrMissingCompatMap,"XkbWriteXKBCompatMap",0); + return False; + } + if ((xkb->names==NULL)||(xkb->names->compat==None)) + fprintf(file,"xkb_compatibility {\n\n"); + else fprintf(file,"xkb_compatibility \"%s\" {\n\n", + XkbAtomText(dpy,xkb->names->compat,XkbXKBFile)); + WriteXKBVModDecl(file,dpy,xkb, + (showImplicit?VMOD_COMMENT_VALUE:VMOD_HIDE_VALUE)); + + fprintf(file," interpret.useModMapMods= AnyLevel;\n"); + fprintf(file," interpret.repeat= False;\n"); + fprintf(file," interpret.locking= False;\n"); + interp= xkb->compat->sym_interpret; + for (i=0;i<xkb->compat->num_si;i++,interp++) { + fprintf(file," interpret %s+%s(%s) {\n", + ((interp->sym==NoSymbol)?"Any": + XkbKeysymText(interp->sym,XkbXKBFile)), + XkbSIMatchText(interp->match,XkbXKBFile), + XkbModMaskText(interp->mods,XkbXKBFile)); + if (interp->virtual_mod!=XkbNoModifier) { + fprintf(file," virtualModifier= %s;\n", + XkbVModIndexText(dpy,xkb,interp->virtual_mod,XkbXKBFile)); + } + if (interp->match&XkbSI_LevelOneOnly) + fprintf(file," useModMapMods=level1;\n"); + if (interp->flags&XkbSI_LockingKey) + fprintf(file," locking= True;\n"); + if (interp->flags&XkbSI_AutoRepeat) + fprintf(file," repeat= True;\n"); + fprintf(file," action= "); + WriteXKBAction(file,result,&interp->act); + fprintf(file,";\n"); + fprintf(file," };\n"); + } + for (i=0;i<XkbNumKbdGroups;i++) { + XkbModsPtr gc; + + gc= &xkb->compat->groups[i]; + if ((gc->real_mods==0)&&(gc->vmods==0)) + continue; + fprintf(file," group %d = %s;\n",i+1,XkbVModMaskText(xkb->dpy,xkb, + gc->real_mods,gc->vmods, + XkbXKBFile)); + } + if (xkb->indicators) { + for (i=0;i<XkbNumIndicators;i++) { + XkbIndicatorMapPtr map= &xkb->indicators->maps[i]; + if ((map->flags!=0)||(map->which_groups!=0)||(map->groups!=0)|| + (map->which_mods!=0)|| + (map->mods.real_mods!=0)||(map->mods.vmods!=0)|| + (map->ctrls!=0)) { + WriteXKBIndicatorMap(file,result,xkb->names->indicators[i],map, + addOn,priv); + } + } + } + if (addOn) + (*addOn)(file,result,topLevel,showImplicit,XkmCompatMapIndex,priv); + fprintf(file,"};\n\n"); + return True; +} + +Bool +XkbWriteXKBSymbols( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Display * dpy; +register unsigned i,tmp; +XkbDescPtr xkb; +XkbClientMapPtr map; +XkbServerMapPtr srv; +Bool showActions; + + xkb= result->xkb; + map= xkb->map; + srv= xkb->server; + dpy= xkb->dpy; + if ((!xkb)||(!map)||(!map->syms)||(!map->key_sym_map)) { + _XkbLibError(_XkbErrMissingSymbols,"XkbWriteXKBSymbols",0); + return False; + } + if ((!xkb->names)||(!xkb->names->keys)) { + _XkbLibError(_XkbErrMissingNames,"XkbWriteXKBSymbols",0); + return False; + } + if ((xkb->names==NULL)||(xkb->names->symbols==None)) + fprintf(file,"xkb_symbols {\n\n"); + else fprintf(file,"xkb_symbols \"%s\" {\n\n", + XkbAtomText(dpy,xkb->names->symbols,XkbXKBFile)); + for (tmp=i=0;i<XkbNumKbdGroups;i++) { + if (xkb->names->groups[i]!=None) { + fprintf(file," name[group%d]=\"%s\";\n",i+1, + XkbAtomText(dpy,xkb->names->groups[i],XkbXKBFile)); + tmp++; + } + } + if (tmp>0) + fprintf(file,"\n"); + for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + Bool simple; + if ((int)XkbKeyNumSyms(xkb,i)<1) + continue; + if (XkbFindKeycodeByName(xkb,xkb->names->keys[i].name,True)!=i) + continue; + simple= True; + fprintf(file," key %6s {", + XkbKeyNameText(xkb->names->keys[i].name,XkbXKBFile)); + if (srv->explicit) { + if (((srv->explicit[i]&XkbExplicitKeyTypesMask)!=0)|| + (showImplicit)) { + int typeNdx,g; + Bool multi; + char * comment=" "; + + if ((srv->explicit[i]&XkbExplicitKeyTypesMask)==0) + comment= "//"; + multi= False; + typeNdx= XkbKeyKeyTypeIndex(xkb,i,0); + for (g=1;(g<XkbKeyNumGroups(xkb,i))&&(!multi);g++) { + if (XkbKeyKeyTypeIndex(xkb,i,g)!=typeNdx) + multi= True; + } + if (multi) { + for (g=0;g<XkbKeyNumGroups(xkb,i);g++) { + typeNdx= XkbKeyKeyTypeIndex(xkb,i,g); + if (srv->explicit[i]&(1<<g)) { + fprintf(file,"\n%s type[group%d]= \"%s\",", + comment,g+1, + XkbAtomText(dpy,map->types[typeNdx].name, + XkbXKBFile)); + } + else if (showImplicit) { + fprintf(file,"\n// type[group%d]= \"%s\",",g+1, + XkbAtomText(dpy,map->types[typeNdx].name, + XkbXKBFile)); + } + } + } + else { + fprintf(file,"\n%s type= \"%s\",",comment, + XkbAtomText(dpy,map->types[typeNdx].name, + XkbXKBFile)); + } + simple= False; + } + if (((srv->explicit[i]&XkbExplicitAutoRepeatMask)!=0)&& + (xkb->ctrls!=NULL)) { + if (xkb->ctrls->per_key_repeat[i/8]&(1<<(i%8))) + fprintf(file,"\n repeat= Yes,"); + else fprintf(file,"\n repeat= No,"); + simple= False; + } + if ((xkb->server!=NULL)&&(xkb->server->vmodmap!=NULL)&& + (xkb->server->vmodmap[i]!=0)) { + if ((srv->explicit[i]&XkbExplicitVModMapMask)!=0) { + fprintf(file,"\n virtualMods= %s,", + XkbVModMaskText(dpy,xkb,0, + xkb->server->vmodmap[i], + XkbXKBFile)); + } + else if (showImplicit) { + fprintf(file,"\n// virtualMods= %s,", + XkbVModMaskText(dpy,xkb,0, + xkb->server->vmodmap[i], + XkbXKBFile)); + } + } + } + switch (XkbOutOfRangeGroupAction(XkbKeyGroupInfo(xkb,i))) { + case XkbClampIntoRange: + fprintf(file,"\n groupsClamp,"); + break; + case XkbRedirectIntoRange: + fprintf(file,"\n groupsRedirect= Group%d,", + XkbOutOfRangeGroupNumber(XkbKeyGroupInfo(xkb,i))+1); + break; + } + if (srv->behaviors!=NULL) { + unsigned type; + type= srv->behaviors[i].type&XkbKB_OpMask; + + if (type!=XkbKB_Default) { + simple= False; + fprintf(file,"\n %s,", + XkbBehaviorText(xkb,&srv->behaviors[i],XkbXKBFile)); + } + } + if ((srv->explicit==NULL) || showImplicit || + ((srv->explicit[i]&XkbExplicitInterpretMask)!=0)) + showActions= XkbKeyHasActions(xkb,i); + else showActions= False; + + if (((unsigned)XkbKeyNumGroups(xkb,i)>1)||showActions) + simple= False; + if (simple) { + KeySym *syms; + unsigned s; + + syms= XkbKeySymsPtr(xkb,i); + fprintf(file," [ "); + for (s=0;s<XkbKeyGroupWidth(xkb,i,XkbGroup1Index);s++) { + if (s!=0) + fprintf(file,", "); + fprintf(file,"%15s",XkbKeysymText(*syms++,XkbXKBFile)); + } + fprintf(file," ] };\n"); + } + else { + unsigned g,s; + KeySym *syms; + XkbAction *acts; + syms= XkbKeySymsPtr(xkb,i); + acts= XkbKeyActionsPtr(xkb,i); + for (g=0;g<XkbKeyNumGroups(xkb,i);g++) { + if (g!=0) + fprintf(file,","); + fprintf(file,"\n symbols[Group%d]= [ ",g+1); + for (s=0;s<XkbKeyGroupWidth(xkb,i,g);s++) { + if (s!=0) + fprintf(file,", "); + fprintf(file,"%15s",XkbKeysymText(syms[s],XkbXKBFile)); + } + fprintf(file," ]"); + syms+= XkbKeyGroupsWidth(xkb,i); + if (showActions) { + fprintf(file,",\n actions[Group%d]= [ ",g+1); + for (s=0;s<XkbKeyGroupWidth(xkb,i,g);s++) { + if (s!=0) + fprintf(file,", "); + WriteXKBAction(file,result,(XkbAnyAction *)&acts[s]); + } + fprintf(file," ]"); + acts+= XkbKeyGroupsWidth(xkb,i); + } + } + fprintf(file,"\n };\n"); + } + } + if (map && map->modmap) { + for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + if (map->modmap[i]!=0) { + register int n,bit; + for (bit=1,n=0;n<XkbNumModifiers;n++,bit<<=1) { + if (map->modmap[i]&bit) { + char buf[5]; + memcpy(buf,xkb->names->keys[i].name,4); + buf[4]= '\0'; + fprintf(file," modifier_map %s { <%s> };\n", + XkbModIndexText(n,XkbXKBFile),buf); + } + } + } + } + } + if (addOn) + (*addOn)(file,result,topLevel,showImplicit,XkmSymbolsIndex,priv); + fprintf(file,"};\n\n"); + return True; +} + +static Bool +WriteXKBOutline( FILE * file, + XkbShapePtr shape, + XkbOutlinePtr outline, + int lastRadius, + int first, + int indent) +{ +register int i; +XkbPointPtr pt; +char * iStr; + + fprintf(file,"%s",iStr= XkbIndentText(first)); + if (first!=indent) + iStr= XkbIndentText(indent); + if (outline->corner_radius!=lastRadius) { + fprintf(file,"corner= %s,", + XkbGeomFPText(outline->corner_radius,XkbMessage)); + if (shape!=NULL) { + fprintf(file,"\n%s",iStr); + } + } + if (shape) { + if (outline==shape->approx) + fprintf(file,"approx= "); + else if (outline==shape->primary) + fprintf(file,"primary= "); + } + fprintf(file,"{"); + for (pt=outline->points,i=0;i<outline->num_points;i++,pt++) { + if (i==0) fprintf(file," "); + else if ((i%4)==0) fprintf(file,",\n%s ",iStr); + else fprintf(file,", "); + fprintf(file,"[ %3s, %3s ]",XkbGeomFPText(pt->x,XkbXKBFile), + XkbGeomFPText(pt->y,XkbXKBFile)); + } + fprintf(file," }"); + return True; +} + +static Bool +WriteXKBDoodad( FILE * file, + Display * dpy, + unsigned indent, + XkbGeometryPtr geom, + XkbDoodadPtr doodad) +{ +register char * i_str; +XkbShapePtr shape; +XkbColorPtr color; + + i_str= XkbIndentText(indent); + fprintf(file,"%s%s \"%s\" {\n",i_str, + XkbDoodadTypeText(doodad->any.type,XkbMessage), + XkbAtomText(dpy,doodad->any.name,XkbMessage)); + fprintf(file,"%s top= %s;\n",i_str, + XkbGeomFPText(doodad->any.top,XkbXKBFile)); + fprintf(file,"%s left= %s;\n",i_str, + XkbGeomFPText(doodad->any.left,XkbXKBFile)); + fprintf(file,"%s priority= %d;\n",i_str,doodad->any.priority); + switch (doodad->any.type) { + case XkbOutlineDoodad: + case XkbSolidDoodad: + if (doodad->shape.angle!=0) { + fprintf(file,"%s angle= %s;\n",i_str, + XkbGeomFPText(doodad->shape.angle,XkbXKBFile)); + } + if (doodad->shape.color_ndx!=0) { + fprintf(file,"%s color= \"%s\";\n",i_str, + XkbShapeDoodadColor(geom,&doodad->shape)->spec); + } + shape= XkbShapeDoodadShape(geom,&doodad->shape); + fprintf(file,"%s shape= \"%s\";\n",i_str, + XkbAtomText(dpy,shape->name,XkbXKBFile)); + break; + case XkbTextDoodad: + if (doodad->text.angle!=0) { + fprintf(file,"%s angle= %s;\n",i_str, + XkbGeomFPText(doodad->text.angle,XkbXKBFile)); + } + if (doodad->text.width!=0) { + fprintf(file,"%s width= %s;\n",i_str, + XkbGeomFPText(doodad->text.width,XkbXKBFile)); + + } + if (doodad->text.height!=0) { + fprintf(file,"%s height= %s;\n",i_str, + XkbGeomFPText(doodad->text.height,XkbXKBFile)); + + } + if (doodad->text.color_ndx!=0) { + color= XkbTextDoodadColor(geom,&doodad->text); + fprintf(file,"%s color= \"%s\";\n",i_str, + XkbStringText(color->spec,XkbXKBFile)); + } + fprintf(file,"%s XFont= \"%s\";\n",i_str, + XkbStringText(doodad->text.font,XkbXKBFile)); + fprintf(file,"%s text= \"%s\";\n",i_str, + XkbStringText(doodad->text.text,XkbXKBFile)); + break; + case XkbIndicatorDoodad: + shape= XkbIndicatorDoodadShape(geom,&doodad->indicator); + color= XkbIndicatorDoodadOnColor(geom,&doodad->indicator); + fprintf(file,"%s onColor= \"%s\";\n",i_str, + XkbStringText(color->spec,XkbXKBFile)); + color= XkbIndicatorDoodadOffColor(geom,&doodad->indicator); + fprintf(file,"%s offColor= \"%s\";\n",i_str, + XkbStringText(color->spec,XkbXKBFile)); + fprintf(file,"%s shape= \"%s\";\n",i_str, + XkbAtomText(dpy,shape->name,XkbXKBFile)); + break; + case XkbLogoDoodad: + fprintf(file,"%s logoName= \"%s\";\n",i_str, + XkbStringText(doodad->logo.logo_name,XkbXKBFile)); + if (doodad->shape.angle!=0) { + fprintf(file,"%s angle= %s;\n",i_str, + XkbGeomFPText(doodad->logo.angle,XkbXKBFile)); + } + if (doodad->shape.color_ndx!=0) { + fprintf(file,"%s color= \"%s\";\n",i_str, + XkbLogoDoodadColor(geom,&doodad->logo)->spec); + } + shape= XkbLogoDoodadShape(geom,&doodad->logo); + fprintf(file,"%s shape= \"%s\";\n",i_str, + XkbAtomText(dpy,shape->name,XkbXKBFile)); + break; + } + fprintf(file,"%s};\n",i_str); + return True; +} + +/*ARGSUSED*/ +static Bool +WriteXKBOverlay( FILE * file, + Display * dpy, + unsigned indent, + XkbGeometryPtr geom, + XkbOverlayPtr ol) +{ +register char * i_str; +int r,k,nOut; +XkbOverlayRowPtr row; +XkbOverlayKeyPtr key; + + i_str= XkbIndentText(indent); + if (ol->name!=None) { + fprintf(file,"%soverlay \"%s\" {\n",i_str, + XkbAtomText(dpy,ol->name,XkbMessage)); + } + else fprintf(file,"%soverlay {\n",i_str); + for (nOut=r=0,row=ol->rows;r<ol->num_rows;r++,row++) { + for (k=0,key=row->keys;k<row->num_keys;k++,key++) { + char *over,*under; + over= XkbKeyNameText(key->over.name,XkbXKBFile); + under= XkbKeyNameText(key->under.name,XkbXKBFile); + if (nOut==0) + fprintf(file,"%s %6s=%6s",i_str,under,over); + else if ((nOut%4)==0) + fprintf(file,",\n%s %6s=%6s",i_str,under,over); + else fprintf(file,", %6s=%6s",under,over); + nOut++; + } + } + fprintf(file,"\n%s};\n",i_str); + return True; +} + +static Bool +WriteXKBSection( FILE * file, + Display * dpy, + XkbSectionPtr s, + XkbGeometryPtr geom) +{ +register int i; +XkbRowPtr row; +int dfltKeyColor = 0; + + fprintf(file," section \"%s\" {\n", + XkbAtomText(dpy,s->name,XkbXKBFile)); + if (s->rows&&(s->rows->num_keys>0)) { + dfltKeyColor= s->rows->keys[0].color_ndx; + fprintf(file," key.color= \"%s\";\n", + XkbStringText(geom->colors[dfltKeyColor].spec,XkbXKBFile)); + } + fprintf(file," priority= %d;\n",s->priority); + fprintf(file," top= %s;\n",XkbGeomFPText(s->top,XkbXKBFile)); + fprintf(file," left= %s;\n",XkbGeomFPText(s->left,XkbXKBFile)); + fprintf(file," width= %s;\n",XkbGeomFPText(s->width,XkbXKBFile)); + fprintf(file," height= %s;\n", + XkbGeomFPText(s->height,XkbXKBFile)); + if (s->angle!=0) { + fprintf(file," angle= %s;\n", + XkbGeomFPText(s->angle,XkbXKBFile)); + } + for (i=0,row=s->rows;i<s->num_rows;i++,row++) { + fprintf(file," row {\n"); + fprintf(file," top= %s;\n", + XkbGeomFPText(row->top,XkbXKBFile)); + fprintf(file," left= %s;\n", + XkbGeomFPText(row->left,XkbXKBFile)); + if (row->vertical) + fprintf(file," vertical;\n"); + if (row->num_keys>0) { + register int k; + register XkbKeyPtr key; + int forceNL=0; + int nThisLine= 0; + fprintf(file," keys {\n"); + for (k=0,key=row->keys;k<row->num_keys;k++,key++) { + XkbShapePtr shape; + if (key->color_ndx!=dfltKeyColor) + forceNL= 1; + if (k==0) { + fprintf(file," "); + nThisLine= 0; + } + else if (((nThisLine%2)==1)||(forceNL)) { + fprintf(file,",\n "); + forceNL= nThisLine= 0; + } + else { + fprintf(file,", "); + nThisLine++; + } + shape= XkbKeyShape(geom,key); + fprintf(file,"{ %6s, \"%s\", %3s", + XkbKeyNameText(key->name.name,XkbXKBFile), + XkbAtomText(dpy,shape->name,XkbXKBFile), + XkbGeomFPText(key->gap,XkbXKBFile)); + if (key->color_ndx!=dfltKeyColor) { + fprintf(file,", color=\"%s\"",XkbKeyColor(geom,key)->spec); + forceNL= 1; + } + fprintf(file," }"); + } + fprintf(file,"\n };\n"); + } + fprintf(file," };\n"); + } + if (s->doodads!=NULL) { + XkbDoodadPtr doodad; + for (i=0,doodad=s->doodads;i<s->num_doodads;i++,doodad++) { + WriteXKBDoodad(file,dpy,8,geom,doodad); + } + } + if (s->overlays!=NULL) { + XkbOverlayPtr ol; + for (i=0,ol=s->overlays;i<s->num_overlays;i++,ol++) { + WriteXKBOverlay(file,dpy,8,geom,ol); + } + } + fprintf(file," }; // End of \"%s\" section\n\n", + XkbAtomText(dpy,s->name,XkbXKBFile)); + return True; +} + +Bool +XkbWriteXKBGeometry( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Display * dpy; +register unsigned i,n; +XkbDescPtr xkb; +XkbGeometryPtr geom; + + xkb= result->xkb; + if ((!xkb)||(!xkb->geom)) { + _XkbLibError(_XkbErrMissingGeometry,"XkbWriteXKBGeometry",0); + return False; + } + dpy= xkb->dpy; + geom= xkb->geom; + if (geom->name==None) + fprintf(file,"xkb_geometry {\n\n"); + else fprintf(file,"xkb_geometry \"%s\" {\n\n", + XkbAtomText(dpy,geom->name,XkbXKBFile)); + fprintf(file," width= %s;\n", + XkbGeomFPText(geom->width_mm,XkbXKBFile)); + fprintf(file," height= %s;\n\n", + XkbGeomFPText(geom->height_mm,XkbXKBFile)); + + if (geom->key_aliases!=NULL) { + XkbKeyAliasPtr pAl; + pAl= geom->key_aliases; + for (i=0;i<geom->num_key_aliases;i++,pAl++) { + fprintf(file," alias %6s = %6s;\n", + XkbKeyNameText(pAl->alias,XkbXKBFile), + XkbKeyNameText(pAl->real,XkbXKBFile)); + } + fprintf(file,"\n"); + } + + if (geom->base_color!=NULL) + fprintf(file," baseColor= \"%s\";\n", + XkbStringText(geom->base_color->spec,XkbXKBFile)); + if (geom->label_color!=NULL) + fprintf(file," labelColor= \"%s\";\n", + XkbStringText(geom->label_color->spec,XkbXKBFile)); + if (geom->label_font!=NULL) + fprintf(file," xfont= \"%s\";\n", + XkbStringText(geom->label_font,XkbXKBFile)); + if ((geom->num_colors>0)&&(showImplicit)) { + XkbColorPtr color; + for (color=geom->colors,i=0;i<geom->num_colors;i++,color++) { + fprintf(file,"// color[%d]= \"%s\"\n",i, + XkbStringText(color->spec,XkbXKBFile)); + } + fprintf(file,"\n"); + } + if (geom->num_properties>0) { + XkbPropertyPtr prop; + for (prop=geom->properties,i=0;i<geom->num_properties;i++,prop++) { + fprintf(file," %s= \"%s\";\n",prop->name, + XkbStringText(prop->value,XkbXKBFile)); + } + fprintf(file,"\n"); + } + if (geom->num_shapes>0) { + XkbShapePtr shape; + XkbOutlinePtr outline; + int lastR; + for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) { + lastR=0; + fprintf(file," shape \"%s\" {", + XkbAtomText(dpy,shape->name,XkbXKBFile)); + outline= shape->outlines; + if (shape->num_outlines>1) { + for (n=0;n<shape->num_outlines;n++,outline++) { + if (n==0) fprintf(file,"\n"); + else fprintf(file,",\n"); + WriteXKBOutline(file,shape,outline,lastR,8,8); + lastR= outline->corner_radius; + } + fprintf(file,"\n };\n"); + } + else { + WriteXKBOutline(file,NULL,outline,lastR,1,8); + fprintf(file," };\n"); + } + } + } + if (geom->num_sections>0) { + XkbSectionPtr section; + for (section=geom->sections,i=0;i<geom->num_sections;i++,section++){ + WriteXKBSection(file,dpy,section,geom); + } + } + if (geom->num_doodads>0) { + XkbDoodadPtr doodad; + for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) { + WriteXKBDoodad(file,dpy,4,geom,doodad); + } + } + if (addOn) + (*addOn)(file,result,topLevel,showImplicit,XkmGeometryIndex,priv); + fprintf(file,"};\n\n"); + return True; +} + +/*ARGSUSED*/ +Bool +XkbWriteXKBSemantics( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Bool ok; + + fprintf(file,"xkb_semantics {\n"); + ok= XkbWriteXKBKeyTypes(file,result,False,False,addOn,priv); + ok= ok&&XkbWriteXKBCompatMap(file,result,False,False,addOn,priv); + fprintf(file,"};\n"); + return ok; +} + +/*ARGSUSED*/ +Bool +XkbWriteXKBLayout( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Bool ok; +XkbDescPtr xkb; + + xkb= result->xkb; + fprintf(file,"xkb_layout {\n"); + ok= XkbWriteXKBKeycodes(file,result,False,showImplicit,addOn,priv); + ok= ok&&XkbWriteXKBKeyTypes(file,result,False,showImplicit,addOn,priv); + ok= ok&&XkbWriteXKBSymbols(file,result,False,showImplicit,addOn,priv); + if (xkb->geom) + ok= ok&&XkbWriteXKBGeometry(file,result,False,showImplicit,addOn,priv); + fprintf(file,"};\n"); + return ok; +} + +/*ARGSUSED*/ +Bool +XkbWriteXKBKeymap( FILE * file, + XkbFileInfo * result, + Bool topLevel, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Bool ok; +XkbDescPtr xkb; + + xkb= result->xkb; + fprintf(file,"xkb_keymap {\n"); + ok= XkbWriteXKBKeycodes(file,result,False,showImplicit,addOn,priv); + ok= ok&&XkbWriteXKBKeyTypes(file,result,False,showImplicit,addOn,priv); + ok= ok&&XkbWriteXKBCompatMap(file,result,False,showImplicit,addOn,priv); + ok= ok&&XkbWriteXKBSymbols(file,result,False,showImplicit,addOn,priv); + if (xkb->geom) + ok= ok&&XkbWriteXKBGeometry(file,result,False,showImplicit,addOn,priv); + fprintf(file,"};\n"); + return ok; +} + +Bool +XkbWriteXKBFile( FILE * out, + XkbFileInfo * result, + Bool showImplicit, + XkbFileAddOnFunc addOn, + void * priv) +{ +Bool ok = False; +Bool (*func)( + FILE * /* file */, + XkbFileInfo * /* result */, + Bool /* topLevel */, + Bool /* showImplicit */, + XkbFileAddOnFunc /* addOn */, + void * /* priv */ +) = NULL; + + switch (result->type) { + case XkmSemanticsFile: + func= XkbWriteXKBSemantics; + break; + case XkmLayoutFile: + func= XkbWriteXKBLayout; + break; + case XkmKeymapFile: + func= XkbWriteXKBKeymap; + break; + case XkmTypesIndex: + func= XkbWriteXKBKeyTypes; + break; + case XkmCompatMapIndex: + func= XkbWriteXKBCompatMap; + break; + case XkmSymbolsIndex: + func= XkbWriteXKBSymbols; + break; + case XkmKeyNamesIndex: + func= XkbWriteXKBKeycodes; + break; + case XkmGeometryFile: + case XkmGeometryIndex: + func= XkbWriteXKBGeometry; + break; + case XkmVirtualModsIndex: + case XkmIndicatorsIndex: + _XkbLibError(_XkbErrBadImplementation, + XkbConfigText(result->type,XkbMessage),0); + return False; + } + if (out==NULL) { + _XkbLibError(_XkbErrFileCannotOpen,"XkbWriteXkbFile",0); + ok= False; + } + else if (func) { + ok= (*func)(out,result,True,showImplicit,addOn,priv); + } + return ok; +} diff --git a/xkb/xkbtext.c b/xkb/xkbtext.c new file mode 100644 index 000000000..defd45a64 --- /dev/null +++ b/xkb/xkbtext.c @@ -0,0 +1,1325 @@ +/* $Xorg: xkbtext.c,v 1.3 2000/08/17 19:46:44 cpqbld Exp $ */ +/************************************************************ + 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. + + ********************************************************/ +/* $XFree86: xc/lib/xkbfile/xkbtext.c,v 3.11 2002/12/21 18:49:02 paulo Exp $ */ + +#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 <X11/extensions/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; +} + +char * +XkbAccessXDetailText(unsigned state,unsigned format) +{ +char *buf,*prefix; + + buf= tbGetBuffer(32); + if (format==XkbMessage) prefix= ""; + else prefix= "XkbAXN_"; + switch (state){ + case XkbAXN_SKPress: sprintf(buf,"%sSKPress",prefix); break; + case XkbAXN_SKAccept: sprintf(buf,"%sSKAccept",prefix); break; + case XkbAXN_SKRelease: sprintf(buf,"%sSKRelease",prefix); break; + case XkbAXN_SKReject: sprintf(buf,"%sSKReject",prefix); break; + case XkbAXN_BKAccept: sprintf(buf,"%sBKAccept",prefix); break; + case XkbAXN_BKReject: sprintf(buf,"%sBKReject",prefix); break; + case XkbAXN_AXKWarning: sprintf(buf,"%sAXKWarning",prefix); break; + default: sprintf(buf,"ILLEGAL"); break; + } + return buf; +} + +static char *nknNames[] = { + "keycodes", "geometry", "deviceID" +}; +#define NUM_NKN (sizeof(nknNames)/sizeof(char *)) + +char * +XkbNKNDetailMaskText(unsigned detail,unsigned format) +{ +char *buf,*prefix,*suffix; +register int i; +register unsigned bit; +int len,plen,slen; + + + if ((detail&XkbAllNewKeyboardEventsMask)==0) { + char *tmp = ""; + if (format==XkbCFile) tmp= "0"; + else if (format==XkbMessage) tmp= "none"; + buf= tbGetBuffer(strlen(tmp)+1); + strcpy(buf,tmp); + return buf; + } + else if ((detail&XkbAllNewKeyboardEventsMask)==XkbAllNewKeyboardEventsMask){ + char * tmp; + if (format==XkbCFile) tmp= "XkbAllNewKeyboardEventsMask"; + else tmp= "all"; + buf= tbGetBuffer(strlen(tmp)+1); + strcpy(buf,tmp); + return buf; + } + if (format==XkbMessage) { + prefix= ""; + suffix= ""; + slen= plen= 0; + } + else { + prefix= "XkbNKN_"; + plen= 7; + if (format==XkbCFile) + suffix= "Mask"; + else suffix= ""; + slen= strlen(suffix); + } + for (len=0,i=0,bit=1;i<NUM_NKN;i++,bit<<=1) { + if (detail&bit) { + if (len!=0) len+= 1; /* room for '+' or '|' */ + len+= plen+slen+strlen(nknNames[i]); + } + } + buf= tbGetBuffer(len+1); + buf[0]= '\0'; + for (len=0,i=0,bit=1;i<NUM_NKN;i++,bit<<=1) { + if (detail&bit) { + if (len!=0) { + if (format==XkbCFile) buf[len++]= '|'; + else buf[len++]= '+'; + } + if (plen) { + strcpy(&buf[len],prefix); + len+= plen; + } + strcpy(&buf[len],nknNames[i]); + len+= strlen(nknNames[i]); + if (slen) { + strcpy(&buf[len],suffix); + len+= slen; + } + } + } + buf[len++]= '\0'; + return buf; +} + +static char *ctrlNames[] = { + "repeatKeys", + "slowKeys", + "bounceKeys", + "stickyKeys", + "mouseKeys", + "mouseKeysAccel", + "accessXKeys", + "accessXTimeout", + "accessXFeedback", + "audibleBell", + "overlay1", + "overlay2", + "ignoreGroupLock" +}; + +char * +XkbControlsMaskText(unsigned ctrls,unsigned format) +{ +int len; +unsigned i,bit,tmp; +char * buf; + + if (ctrls==0) { + buf= tbGetBuffer(5); + if (format==XkbCFile) + strcpy(buf,"0"); + else strcpy(buf,"none"); + return buf; + } + tmp= ctrls&XkbAllBooleanCtrlsMask; + for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) { + if (tmp&bit) { + tmp&= ~bit; + len+= strlen(ctrlNames[i])+1; + if (format==XkbCFile) + len+= 7; + } + } + buf= tbGetBuffer(len+1); + tmp= ctrls&XkbAllBooleanCtrlsMask; + for (len=i=0,bit=1;tmp!=0;i++,bit<<=1) { + if (tmp&bit) { + tmp&= ~bit; + if (format==XkbCFile) { + if (len!=0) + buf[len++]= '|'; + sprintf(&buf[len],"Xkb%sMask",ctrlNames[i]); + buf[len+3]= toupper(buf[len+3]); + } + else { + if (len!=0) + buf[len++]= '+'; + sprintf(&buf[len],"%s",ctrlNames[i]); + } + len+= strlen(&buf[len]); + } + } + return buf; +} + +/***====================================================================***/ + +char * +XkbStringText(char *str,unsigned format) +{ +char * buf; +register char *in,*out; +int len; +Bool ok; + + if (str==NULL) { + buf= tbGetBuffer(2); + buf[0]='\0'; + return buf; + } + else if (format==XkbXKMFile) + return str; + for (ok= True,len=0,in=str;*in!='\0';in++,len++) { + if (!isprint(*in)) { + ok= False; + switch (*in) { + case '\n': case '\t': case '\v': + case '\b': case '\r': case '\f': + len++; + break; + default: + len+= 4; + break; + } + } + } + if (ok) + return str; + buf= tbGetBuffer(len+1); + for (in=str,out=buf;*in!='\0';in++) { + if (isprint(*in)) + *out++= *in; + else { + *out++= '\\'; + if (*in=='\n') *out++= 'n'; + else if (*in=='\t') *out++= 't'; + else if (*in=='\v') *out++= 'v'; + else if (*in=='\b') *out++= 'b'; + else if (*in=='\r') *out++= 'r'; + else if (*in=='\f') *out++= 'f'; + else if ((*in=='\033')&&(format==XkbXKMFile)) { + *out++= 'e'; + } + else { + *out++= '0'; + sprintf(out,"%o",*in); + while (*out!='\0') + out++; + } + } + } + *out++= '\0'; + return buf; +} + +/***====================================================================***/ + +char * +XkbGeomFPText(int val,unsigned format) +{ +int whole,frac; +char * buf; + + buf= tbGetBuffer(12); + if (format==XkbCFile) { + sprintf(buf,"%d",val); + } + else { + whole= val/XkbGeomPtsPerMM; + frac= val%XkbGeomPtsPerMM; + if (frac!=0) + sprintf(buf,"%d.%d",whole,frac); + else sprintf(buf,"%d",whole); + } + return buf; +} + +char * +XkbDoodadTypeText(unsigned type,unsigned format) +{ +char * buf; + if (format==XkbCFile) { + buf= tbGetBuffer(24); + if (type==XkbOutlineDoodad) strcpy(buf,"XkbOutlineDoodad"); + else if (type==XkbSolidDoodad) strcpy(buf,"XkbSolidDoodad"); + else if (type==XkbTextDoodad) strcpy(buf,"XkbTextDoodad"); + else if (type==XkbIndicatorDoodad) strcpy(buf,"XkbIndicatorDoodad"); + else if (type==XkbLogoDoodad) strcpy(buf,"XkbLogoDoodad"); + else sprintf(buf,"UnknownDoodad%d",type); + } + else { + buf= tbGetBuffer(12); + if (type==XkbOutlineDoodad) strcpy(buf,"outline"); + else if (type==XkbSolidDoodad) strcpy(buf,"solid"); + else if (type==XkbTextDoodad) strcpy(buf,"text"); + else if (type==XkbIndicatorDoodad) strcpy(buf,"indicator"); + else if (type==XkbLogoDoodad) strcpy(buf,"logo"); + else sprintf(buf,"unknown%d",type); + } + return buf; +} + +static char *actionTypeNames[XkbSA_NumActions]= { + "NoAction", + "SetMods", "LatchMods", "LockMods", + "SetGroup", "LatchGroup", "LockGroup", + "MovePtr", + "PtrBtn", "LockPtrBtn", + "SetPtrDflt", + "ISOLock", + "Terminate", "SwitchScreen", + "SetControls", "LockControls", + "ActionMessage", + "RedirectKey", + "DeviceBtn", "LockDeviceBtn" +}; + +char * +XkbActionTypeText(unsigned type,unsigned format) +{ +static char buf[32]; +char *rtrn; + + if (type<=XkbSA_LastAction) { + rtrn= actionTypeNames[type]; + if (format==XkbCFile) { + sprintf(buf,"XkbSA_%s",rtrn); + return buf; + } + return rtrn; + } + sprintf(buf,"Private"); + return buf; +} + +/***====================================================================***/ + +static int +TryCopyStr(char *to,char *from,int *pLeft) +{ +register int len; + if (*pLeft>0) { + len= strlen(from); + if (len<((*pLeft)-3)) { + strcat(to,from); + *pLeft-= len; + return True; + } + } + *pLeft= -1; + return False; +} + +/*ARGSUSED*/ +static Bool +CopyNoActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int*sz) +{ + return True; +} + +static Bool +CopyModActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf, + int* sz) +{ +XkbModAction * act; +unsigned tmp; + + act= &action->mods; + tmp= XkbModActionVMods(act); + TryCopyStr(buf,"modifiers=",sz); + if (act->flags&XkbSA_UseModMapMods) + TryCopyStr(buf,"modMapMods",sz); + else if (act->real_mods || tmp) { + TryCopyStr(buf, + XkbVModMaskText(dpy,xkb,act->real_mods,tmp,XkbXKBFile), + sz); + } + else TryCopyStr(buf,"none",sz); + if (act->type==XkbSA_LockMods) + return True; + if (act->flags&XkbSA_ClearLocks) + TryCopyStr(buf,",clearLocks",sz); + if (act->flags&XkbSA_LatchToLock) + TryCopyStr(buf,",latchToLock",sz); + return True; +} + +/*ARGSUSED*/ +static Bool +CopyGroupActionArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf, + int *sz) +{ +XkbGroupAction * act; +char tbuf[32]; + + act= &action->group; + TryCopyStr(buf,"group=",sz); + if (act->flags&XkbSA_GroupAbsolute) + sprintf(tbuf,"%d",XkbSAGroup(act)+1); + else if (XkbSAGroup(act)<0) + sprintf(tbuf,"%d",XkbSAGroup(act)); + else sprintf(tbuf,"+%d",XkbSAGroup(act)); + TryCopyStr(buf,tbuf,sz); + if (act->type==XkbSA_LockGroup) + return True; + if (act->flags&XkbSA_ClearLocks) + TryCopyStr(buf,",clearLocks",sz); + if (act->flags&XkbSA_LatchToLock) + TryCopyStr(buf,",latchToLock",sz); + return True; +} + +/*ARGSUSED*/ +static Bool +CopyMovePtrArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz) +{ +XkbPtrAction * act; +int x,y; +char tbuf[32]; + + act= &action->ptr; + x= XkbPtrActionX(act); + y= XkbPtrActionY(act); + if ((act->flags&XkbSA_MoveAbsoluteX)||(x<0)) + sprintf(tbuf,"x=%d",x); + else sprintf(tbuf,"x=+%d",x); + TryCopyStr(buf,tbuf,sz); + + if ((act->flags&XkbSA_MoveAbsoluteY)||(y<0)) + sprintf(tbuf,",y=%d",y); + else sprintf(tbuf,",y=+%d",y); + TryCopyStr(buf,tbuf,sz); + if (act->flags&XkbSA_NoAcceleration) + TryCopyStr(buf,",!accel",sz); + return True; +} + +/*ARGSUSED*/ +static Bool +CopyPtrBtnArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz) +{ +XkbPtrBtnAction * act; +char tbuf[32]; + + act= &action->btn; + TryCopyStr(buf,"button=",sz); + if ((act->button>0)&&(act->button<6)) { + sprintf(tbuf,"%d",act->button); + TryCopyStr(buf,tbuf,sz); + } + else TryCopyStr(buf,"default",sz); + if (act->count>0) { + sprintf(tbuf,",count=%d",act->count); + TryCopyStr(buf,tbuf,sz); + } + if (action->type==XkbSA_LockPtrBtn) { + switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) { + case XkbSA_LockNoLock: + sprintf(tbuf,",affect=unlock"); break; + case XkbSA_LockNoUnlock: + sprintf(tbuf,",affect=lock"); break; + case XkbSA_LockNoUnlock|XkbSA_LockNoLock: + sprintf(tbuf,",affect=neither"); break; + default: + sprintf(tbuf,",affect=both"); break; + } + TryCopyStr(buf,tbuf,sz); + } + return True; +} + +/*ARGSUSED*/ +static Bool +CopySetPtrDfltArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf, + int *sz) +{ +XkbPtrDfltAction * act; +char tbuf[32]; + + act= &action->dflt; + if (act->affect==XkbSA_AffectDfltBtn) { + TryCopyStr(buf,"affect=button,button=",sz); + if ((act->flags&XkbSA_DfltBtnAbsolute)||(XkbSAPtrDfltValue(act)<0)) + sprintf(tbuf,"%d",XkbSAPtrDfltValue(act)); + else sprintf(tbuf,"+%d",XkbSAPtrDfltValue(act)); + TryCopyStr(buf,tbuf,sz); + } + return True; +} + +static Bool +CopyISOLockArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz) +{ +XkbISOAction * act; +char tbuf[64]; + + act= &action->iso; + if (act->flags&XkbSA_ISODfltIsGroup) { + TryCopyStr(tbuf,"group=",sz); + if (act->flags&XkbSA_GroupAbsolute) + sprintf(tbuf,"%d",XkbSAGroup(act)+1); + else if (XkbSAGroup(act)<0) + sprintf(tbuf,"%d",XkbSAGroup(act)); + else sprintf(tbuf,"+%d",XkbSAGroup(act)); + TryCopyStr(buf,tbuf,sz); + } + else { + unsigned tmp; + tmp= XkbModActionVMods(act); + TryCopyStr(buf,"modifiers=",sz); + if (act->flags&XkbSA_UseModMapMods) + TryCopyStr(buf,"modMapMods",sz); + else if (act->real_mods || tmp) { + if (act->real_mods) { + TryCopyStr(buf,XkbModMaskText(act->real_mods,XkbXKBFile),sz); + if (tmp) + TryCopyStr(buf,"+",sz); + } + if (tmp) + TryCopyStr(buf,XkbVModMaskText(dpy,xkb,0,tmp,XkbXKBFile),sz); + } + else TryCopyStr(buf,"none",sz); + } + TryCopyStr(buf,",affect=",sz); + if ((act->affect&XkbSA_ISOAffectMask)==0) + TryCopyStr(buf,"all",sz); + else { + int nOut= 0; + if ((act->affect&XkbSA_ISONoAffectMods)==0) { + TryCopyStr(buf,"mods",sz); + nOut++; + } + if ((act->affect&XkbSA_ISONoAffectGroup)==0) { + sprintf(tbuf,"%sgroups",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if ((act->affect&XkbSA_ISONoAffectPtr)==0) { + sprintf(tbuf,"%spointer",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if ((act->affect&XkbSA_ISONoAffectCtrls)==0) { + sprintf(tbuf,"%scontrols",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + } + return True; +} + +/*ARGSUSED*/ +static Bool +CopySwitchScreenArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf, + int *sz) +{ +XkbSwitchScreenAction * act; +char tbuf[32]; + + act= &action->screen; + if ((act->flags&XkbSA_SwitchAbsolute)||(XkbSAScreen(act)<0)) + sprintf(tbuf,"screen=%d",XkbSAScreen(act)); + else sprintf(tbuf,"screen=+%d",XkbSAScreen(act)); + TryCopyStr(buf,tbuf,sz); + if (act->flags&XkbSA_SwitchApplication) + TryCopyStr(buf,",!same",sz); + else TryCopyStr(buf,",same",sz); + return True; +} + +/*ARGSUSED*/ +static Bool +CopySetLockControlsArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action, + char *buf,int *sz) +{ +XkbCtrlsAction * act; +unsigned tmp; +char tbuf[32]; + + act= &action->ctrls; + tmp= XkbActionCtrls(act); + TryCopyStr(buf,"controls=",sz); + if (tmp==0) + TryCopyStr(buf,"none",sz); + else if ((tmp&XkbAllBooleanCtrlsMask)==XkbAllBooleanCtrlsMask) + TryCopyStr(buf,"all",sz); + else { + int nOut= 0; + if (tmp&XkbRepeatKeysMask) { + sprintf(tbuf,"%sRepeatKeys",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbSlowKeysMask) { + sprintf(tbuf,"%sSlowKeys",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbBounceKeysMask) { + sprintf(tbuf,"%sBounceKeys",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbStickyKeysMask) { + sprintf(tbuf,"%sStickyKeys",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbMouseKeysMask) { + sprintf(tbuf,"%sMouseKeys",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbMouseKeysAccelMask) { + sprintf(tbuf,"%sMouseKeysAccel",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbAccessXKeysMask) { + sprintf(tbuf,"%sAccessXKeys",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbAccessXTimeoutMask) { + sprintf(tbuf,"%sAccessXTimeout",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbAccessXFeedbackMask) { + sprintf(tbuf,"%sAccessXFeedback",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbAudibleBellMask) { + sprintf(tbuf,"%sAudibleBell",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbOverlay1Mask) { + sprintf(tbuf,"%sOverlay1",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbOverlay2Mask) { + sprintf(tbuf,"%sOverlay2",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + if (tmp&XkbIgnoreGroupLockMask) { + sprintf(tbuf,"%sIgnoreGroupLock",(nOut>0?"+":"")); + TryCopyStr(buf,tbuf,sz); + nOut++; + } + } + return True; +} + +/*ARGSUSED*/ +static Bool +CopyActionMessageArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf, + int *sz) +{ +XkbMessageAction * act; +unsigned all; +char tbuf[32]; + + act= &action->msg; + all= XkbSA_MessageOnPress|XkbSA_MessageOnRelease; + TryCopyStr(buf,"report=",sz); + if ((act->flags&all)==0) + TryCopyStr(buf,"none",sz); + else if ((act->flags&all)==all) + TryCopyStr(buf,"all",sz); + else if (act->flags&XkbSA_MessageOnPress) + TryCopyStr(buf,"KeyPress",sz); + else TryCopyStr(buf,"KeyRelease",sz); + sprintf(tbuf,",data[0]=0x%02x",act->message[0]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[1]=0x%02x",act->message[1]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[2]=0x%02x",act->message[2]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[3]=0x%02x",act->message[3]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[4]=0x%02x",act->message[4]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[5]=0x%02x",act->message[5]); TryCopyStr(buf,tbuf,sz); + return True; +} + +static Bool +CopyRedirectKeyArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf, + int *sz) +{ +XkbRedirectKeyAction * act; +char tbuf[32],*tmp; +unsigned kc; +unsigned vmods,vmods_mask; + + act= &action->redirect; + kc= act->new_key; + vmods= XkbSARedirectVMods(act); + vmods_mask= XkbSARedirectVModsMask(act); + if (xkb && xkb->names && xkb->names->keys && (kc<=xkb->max_key_code) && + (xkb->names->keys[kc].name[0]!='\0')) { + char *kn; + kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile); + sprintf(tbuf,"key=%s",kn); + } + else sprintf(tbuf,"key=%d",kc); + TryCopyStr(buf,tbuf,sz); + if ((act->mods_mask==0)&&(vmods_mask==0)) + return True; + if ((act->mods_mask==XkbAllModifiersMask)&& + (vmods_mask==XkbAllVirtualModsMask)) { + tmp= XkbVModMaskText(dpy,xkb,act->mods,vmods,XkbXKBFile); + TryCopyStr(buf,",mods=",sz); + TryCopyStr(buf,tmp,sz); + } + else { + if ((act->mods_mask&act->mods)||(vmods_mask&vmods)) { + tmp= XkbVModMaskText(dpy,xkb,act->mods_mask&act->mods, + vmods_mask&vmods,XkbXKBFile); + TryCopyStr(buf,",mods= ",sz); + TryCopyStr(buf,tmp,sz); + } + if ((act->mods_mask&(~act->mods))||(vmods_mask&(~vmods))) { + tmp= XkbVModMaskText(dpy,xkb,act->mods_mask&(~act->mods), + vmods_mask&(~vmods),XkbXKBFile); + TryCopyStr(buf,",clearMods= ",sz); + TryCopyStr(buf,tmp,sz); + } + } + return True; +} + +/*ARGSUSED*/ +static Bool +CopyDeviceBtnArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf, + int *sz) +{ +XkbDeviceBtnAction * act; +char tbuf[32]; + + act= &action->devbtn; + sprintf(tbuf,"device= %d",act->device); TryCopyStr(buf,tbuf,sz); + TryCopyStr(buf,",button=",sz); + sprintf(tbuf,"%d",act->button); + TryCopyStr(buf,tbuf,sz); + if (act->count>0) { + sprintf(tbuf,",count=%d",act->count); + TryCopyStr(buf,tbuf,sz); + } + if (action->type==XkbSA_LockDeviceBtn) { + switch (act->flags&(XkbSA_LockNoUnlock|XkbSA_LockNoLock)) { + case XkbSA_LockNoLock: + sprintf(tbuf,",affect=unlock"); break; + case XkbSA_LockNoUnlock: + sprintf(tbuf,",affect=lock"); break; + case XkbSA_LockNoUnlock|XkbSA_LockNoLock: + sprintf(tbuf,",affect=neither"); break; + default: + sprintf(tbuf,",affect=both"); break; + } + TryCopyStr(buf,tbuf,sz); + } + return True; +} + +/*ARGSUSED*/ +static Bool +CopyOtherArgs(Display *dpy,XkbDescPtr xkb,XkbAction *action,char *buf,int *sz) +{ +XkbAnyAction * act; +char tbuf[32]; + + act= &action->any; + sprintf(tbuf,"type=0x%02x",act->type); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[0]=0x%02x",act->data[0]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[1]=0x%02x",act->data[1]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[2]=0x%02x",act->data[2]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[3]=0x%02x",act->data[3]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[4]=0x%02x",act->data[4]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[5]=0x%02x",act->data[5]); TryCopyStr(buf,tbuf,sz); + sprintf(tbuf,",data[6]=0x%02x",act->data[6]); TryCopyStr(buf,tbuf,sz); + return True; +} + +typedef Bool (*actionCopy)( + Display * /* dpy */, + XkbDescPtr /* xkb */, + XkbAction * /* action */, + char * /* buf */, + int* /* sz */ +); +static actionCopy copyActionArgs[XkbSA_NumActions] = { + CopyNoActionArgs /* NoAction */, + CopyModActionArgs /* SetMods */, + CopyModActionArgs /* LatchMods */, + CopyModActionArgs /* LockMods */, + CopyGroupActionArgs /* SetGroup */, + CopyGroupActionArgs /* LatchGroup */, + CopyGroupActionArgs /* LockGroup */, + CopyMovePtrArgs /* MovePtr */, + CopyPtrBtnArgs /* PtrBtn */, + CopyPtrBtnArgs /* LockPtrBtn */, + CopySetPtrDfltArgs /* SetPtrDflt */, + CopyISOLockArgs /* ISOLock */, + CopyNoActionArgs /* Terminate */, + CopySwitchScreenArgs /* SwitchScreen */, + CopySetLockControlsArgs /* SetControls */, + CopySetLockControlsArgs /* LockControls */, + CopyActionMessageArgs /* ActionMessage*/, + CopyRedirectKeyArgs /* RedirectKey */, + CopyDeviceBtnArgs /* DeviceBtn */, + CopyDeviceBtnArgs /* LockDeviceBtn*/ +}; + +#define ACTION_SZ 256 + +char * +XkbActionText(Display *dpy,XkbDescPtr xkb,XkbAction *action,unsigned format) +{ +char buf[ACTION_SZ],*tmp; +int sz; + + if (format==XkbCFile) { + sprintf(buf, + "{ %20s, { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x } }", + XkbActionTypeText(action->type,XkbCFile), + action->any.data[0],action->any.data[1],action->any.data[2], + action->any.data[3],action->any.data[4],action->any.data[5], + action->any.data[6]); + } + else { + sprintf(buf,"%s(",XkbActionTypeText(action->type,XkbXKBFile)); + sz= ACTION_SZ-strlen(buf)+2; /* room for close paren and NULL */ + if (action->type<(unsigned)XkbSA_NumActions) + (*copyActionArgs[action->type])(dpy,xkb,action,buf,&sz); + else CopyOtherArgs(dpy,xkb,action,buf,&sz); + TryCopyStr(buf,")",&sz); + } + tmp= tbGetBuffer(strlen(buf)+1); + if (tmp!=NULL) + strcpy(tmp,buf); + return tmp; +} + +char * +XkbBehaviorText(XkbDescPtr xkb,XkbBehavior *behavior,unsigned format) +{ +char buf[256],*tmp; + + if (format==XkbCFile) { + if (behavior->type==XkbKB_Default) + sprintf(buf,"{ 0, 0 }"); + else sprintf(buf,"{ %3d, 0x%02x }",behavior->type,behavior->data); + } + else { + unsigned type,permanent; + type= behavior->type&XkbKB_OpMask; + permanent=((behavior->type&XkbKB_Permanent)!=0); + + if (type==XkbKB_Lock) { + sprintf(buf,"lock= %s",(permanent?"Permanent":"True")); + } + else if (type==XkbKB_RadioGroup) { + int g; + char *tmp; + g= ((behavior->data)&(~XkbKB_RGAllowNone))+1; + if (XkbKB_RGAllowNone&behavior->data) { + sprintf(buf,"allowNone,"); + tmp= &buf[strlen(buf)]; + } + else tmp= buf; + if (permanent) + sprintf(tmp,"permanentRadioGroup= %d",g); + else sprintf(tmp,"radioGroup= %d",g); + } + else if ((type==XkbKB_Overlay1)||(type==XkbKB_Overlay2)) { + int ndx,kc; + char *kn; + + ndx= ((type==XkbKB_Overlay1)?1:2); + kc= behavior->data; + if ((xkb)&&(xkb->names)&&(xkb->names->keys)) + kn= XkbKeyNameText(xkb->names->keys[kc].name,XkbXKBFile); + else { + static char tbuf[8]; + sprintf(tbuf,"%d",kc); + kn= tbuf; + } + if (permanent) + sprintf(buf,"permanentOverlay%d= %s",ndx,kn); + else sprintf(buf,"overlay%d= %s",ndx,kn); + } + } + tmp= tbGetBuffer(strlen(buf)+1); + if (tmp!=NULL) + strcpy(tmp,buf); + return tmp; +} + +/***====================================================================***/ + +char * +XkbIndentText(unsigned size) +{ +static char buf[32]; +register int i; + + if (size>31) + size= 31; + + for (i=0;i<size;i++) { + buf[i]= ' '; + } + buf[size]= '\0'; + return buf; +} diff --git a/xkb/xkmread.c b/xkb/xkmread.c index 5441243ed..fec86874f 100644 --- a/xkb/xkmread.c +++ b/xkb/xkmread.c @@ -167,89 +167,6 @@ int count,nRead=0; return nRead; } -unsigned -_XkbKSCheckCase(KeySym ks) -{ -unsigned set,rtrn; - - set= (ks & (~0xff)) >> 8; - rtrn= 0; - switch (set) { - case 0: /* latin 1 */ - if (((ks>=XK_A)&&(ks<=XK_Z))|| - ((ks>=XK_Agrave)&&(ks<=XK_THORN)&&(ks!=XK_multiply))) { - rtrn|= _XkbKSUpper; - } - if (((ks>=XK_a)&&(ks<=XK_z))|| - ((ks>=XK_agrave)&&(ks<=XK_ydiaeresis))) { - rtrn|= _XkbKSLower; - } - break; - case 1: /* latin 2 */ - if (((ks>=XK_Aogonek)&&(ks<=XK_Zabovedot)&&(ks!=XK_breve))|| - ((ks>=XK_Racute)&&(ks<=XK_Tcedilla))) { - rtrn|= _XkbKSUpper; - } - if (((ks>=XK_aogonek)&&(ks<=XK_zabovedot)&&(ks!=XK_caron))|| - ((ks>=XK_racute)&&(ks<=XK_tcedilla))) { - rtrn|= _XkbKSLower; - } - break; - case 2: /* latin 3 */ - if (((ks>=XK_Hstroke)&&(ks<=XK_Jcircumflex))|| - ((ks>=XK_Cabovedot)&&(ks<=XK_Scircumflex))) { - rtrn|= _XkbKSUpper; - } - if (((ks>=XK_hstroke)&&(ks<=XK_jcircumflex))|| - ((ks>=XK_cabovedot)&&(ks<=XK_scircumflex))) { - rtrn|= _XkbKSLower; - } - break; - case 3: /* latin 4 */ - if (((ks>=XK_Rcedilla)&&(ks<=XK_Tslash))|| - (ks==XK_ENG)|| - ((ks>=XK_Amacron)&&(ks<=XK_Umacron))) { - rtrn|= _XkbKSUpper; - } - if (((ks>=XK_rcedilla)&&(ks<=XK_tslash))|| - (ks==XK_eng)|| - ((ks>=XK_amacron)&&(ks<=XK_umacron))) { - rtrn|= _XkbKSLower; - } - break; - case 18: /* latin 8 */ - if ((ks==XK_Babovedot)|| - ((ks>=XK_Dabovedot)&&(ks<=XK_Wacute))|| - ((ks>=XK_Ygrave)&&(ks<=XK_Fabovedot))|| - (ks==XK_Mabovedot)|| - (ks==XK_Pabovedot)|| - (ks==XK_Sabovedot)|| - (ks==XK_Wdiaeresis)|| - ((ks>=XK_Wcircumflex)&&(ks<=XK_Ycircumflex))) { - rtrn|= _XkbKSUpper; - } - if ((ks==XK_babovedot)|| - (ks==XK_dabovedot)|| - (ks==XK_fabovedot)|| - (ks==XK_mabovedot)|| - ((ks>=XK_wgrave)&&(ks<=XK_wacute))|| - (ks==XK_ygrave)|| - ((ks>=XK_wdiaeresis)&&(ks<=XK_ycircumflex))) { - rtrn|= _XkbKSLower; - } - break; - case 19: /* latin 9 */ - if ((ks==XK_OE)||(ks==XK_Ydiaeresis)) { - rtrn|= _XkbKSUpper; - } - if (ks==XK_oe) { - rtrn|= _XkbKSLower; - } - break; - } - return rtrn; -} - /***====================================================================***/ static int @@ -1251,10 +1168,14 @@ int nRead; *loaded_rtrn|= XkmGeometryMask; break; default: + _XkbLibError(_XkbErrBadImplementation, + XkbConfigText(tmpTOC.type,XkbMessage),0); nRead= 0; break; } if (nRead!=tmpTOC.size) { + _XkbLibError(_XkbErrBadLength,XkbConfigText(tmpTOC.type,XkbMessage), + nRead-tmpTOC.size); return 0; } return (nRead>=0); @@ -1288,6 +1209,8 @@ char name[100]; return _XkbDupString(name); break; default: + _XkbLibError(_XkbErrBadImplementation, + XkbConfigText(tmpTOC.type,XkbMessage),0); break; } return NULL; @@ -1353,6 +1276,8 @@ unsigned which= need|want; tmp= ReadXkmGeometry(file,result); break; default: + _XkbLibError(_XkbErrBadImplementation, + XkbConfigText(tmpTOC.type,XkbMessage),0); tmp= 0; break; } @@ -1362,7 +1287,8 @@ unsigned which= need|want; result->defined|= (1<<toc[i].type); } if (nRead!=tmpTOC.size) { - return 0; + _XkbLibError(_XkbErrBadLength,XkbConfigText(tmpTOC.type,XkbMessage), + nRead-tmpTOC.size); } } return which; |