diff options
Diffstat (limited to 'libxkbfile/src/xkmout.c')
-rw-r--r-- | libxkbfile/src/xkmout.c | 2776 |
1 files changed, 1387 insertions, 1389 deletions
diff --git a/libxkbfile/src/xkmout.c b/libxkbfile/src/xkmout.c index 08efea68d..599bce172 100644 --- a/libxkbfile/src/xkmout.c +++ b/libxkbfile/src/xkmout.c @@ -1,1389 +1,1387 @@ -/* $Xorg: xkmout.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/xkmout.c,v 1.5 2001/07/25 15:04:58 dawes Exp $ */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <ctype.h> -#include <stdlib.h> -#include <X11/Xfuncs.h> -#include <X11/Xlib.h> -#include <X11/XKBlib.h> -#include <X11/extensions/XKBgeom.h> - -#include "XKMformat.h" -#include "XKBfileInt.h" - -typedef struct _XkmInfo { - unsigned short bound_vmods; - unsigned short named_vmods; - unsigned char num_bound; - unsigned char group_compat; - unsigned short num_group_compat; - unsigned short num_leds; - int total_vmodmaps; -} XkmInfo; - -/***====================================================================***/ - -#define xkmPutCARD8(f,v) (putc(v,f),1) - -static int -xkmPutCARD16(FILE *file,unsigned val) -{ -CARD16 tmp= val; - - fwrite(&tmp,2,1,file); - return 2; -} - -static int -xkmPutCARD32(FILE *file,unsigned long val) -{ -CARD32 tmp= val; - - fwrite(&tmp,4,1,file); - return 4; -} - -static int -xkmPutPadding(FILE *file,unsigned pad) -{ -int i; - for (i=0;i<pad;i++) { - putc('\0',file); - } - return pad; -} - -static int -xkmPutCountedBytes(FILE *file,char *ptr,unsigned count) -{ -register int nOut; -register unsigned pad; - - if (count==0) - return xkmPutCARD32(file,(unsigned long)0); - - xkmPutCARD16(file,count); - nOut= fwrite(ptr,1,count,file); - if (nOut<0) - return 2; - nOut= count+2; - pad= XkbPaddedSize(nOut)-nOut; - if (pad) - xkmPutPadding(file,pad); - return nOut+pad; -} - -static unsigned -xkmSizeCountedString(char *str) -{ - if (str==NULL) - return 4; - return XkbPaddedSize(strlen(str)+2); -} - -static int -xkmPutCountedString(FILE *file,char *str) -{ - if (str==NULL) - return xkmPutCARD32(file,(unsigned long)0); - return xkmPutCountedBytes(file,str,strlen(str)); -} - -#define xkmSizeCountedAtomString(d,a) \ - xkmSizeCountedString(XkbAtomGetString((d),(a))) - -#define xkmPutCountedAtomString(d,f,a) \ - xkmPutCountedString((f),XkbAtomGetString((d),(a))) - -/***====================================================================***/ - -static unsigned -SizeXKMVirtualMods( XkbFileInfo * result, - XkmInfo * info, - xkmSectionInfo * toc, - int * offset_inout) -{ -Display * dpy; -XkbDescPtr xkb; -unsigned nBound,bound; -unsigned nNamed,named,szNames; -register unsigned i,bit; - - xkb= result->xkb; - dpy= xkb->dpy; - if ((!xkb)||(!xkb->names)||(!xkb->server)) { - _XkbLibError(_XkbErrMissingVMods,"SizeXKMVirtualMods",0); - return 0; - } - bound=named=0; - for (i=nBound=nNamed=szNames=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { - if (xkb->server->vmods[i]!=XkbNoModifierMask) { - bound|= bit; - nBound++; - } - if (xkb->names->vmods[i]!=None) { - named|= bit; - szNames+= xkmSizeCountedAtomString(dpy,xkb->names->vmods[i]); - nNamed++; - } - } - info->num_bound= nBound; - info->bound_vmods= bound; - info->named_vmods= named; - if ((nBound==0)&&(nNamed==0)) - return 0; - toc->type= XkmVirtualModsIndex; - toc->format= MSBFirst; - toc->size= 4+XkbPaddedSize(nBound)+szNames+SIZEOF(xkmSectionInfo); - toc->offset= *offset_inout; - (*offset_inout)+= toc->size; - return 1; -} - -static unsigned -WriteXKMVirtualMods(FILE *file,XkbFileInfo *result,XkmInfo *info) -{ -register unsigned int i,bit; -XkbDescPtr xkb; -Display * dpy; -unsigned size= 0; - - xkb= result->xkb; - dpy= xkb->dpy; - size+= xkmPutCARD16(file,info->bound_vmods); - size+= xkmPutCARD16(file,info->named_vmods); - for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { - if (info->bound_vmods&bit) - size+= xkmPutCARD8(file,xkb->server->vmods[i]); - } - if ((i= XkbPaddedSize(info->num_bound)-info->num_bound)>0) - size+= xkmPutPadding(file,i); - for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { - if (info->named_vmods&bit) { - register char *name; - name= XkbAtomGetString(dpy,xkb->names->vmods[i]); - size+= xkmPutCountedString(file,name); - } - } - return size; -} - -/***====================================================================***/ - -static unsigned -SizeXKMKeycodes(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout) -{ -XkbDescPtr xkb; -Atom kcName; -int size=0; -Display * dpy; - - xkb= result->xkb; - dpy= xkb->dpy; - if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) { - _XkbLibError(_XkbErrMissingNames,"SizeXKMKeycodes",0); - return 0; - } - kcName= xkb->names->keycodes; - size+= 4; /* min and max keycode */ - size+= xkmSizeCountedAtomString(dpy,kcName); - size+= XkbNumKeys(xkb)*sizeof(XkbKeyNameRec); - if (xkb->names->num_key_aliases>0) { - if (xkb->names->key_aliases!=NULL) - size+= xkb->names->num_key_aliases*sizeof(XkbKeyAliasRec); - else xkb->names->num_key_aliases= 0; - } - toc->type= XkmKeyNamesIndex; - toc->format= MSBFirst; - toc->size= size+SIZEOF(xkmSectionInfo); - toc->offset= (*offset_inout); - (*offset_inout)+= toc->size; - return 1; -} - -static unsigned -WriteXKMKeycodes(FILE *file,XkbFileInfo *result) -{ -XkbDescPtr xkb; -Atom kcName; -char *start; -Display * dpy; -unsigned tmp,size= 0; - - xkb= result->xkb; - dpy= xkb->dpy; - kcName= xkb->names->keycodes; - start= xkb->names->keys[xkb->min_key_code].name; - - size+= xkmPutCountedString(file,XkbAtomGetString(dpy,kcName)); - size+= xkmPutCARD8(file,xkb->min_key_code); - size+= xkmPutCARD8(file,xkb->max_key_code); - size+= xkmPutCARD8(file,xkb->names->num_key_aliases); - size+= xkmPutPadding(file,1); - tmp= fwrite(start,sizeof(XkbKeyNameRec),XkbNumKeys(xkb),file); - size+= tmp*sizeof(XkbKeyNameRec); - if (xkb->names->num_key_aliases>0) { - tmp= fwrite((char *)xkb->names->key_aliases, - sizeof(XkbKeyAliasRec),xkb->names->num_key_aliases, - file); - size+= tmp*sizeof(XkbKeyAliasRec); - } - return size; -} - -/***====================================================================***/ - -static unsigned -SizeXKMKeyTypes(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout) -{ -register unsigned i,n,size; -XkbKeyTypePtr type; -XkbDescPtr xkb; -Display * dpy; -char * name; - - xkb= result->xkb; - dpy= xkb->dpy; - if ((!xkb)||(!xkb->map)||(!xkb->map->types)) { - _XkbLibError(_XkbErrMissingTypes,"SizeXKBKeyTypes",0); - return 0; - } - if (xkb->map->num_types<XkbNumRequiredTypes) { - _XkbLibError(_XkbErrMissingReqTypes,"SizeXKBKeyTypes",0); - return 0; - } - if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->types); - else name= NULL; - size= xkmSizeCountedString(name); - size+= 4; /* room for # of key types + padding */ - for (i=0,type=xkb->map->types;i<xkb->map->num_types;i++,type++) { - size+= SIZEOF(xkmKeyTypeDesc); - size+= SIZEOF(xkmKTMapEntryDesc)*type->map_count; - size+= xkmSizeCountedAtomString(dpy,type->name); - if (type->preserve) - size+= SIZEOF(xkmModsDesc)*type->map_count; - if (type->level_names) { - Atom *names; - names= type->level_names; - for (n=0;n<(unsigned)type->num_levels;n++) { - size+= xkmSizeCountedAtomString(dpy,names[n]); - } - } - } - toc->type= XkmTypesIndex; - toc->format= MSBFirst; - toc->size= size+SIZEOF(xkmSectionInfo); - toc->offset= (*offset_inout); - (*offset_inout)+= toc->size; - return 1; -} - -static unsigned -WriteXKMKeyTypes(FILE *file,XkbFileInfo *result) -{ -register unsigned i,n; -XkbDescPtr xkb; -XkbKeyTypePtr type; -xkmKeyTypeDesc wire; -XkbKTMapEntryPtr entry; -xkmKTMapEntryDesc wire_entry; -Atom * names; -Display * dpy; -unsigned tmp,size= 0; -char * name; - - xkb= result->xkb; - dpy= xkb->dpy; - if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->types); - else name= NULL; - size+= xkmPutCountedString(file,name); - size+= xkmPutCARD16(file,xkb->map->num_types); - size+= xkmPutPadding(file,2); - type= xkb->map->types; - for (i=0;i<xkb->map->num_types;i++,type++) { - wire.realMods= type->mods.real_mods; - wire.virtualMods= type->mods.vmods; - wire.numLevels= type->num_levels; - wire.nMapEntries= type->map_count; - wire.preserve= (type->preserve!=NULL); - if (type->level_names!=NULL) - wire.nLevelNames= type->num_levels; - else wire.nLevelNames= 0; - tmp= fwrite(&wire,SIZEOF(xkmKeyTypeDesc),1,file); - size+= tmp*SIZEOF(xkmKeyTypeDesc); - for (n=0,entry= type->map;n<type->map_count;n++,entry++) { - wire_entry.level= entry->level; - wire_entry.realMods= entry->mods.real_mods; - wire_entry.virtualMods= entry->mods.vmods; - tmp= fwrite(&wire_entry,SIZEOF(xkmKTMapEntryDesc),1,file); - size+= tmp*SIZEOF(xkmKTMapEntryDesc); - } - size+= xkmPutCountedString(file,XkbAtomGetString(dpy,type->name)); - if (type->preserve) { - xkmModsDesc p_entry; - XkbModsPtr pre; - for (n=0,pre=type->preserve;n<type->map_count;n++,pre++) { - p_entry.realMods= pre->real_mods; - p_entry.virtualMods= pre->vmods; - tmp= fwrite(&p_entry,SIZEOF(xkmModsDesc),1,file); - size+= tmp*SIZEOF(xkmModsDesc); - } - } - if (type->level_names!=NULL) { - names= type->level_names; - for (n=0;n<wire.nLevelNames;n++) { - size+= xkmPutCountedString(file,XkbAtomGetString(dpy,names[n])); - } - } - } - return size; -} - -/***====================================================================***/ - -static unsigned -SizeXKMCompatMap( XkbFileInfo * result, - XkmInfo * info, - xkmSectionInfo * toc, - int * offset_inout) -{ -XkbDescPtr xkb; -char * name; -int size; -register int i; -unsigned groups,nGroups; -Display * dpy; - - xkb= result->xkb; - dpy= xkb->dpy; - if ((!xkb)||(!xkb->compat)||(!xkb->compat->sym_interpret)) { - _XkbLibError(_XkbErrMissingCompatMap,"SizeXKMCompatMap",0); - return 0; - } - if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->compat); - else name= NULL; - - for (i=groups=nGroups=0;i<XkbNumKbdGroups;i++) { - if ((xkb->compat->groups[i].real_mods!=0)|| - (xkb->compat->groups[i].vmods!=0)) { - groups|= (1<<i); - nGroups++; - } - } - info->group_compat= groups; - info->num_group_compat= nGroups; - size= 4; /* room for num_si and group_compat mask */ - size+= xkmSizeCountedString(name); - size+= (SIZEOF(xkmSymInterpretDesc)*xkb->compat->num_si); - size+= (SIZEOF(xkmModsDesc)*nGroups); - toc->type= XkmCompatMapIndex; - toc->format= MSBFirst; - toc->size= size+SIZEOF(xkmSectionInfo); - toc->offset= (*offset_inout); - (*offset_inout)+= toc->size; - return 1; -} - -static unsigned -WriteXKMCompatMap(FILE *file,XkbFileInfo *result,XkmInfo *info) -{ -register unsigned i; -char * name; -XkbDescPtr xkb; -XkbSymInterpretPtr interp; -xkmSymInterpretDesc wire; -Display * dpy; -unsigned tmp,size=0; - - xkb= result->xkb; - dpy= xkb->dpy; - if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->compat); - else name= NULL; - size+= xkmPutCountedString(file,name); - size+= xkmPutCARD16(file,xkb->compat->num_si); - size+= xkmPutCARD8(file,info->group_compat); - size+= xkmPutPadding(file,1); - interp= xkb->compat->sym_interpret; - for (i=0;i<xkb->compat->num_si;i++,interp++) { - wire.sym= interp->sym; - wire.mods= interp->mods; - wire.match= interp->match; - wire.virtualMod= interp->virtual_mod; - wire.flags= interp->flags; - wire.actionType= interp->act.type; - wire.actionData[0]= interp->act.data[0]; - wire.actionData[1]= interp->act.data[1]; - wire.actionData[2]= interp->act.data[2]; - wire.actionData[3]= interp->act.data[3]; - wire.actionData[4]= interp->act.data[4]; - wire.actionData[5]= interp->act.data[5]; - wire.actionData[6]= interp->act.data[6]; - tmp= fwrite(&wire,SIZEOF(xkmSymInterpretDesc),1,file); - size+= tmp*SIZEOF(xkmSymInterpretDesc); - } - if (info->group_compat) { - register unsigned bit; - xkmModsDesc modsWire; - for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { - if (info->group_compat&bit) { - modsWire.realMods= xkb->compat->groups[i].real_mods; - modsWire.virtualMods= xkb->compat->groups[i].vmods; - fwrite(&modsWire,SIZEOF(xkmModsDesc),1,file); - size+= SIZEOF(xkmModsDesc); - } - } - } - return size; -} - -/***====================================================================***/ - -static unsigned -SizeXKMSymbols( XkbFileInfo * result, - XkmInfo * info, - xkmSectionInfo * toc, - int * offset_inout) -{ -Display * dpy; -XkbDescPtr xkb; -unsigned size; -register int i,nSyms; -char * name; - - xkb= result->xkb; - dpy= xkb->dpy; - if ((!xkb)||(!xkb->map)||((!xkb->map->syms))) { - _XkbLibError(_XkbErrMissingSymbols,"SizeXKMSymbols",0); - return 0; - } - if (xkb->names && (xkb->names->symbols!=None)) - name= XkbAtomGetString(dpy,xkb->names->symbols); - else name= NULL; - size= xkmSizeCountedString(name); - size+= 4; /* min and max keycode, group names mask */ - for (i=0;i<XkbNumKbdGroups;i++) { - if (xkb->names->groups[i]!=None) - size+= xkmSizeCountedAtomString(dpy,xkb->names->groups[i]); - } - info->total_vmodmaps= 0; - for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { - nSyms= XkbKeyNumSyms(xkb,i); - size+= SIZEOF(xkmKeySymMapDesc)+(nSyms*4); - if (xkb->server) { - if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) { - register int g; - for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) { - if (xkb->server->explicit[i]&(1<<g)) { - XkbKeyTypePtr type; - char * name; - type= XkbKeyKeyType(xkb,i,g); - name= XkbAtomGetString(dpy,type->name); - if (name!=NULL) - size+= xkmSizeCountedString(name); - } - } - } - if (XkbKeyHasActions(xkb,i)) - size+= nSyms*SIZEOF(xkmActionDesc); - if (xkb->server->behaviors[i].type!=XkbKB_Default) - size+= SIZEOF(xkmBehaviorDesc); - if (xkb->server->vmodmap && (xkb->server->vmodmap[i]!=0)) - info->total_vmodmaps++; - } - } - size+= info->total_vmodmaps*SIZEOF(xkmVModMapDesc); - toc->type= XkmSymbolsIndex; - toc->format= MSBFirst; - toc->size= size+SIZEOF(xkmSectionInfo); - toc->offset= (*offset_inout); - (*offset_inout)+= toc->size; - return 1; -} - -static unsigned -WriteXKMSymbols(FILE *file,XkbFileInfo *result,XkmInfo *info) -{ -Display * dpy; -XkbDescPtr xkb; -register int i,n; -xkmKeySymMapDesc wireMap; -char * name; -unsigned tmp,size= 0; - - xkb= result->xkb; - dpy= xkb->dpy; - if (xkb->names && (xkb->names->symbols!=None)) - name= XkbAtomGetString(dpy,xkb->names->symbols); - else name= NULL; - size+= xkmPutCountedString(file,name); - for (tmp=i=0;i<XkbNumKbdGroups;i++) { - if (xkb->names->groups[i]!=None) - tmp|= (1<<i); - } - size+= xkmPutCARD8(file,xkb->min_key_code); - size+= xkmPutCARD8(file,xkb->max_key_code); - size+= xkmPutCARD8(file,tmp); - size+= xkmPutCARD8(file,info->total_vmodmaps); - for (i=0,n=1;i<XkbNumKbdGroups;i++,n<<=1) { - if ((tmp&n)==0) - continue; - size+= xkmPutCountedAtomString(dpy,file,xkb->names->groups[i]); - } - for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { - char *typeName[XkbNumKbdGroups]; - wireMap.width= XkbKeyGroupsWidth(xkb,i); - wireMap.num_groups= XkbKeyGroupInfo(xkb,i); - if (xkb->map && xkb->map->modmap) - wireMap.modifier_map= xkb->map->modmap[i]; - else wireMap.modifier_map= 0; - wireMap.flags= 0; - bzero((char *)typeName,XkbNumKbdGroups*sizeof(char *)); - if (xkb->server) { - if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) { - register int g; - for (g=0;g<XkbKeyNumGroups(xkb,i);g++) { - if (xkb->server->explicit[i]&(1<<g)) { - XkbKeyTypePtr type; - type= XkbKeyKeyType(xkb,i,g); - typeName[g]= XkbAtomGetString(dpy,type->name); - if (typeName[g]!=NULL) - wireMap.flags|= (1<<g); - } - } - } - if (XkbKeyHasActions(xkb,i)) - wireMap.flags|= XkmKeyHasActions; - if (xkb->server->behaviors[i].type!=XkbKB_Default) - wireMap.flags|= XkmKeyHasBehavior; - if ((xkb->server->explicit[i]&XkbExplicitAutoRepeatMask)&& - (xkb->ctrls!=NULL)) { - if (xkb->ctrls->per_key_repeat[(i/8)]&(1<<(i%8))) - wireMap.flags|= XkmRepeatingKey; - else wireMap.flags|= XkmNonRepeatingKey; - } - } - tmp= fwrite(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file); - size+= tmp*SIZEOF(xkmKeySymMapDesc); - if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) { - register int g; - for (g=0;g<XkbNumKbdGroups;g++) { - if (typeName[g]!=NULL) - size+= xkmPutCountedString(file,typeName[g]); - } - } - if (XkbNumGroups(wireMap.num_groups)>0) { - KeySym *sym; - sym= XkbKeySymsPtr(xkb,i); - for (n=XkbKeyNumSyms(xkb,i);n>0;n--,sym++) { - size+= xkmPutCARD32(file,(CARD32)*sym); - } - if (wireMap.flags&XkmKeyHasActions) { - XkbAction * act; - act= XkbKeyActionsPtr(xkb,i); - for (n=XkbKeyNumActions(xkb,i);n>0;n--,act++) { - tmp= fwrite(act,SIZEOF(xkmActionDesc),1,file); - size+= tmp*SIZEOF(xkmActionDesc); - } - } - } - if (wireMap.flags&XkmKeyHasBehavior) { - xkmBehaviorDesc b; - b.type= xkb->server->behaviors[i].type; - b.data= xkb->server->behaviors[i].data; - tmp= fwrite(&b,SIZEOF(xkmBehaviorDesc),1,file); - size+= tmp*SIZEOF(xkmBehaviorDesc); - } - } - if (info->total_vmodmaps>0) { - xkmVModMapDesc v; - for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { - if (xkb->server->vmodmap[i]!=0) { - v.key= i; - v.vmods= xkb->server->vmodmap[i]; - tmp= fwrite(&v,SIZEOF(xkmVModMapDesc),1,file); - size+= tmp*SIZEOF(xkmVModMapDesc); - } - } - } - return size; -} - -/***====================================================================***/ - -static unsigned -SizeXKMIndicators(XkbFileInfo *result,XkmInfo *info,xkmSectionInfo *toc, - int *offset_inout) -{ -Display * dpy; -XkbDescPtr xkb; -unsigned size; -register unsigned i,nLEDs; - - xkb= result->xkb; - dpy= xkb->dpy; - if ((xkb==NULL)||(xkb->indicators==NULL)) { -/* _XkbLibError(_XkbErrMissingIndicators,"SizeXKMIndicators",0);*/ - return 0; - } - nLEDs=0; - size= 8; /* number of indicator maps/physical indicators */ - if (xkb->indicators!=NULL) { - 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) || - (xkb->names && (xkb->names->indicators[i]!=None))) { - char *name; - if (xkb->names && xkb->names->indicators[i]!=None) { - name= XkbAtomGetString(dpy,xkb->names->indicators[i]); - } - else name= NULL; - size+= xkmSizeCountedString(name); - size+= SIZEOF(xkmIndicatorMapDesc); - nLEDs++; - } - } - } - info->num_leds= nLEDs; - toc->type= XkmIndicatorsIndex; - toc->format= MSBFirst; - toc->size= size+SIZEOF(xkmSectionInfo); - toc->offset= (*offset_inout); - (*offset_inout)+= toc->size; - return 1; -} - -static unsigned -WriteXKMIndicators(FILE *file,XkbFileInfo *result,XkmInfo *info) -{ -Display * dpy; -XkbDescPtr xkb; -register unsigned i; -xkmIndicatorMapDesc wire; -unsigned tmp,size= 0; - - xkb= result->xkb; - dpy= xkb->dpy; - size+= xkmPutCARD8(file,info->num_leds); - size+= xkmPutPadding(file,3); - size+= xkmPutCARD32(file,xkb->indicators->phys_indicators); - if (xkb->indicators!=NULL) { - 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) || - (xkb->names && (xkb->names->indicators[i]!=None))) { - char *name; - if (xkb->names && xkb->names->indicators[i]!=None) { - name= XkbAtomGetString(dpy,xkb->names->indicators[i]); - } - else name= NULL; - size+= xkmPutCountedString(file,name); - wire.indicator= i+1; - wire.flags= map->flags; - wire.which_mods= map->which_mods; - wire.real_mods= map->mods.real_mods; - wire.vmods= map->mods.vmods; - wire.which_groups= map->which_groups; - wire.groups= map->groups; - wire.ctrls= map->ctrls; - tmp= fwrite(&wire,SIZEOF(xkmIndicatorMapDesc),1,file); - size+= tmp*SIZEOF(xkmIndicatorMapDesc); - } - } - } - return size; -} - -/***====================================================================***/ - -static unsigned -SizeXKMGeomDoodad(XkbFileInfo *result,XkbDoodadPtr doodad) -{ -unsigned size; - - size= SIZEOF(xkmAnyDoodadDesc); - size+= xkmSizeCountedAtomString(result->xkb->dpy,doodad->any.name); - if (doodad->any.type==XkbTextDoodad) { - size+= xkmSizeCountedString(doodad->text.text); - size+= xkmSizeCountedString(doodad->text.font); - } - else if (doodad->any.type==XkbLogoDoodad) { - size+= xkmSizeCountedString(doodad->logo.logo_name); - } - return size; -} - -static unsigned -SizeXKMGeomSection(XkbFileInfo *result,XkbSectionPtr section) -{ -register int i; -unsigned size; - - size= SIZEOF(xkmSectionDesc); - size+= xkmSizeCountedAtomString(result->xkb->dpy,section->name); - if (section->rows) { - XkbRowPtr row; - for (row=section->rows,i=0;i<section->num_rows;i++,row++) { - size+= SIZEOF(xkmRowDesc); - size+= row->num_keys*SIZEOF(xkmKeyDesc); - } - } - if (section->doodads) { - XkbDoodadPtr doodad; - for (doodad=section->doodads,i=0;i<section->num_doodads;i++,doodad++) { - size+= SizeXKMGeomDoodad(result,doodad); - } - } - if (section->overlays) { - XkbOverlayPtr ol; - for (ol=section->overlays,i=0;i<section->num_overlays;i++,ol++) { - register int r; - XkbOverlayRowPtr row; - size+= xkmSizeCountedAtomString(result->xkb->dpy,ol->name); - size+= SIZEOF(xkmOverlayDesc); - for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { - size+= SIZEOF(xkmOverlayRowDesc); - size+= row->num_keys*SIZEOF(xkmOverlayKeyDesc); - } - } - } - return size; -} - -static unsigned -SizeXKMGeometry(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout) -{ -register int i; -Display * dpy; -XkbDescPtr xkb; -XkbGeometryPtr geom; -unsigned size; - - xkb= result->xkb; - dpy= xkb->dpy; - if ((!xkb)||(!xkb->geom)) - return 0; - geom= xkb->geom; - size= xkmSizeCountedAtomString(dpy,geom->name); - size+= SIZEOF(xkmGeometryDesc); - size+= xkmSizeCountedString(geom->label_font); - if (geom->properties) { - XkbPropertyPtr prop; - for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { - size+= xkmSizeCountedString(prop->name); - size+= xkmSizeCountedString(prop->value); - } - } - if (geom->colors) { - XkbColorPtr color; - for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) { - size+= xkmSizeCountedString(color->spec); - } - } - if (geom->shapes) { - XkbShapePtr shape; - for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { - register int n; - register XkbOutlinePtr ol; - size+= xkmSizeCountedAtomString(dpy,shape->name); - size+= SIZEOF(xkmShapeDesc); - for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) { - size+= SIZEOF(xkmOutlineDesc); - size+= ol->num_points*SIZEOF(xkmPointDesc); - } - } - } - if (geom->sections) { - XkbSectionPtr section; - for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { - size+= SizeXKMGeomSection(result,section); - } - } - if (geom->doodads) { - XkbDoodadPtr doodad; - for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) { - size+= SizeXKMGeomDoodad(result,doodad); - } - } - if (geom->key_aliases) { - size+= geom->num_key_aliases*(XkbKeyNameLength*2); - } - toc->type= XkmGeometryIndex; - toc->format= MSBFirst; - toc->size= size+SIZEOF(xkmSectionInfo); - toc->offset= (*offset_inout); - (*offset_inout)+= toc->size; - return 1; -} - -static unsigned -WriteXKMGeomDoodad(FILE *file,XkbFileInfo *result,XkbDoodadPtr doodad) -{ -Display * dpy; -XkbDescPtr xkb; -xkmDoodadDesc doodadWire; -unsigned tmp,size= 0; - - xkb= result->xkb; - dpy= xkb->dpy; - bzero((char *)&doodadWire,sizeof(doodadWire)); - doodadWire.any.type= doodad->any.type; - doodadWire.any.priority= doodad->any.priority; - doodadWire.any.top= doodad->any.top; - doodadWire.any.left= doodad->any.left; - switch (doodad->any.type) { - case XkbOutlineDoodad: - case XkbSolidDoodad: - doodadWire.shape.angle= doodad->shape.angle; - doodadWire.shape.color_ndx= doodad->shape.color_ndx; - doodadWire.shape.shape_ndx= doodad->shape.shape_ndx; - break; - case XkbTextDoodad: - doodadWire.text.angle= doodad->text.angle; - doodadWire.text.width= doodad->text.width; - doodadWire.text.height= doodad->text.height; - doodadWire.text.color_ndx= doodad->text.color_ndx; - break; - case XkbIndicatorDoodad: - doodadWire.indicator.shape_ndx= doodad->indicator.shape_ndx; - doodadWire.indicator.on_color_ndx= doodad->indicator.on_color_ndx; - doodadWire.indicator.off_color_ndx= doodad->indicator.off_color_ndx; - break; - case XkbLogoDoodad: - doodadWire.logo.angle= doodad->logo.angle; - doodadWire.logo.color_ndx= doodad->logo.color_ndx; - doodadWire.logo.shape_ndx= doodad->logo.shape_ndx; - break; - default: - _XkbLibError(_XkbErrIllegalDoodad,"WriteXKMGeomDoodad", - doodad->any.type); - return 0; - } - size+= xkmPutCountedAtomString(dpy,file,doodad->any.name); - tmp= fwrite(&doodadWire,SIZEOF(xkmDoodadDesc),1,file); - size+= tmp*SIZEOF(xkmDoodadDesc); - if (doodad->any.type==XkbTextDoodad) { - size+= xkmPutCountedString(file,doodad->text.text); - size+= xkmPutCountedString(file,doodad->text.font); - } - else if (doodad->any.type==XkbLogoDoodad) { - size+= xkmPutCountedString(file,doodad->logo.logo_name); - } - return size; -} - -static unsigned -WriteXKMGeomOverlay(FILE *file,XkbFileInfo *result,XkbOverlayPtr ol) -{ -register int r,k; -Display * dpy; -XkbDescPtr xkb; -XkbOverlayRowPtr row; -xkmOverlayDesc olWire; -xkmOverlayRowDesc rowWire; -xkmOverlayKeyDesc keyWire; -unsigned tmp,size= 0; - - xkb= result->xkb; - dpy= xkb->dpy; - bzero((char *)&olWire,sizeof(olWire)); - bzero((char *)&rowWire,sizeof(rowWire)); - bzero((char *)&keyWire,sizeof(keyWire)); - size+= xkmPutCountedAtomString(dpy,file,ol->name); - olWire.num_rows= ol->num_rows; - tmp= fwrite(&olWire,SIZEOF(xkmOverlayDesc),1,file); - size+= tmp*SIZEOF(xkmOverlayDesc); - for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { - XkbOverlayKeyPtr key; - rowWire.row_under= row->row_under; - rowWire.num_keys= row->num_keys; - tmp= fwrite(&rowWire,SIZEOF(xkmOverlayRowDesc),1,file); - size+= tmp*SIZEOF(xkmOverlayRowDesc); - for (k=0,key=row->keys;k<row->num_keys;k++,key++) { - memcpy(keyWire.over,key->over.name,XkbKeyNameLength); - memcpy(keyWire.under,key->under.name,XkbKeyNameLength); - tmp= fwrite(&keyWire,SIZEOF(xkmOverlayKeyDesc),1,file); - size+= tmp*SIZEOF(xkmOverlayKeyDesc); - } - } - return size; -} - -static unsigned -WriteXKMGeomSection(FILE *file,XkbFileInfo *result,XkbSectionPtr section) -{ -register int i; -Display * dpy; -XkbDescPtr xkb; -xkmSectionDesc sectionWire; -unsigned tmp,size= 0; - - xkb= result->xkb; - dpy= xkb->dpy; - size+= xkmPutCountedAtomString(dpy,file,section->name); - sectionWire.top= section->top; - sectionWire.left= section->left; - sectionWire.width= section->width; - sectionWire.height= section->height; - sectionWire.angle= section->angle; - sectionWire.priority= section->priority; - sectionWire.num_rows= section->num_rows; - sectionWire.num_doodads= section->num_doodads; - sectionWire.num_overlays= section->num_overlays; - tmp= fwrite(§ionWire,SIZEOF(xkmSectionDesc),1,file); - size+= tmp*SIZEOF(xkmSectionDesc); - if (section->rows) { - register unsigned k; - XkbRowPtr row; - xkmRowDesc rowWire; - XkbKeyPtr key; - xkmKeyDesc keyWire; - for (i=0,row=section->rows;i<section->num_rows;i++,row++) { - rowWire.top= row->top; - rowWire.left= row->left; - rowWire.num_keys= row->num_keys; - rowWire.vertical= row->vertical; - tmp= fwrite(&rowWire,SIZEOF(xkmRowDesc),1,file); - size+= tmp*SIZEOF(xkmRowDesc); - for (k=0,key=row->keys;k<row->num_keys;k++,key++) { - memcpy(keyWire.name,key->name.name,XkbKeyNameLength); - keyWire.gap= key->gap; - keyWire.shape_ndx= key->shape_ndx; - keyWire.color_ndx= key->color_ndx; - tmp= fwrite(&keyWire,SIZEOF(xkmKeyDesc),1,file); - size+= tmp*SIZEOF(xkmKeyDesc); - } - } - } - if (section->doodads) { - XkbDoodadPtr doodad; - for (i=0,doodad=section->doodads;i<section->num_doodads;i++,doodad++) { - size+= WriteXKMGeomDoodad(file,result,doodad); - } - } - if (section->overlays) { - XkbOverlayPtr ol; - for (i=0,ol=section->overlays;i<section->num_overlays;i++,ol++) { - size+= WriteXKMGeomOverlay(file,result,ol); - } - } - return size; -} - -static unsigned -WriteXKMGeometry(FILE *file,XkbFileInfo *result) -{ -register int i; -Display * dpy; -XkbDescPtr xkb; -XkbGeometryPtr geom; -xkmGeometryDesc wire; -unsigned tmp,size= 0; - - xkb= result->xkb; - dpy= xkb->dpy; - if ((!xkb)||(!xkb->geom)) - return 0; - geom= xkb->geom; - wire.width_mm= geom->width_mm; - wire.height_mm= geom->height_mm; - wire.base_color_ndx= XkbGeomColorIndex(geom,geom->base_color); - wire.label_color_ndx= XkbGeomColorIndex(geom,geom->label_color); - wire.num_properties= geom->num_properties; - wire.num_colors= geom->num_colors; - wire.num_shapes= geom->num_shapes; - wire.num_sections= geom->num_sections; - wire.num_doodads= geom->num_doodads; - wire.num_key_aliases= geom->num_key_aliases; - size+= xkmPutCountedAtomString(dpy,file,geom->name); - tmp= fwrite(&wire,SIZEOF(xkmGeometryDesc),1,file); - size+= tmp*SIZEOF(xkmGeometryDesc); - size+= xkmPutCountedString(file,geom->label_font); - if (geom->properties) { - XkbPropertyPtr prop; - for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { - size+= xkmPutCountedString(file,prop->name); - size+= xkmPutCountedString(file,prop->value); - } - } - if (geom->colors) { - XkbColorPtr color; - for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) { - size+= xkmPutCountedString(file,color->spec); - } - } - if (geom->shapes) { - XkbShapePtr shape; - xkmShapeDesc shapeWire; - - for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { - register int n; - XkbOutlinePtr ol; - xkmOutlineDesc olWire; - bzero((char *)&shapeWire,sizeof(xkmShapeDesc)); - size+= xkmPutCountedAtomString(dpy,file,shape->name); - shapeWire.num_outlines= shape->num_outlines; - if (shape->primary!=NULL) - shapeWire.primary_ndx= XkbOutlineIndex(shape,shape->primary); - else shapeWire.primary_ndx= XkbNoShape; - if (shape->approx!=NULL) - shapeWire.approx_ndx= XkbOutlineIndex(shape,shape->approx); - else shapeWire.approx_ndx= XkbNoShape; - tmp= fwrite(&shapeWire,SIZEOF(xkmShapeDesc),1,file); - size+= tmp*SIZEOF(xkmShapeDesc); - for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) { - register int p; - XkbPointPtr pt; - xkmPointDesc ptWire; - olWire.num_points= ol->num_points; - olWire.corner_radius= ol->corner_radius; - tmp= fwrite(&olWire,SIZEOF(xkmOutlineDesc),1,file); - size+= tmp*SIZEOF(xkmOutlineDesc); - for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) { - ptWire.x= pt->x; - ptWire.y= pt->y; - tmp= fwrite(&ptWire,SIZEOF(xkmPointDesc),1,file); - size+= tmp*SIZEOF(xkmPointDesc); - } - } - } - } - if (geom->sections) { - XkbSectionPtr section; - for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { - size+= WriteXKMGeomSection(file,result,section); - } - } - if (geom->doodads) { - XkbDoodadPtr doodad; - for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) { - size+= WriteXKMGeomDoodad(file,result,doodad); - } - } - if (geom->key_aliases) { - tmp= fwrite(geom->key_aliases,2*XkbKeyNameLength,geom->num_key_aliases, - file); - size+= tmp*(2*XkbKeyNameLength); - } - return size; -} - -/***====================================================================***/ - -/*ARGSUSED*/ -static int -GetXKMKeyNamesTOC( XkbFileInfo * result, - XkmInfo * info, - int max_toc, - xkmSectionInfo *toc_rtrn) -{ -int num_toc; -int total_size; - - total_size= num_toc=0; - if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) - num_toc++; - return num_toc; -} - -/*ARGSUSED*/ -static int -GetXKMTypesTOC( XkbFileInfo * result, - XkmInfo * info, - int max_toc, - xkmSectionInfo *toc_rtrn) -{ -int num_toc; -int total_size; - - total_size= num_toc=0; - if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size)) - num_toc++; - return num_toc; -} - -/*ARGSUSED*/ -static int -GetXKMCompatMapTOC( XkbFileInfo * result, - XkmInfo * info, - int max_toc, - xkmSectionInfo *toc_rtrn) -{ -int num_toc; -int total_size; - - total_size= num_toc=0; - if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) - num_toc++; - return num_toc; -} - -/*ARGSUSED*/ -static int -GetXKMSemanticsTOC( XkbFileInfo * result, - XkmInfo * info, - int max_toc, - xkmSectionInfo *toc_rtrn) -{ -int num_toc; -int total_size; - - total_size= num_toc=0; - if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) - num_toc++; - return num_toc; -} - -/*ARGSUSED*/ -static int -GetXKMLayoutTOC( XkbFileInfo * result, - XkmInfo * info, - int max_toc, - xkmSectionInfo *toc_rtrn) -{ -int num_toc; -int total_size; - - total_size= num_toc=0; - if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMSymbols(result,info,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size)) - num_toc++; - return num_toc; -} - -/*ARGSUSED*/ -static int -GetXKMKeymapTOC( XkbFileInfo * result, - XkmInfo * info, - int max_toc, - xkmSectionInfo *toc_rtrn) -{ -int num_toc; -int total_size; - - total_size= num_toc=0; - if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMSymbols(result,info,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) - num_toc++; - if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size)) - num_toc++; - return num_toc; -} - -/*ARGSUSED*/ -static int -GetXKMGeometryTOC( XkbFileInfo * result, - XkmInfo * info, - int max_toc, - xkmSectionInfo *toc_rtrn) -{ -int num_toc; -int total_size; - - total_size= num_toc=0; - if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size)) - num_toc++; - return num_toc; -} - -static Bool -WriteXKMFile( FILE * file, - XkbFileInfo * result, - int num_toc, - xkmSectionInfo *toc, - XkmInfo * info) -{ -register int i; -unsigned tmp,size,total= 0; - - for (i=0;i<num_toc;i++) { - tmp= fwrite(&toc[i],SIZEOF(xkmSectionInfo),1,file); - total+= tmp*SIZEOF(xkmSectionInfo); - switch (toc[i].type) { - case XkmTypesIndex: - size= WriteXKMKeyTypes(file,result); - break; - case XkmCompatMapIndex: - size= WriteXKMCompatMap(file,result,info); - break; - case XkmSymbolsIndex: - size= WriteXKMSymbols(file,result,info); - break; - case XkmIndicatorsIndex: - size= WriteXKMIndicators(file,result,info); - break; - case XkmKeyNamesIndex: - size= WriteXKMKeycodes(file,result); - break; - case XkmGeometryIndex: - size= WriteXKMGeometry(file,result); - break; - case XkmVirtualModsIndex: - size= WriteXKMVirtualMods(file,result,info); - break; - default: - _XkbLibError(_XkbErrIllegalTOCType,"WriteXKMFile",toc[i].type); - return False; - } - size+= SIZEOF(xkmSectionInfo); - if (size!=toc[i].size) { - _XkbLibError(_XkbErrBadLength,XkbConfigText(toc[i].type,XkbMessage), - size-toc[i].size); - return False; - } - } - return True; -} - - -#define MAX_TOC 16 - -Bool -XkbWriteXKMFile(FILE *out,XkbFileInfo *result) -{ -Bool ok; -XkbDescPtr xkb; -XkmInfo info; -int size_toc,i; -unsigned hdr,present; -xkmFileInfo fileInfo; -xkmSectionInfo toc[MAX_TOC]; -int (*getTOC)( - XkbFileInfo * /* result */, - XkmInfo * /* info */, - int /* max_to */, - xkmSectionInfo * /* toc_rtrn */ -); - - switch (result->type) { - case XkmKeyNamesIndex: - getTOC= GetXKMKeyNamesTOC; - break; - case XkmTypesIndex: - getTOC= GetXKMTypesTOC; - break; - case XkmCompatMapIndex: - getTOC= GetXKMCompatMapTOC; - break; - case XkmSemanticsFile: - getTOC= GetXKMSemanticsTOC; - break; - case XkmLayoutFile: - getTOC= GetXKMLayoutTOC; - break; - case XkmKeymapFile: - getTOC= GetXKMKeymapTOC; - break; - case XkmGeometryFile: - case XkmGeometryIndex: - getTOC= GetXKMGeometryTOC; - break; - default: - _XkbLibError(_XkbErrIllegalContents, - XkbConfigText(result->type,XkbMessage),0); - return False; - } - xkb= result->xkb; - - bzero((char *)&info,sizeof(XkmInfo)); - size_toc= (*getTOC)(result,&info,MAX_TOC,toc); - if (size_toc<1) { - _XkbLibError(_XkbErrEmptyFile,"XkbWriteXKMFile",0); - return False; - } - if (out==NULL) { - _XkbLibError(_XkbErrFileCannotOpen,"XkbWriteXKMFile",0); - return False; - } - for (i=present=0;i<size_toc;i++) { - toc[i].offset+= 4+SIZEOF(xkmFileInfo); - toc[i].offset+= (size_toc*SIZEOF(xkmSectionInfo)); - if (toc[i].type<=XkmLastIndex) { - present|= (1<<toc[i].type); - } -#ifdef DEBUG - else { - fprintf(stderr,"Illegal section type %d\n",toc[i].type); - fprintf(stderr,"Ignored\n"); - } -#endif - } - hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion); - xkmPutCARD32(out,(unsigned long)hdr); - fileInfo.type= result->type; - fileInfo.min_kc= xkb->min_key_code; - fileInfo.max_kc= xkb->max_key_code; - fileInfo.num_toc= size_toc; - fileInfo.present= present; - fileInfo.pad= 0; - fwrite(&fileInfo,SIZEOF(xkmFileInfo),1,out); - fwrite(toc,SIZEOF(xkmSectionInfo),size_toc,out); - ok= WriteXKMFile(out,result,size_toc,toc,&info); - return ok; -} +/************************************************************
+ 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_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <X11/Xfuncs.h>
+#include <X11/Xlib.h>
+#include <X11/XKBlib.h>
+#include <X11/extensions/XKBgeom.h>
+
+#include "XKMformat.h"
+#include "XKBfileInt.h"
+
+typedef struct _XkmInfo {
+ unsigned short bound_vmods;
+ unsigned short named_vmods;
+ unsigned char num_bound;
+ unsigned char group_compat;
+ unsigned short num_group_compat;
+ unsigned short num_leds;
+ int total_vmodmaps;
+} XkmInfo;
+
+/***====================================================================***/
+
+#define xkmPutCARD8(f,v) (putc(v,f),1)
+
+static int
+xkmPutCARD16(FILE *file,unsigned val)
+{
+CARD16 tmp= val;
+
+ fwrite(&tmp,2,1,file);
+ return 2;
+}
+
+static int
+xkmPutCARD32(FILE *file,unsigned long val)
+{
+CARD32 tmp= val;
+
+ fwrite(&tmp,4,1,file);
+ return 4;
+}
+
+static int
+xkmPutPadding(FILE *file,unsigned pad)
+{
+int i;
+ for (i=0;i<pad;i++) {
+ putc('\0',file);
+ }
+ return pad;
+}
+
+static int
+xkmPutCountedBytes(FILE *file,char *ptr,unsigned count)
+{
+register int nOut;
+register unsigned pad;
+
+ if (count==0)
+ return xkmPutCARD32(file,(unsigned long)0);
+
+ xkmPutCARD16(file,count);
+ nOut= fwrite(ptr,1,count,file);
+ if (nOut<0)
+ return 2;
+ nOut= count+2;
+ pad= XkbPaddedSize(nOut)-nOut;
+ if (pad)
+ xkmPutPadding(file,pad);
+ return nOut+pad;
+}
+
+static unsigned
+xkmSizeCountedString(char *str)
+{
+ if (str==NULL)
+ return 4;
+ return XkbPaddedSize(strlen(str)+2);
+}
+
+static int
+xkmPutCountedString(FILE *file,char *str)
+{
+ if (str==NULL)
+ return xkmPutCARD32(file,(unsigned long)0);
+ return xkmPutCountedBytes(file,str,strlen(str));
+}
+
+#define xkmSizeCountedAtomString(d,a) \
+ xkmSizeCountedString(XkbAtomGetString((d),(a)))
+
+#define xkmPutCountedAtomString(d,f,a) \
+ xkmPutCountedString((f),XkbAtomGetString((d),(a)))
+
+/***====================================================================***/
+
+static unsigned
+SizeXKMVirtualMods( XkbFileInfo * result,
+ XkmInfo * info,
+ xkmSectionInfo * toc,
+ int * offset_inout)
+{
+Display * dpy;
+XkbDescPtr xkb;
+unsigned nBound,bound;
+unsigned nNamed,named,szNames;
+register unsigned i,bit;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ if ((!xkb)||(!xkb->names)||(!xkb->server)) {
+ _XkbLibError(_XkbErrMissingVMods,"SizeXKMVirtualMods",0);
+ return 0;
+ }
+ bound=named=0;
+ for (i=nBound=nNamed=szNames=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (xkb->server->vmods[i]!=XkbNoModifierMask) {
+ bound|= bit;
+ nBound++;
+ }
+ if (xkb->names->vmods[i]!=None) {
+ named|= bit;
+ szNames+= xkmSizeCountedAtomString(dpy,xkb->names->vmods[i]);
+ nNamed++;
+ }
+ }
+ info->num_bound= nBound;
+ info->bound_vmods= bound;
+ info->named_vmods= named;
+ if ((nBound==0)&&(nNamed==0))
+ return 0;
+ toc->type= XkmVirtualModsIndex;
+ toc->format= MSBFirst;
+ toc->size= 4+XkbPaddedSize(nBound)+szNames+SIZEOF(xkmSectionInfo);
+ toc->offset= *offset_inout;
+ (*offset_inout)+= toc->size;
+ return 1;
+}
+
+static unsigned
+WriteXKMVirtualMods(FILE *file,XkbFileInfo *result,XkmInfo *info)
+{
+register unsigned int i,bit;
+XkbDescPtr xkb;
+Display * dpy;
+unsigned size= 0;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ size+= xkmPutCARD16(file,info->bound_vmods);
+ size+= xkmPutCARD16(file,info->named_vmods);
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (info->bound_vmods&bit)
+ size+= xkmPutCARD8(file,xkb->server->vmods[i]);
+ }
+ if ((i= XkbPaddedSize(info->num_bound)-info->num_bound)>0)
+ size+= xkmPutPadding(file,i);
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (info->named_vmods&bit) {
+ register char *name;
+ name= XkbAtomGetString(dpy,xkb->names->vmods[i]);
+ size+= xkmPutCountedString(file,name);
+ }
+ }
+ return size;
+}
+
+/***====================================================================***/
+
+static unsigned
+SizeXKMKeycodes(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout)
+{
+XkbDescPtr xkb;
+Atom kcName;
+int size=0;
+Display * dpy;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) {
+ _XkbLibError(_XkbErrMissingNames,"SizeXKMKeycodes",0);
+ return 0;
+ }
+ kcName= xkb->names->keycodes;
+ size+= 4; /* min and max keycode */
+ size+= xkmSizeCountedAtomString(dpy,kcName);
+ size+= XkbNumKeys(xkb)*sizeof(XkbKeyNameRec);
+ if (xkb->names->num_key_aliases>0) {
+ if (xkb->names->key_aliases!=NULL)
+ size+= xkb->names->num_key_aliases*sizeof(XkbKeyAliasRec);
+ else xkb->names->num_key_aliases= 0;
+ }
+ toc->type= XkmKeyNamesIndex;
+ toc->format= MSBFirst;
+ toc->size= size+SIZEOF(xkmSectionInfo);
+ toc->offset= (*offset_inout);
+ (*offset_inout)+= toc->size;
+ return 1;
+}
+
+static unsigned
+WriteXKMKeycodes(FILE *file,XkbFileInfo *result)
+{
+XkbDescPtr xkb;
+Atom kcName;
+char *start;
+Display * dpy;
+unsigned tmp,size= 0;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ kcName= xkb->names->keycodes;
+ start= xkb->names->keys[xkb->min_key_code].name;
+
+ size+= xkmPutCountedString(file,XkbAtomGetString(dpy,kcName));
+ size+= xkmPutCARD8(file,xkb->min_key_code);
+ size+= xkmPutCARD8(file,xkb->max_key_code);
+ size+= xkmPutCARD8(file,xkb->names->num_key_aliases);
+ size+= xkmPutPadding(file,1);
+ tmp= fwrite(start,sizeof(XkbKeyNameRec),XkbNumKeys(xkb),file);
+ size+= tmp*sizeof(XkbKeyNameRec);
+ if (xkb->names->num_key_aliases>0) {
+ tmp= fwrite((char *)xkb->names->key_aliases,
+ sizeof(XkbKeyAliasRec),xkb->names->num_key_aliases,
+ file);
+ size+= tmp*sizeof(XkbKeyAliasRec);
+ }
+ return size;
+}
+
+/***====================================================================***/
+
+static unsigned
+SizeXKMKeyTypes(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout)
+{
+register unsigned i,n,size;
+XkbKeyTypePtr type;
+XkbDescPtr xkb;
+Display * dpy;
+char * name;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ if ((!xkb)||(!xkb->map)||(!xkb->map->types)) {
+ _XkbLibError(_XkbErrMissingTypes,"SizeXKBKeyTypes",0);
+ return 0;
+ }
+ if (xkb->map->num_types<XkbNumRequiredTypes) {
+ _XkbLibError(_XkbErrMissingReqTypes,"SizeXKBKeyTypes",0);
+ return 0;
+ }
+ if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->types);
+ else name= NULL;
+ size= xkmSizeCountedString(name);
+ size+= 4; /* room for # of key types + padding */
+ for (i=0,type=xkb->map->types;i<xkb->map->num_types;i++,type++) {
+ size+= SIZEOF(xkmKeyTypeDesc);
+ size+= SIZEOF(xkmKTMapEntryDesc)*type->map_count;
+ size+= xkmSizeCountedAtomString(dpy,type->name);
+ if (type->preserve)
+ size+= SIZEOF(xkmModsDesc)*type->map_count;
+ if (type->level_names) {
+ Atom *names;
+ names= type->level_names;
+ for (n=0;n<(unsigned)type->num_levels;n++) {
+ size+= xkmSizeCountedAtomString(dpy,names[n]);
+ }
+ }
+ }
+ toc->type= XkmTypesIndex;
+ toc->format= MSBFirst;
+ toc->size= size+SIZEOF(xkmSectionInfo);
+ toc->offset= (*offset_inout);
+ (*offset_inout)+= toc->size;
+ return 1;
+}
+
+static unsigned
+WriteXKMKeyTypes(FILE *file,XkbFileInfo *result)
+{
+register unsigned i,n;
+XkbDescPtr xkb;
+XkbKeyTypePtr type;
+xkmKeyTypeDesc wire;
+XkbKTMapEntryPtr entry;
+xkmKTMapEntryDesc wire_entry;
+Atom * names;
+Display * dpy;
+unsigned tmp,size= 0;
+char * name;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->types);
+ else name= NULL;
+ size+= xkmPutCountedString(file,name);
+ size+= xkmPutCARD16(file,xkb->map->num_types);
+ size+= xkmPutPadding(file,2);
+ type= xkb->map->types;
+ for (i=0;i<xkb->map->num_types;i++,type++) {
+ wire.realMods= type->mods.real_mods;
+ wire.virtualMods= type->mods.vmods;
+ wire.numLevels= type->num_levels;
+ wire.nMapEntries= type->map_count;
+ wire.preserve= (type->preserve!=NULL);
+ if (type->level_names!=NULL)
+ wire.nLevelNames= type->num_levels;
+ else wire.nLevelNames= 0;
+ tmp= fwrite(&wire,SIZEOF(xkmKeyTypeDesc),1,file);
+ size+= tmp*SIZEOF(xkmKeyTypeDesc);
+ for (n=0,entry= type->map;n<type->map_count;n++,entry++) {
+ wire_entry.level= entry->level;
+ wire_entry.realMods= entry->mods.real_mods;
+ wire_entry.virtualMods= entry->mods.vmods;
+ tmp= fwrite(&wire_entry,SIZEOF(xkmKTMapEntryDesc),1,file);
+ size+= tmp*SIZEOF(xkmKTMapEntryDesc);
+ }
+ size+= xkmPutCountedString(file,XkbAtomGetString(dpy,type->name));
+ if (type->preserve) {
+ xkmModsDesc p_entry;
+ XkbModsPtr pre;
+ for (n=0,pre=type->preserve;n<type->map_count;n++,pre++) {
+ p_entry.realMods= pre->real_mods;
+ p_entry.virtualMods= pre->vmods;
+ tmp= fwrite(&p_entry,SIZEOF(xkmModsDesc),1,file);
+ size+= tmp*SIZEOF(xkmModsDesc);
+ }
+ }
+ if (type->level_names!=NULL) {
+ names= type->level_names;
+ for (n=0;n<wire.nLevelNames;n++) {
+ size+= xkmPutCountedString(file,XkbAtomGetString(dpy,names[n]));
+ }
+ }
+ }
+ return size;
+}
+
+/***====================================================================***/
+
+static unsigned
+SizeXKMCompatMap( XkbFileInfo * result,
+ XkmInfo * info,
+ xkmSectionInfo * toc,
+ int * offset_inout)
+{
+XkbDescPtr xkb;
+char * name;
+int size;
+register int i;
+unsigned groups,nGroups;
+Display * dpy;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ if ((!xkb)||(!xkb->compat)||(!xkb->compat->sym_interpret)) {
+ _XkbLibError(_XkbErrMissingCompatMap,"SizeXKMCompatMap",0);
+ return 0;
+ }
+ if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->compat);
+ else name= NULL;
+
+ for (i=groups=nGroups=0;i<XkbNumKbdGroups;i++) {
+ if ((xkb->compat->groups[i].real_mods!=0)||
+ (xkb->compat->groups[i].vmods!=0)) {
+ groups|= (1<<i);
+ nGroups++;
+ }
+ }
+ info->group_compat= groups;
+ info->num_group_compat= nGroups;
+ size= 4; /* room for num_si and group_compat mask */
+ size+= xkmSizeCountedString(name);
+ size+= (SIZEOF(xkmSymInterpretDesc)*xkb->compat->num_si);
+ size+= (SIZEOF(xkmModsDesc)*nGroups);
+ toc->type= XkmCompatMapIndex;
+ toc->format= MSBFirst;
+ toc->size= size+SIZEOF(xkmSectionInfo);
+ toc->offset= (*offset_inout);
+ (*offset_inout)+= toc->size;
+ return 1;
+}
+
+static unsigned
+WriteXKMCompatMap(FILE *file,XkbFileInfo *result,XkmInfo *info)
+{
+register unsigned i;
+char * name;
+XkbDescPtr xkb;
+XkbSymInterpretPtr interp;
+xkmSymInterpretDesc wire;
+Display * dpy;
+unsigned tmp,size=0;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->compat);
+ else name= NULL;
+ size+= xkmPutCountedString(file,name);
+ size+= xkmPutCARD16(file,xkb->compat->num_si);
+ size+= xkmPutCARD8(file,info->group_compat);
+ size+= xkmPutPadding(file,1);
+ interp= xkb->compat->sym_interpret;
+ for (i=0;i<xkb->compat->num_si;i++,interp++) {
+ wire.sym= interp->sym;
+ wire.mods= interp->mods;
+ wire.match= interp->match;
+ wire.virtualMod= interp->virtual_mod;
+ wire.flags= interp->flags;
+ wire.actionType= interp->act.type;
+ wire.actionData[0]= interp->act.data[0];
+ wire.actionData[1]= interp->act.data[1];
+ wire.actionData[2]= interp->act.data[2];
+ wire.actionData[3]= interp->act.data[3];
+ wire.actionData[4]= interp->act.data[4];
+ wire.actionData[5]= interp->act.data[5];
+ wire.actionData[6]= interp->act.data[6];
+ tmp= fwrite(&wire,SIZEOF(xkmSymInterpretDesc),1,file);
+ size+= tmp*SIZEOF(xkmSymInterpretDesc);
+ }
+ if (info->group_compat) {
+ register unsigned bit;
+ xkmModsDesc modsWire;
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (info->group_compat&bit) {
+ modsWire.realMods= xkb->compat->groups[i].real_mods;
+ modsWire.virtualMods= xkb->compat->groups[i].vmods;
+ fwrite(&modsWire,SIZEOF(xkmModsDesc),1,file);
+ size+= SIZEOF(xkmModsDesc);
+ }
+ }
+ }
+ return size;
+}
+
+/***====================================================================***/
+
+static unsigned
+SizeXKMSymbols( XkbFileInfo * result,
+ XkmInfo * info,
+ xkmSectionInfo * toc,
+ int * offset_inout)
+{
+Display * dpy;
+XkbDescPtr xkb;
+unsigned size;
+register int i,nSyms;
+char * name;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ if ((!xkb)||(!xkb->map)||((!xkb->map->syms))) {
+ _XkbLibError(_XkbErrMissingSymbols,"SizeXKMSymbols",0);
+ return 0;
+ }
+ if (xkb->names && (xkb->names->symbols!=None))
+ name= XkbAtomGetString(dpy,xkb->names->symbols);
+ else name= NULL;
+ size= xkmSizeCountedString(name);
+ size+= 4; /* min and max keycode, group names mask */
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ if (xkb->names->groups[i]!=None)
+ size+= xkmSizeCountedAtomString(dpy,xkb->names->groups[i]);
+ }
+ info->total_vmodmaps= 0;
+ for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
+ nSyms= XkbKeyNumSyms(xkb,i);
+ size+= SIZEOF(xkmKeySymMapDesc)+(nSyms*4);
+ if (xkb->server) {
+ if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) {
+ register int g;
+ for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) {
+ if (xkb->server->explicit[i]&(1<<g)) {
+ XkbKeyTypePtr type;
+ char * name;
+ type= XkbKeyKeyType(xkb,i,g);
+ name= XkbAtomGetString(dpy,type->name);
+ if (name!=NULL)
+ size+= xkmSizeCountedString(name);
+ }
+ }
+ }
+ if (XkbKeyHasActions(xkb,i))
+ size+= nSyms*SIZEOF(xkmActionDesc);
+ if (xkb->server->behaviors[i].type!=XkbKB_Default)
+ size+= SIZEOF(xkmBehaviorDesc);
+ if (xkb->server->vmodmap && (xkb->server->vmodmap[i]!=0))
+ info->total_vmodmaps++;
+ }
+ }
+ size+= info->total_vmodmaps*SIZEOF(xkmVModMapDesc);
+ toc->type= XkmSymbolsIndex;
+ toc->format= MSBFirst;
+ toc->size= size+SIZEOF(xkmSectionInfo);
+ toc->offset= (*offset_inout);
+ (*offset_inout)+= toc->size;
+ return 1;
+}
+
+static unsigned
+WriteXKMSymbols(FILE *file,XkbFileInfo *result,XkmInfo *info)
+{
+Display * dpy;
+XkbDescPtr xkb;
+register int i,n;
+xkmKeySymMapDesc wireMap;
+char * name;
+unsigned tmp,size= 0;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ if (xkb->names && (xkb->names->symbols!=None))
+ name= XkbAtomGetString(dpy,xkb->names->symbols);
+ else name= NULL;
+ size+= xkmPutCountedString(file,name);
+ for (tmp=i=0;i<XkbNumKbdGroups;i++) {
+ if (xkb->names->groups[i]!=None)
+ tmp|= (1<<i);
+ }
+ size+= xkmPutCARD8(file,xkb->min_key_code);
+ size+= xkmPutCARD8(file,xkb->max_key_code);
+ size+= xkmPutCARD8(file,tmp);
+ size+= xkmPutCARD8(file,info->total_vmodmaps);
+ for (i=0,n=1;i<XkbNumKbdGroups;i++,n<<=1) {
+ if ((tmp&n)==0)
+ continue;
+ size+= xkmPutCountedAtomString(dpy,file,xkb->names->groups[i]);
+ }
+ for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
+ char *typeName[XkbNumKbdGroups];
+ wireMap.width= XkbKeyGroupsWidth(xkb,i);
+ wireMap.num_groups= XkbKeyGroupInfo(xkb,i);
+ if (xkb->map && xkb->map->modmap)
+ wireMap.modifier_map= xkb->map->modmap[i];
+ else wireMap.modifier_map= 0;
+ wireMap.flags= 0;
+ bzero((char *)typeName,XkbNumKbdGroups*sizeof(char *));
+ if (xkb->server) {
+ if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) {
+ register int g;
+ for (g=0;g<XkbKeyNumGroups(xkb,i);g++) {
+ if (xkb->server->explicit[i]&(1<<g)) {
+ XkbKeyTypePtr type;
+ type= XkbKeyKeyType(xkb,i,g);
+ typeName[g]= XkbAtomGetString(dpy,type->name);
+ if (typeName[g]!=NULL)
+ wireMap.flags|= (1<<g);
+ }
+ }
+ }
+ if (XkbKeyHasActions(xkb,i))
+ wireMap.flags|= XkmKeyHasActions;
+ if (xkb->server->behaviors[i].type!=XkbKB_Default)
+ wireMap.flags|= XkmKeyHasBehavior;
+ if ((xkb->server->explicit[i]&XkbExplicitAutoRepeatMask)&&
+ (xkb->ctrls!=NULL)) {
+ if (xkb->ctrls->per_key_repeat[(i/8)]&(1<<(i%8)))
+ wireMap.flags|= XkmRepeatingKey;
+ else wireMap.flags|= XkmNonRepeatingKey;
+ }
+ }
+ tmp= fwrite(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file);
+ size+= tmp*SIZEOF(xkmKeySymMapDesc);
+ if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) {
+ register int g;
+ for (g=0;g<XkbNumKbdGroups;g++) {
+ if (typeName[g]!=NULL)
+ size+= xkmPutCountedString(file,typeName[g]);
+ }
+ }
+ if (XkbNumGroups(wireMap.num_groups)>0) {
+ KeySym *sym;
+ sym= XkbKeySymsPtr(xkb,i);
+ for (n=XkbKeyNumSyms(xkb,i);n>0;n--,sym++) {
+ size+= xkmPutCARD32(file,(CARD32)*sym);
+ }
+ if (wireMap.flags&XkmKeyHasActions) {
+ XkbAction * act;
+ act= XkbKeyActionsPtr(xkb,i);
+ for (n=XkbKeyNumActions(xkb,i);n>0;n--,act++) {
+ tmp= fwrite(act,SIZEOF(xkmActionDesc),1,file);
+ size+= tmp*SIZEOF(xkmActionDesc);
+ }
+ }
+ }
+ if (wireMap.flags&XkmKeyHasBehavior) {
+ xkmBehaviorDesc b;
+ b.type= xkb->server->behaviors[i].type;
+ b.data= xkb->server->behaviors[i].data;
+ tmp= fwrite(&b,SIZEOF(xkmBehaviorDesc),1,file);
+ size+= tmp*SIZEOF(xkmBehaviorDesc);
+ }
+ }
+ if (info->total_vmodmaps>0) {
+ xkmVModMapDesc v;
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ if (xkb->server->vmodmap[i]!=0) {
+ v.key= i;
+ v.vmods= xkb->server->vmodmap[i];
+ tmp= fwrite(&v,SIZEOF(xkmVModMapDesc),1,file);
+ size+= tmp*SIZEOF(xkmVModMapDesc);
+ }
+ }
+ }
+ return size;
+}
+
+/***====================================================================***/
+
+static unsigned
+SizeXKMIndicators(XkbFileInfo *result,XkmInfo *info,xkmSectionInfo *toc,
+ int *offset_inout)
+{
+Display * dpy;
+XkbDescPtr xkb;
+unsigned size;
+register unsigned i,nLEDs;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ if ((xkb==NULL)||(xkb->indicators==NULL)) {
+/* _XkbLibError(_XkbErrMissingIndicators,"SizeXKMIndicators",0);*/
+ return 0;
+ }
+ nLEDs=0;
+ size= 8; /* number of indicator maps/physical indicators */
+ if (xkb->indicators!=NULL) {
+ 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) ||
+ (xkb->names && (xkb->names->indicators[i]!=None))) {
+ char *name;
+ if (xkb->names && xkb->names->indicators[i]!=None) {
+ name= XkbAtomGetString(dpy,xkb->names->indicators[i]);
+ }
+ else name= NULL;
+ size+= xkmSizeCountedString(name);
+ size+= SIZEOF(xkmIndicatorMapDesc);
+ nLEDs++;
+ }
+ }
+ }
+ info->num_leds= nLEDs;
+ toc->type= XkmIndicatorsIndex;
+ toc->format= MSBFirst;
+ toc->size= size+SIZEOF(xkmSectionInfo);
+ toc->offset= (*offset_inout);
+ (*offset_inout)+= toc->size;
+ return 1;
+}
+
+static unsigned
+WriteXKMIndicators(FILE *file,XkbFileInfo *result,XkmInfo *info)
+{
+Display * dpy;
+XkbDescPtr xkb;
+register unsigned i;
+xkmIndicatorMapDesc wire;
+unsigned tmp,size= 0;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ size+= xkmPutCARD8(file,info->num_leds);
+ size+= xkmPutPadding(file,3);
+ size+= xkmPutCARD32(file,xkb->indicators->phys_indicators);
+ if (xkb->indicators!=NULL) {
+ 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) ||
+ (xkb->names && (xkb->names->indicators[i]!=None))) {
+ char *name;
+ if (xkb->names && xkb->names->indicators[i]!=None) {
+ name= XkbAtomGetString(dpy,xkb->names->indicators[i]);
+ }
+ else name= NULL;
+ size+= xkmPutCountedString(file,name);
+ wire.indicator= i+1;
+ wire.flags= map->flags;
+ wire.which_mods= map->which_mods;
+ wire.real_mods= map->mods.real_mods;
+ wire.vmods= map->mods.vmods;
+ wire.which_groups= map->which_groups;
+ wire.groups= map->groups;
+ wire.ctrls= map->ctrls;
+ tmp= fwrite(&wire,SIZEOF(xkmIndicatorMapDesc),1,file);
+ size+= tmp*SIZEOF(xkmIndicatorMapDesc);
+ }
+ }
+ }
+ return size;
+}
+
+/***====================================================================***/
+
+static unsigned
+SizeXKMGeomDoodad(XkbFileInfo *result,XkbDoodadPtr doodad)
+{
+unsigned size;
+
+ size= SIZEOF(xkmAnyDoodadDesc);
+ size+= xkmSizeCountedAtomString(result->xkb->dpy,doodad->any.name);
+ if (doodad->any.type==XkbTextDoodad) {
+ size+= xkmSizeCountedString(doodad->text.text);
+ size+= xkmSizeCountedString(doodad->text.font);
+ }
+ else if (doodad->any.type==XkbLogoDoodad) {
+ size+= xkmSizeCountedString(doodad->logo.logo_name);
+ }
+ return size;
+}
+
+static unsigned
+SizeXKMGeomSection(XkbFileInfo *result,XkbSectionPtr section)
+{
+register int i;
+unsigned size;
+
+ size= SIZEOF(xkmSectionDesc);
+ size+= xkmSizeCountedAtomString(result->xkb->dpy,section->name);
+ if (section->rows) {
+ XkbRowPtr row;
+ for (row=section->rows,i=0;i<section->num_rows;i++,row++) {
+ size+= SIZEOF(xkmRowDesc);
+ size+= row->num_keys*SIZEOF(xkmKeyDesc);
+ }
+ }
+ if (section->doodads) {
+ XkbDoodadPtr doodad;
+ for (doodad=section->doodads,i=0;i<section->num_doodads;i++,doodad++) {
+ size+= SizeXKMGeomDoodad(result,doodad);
+ }
+ }
+ if (section->overlays) {
+ XkbOverlayPtr ol;
+ for (ol=section->overlays,i=0;i<section->num_overlays;i++,ol++) {
+ register int r;
+ XkbOverlayRowPtr row;
+ size+= xkmSizeCountedAtomString(result->xkb->dpy,ol->name);
+ size+= SIZEOF(xkmOverlayDesc);
+ for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
+ size+= SIZEOF(xkmOverlayRowDesc);
+ size+= row->num_keys*SIZEOF(xkmOverlayKeyDesc);
+ }
+ }
+ }
+ return size;
+}
+
+static unsigned
+SizeXKMGeometry(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout)
+{
+register int i;
+Display * dpy;
+XkbDescPtr xkb;
+XkbGeometryPtr geom;
+unsigned size;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ if ((!xkb)||(!xkb->geom))
+ return 0;
+ geom= xkb->geom;
+ size= xkmSizeCountedAtomString(dpy,geom->name);
+ size+= SIZEOF(xkmGeometryDesc);
+ size+= xkmSizeCountedString(geom->label_font);
+ if (geom->properties) {
+ XkbPropertyPtr prop;
+ for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
+ size+= xkmSizeCountedString(prop->name);
+ size+= xkmSizeCountedString(prop->value);
+ }
+ }
+ if (geom->colors) {
+ XkbColorPtr color;
+ for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
+ size+= xkmSizeCountedString(color->spec);
+ }
+ }
+ if (geom->shapes) {
+ XkbShapePtr shape;
+ for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
+ register int n;
+ register XkbOutlinePtr ol;
+ size+= xkmSizeCountedAtomString(dpy,shape->name);
+ size+= SIZEOF(xkmShapeDesc);
+ for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) {
+ size+= SIZEOF(xkmOutlineDesc);
+ size+= ol->num_points*SIZEOF(xkmPointDesc);
+ }
+ }
+ }
+ if (geom->sections) {
+ XkbSectionPtr section;
+ for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
+ size+= SizeXKMGeomSection(result,section);
+ }
+ }
+ if (geom->doodads) {
+ XkbDoodadPtr doodad;
+ for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) {
+ size+= SizeXKMGeomDoodad(result,doodad);
+ }
+ }
+ if (geom->key_aliases) {
+ size+= geom->num_key_aliases*(XkbKeyNameLength*2);
+ }
+ toc->type= XkmGeometryIndex;
+ toc->format= MSBFirst;
+ toc->size= size+SIZEOF(xkmSectionInfo);
+ toc->offset= (*offset_inout);
+ (*offset_inout)+= toc->size;
+ return 1;
+}
+
+static unsigned
+WriteXKMGeomDoodad(FILE *file,XkbFileInfo *result,XkbDoodadPtr doodad)
+{
+Display * dpy;
+XkbDescPtr xkb;
+xkmDoodadDesc doodadWire;
+unsigned tmp,size= 0;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ bzero((char *)&doodadWire,sizeof(doodadWire));
+ doodadWire.any.type= doodad->any.type;
+ doodadWire.any.priority= doodad->any.priority;
+ doodadWire.any.top= doodad->any.top;
+ doodadWire.any.left= doodad->any.left;
+ switch (doodad->any.type) {
+ case XkbOutlineDoodad:
+ case XkbSolidDoodad:
+ doodadWire.shape.angle= doodad->shape.angle;
+ doodadWire.shape.color_ndx= doodad->shape.color_ndx;
+ doodadWire.shape.shape_ndx= doodad->shape.shape_ndx;
+ break;
+ case XkbTextDoodad:
+ doodadWire.text.angle= doodad->text.angle;
+ doodadWire.text.width= doodad->text.width;
+ doodadWire.text.height= doodad->text.height;
+ doodadWire.text.color_ndx= doodad->text.color_ndx;
+ break;
+ case XkbIndicatorDoodad:
+ doodadWire.indicator.shape_ndx= doodad->indicator.shape_ndx;
+ doodadWire.indicator.on_color_ndx= doodad->indicator.on_color_ndx;
+ doodadWire.indicator.off_color_ndx= doodad->indicator.off_color_ndx;
+ break;
+ case XkbLogoDoodad:
+ doodadWire.logo.angle= doodad->logo.angle;
+ doodadWire.logo.color_ndx= doodad->logo.color_ndx;
+ doodadWire.logo.shape_ndx= doodad->logo.shape_ndx;
+ break;
+ default:
+ _XkbLibError(_XkbErrIllegalDoodad,"WriteXKMGeomDoodad",
+ doodad->any.type);
+ return 0;
+ }
+ size+= xkmPutCountedAtomString(dpy,file,doodad->any.name);
+ tmp= fwrite(&doodadWire,SIZEOF(xkmDoodadDesc),1,file);
+ size+= tmp*SIZEOF(xkmDoodadDesc);
+ if (doodad->any.type==XkbTextDoodad) {
+ size+= xkmPutCountedString(file,doodad->text.text);
+ size+= xkmPutCountedString(file,doodad->text.font);
+ }
+ else if (doodad->any.type==XkbLogoDoodad) {
+ size+= xkmPutCountedString(file,doodad->logo.logo_name);
+ }
+ return size;
+}
+
+static unsigned
+WriteXKMGeomOverlay(FILE *file,XkbFileInfo *result,XkbOverlayPtr ol)
+{
+register int r,k;
+Display * dpy;
+XkbDescPtr xkb;
+XkbOverlayRowPtr row;
+xkmOverlayDesc olWire;
+xkmOverlayRowDesc rowWire;
+xkmOverlayKeyDesc keyWire;
+unsigned tmp,size= 0;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ bzero((char *)&olWire,sizeof(olWire));
+ bzero((char *)&rowWire,sizeof(rowWire));
+ bzero((char *)&keyWire,sizeof(keyWire));
+ size+= xkmPutCountedAtomString(dpy,file,ol->name);
+ olWire.num_rows= ol->num_rows;
+ tmp= fwrite(&olWire,SIZEOF(xkmOverlayDesc),1,file);
+ size+= tmp*SIZEOF(xkmOverlayDesc);
+ for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
+ XkbOverlayKeyPtr key;
+ rowWire.row_under= row->row_under;
+ rowWire.num_keys= row->num_keys;
+ tmp= fwrite(&rowWire,SIZEOF(xkmOverlayRowDesc),1,file);
+ size+= tmp*SIZEOF(xkmOverlayRowDesc);
+ for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
+ memcpy(keyWire.over,key->over.name,XkbKeyNameLength);
+ memcpy(keyWire.under,key->under.name,XkbKeyNameLength);
+ tmp= fwrite(&keyWire,SIZEOF(xkmOverlayKeyDesc),1,file);
+ size+= tmp*SIZEOF(xkmOverlayKeyDesc);
+ }
+ }
+ return size;
+}
+
+static unsigned
+WriteXKMGeomSection(FILE *file,XkbFileInfo *result,XkbSectionPtr section)
+{
+register int i;
+Display * dpy;
+XkbDescPtr xkb;
+xkmSectionDesc sectionWire;
+unsigned tmp,size= 0;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ size+= xkmPutCountedAtomString(dpy,file,section->name);
+ sectionWire.top= section->top;
+ sectionWire.left= section->left;
+ sectionWire.width= section->width;
+ sectionWire.height= section->height;
+ sectionWire.angle= section->angle;
+ sectionWire.priority= section->priority;
+ sectionWire.num_rows= section->num_rows;
+ sectionWire.num_doodads= section->num_doodads;
+ sectionWire.num_overlays= section->num_overlays;
+ tmp= fwrite(§ionWire,SIZEOF(xkmSectionDesc),1,file);
+ size+= tmp*SIZEOF(xkmSectionDesc);
+ if (section->rows) {
+ register unsigned k;
+ XkbRowPtr row;
+ xkmRowDesc rowWire;
+ XkbKeyPtr key;
+ xkmKeyDesc keyWire;
+ for (i=0,row=section->rows;i<section->num_rows;i++,row++) {
+ rowWire.top= row->top;
+ rowWire.left= row->left;
+ rowWire.num_keys= row->num_keys;
+ rowWire.vertical= row->vertical;
+ tmp= fwrite(&rowWire,SIZEOF(xkmRowDesc),1,file);
+ size+= tmp*SIZEOF(xkmRowDesc);
+ for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
+ memcpy(keyWire.name,key->name.name,XkbKeyNameLength);
+ keyWire.gap= key->gap;
+ keyWire.shape_ndx= key->shape_ndx;
+ keyWire.color_ndx= key->color_ndx;
+ tmp= fwrite(&keyWire,SIZEOF(xkmKeyDesc),1,file);
+ size+= tmp*SIZEOF(xkmKeyDesc);
+ }
+ }
+ }
+ if (section->doodads) {
+ XkbDoodadPtr doodad;
+ for (i=0,doodad=section->doodads;i<section->num_doodads;i++,doodad++) {
+ size+= WriteXKMGeomDoodad(file,result,doodad);
+ }
+ }
+ if (section->overlays) {
+ XkbOverlayPtr ol;
+ for (i=0,ol=section->overlays;i<section->num_overlays;i++,ol++) {
+ size+= WriteXKMGeomOverlay(file,result,ol);
+ }
+ }
+ return size;
+}
+
+static unsigned
+WriteXKMGeometry(FILE *file,XkbFileInfo *result)
+{
+register int i;
+Display * dpy;
+XkbDescPtr xkb;
+XkbGeometryPtr geom;
+xkmGeometryDesc wire;
+unsigned tmp,size= 0;
+
+ xkb= result->xkb;
+ dpy= xkb->dpy;
+ if ((!xkb)||(!xkb->geom))
+ return 0;
+ geom= xkb->geom;
+ wire.width_mm= geom->width_mm;
+ wire.height_mm= geom->height_mm;
+ wire.base_color_ndx= XkbGeomColorIndex(geom,geom->base_color);
+ wire.label_color_ndx= XkbGeomColorIndex(geom,geom->label_color);
+ wire.num_properties= geom->num_properties;
+ wire.num_colors= geom->num_colors;
+ wire.num_shapes= geom->num_shapes;
+ wire.num_sections= geom->num_sections;
+ wire.num_doodads= geom->num_doodads;
+ wire.num_key_aliases= geom->num_key_aliases;
+ size+= xkmPutCountedAtomString(dpy,file,geom->name);
+ tmp= fwrite(&wire,SIZEOF(xkmGeometryDesc),1,file);
+ size+= tmp*SIZEOF(xkmGeometryDesc);
+ size+= xkmPutCountedString(file,geom->label_font);
+ if (geom->properties) {
+ XkbPropertyPtr prop;
+ for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
+ size+= xkmPutCountedString(file,prop->name);
+ size+= xkmPutCountedString(file,prop->value);
+ }
+ }
+ if (geom->colors) {
+ XkbColorPtr color;
+ for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
+ size+= xkmPutCountedString(file,color->spec);
+ }
+ }
+ if (geom->shapes) {
+ XkbShapePtr shape;
+ xkmShapeDesc shapeWire;
+
+ for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
+ register int n;
+ XkbOutlinePtr ol;
+ xkmOutlineDesc olWire;
+ bzero((char *)&shapeWire,sizeof(xkmShapeDesc));
+ size+= xkmPutCountedAtomString(dpy,file,shape->name);
+ shapeWire.num_outlines= shape->num_outlines;
+ if (shape->primary!=NULL)
+ shapeWire.primary_ndx= XkbOutlineIndex(shape,shape->primary);
+ else shapeWire.primary_ndx= XkbNoShape;
+ if (shape->approx!=NULL)
+ shapeWire.approx_ndx= XkbOutlineIndex(shape,shape->approx);
+ else shapeWire.approx_ndx= XkbNoShape;
+ tmp= fwrite(&shapeWire,SIZEOF(xkmShapeDesc),1,file);
+ size+= tmp*SIZEOF(xkmShapeDesc);
+ for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) {
+ register int p;
+ XkbPointPtr pt;
+ xkmPointDesc ptWire;
+ olWire.num_points= ol->num_points;
+ olWire.corner_radius= ol->corner_radius;
+ tmp= fwrite(&olWire,SIZEOF(xkmOutlineDesc),1,file);
+ size+= tmp*SIZEOF(xkmOutlineDesc);
+ for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) {
+ ptWire.x= pt->x;
+ ptWire.y= pt->y;
+ tmp= fwrite(&ptWire,SIZEOF(xkmPointDesc),1,file);
+ size+= tmp*SIZEOF(xkmPointDesc);
+ }
+ }
+ }
+ }
+ if (geom->sections) {
+ XkbSectionPtr section;
+ for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
+ size+= WriteXKMGeomSection(file,result,section);
+ }
+ }
+ if (geom->doodads) {
+ XkbDoodadPtr doodad;
+ for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) {
+ size+= WriteXKMGeomDoodad(file,result,doodad);
+ }
+ }
+ if (geom->key_aliases) {
+ tmp= fwrite(geom->key_aliases,2*XkbKeyNameLength,geom->num_key_aliases,
+ file);
+ size+= tmp*(2*XkbKeyNameLength);
+ }
+ return size;
+}
+
+/***====================================================================***/
+
+/*ARGSUSED*/
+static int
+GetXKMKeyNamesTOC( XkbFileInfo * result,
+ XkmInfo * info,
+ int max_toc,
+ xkmSectionInfo *toc_rtrn)
+{
+int num_toc;
+int total_size;
+
+ total_size= num_toc=0;
+ if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ return num_toc;
+}
+
+/*ARGSUSED*/
+static int
+GetXKMTypesTOC( XkbFileInfo * result,
+ XkmInfo * info,
+ int max_toc,
+ xkmSectionInfo *toc_rtrn)
+{
+int num_toc;
+int total_size;
+
+ total_size= num_toc=0;
+ if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ return num_toc;
+}
+
+/*ARGSUSED*/
+static int
+GetXKMCompatMapTOC( XkbFileInfo * result,
+ XkmInfo * info,
+ int max_toc,
+ xkmSectionInfo *toc_rtrn)
+{
+int num_toc;
+int total_size;
+
+ total_size= num_toc=0;
+ if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ return num_toc;
+}
+
+/*ARGSUSED*/
+static int
+GetXKMSemanticsTOC( XkbFileInfo * result,
+ XkmInfo * info,
+ int max_toc,
+ xkmSectionInfo *toc_rtrn)
+{
+int num_toc;
+int total_size;
+
+ total_size= num_toc=0;
+ if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ return num_toc;
+}
+
+/*ARGSUSED*/
+static int
+GetXKMLayoutTOC( XkbFileInfo * result,
+ XkmInfo * info,
+ int max_toc,
+ xkmSectionInfo *toc_rtrn)
+{
+int num_toc;
+int total_size;
+
+ total_size= num_toc=0;
+ if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMSymbols(result,info,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ return num_toc;
+}
+
+/*ARGSUSED*/
+static int
+GetXKMKeymapTOC( XkbFileInfo * result,
+ XkmInfo * info,
+ int max_toc,
+ xkmSectionInfo *toc_rtrn)
+{
+int num_toc;
+int total_size;
+
+ total_size= num_toc=0;
+ if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMSymbols(result,info,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ return num_toc;
+}
+
+/*ARGSUSED*/
+static int
+GetXKMGeometryTOC( XkbFileInfo * result,
+ XkmInfo * info,
+ int max_toc,
+ xkmSectionInfo *toc_rtrn)
+{
+int num_toc;
+int total_size;
+
+ total_size= num_toc=0;
+ if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size))
+ num_toc++;
+ return num_toc;
+}
+
+static Bool
+WriteXKMFile( FILE * file,
+ XkbFileInfo * result,
+ int num_toc,
+ xkmSectionInfo *toc,
+ XkmInfo * info)
+{
+register int i;
+unsigned tmp,size,total= 0;
+
+ for (i=0;i<num_toc;i++) {
+ tmp= fwrite(&toc[i],SIZEOF(xkmSectionInfo),1,file);
+ total+= tmp*SIZEOF(xkmSectionInfo);
+ switch (toc[i].type) {
+ case XkmTypesIndex:
+ size= WriteXKMKeyTypes(file,result);
+ break;
+ case XkmCompatMapIndex:
+ size= WriteXKMCompatMap(file,result,info);
+ break;
+ case XkmSymbolsIndex:
+ size= WriteXKMSymbols(file,result,info);
+ break;
+ case XkmIndicatorsIndex:
+ size= WriteXKMIndicators(file,result,info);
+ break;
+ case XkmKeyNamesIndex:
+ size= WriteXKMKeycodes(file,result);
+ break;
+ case XkmGeometryIndex:
+ size= WriteXKMGeometry(file,result);
+ break;
+ case XkmVirtualModsIndex:
+ size= WriteXKMVirtualMods(file,result,info);
+ break;
+ default:
+ _XkbLibError(_XkbErrIllegalTOCType,"WriteXKMFile",toc[i].type);
+ return False;
+ }
+ size+= SIZEOF(xkmSectionInfo);
+ if (size!=toc[i].size) {
+ _XkbLibError(_XkbErrBadLength,XkbConfigText(toc[i].type,XkbMessage),
+ size-toc[i].size);
+ return False;
+ }
+ }
+ return True;
+}
+
+
+#define MAX_TOC 16
+
+Bool
+XkbWriteXKMFile(FILE *out,XkbFileInfo *result)
+{
+Bool ok;
+XkbDescPtr xkb;
+XkmInfo info;
+int size_toc,i;
+unsigned hdr,present;
+xkmFileInfo fileInfo;
+xkmSectionInfo toc[MAX_TOC];
+int (*getTOC)(
+ XkbFileInfo * /* result */,
+ XkmInfo * /* info */,
+ int /* max_to */,
+ xkmSectionInfo * /* toc_rtrn */
+);
+
+ switch (result->type) {
+ case XkmKeyNamesIndex:
+ getTOC= GetXKMKeyNamesTOC;
+ break;
+ case XkmTypesIndex:
+ getTOC= GetXKMTypesTOC;
+ break;
+ case XkmCompatMapIndex:
+ getTOC= GetXKMCompatMapTOC;
+ break;
+ case XkmSemanticsFile:
+ getTOC= GetXKMSemanticsTOC;
+ break;
+ case XkmLayoutFile:
+ getTOC= GetXKMLayoutTOC;
+ break;
+ case XkmKeymapFile:
+ getTOC= GetXKMKeymapTOC;
+ break;
+ case XkmGeometryFile:
+ case XkmGeometryIndex:
+ getTOC= GetXKMGeometryTOC;
+ break;
+ default:
+ _XkbLibError(_XkbErrIllegalContents,
+ XkbConfigText(result->type,XkbMessage),0);
+ return False;
+ }
+ xkb= result->xkb;
+
+ bzero((char *)&info,sizeof(XkmInfo));
+ size_toc= (*getTOC)(result,&info,MAX_TOC,toc);
+ if (size_toc<1) {
+ _XkbLibError(_XkbErrEmptyFile,"XkbWriteXKMFile",0);
+ return False;
+ }
+ if (out==NULL) {
+ _XkbLibError(_XkbErrFileCannotOpen,"XkbWriteXKMFile",0);
+ return False;
+ }
+ for (i=present=0;i<size_toc;i++) {
+ toc[i].offset+= 4+SIZEOF(xkmFileInfo);
+ toc[i].offset+= (size_toc*SIZEOF(xkmSectionInfo));
+ if (toc[i].type<=XkmLastIndex) {
+ present|= (1<<toc[i].type);
+ }
+#ifdef DEBUG
+ else {
+ fprintf(stderr,"Illegal section type %d\n",toc[i].type);
+ fprintf(stderr,"Ignored\n");
+ }
+#endif
+ }
+ hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion);
+ xkmPutCARD32(out,(unsigned long)hdr);
+ fileInfo.type= result->type;
+ fileInfo.min_kc= xkb->min_key_code;
+ fileInfo.max_kc= xkb->max_key_code;
+ fileInfo.num_toc= size_toc;
+ fileInfo.present= present;
+ fileInfo.pad= 0;
+ fwrite(&fileInfo,SIZEOF(xkmFileInfo),1,out);
+ fwrite(toc,SIZEOF(xkmSectionInfo),size_toc,out);
+ ok= WriteXKMFile(out,result,size_toc,toc,&info);
+ return ok;
+}
|