/* $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. ********************************************************/ #include #include #ifndef X_NOT_STDC_ENV #include #endif #include #include #include #include #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 #if NeedFunctionPrototypes xkmPutCARD16(FILE *file,unsigned val) #else xkmPutCARD16(file,val) FILE * file; unsigned val; #endif { CARD16 tmp= val; fwrite(&tmp,2,1,file); return 2; } static int #if NeedFunctionPrototypes xkmPutCARD32(FILE *file,unsigned long val) #else xkmPutCARD32(file,val) FILE * file; unsigned long val; #endif { CARD32 tmp= val; fwrite(&tmp,4,1,file); return 4; } static int #if NeedFunctionPrototypes xkmPutPadding(FILE *file,unsigned pad) #else xkmPutPadding(file,pad) FILE * file; unsigned pad; #endif { int i; for (i=0;ixkb; 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;iserver->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 #if NeedFunctionPrototypes WriteXKMVirtualMods(FILE *file,XkbFileInfo *result,XkmInfo *info) #else WriteXKMVirtualMods(file,result,info) FILE * file; XkbFileInfo * result; XkmInfo * info; #endif { 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;ibound_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;inamed_vmods&bit) { register char *name; name= XkbAtomGetString(dpy,xkb->names->vmods[i]); size+= xkmPutCountedString(file,name); } } return size; } /***====================================================================***/ static unsigned #if NeedFunctionPrototypes SizeXKMKeycodes(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout) #else SizeXKMKeycodes(result,toc,offset_inout) XkbFileInfo * result; xkmSectionInfo * toc; int * offset_inout; #endif { 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 #if NeedFunctionPrototypes WriteXKMKeycodes(FILE *file,XkbFileInfo *result) #else WriteXKMKeycodes(file,result) FILE * file; XkbFileInfo * result; #endif { 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 #if NeedFunctionPrototypes SizeXKMKeyTypes(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout) #else SizeXKMKeyTypes(result,toc,offset_inout) XkbFileInfo * result; xkmSectionInfo * toc; int * offset_inout; #endif { 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_typesnames) 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;imap->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 #if NeedFunctionPrototypes WriteXKMKeyTypes(FILE *file,XkbFileInfo *result) #else WriteXKMKeyTypes(file,result) FILE * file; XkbFileInfo * result; #endif { 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;imap->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;nmap_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;nmap_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;nxkb; 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;icompat->groups[i].real_mods!=0)|| (xkb->compat->groups[i].vmods!=0)) { groups|= (1<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 #if NeedFunctionPrototypes WriteXKMCompatMap(FILE *file,XkbFileInfo *result,XkmInfo *info) #else WriteXKMCompatMap(file,result,info) FILE * file; XkbFileInfo * result; XkmInfo * info; #endif { 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;icompat->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;igroup_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 #if NeedFunctionPrototypes SizeXKMSymbols( XkbFileInfo * result, XkmInfo * info, xkmSectionInfo * toc, int * offset_inout) #else SizeXKMSymbols(result,info,toc,offset_inout) XkbFileInfo * result; XkmInfo * info; xkmSectionInfo * toc; int * offset_inout; #endif { 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;inames->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<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 #if NeedFunctionPrototypes WriteXKMSymbols(FILE *file,XkbFileInfo *result,XkmInfo *info) #else WriteXKMSymbols(file,result,info) FILE * file; XkbFileInfo * result; XkmInfo * info; #endif { 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;inames->groups[i]!=None) tmp|= (1<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;inames->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= XkbKeyNumGroups(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;gserver->explicit[i]&(1<name); if (typeName[g]!=NULL) wireMap.flags|= (1<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;g0) { 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 #if NeedFunctionPrototypes SizeXKMIndicators(XkbFileInfo *result,XkmInfo *info,xkmSectionInfo *toc, int *offset_inout) #else SizeXKMIndicators(result,info,toc,offset_inout) XkbFileInfo * result; XkmInfo * info; xkmSectionInfo * toc; int * offset_inout; #endif { 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;iindicators->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 #if NeedFunctionPrototypes WriteXKMIndicators(FILE *file,XkbFileInfo *result,XkmInfo *info) #else WriteXKMIndicators(file,result,info) FILE * file; XkbFileInfo * result; XkmInfo * info; #endif { 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;iindicators->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 #if NeedFunctionPrototypes SizeXKMGeomDoodad(XkbFileInfo *result,XkbDoodadPtr doodad) #else SizeXKMGeomDoodad(result,doodad) XkbFileInfo * result; XkbDoodadPtr doodad; #endif { 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 #if NeedFunctionPrototypes SizeXKMGeomSection(XkbFileInfo *result,XkbSectionPtr section) #else SizeXKMGeomSection(result,section) XkbFileInfo * result; XkbSectionPtr section; #endif { 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;inum_rows;i++,row++) { size+= SIZEOF(xkmRowDesc); size+= row->num_keys*SIZEOF(xkmKeyDesc); } } if (section->doodads) { XkbDoodadPtr doodad; for (doodad=section->doodads,i=0;inum_doodads;i++,doodad++) { size+= SizeXKMGeomDoodad(result,doodad); } } if (section->overlays) { XkbOverlayPtr ol; for (ol=section->overlays,i=0;inum_overlays;i++,ol++) { register int r; XkbOverlayRowPtr row; size+= xkmSizeCountedAtomString(result->xkb->dpy,ol->name); size+= SIZEOF(xkmOverlayDesc); for (r=0,row=ol->rows;rnum_rows;r++,row++) { size+= SIZEOF(xkmOverlayRowDesc); size+= row->num_keys*SIZEOF(xkmOverlayKeyDesc); } } } return size; } static unsigned #if NeedFunctionPrototypes SizeXKMGeometry(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout) #else SizeXKMGeometry(result,toc,offset_inout) XkbFileInfo * result; xkmSectionInfo * toc; int * offset_inout; #endif { 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;inum_properties;i++,prop++) { size+= xkmSizeCountedString(prop->name); size+= xkmSizeCountedString(prop->value); } } if (geom->colors) { XkbColorPtr color; for (i=0,color=geom->colors;inum_colors;i++,color++) { size+= xkmSizeCountedString(color->spec); } } if (geom->shapes) { XkbShapePtr shape; for (i=0,shape=geom->shapes;inum_shapes;i++,shape++) { register int n; register XkbOutlinePtr ol; size+= xkmSizeCountedAtomString(dpy,shape->name); size+= SIZEOF(xkmShapeDesc); for (n=0,ol=shape->outlines;nnum_outlines;n++,ol++) { size+= SIZEOF(xkmOutlineDesc); size+= ol->num_points*SIZEOF(xkmPointDesc); } } } if (geom->sections) { XkbSectionPtr section; for (i=0,section=geom->sections;inum_sections;i++,section++) { size+= SizeXKMGeomSection(result,section); } } if (geom->doodads) { XkbDoodadPtr doodad; for (i=0,doodad=geom->doodads;inum_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 #if NeedFunctionPrototypes WriteXKMGeomDoodad(FILE *file,XkbFileInfo *result,XkbDoodadPtr doodad) #else WriteXKMGeomDoodad(file,result,doodad) FILE * file; XkbFileInfo * result; XkbDoodadPtr doodad; #endif { 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 #if NeedFunctionPrototypes WriteXKMGeomOverlay(FILE *file,XkbFileInfo *result,XkbOverlayPtr ol) #else WriteXKMGeomOverlay(file,result,ol) FILE * file; XkbFileInfo * result; XkbOverlayPtr ol; #endif { 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;rnum_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;knum_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 #if NeedFunctionPrototypes WriteXKMGeomSection(FILE *file,XkbFileInfo *result,XkbSectionPtr section) #else WriteXKMGeomSection(file,result,section) FILE * file; XkbFileInfo * result; XkbSectionPtr section; #endif { 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;inum_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;knum_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;inum_doodads;i++,doodad++) { size+= WriteXKMGeomDoodad(file,result,doodad); } } if (section->overlays) { XkbOverlayPtr ol; for (i=0,ol=section->overlays;inum_overlays;i++,ol++) { size+= WriteXKMGeomOverlay(file,result,ol); } } return size; } static unsigned #if NeedFunctionPrototypes WriteXKMGeometry(FILE *file,XkbFileInfo *result) #else WriteXKMGeometry(file,result) FILE * file; XkbFileInfo * result; #endif { 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;inum_properties;i++,prop++) { size+= xkmPutCountedString(file,prop->name); size+= xkmPutCountedString(file,prop->value); } } if (geom->colors) { XkbColorPtr color; for (i=0,color=geom->colors;inum_colors;i++,color++) { size+= xkmPutCountedString(file,color->spec); } } if (geom->shapes) { XkbShapePtr shape; xkmShapeDesc shapeWire; for (i=0,shape=geom->shapes;inum_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;nnum_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;pnum_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;inum_sections;i++,section++) { size+= WriteXKMGeomSection(file,result,section); } } if (geom->doodads) { XkbDoodadPtr doodad; for (i=0,doodad=geom->doodads;inum_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 #if NeedFunctionPrototypes GetXKMKeyNamesTOC( XkbFileInfo * result, XkmInfo * info, int max_toc, xkmSectionInfo *toc_rtrn) #else GetXKMKeyNamesTOC(result,info,max_toc,toc_rtrn) XkbFileInfo * result; XkmInfo * info; int max_toc; xkmSectionInfo * toc_rtrn; #endif { 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 #if NeedFunctionPrototypes GetXKMTypesTOC( XkbFileInfo * result, XkmInfo * info, int max_toc, xkmSectionInfo *toc_rtrn) #else GetXKMTypesTOC(result,info,max_toc,toc_rtrn) XkbFileInfo * result; XkmInfo * info; int max_toc; xkmSectionInfo * toc_rtrn; #endif { 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 #if NeedFunctionPrototypes GetXKMCompatMapTOC( XkbFileInfo * result, XkmInfo * info, int max_toc, xkmSectionInfo *toc_rtrn) #else GetXKMCompatMapTOC(result,info,max_toc,toc_rtrn) XkbFileInfo * result; XkmInfo * info; int max_toc; xkmSectionInfo * toc_rtrn; #endif { 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 #if NeedFunctionPrototypes GetXKMSemanticsTOC( XkbFileInfo * result, XkmInfo * info, int max_toc, xkmSectionInfo *toc_rtrn) #else GetXKMSemanticsTOC(result,info,max_toc,toc_rtrn) XkbFileInfo * result; XkmInfo * info; int max_toc; xkmSectionInfo * toc_rtrn; #endif { 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 #if NeedFunctionPrototypes GetXKMLayoutTOC( XkbFileInfo * result, XkmInfo * info, int max_toc, xkmSectionInfo *toc_rtrn) #else GetXKMLayoutTOC(result,info,max_toc,toc_rtrn) XkbFileInfo * result; XkmInfo * info; int max_toc; xkmSectionInfo * toc_rtrn; #endif { 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 #if NeedFunctionPrototypes GetXKMKeymapTOC( XkbFileInfo * result, XkmInfo * info, int max_toc, xkmSectionInfo *toc_rtrn) #else GetXKMKeymapTOC(result,info,max_toc,toc_rtrn) XkbFileInfo * result; XkmInfo * info; int max_toc; xkmSectionInfo * toc_rtrn; #endif { 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 #if NeedFunctionPrototypes GetXKMGeometryTOC( XkbFileInfo * result, XkmInfo * info, int max_toc, xkmSectionInfo *toc_rtrn) #else GetXKMGeometryTOC(result,info,max_toc,toc_rtrn) XkbFileInfo * result; XkmInfo * info; int max_toc; xkmSectionInfo * toc_rtrn; #endif { 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 #if NeedFunctionPrototypes WriteXKMFile( FILE * file, XkbFileInfo * result, int num_toc, xkmSectionInfo *toc, XkmInfo * info) #else WriteXKMFile(file,result,num_toc,toc,info) FILE * file; XkbFileInfo * result; int num_toc; xkmSectionInfo * toc; XkmInfo * info; #endif { register int i; unsigned tmp,size,total= 0; for (i=0;itype) { 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;itype; 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; }