xkmout.c revision 4cd6a3ae
18c9fbc29Smrg/************************************************************ 28c9fbc29Smrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. 38c9fbc29Smrg 48c9fbc29Smrg Permission to use, copy, modify, and distribute this 58c9fbc29Smrg software and its documentation for any purpose and without 68c9fbc29Smrg fee is hereby granted, provided that the above copyright 78c9fbc29Smrg notice appear in all copies and that both that copyright 88c9fbc29Smrg notice and this permission notice appear in supporting 94cd6a3aeSmrg documentation, and that the name of Silicon Graphics not be 104cd6a3aeSmrg used in advertising or publicity pertaining to distribution 118c9fbc29Smrg of the software without specific prior written permission. 124cd6a3aeSmrg Silicon Graphics makes no representation about the suitability 138c9fbc29Smrg of this software for any purpose. It is provided "as is" 148c9fbc29Smrg without any express or implied warranty. 154cd6a3aeSmrg 164cd6a3aeSmrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 174cd6a3aeSmrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 188c9fbc29Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 194cd6a3aeSmrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 204cd6a3aeSmrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 214cd6a3aeSmrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 228c9fbc29Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 238c9fbc29Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 248c9fbc29Smrg 258c9fbc29Smrg ********************************************************/ 268c9fbc29Smrg 278c9fbc29Smrg#ifdef HAVE_CONFIG_H 288c9fbc29Smrg#include <config.h> 298c9fbc29Smrg#endif 308c9fbc29Smrg#include <stdio.h> 318c9fbc29Smrg#include <ctype.h> 328c9fbc29Smrg#include <stdlib.h> 338c9fbc29Smrg#include <X11/Xfuncs.h> 348c9fbc29Smrg#include <X11/Xlib.h> 358c9fbc29Smrg#include <X11/XKBlib.h> 368c9fbc29Smrg#include <X11/extensions/XKBgeom.h> 378c9fbc29Smrg 388c9fbc29Smrg#include "XKMformat.h" 398c9fbc29Smrg#include "XKBfileInt.h" 408c9fbc29Smrg 418c9fbc29Smrgtypedef struct _XkmInfo { 428c9fbc29Smrg unsigned short bound_vmods; 438c9fbc29Smrg unsigned short named_vmods; 448c9fbc29Smrg unsigned char num_bound; 458c9fbc29Smrg unsigned char group_compat; 468c9fbc29Smrg unsigned short num_group_compat; 478c9fbc29Smrg unsigned short num_leds; 488c9fbc29Smrg int total_vmodmaps; 498c9fbc29Smrg} XkmInfo; 508c9fbc29Smrg 518c9fbc29Smrg/***====================================================================***/ 528c9fbc29Smrg 538c9fbc29Smrg#define xkmPutCARD8(f,v) (putc(v,f),1) 548c9fbc29Smrg 558c9fbc29Smrgstatic int 568c9fbc29SmrgxkmPutCARD16(FILE *file,unsigned val) 578c9fbc29Smrg{ 588c9fbc29SmrgCARD16 tmp= val; 598c9fbc29Smrg 608c9fbc29Smrg fwrite(&tmp,2,1,file); 618c9fbc29Smrg return 2; 628c9fbc29Smrg} 638c9fbc29Smrg 648c9fbc29Smrgstatic int 658c9fbc29SmrgxkmPutCARD32(FILE *file,unsigned long val) 668c9fbc29Smrg{ 678c9fbc29SmrgCARD32 tmp= val; 688c9fbc29Smrg 698c9fbc29Smrg fwrite(&tmp,4,1,file); 708c9fbc29Smrg return 4; 718c9fbc29Smrg} 728c9fbc29Smrg 738c9fbc29Smrgstatic int 748c9fbc29SmrgxkmPutPadding(FILE *file,unsigned pad) 758c9fbc29Smrg{ 768c9fbc29Smrgint i; 778c9fbc29Smrg for (i=0;i<pad;i++) { 788c9fbc29Smrg putc('\0',file); 798c9fbc29Smrg } 808c9fbc29Smrg return pad; 818c9fbc29Smrg} 828c9fbc29Smrg 838c9fbc29Smrgstatic int 848c9fbc29SmrgxkmPutCountedBytes(FILE *file,char *ptr,unsigned count) 858c9fbc29Smrg{ 868c9fbc29Smrgregister int nOut; 878c9fbc29Smrgregister unsigned pad; 888c9fbc29Smrg 898c9fbc29Smrg if (count==0) 908c9fbc29Smrg return xkmPutCARD32(file,(unsigned long)0); 918c9fbc29Smrg 928c9fbc29Smrg xkmPutCARD16(file,count); 938c9fbc29Smrg nOut= fwrite(ptr,1,count,file); 948c9fbc29Smrg if (nOut<0) 958c9fbc29Smrg return 2; 968c9fbc29Smrg nOut= count+2; 978c9fbc29Smrg pad= XkbPaddedSize(nOut)-nOut; 988c9fbc29Smrg if (pad) 998c9fbc29Smrg xkmPutPadding(file,pad); 1008c9fbc29Smrg return nOut+pad; 1018c9fbc29Smrg} 1028c9fbc29Smrg 1038c9fbc29Smrgstatic unsigned 1048c9fbc29SmrgxkmSizeCountedString(char *str) 1058c9fbc29Smrg{ 1068c9fbc29Smrg if (str==NULL) 1078c9fbc29Smrg return 4; 1088c9fbc29Smrg return XkbPaddedSize(strlen(str)+2); 1098c9fbc29Smrg} 1108c9fbc29Smrg 1118c9fbc29Smrgstatic int 1128c9fbc29SmrgxkmPutCountedString(FILE *file,char *str) 1138c9fbc29Smrg{ 1148c9fbc29Smrg if (str==NULL) 1158c9fbc29Smrg return xkmPutCARD32(file,(unsigned long)0); 1168c9fbc29Smrg return xkmPutCountedBytes(file,str,strlen(str)); 1178c9fbc29Smrg} 1188c9fbc29Smrg 1198c9fbc29Smrg#define xkmSizeCountedAtomString(d,a) \ 1208c9fbc29Smrg xkmSizeCountedString(XkbAtomGetString((d),(a))) 1218c9fbc29Smrg 1228c9fbc29Smrg#define xkmPutCountedAtomString(d,f,a) \ 1238c9fbc29Smrg xkmPutCountedString((f),XkbAtomGetString((d),(a))) 1248c9fbc29Smrg 1258c9fbc29Smrg/***====================================================================***/ 1268c9fbc29Smrg 1278c9fbc29Smrgstatic unsigned 1288c9fbc29SmrgSizeXKMVirtualMods( XkbFileInfo * result, 1298c9fbc29Smrg XkmInfo * info, 1308c9fbc29Smrg xkmSectionInfo * toc, 1318c9fbc29Smrg int * offset_inout) 1328c9fbc29Smrg{ 1338c9fbc29SmrgDisplay * dpy; 1348c9fbc29SmrgXkbDescPtr xkb; 1358c9fbc29Smrgunsigned nBound,bound; 1368c9fbc29Smrgunsigned nNamed,named,szNames; 1378c9fbc29Smrgregister unsigned i,bit; 1388c9fbc29Smrg 1398c9fbc29Smrg xkb= result->xkb; 1408c9fbc29Smrg dpy= xkb->dpy; 1418c9fbc29Smrg if ((!xkb)||(!xkb->names)||(!xkb->server)) { 1428c9fbc29Smrg _XkbLibError(_XkbErrMissingVMods,"SizeXKMVirtualMods",0); 1438c9fbc29Smrg return 0; 1448c9fbc29Smrg } 1458c9fbc29Smrg bound=named=0; 1468c9fbc29Smrg for (i=nBound=nNamed=szNames=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 1478c9fbc29Smrg if (xkb->server->vmods[i]!=XkbNoModifierMask) { 1488c9fbc29Smrg bound|= bit; 1498c9fbc29Smrg nBound++; 1508c9fbc29Smrg } 1518c9fbc29Smrg if (xkb->names->vmods[i]!=None) { 1528c9fbc29Smrg named|= bit; 1538c9fbc29Smrg szNames+= xkmSizeCountedAtomString(dpy,xkb->names->vmods[i]); 1548c9fbc29Smrg nNamed++; 1558c9fbc29Smrg } 1568c9fbc29Smrg } 1578c9fbc29Smrg info->num_bound= nBound; 1588c9fbc29Smrg info->bound_vmods= bound; 1598c9fbc29Smrg info->named_vmods= named; 1608c9fbc29Smrg if ((nBound==0)&&(nNamed==0)) 1618c9fbc29Smrg return 0; 1628c9fbc29Smrg toc->type= XkmVirtualModsIndex; 1638c9fbc29Smrg toc->format= MSBFirst; 1648c9fbc29Smrg toc->size= 4+XkbPaddedSize(nBound)+szNames+SIZEOF(xkmSectionInfo); 1658c9fbc29Smrg toc->offset= *offset_inout; 1668c9fbc29Smrg (*offset_inout)+= toc->size; 1678c9fbc29Smrg return 1; 1688c9fbc29Smrg} 1698c9fbc29Smrg 1708c9fbc29Smrgstatic unsigned 1718c9fbc29SmrgWriteXKMVirtualMods(FILE *file,XkbFileInfo *result,XkmInfo *info) 1728c9fbc29Smrg{ 1738c9fbc29Smrgregister unsigned int i,bit; 1748c9fbc29SmrgXkbDescPtr xkb; 1758c9fbc29SmrgDisplay * dpy; 1768c9fbc29Smrgunsigned size= 0; 1778c9fbc29Smrg 1788c9fbc29Smrg xkb= result->xkb; 1798c9fbc29Smrg dpy= xkb->dpy; 1808c9fbc29Smrg size+= xkmPutCARD16(file,info->bound_vmods); 1818c9fbc29Smrg size+= xkmPutCARD16(file,info->named_vmods); 1828c9fbc29Smrg for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 1838c9fbc29Smrg if (info->bound_vmods&bit) 1848c9fbc29Smrg size+= xkmPutCARD8(file,xkb->server->vmods[i]); 1858c9fbc29Smrg } 1868c9fbc29Smrg if ((i= XkbPaddedSize(info->num_bound)-info->num_bound)>0) 1878c9fbc29Smrg size+= xkmPutPadding(file,i); 1888c9fbc29Smrg for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 1898c9fbc29Smrg if (info->named_vmods&bit) { 1908c9fbc29Smrg register char *name; 1918c9fbc29Smrg name= XkbAtomGetString(dpy,xkb->names->vmods[i]); 1928c9fbc29Smrg size+= xkmPutCountedString(file,name); 1938c9fbc29Smrg } 1948c9fbc29Smrg } 1958c9fbc29Smrg return size; 1968c9fbc29Smrg} 1978c9fbc29Smrg 1988c9fbc29Smrg/***====================================================================***/ 1998c9fbc29Smrg 2008c9fbc29Smrgstatic unsigned 2018c9fbc29SmrgSizeXKMKeycodes(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout) 2028c9fbc29Smrg{ 2038c9fbc29SmrgXkbDescPtr xkb; 2048c9fbc29SmrgAtom kcName; 2058c9fbc29Smrgint size=0; 2068c9fbc29SmrgDisplay * dpy; 2078c9fbc29Smrg 2088c9fbc29Smrg xkb= result->xkb; 2098c9fbc29Smrg dpy= xkb->dpy; 2108c9fbc29Smrg if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) { 2118c9fbc29Smrg _XkbLibError(_XkbErrMissingNames,"SizeXKMKeycodes",0); 2128c9fbc29Smrg return 0; 2138c9fbc29Smrg } 2148c9fbc29Smrg kcName= xkb->names->keycodes; 2158c9fbc29Smrg size+= 4; /* min and max keycode */ 2168c9fbc29Smrg size+= xkmSizeCountedAtomString(dpy,kcName); 2178c9fbc29Smrg size+= XkbNumKeys(xkb)*sizeof(XkbKeyNameRec); 2188c9fbc29Smrg if (xkb->names->num_key_aliases>0) { 2198c9fbc29Smrg if (xkb->names->key_aliases!=NULL) 2208c9fbc29Smrg size+= xkb->names->num_key_aliases*sizeof(XkbKeyAliasRec); 2218c9fbc29Smrg else xkb->names->num_key_aliases= 0; 2228c9fbc29Smrg } 2238c9fbc29Smrg toc->type= XkmKeyNamesIndex; 2248c9fbc29Smrg toc->format= MSBFirst; 2258c9fbc29Smrg toc->size= size+SIZEOF(xkmSectionInfo); 2268c9fbc29Smrg toc->offset= (*offset_inout); 2278c9fbc29Smrg (*offset_inout)+= toc->size; 2288c9fbc29Smrg return 1; 2298c9fbc29Smrg} 2308c9fbc29Smrg 2318c9fbc29Smrgstatic unsigned 2328c9fbc29SmrgWriteXKMKeycodes(FILE *file,XkbFileInfo *result) 2338c9fbc29Smrg{ 2348c9fbc29SmrgXkbDescPtr xkb; 2358c9fbc29SmrgAtom kcName; 2368c9fbc29Smrgchar *start; 2378c9fbc29SmrgDisplay * dpy; 2388c9fbc29Smrgunsigned tmp,size= 0; 2398c9fbc29Smrg 2408c9fbc29Smrg xkb= result->xkb; 2418c9fbc29Smrg dpy= xkb->dpy; 2428c9fbc29Smrg kcName= xkb->names->keycodes; 2438c9fbc29Smrg start= xkb->names->keys[xkb->min_key_code].name; 2444cd6a3aeSmrg 2458c9fbc29Smrg size+= xkmPutCountedString(file,XkbAtomGetString(dpy,kcName)); 2468c9fbc29Smrg size+= xkmPutCARD8(file,xkb->min_key_code); 2478c9fbc29Smrg size+= xkmPutCARD8(file,xkb->max_key_code); 2488c9fbc29Smrg size+= xkmPutCARD8(file,xkb->names->num_key_aliases); 2498c9fbc29Smrg size+= xkmPutPadding(file,1); 2508c9fbc29Smrg tmp= fwrite(start,sizeof(XkbKeyNameRec),XkbNumKeys(xkb),file); 2518c9fbc29Smrg size+= tmp*sizeof(XkbKeyNameRec); 2528c9fbc29Smrg if (xkb->names->num_key_aliases>0) { 2538c9fbc29Smrg tmp= fwrite((char *)xkb->names->key_aliases, 2548c9fbc29Smrg sizeof(XkbKeyAliasRec),xkb->names->num_key_aliases, 2558c9fbc29Smrg file); 2568c9fbc29Smrg size+= tmp*sizeof(XkbKeyAliasRec); 2578c9fbc29Smrg } 2588c9fbc29Smrg return size; 2598c9fbc29Smrg} 2608c9fbc29Smrg 2618c9fbc29Smrg/***====================================================================***/ 2628c9fbc29Smrg 2638c9fbc29Smrgstatic unsigned 2648c9fbc29SmrgSizeXKMKeyTypes(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout) 2658c9fbc29Smrg{ 2668c9fbc29Smrgregister unsigned i,n,size; 2678c9fbc29SmrgXkbKeyTypePtr type; 2688c9fbc29SmrgXkbDescPtr xkb; 2698c9fbc29SmrgDisplay * dpy; 2708c9fbc29Smrgchar * name; 2718c9fbc29Smrg 2728c9fbc29Smrg xkb= result->xkb; 2738c9fbc29Smrg dpy= xkb->dpy; 2748c9fbc29Smrg if ((!xkb)||(!xkb->map)||(!xkb->map->types)) { 2758c9fbc29Smrg _XkbLibError(_XkbErrMissingTypes,"SizeXKBKeyTypes",0); 2768c9fbc29Smrg return 0; 2778c9fbc29Smrg } 2788c9fbc29Smrg if (xkb->map->num_types<XkbNumRequiredTypes) { 2798c9fbc29Smrg _XkbLibError(_XkbErrMissingReqTypes,"SizeXKBKeyTypes",0); 2808c9fbc29Smrg return 0; 2818c9fbc29Smrg } 2828c9fbc29Smrg if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->types); 2838c9fbc29Smrg else name= NULL; 2848c9fbc29Smrg size= xkmSizeCountedString(name); 2858c9fbc29Smrg size+= 4; /* room for # of key types + padding */ 2868c9fbc29Smrg for (i=0,type=xkb->map->types;i<xkb->map->num_types;i++,type++) { 2878c9fbc29Smrg size+= SIZEOF(xkmKeyTypeDesc); 2888c9fbc29Smrg size+= SIZEOF(xkmKTMapEntryDesc)*type->map_count; 2898c9fbc29Smrg size+= xkmSizeCountedAtomString(dpy,type->name); 2908c9fbc29Smrg if (type->preserve) 2918c9fbc29Smrg size+= SIZEOF(xkmModsDesc)*type->map_count; 2928c9fbc29Smrg if (type->level_names) { 2938c9fbc29Smrg Atom *names; 2948c9fbc29Smrg names= type->level_names; 2958c9fbc29Smrg for (n=0;n<(unsigned)type->num_levels;n++) { 2968c9fbc29Smrg size+= xkmSizeCountedAtomString(dpy,names[n]); 2978c9fbc29Smrg } 2988c9fbc29Smrg } 2998c9fbc29Smrg } 3008c9fbc29Smrg toc->type= XkmTypesIndex; 3018c9fbc29Smrg toc->format= MSBFirst; 3028c9fbc29Smrg toc->size= size+SIZEOF(xkmSectionInfo); 3038c9fbc29Smrg toc->offset= (*offset_inout); 3048c9fbc29Smrg (*offset_inout)+= toc->size; 3058c9fbc29Smrg return 1; 3068c9fbc29Smrg} 3078c9fbc29Smrg 3088c9fbc29Smrgstatic unsigned 3098c9fbc29SmrgWriteXKMKeyTypes(FILE *file,XkbFileInfo *result) 3108c9fbc29Smrg{ 3118c9fbc29Smrgregister unsigned i,n; 3128c9fbc29SmrgXkbDescPtr xkb; 3138c9fbc29SmrgXkbKeyTypePtr type; 3148c9fbc29SmrgxkmKeyTypeDesc wire; 3158c9fbc29SmrgXkbKTMapEntryPtr entry; 3168c9fbc29SmrgxkmKTMapEntryDesc wire_entry; 3178c9fbc29SmrgAtom * names; 3188c9fbc29SmrgDisplay * dpy; 3198c9fbc29Smrgunsigned tmp,size= 0; 3208c9fbc29Smrgchar * name; 3218c9fbc29Smrg 3228c9fbc29Smrg xkb= result->xkb; 3238c9fbc29Smrg dpy= xkb->dpy; 3248c9fbc29Smrg if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->types); 3258c9fbc29Smrg else name= NULL; 3268c9fbc29Smrg size+= xkmPutCountedString(file,name); 3278c9fbc29Smrg size+= xkmPutCARD16(file,xkb->map->num_types); 3288c9fbc29Smrg size+= xkmPutPadding(file,2); 3298c9fbc29Smrg type= xkb->map->types; 3308c9fbc29Smrg for (i=0;i<xkb->map->num_types;i++,type++) { 3318c9fbc29Smrg wire.realMods= type->mods.real_mods; 3328c9fbc29Smrg wire.virtualMods= type->mods.vmods; 3338c9fbc29Smrg wire.numLevels= type->num_levels; 3348c9fbc29Smrg wire.nMapEntries= type->map_count; 3358c9fbc29Smrg wire.preserve= (type->preserve!=NULL); 3368c9fbc29Smrg if (type->level_names!=NULL) 3378c9fbc29Smrg wire.nLevelNames= type->num_levels; 3388c9fbc29Smrg else wire.nLevelNames= 0; 3398c9fbc29Smrg tmp= fwrite(&wire,SIZEOF(xkmKeyTypeDesc),1,file); 3408c9fbc29Smrg size+= tmp*SIZEOF(xkmKeyTypeDesc); 3418c9fbc29Smrg for (n=0,entry= type->map;n<type->map_count;n++,entry++) { 3428c9fbc29Smrg wire_entry.level= entry->level; 3438c9fbc29Smrg wire_entry.realMods= entry->mods.real_mods; 3448c9fbc29Smrg wire_entry.virtualMods= entry->mods.vmods; 3458c9fbc29Smrg tmp= fwrite(&wire_entry,SIZEOF(xkmKTMapEntryDesc),1,file); 3468c9fbc29Smrg size+= tmp*SIZEOF(xkmKTMapEntryDesc); 3478c9fbc29Smrg } 3488c9fbc29Smrg size+= xkmPutCountedString(file,XkbAtomGetString(dpy,type->name)); 3498c9fbc29Smrg if (type->preserve) { 3508c9fbc29Smrg xkmModsDesc p_entry; 3518c9fbc29Smrg XkbModsPtr pre; 3528c9fbc29Smrg for (n=0,pre=type->preserve;n<type->map_count;n++,pre++) { 3538c9fbc29Smrg p_entry.realMods= pre->real_mods; 3548c9fbc29Smrg p_entry.virtualMods= pre->vmods; 3558c9fbc29Smrg tmp= fwrite(&p_entry,SIZEOF(xkmModsDesc),1,file); 3568c9fbc29Smrg size+= tmp*SIZEOF(xkmModsDesc); 3578c9fbc29Smrg } 3588c9fbc29Smrg } 3598c9fbc29Smrg if (type->level_names!=NULL) { 3608c9fbc29Smrg names= type->level_names; 3618c9fbc29Smrg for (n=0;n<wire.nLevelNames;n++) { 3628c9fbc29Smrg size+= xkmPutCountedString(file,XkbAtomGetString(dpy,names[n])); 3638c9fbc29Smrg } 3648c9fbc29Smrg } 3658c9fbc29Smrg } 3668c9fbc29Smrg return size; 3678c9fbc29Smrg} 3688c9fbc29Smrg 3698c9fbc29Smrg/***====================================================================***/ 3708c9fbc29Smrg 3718c9fbc29Smrgstatic unsigned 3728c9fbc29SmrgSizeXKMCompatMap( XkbFileInfo * result, 3738c9fbc29Smrg XkmInfo * info, 3748c9fbc29Smrg xkmSectionInfo * toc, 3758c9fbc29Smrg int * offset_inout) 3768c9fbc29Smrg{ 3778c9fbc29SmrgXkbDescPtr xkb; 3788c9fbc29Smrgchar * name; 3798c9fbc29Smrgint size; 3808c9fbc29Smrgregister int i; 3818c9fbc29Smrgunsigned groups,nGroups; 3828c9fbc29SmrgDisplay * dpy; 3838c9fbc29Smrg 3848c9fbc29Smrg xkb= result->xkb; 3858c9fbc29Smrg dpy= xkb->dpy; 3868c9fbc29Smrg if ((!xkb)||(!xkb->compat)||(!xkb->compat->sym_interpret)) { 3878c9fbc29Smrg _XkbLibError(_XkbErrMissingCompatMap,"SizeXKMCompatMap",0); 3888c9fbc29Smrg return 0; 3898c9fbc29Smrg } 3908c9fbc29Smrg if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->compat); 3918c9fbc29Smrg else name= NULL; 3928c9fbc29Smrg 3938c9fbc29Smrg for (i=groups=nGroups=0;i<XkbNumKbdGroups;i++) { 3948c9fbc29Smrg if ((xkb->compat->groups[i].real_mods!=0)|| 3958c9fbc29Smrg (xkb->compat->groups[i].vmods!=0)) { 3968c9fbc29Smrg groups|= (1<<i); 3978c9fbc29Smrg nGroups++; 3988c9fbc29Smrg } 3998c9fbc29Smrg } 4008c9fbc29Smrg info->group_compat= groups; 4018c9fbc29Smrg info->num_group_compat= nGroups; 4028c9fbc29Smrg size= 4; /* room for num_si and group_compat mask */ 4038c9fbc29Smrg size+= xkmSizeCountedString(name); 4048c9fbc29Smrg size+= (SIZEOF(xkmSymInterpretDesc)*xkb->compat->num_si); 4058c9fbc29Smrg size+= (SIZEOF(xkmModsDesc)*nGroups); 4068c9fbc29Smrg toc->type= XkmCompatMapIndex; 4078c9fbc29Smrg toc->format= MSBFirst; 4088c9fbc29Smrg toc->size= size+SIZEOF(xkmSectionInfo); 4098c9fbc29Smrg toc->offset= (*offset_inout); 4108c9fbc29Smrg (*offset_inout)+= toc->size; 4118c9fbc29Smrg return 1; 4128c9fbc29Smrg} 4138c9fbc29Smrg 4148c9fbc29Smrgstatic unsigned 4158c9fbc29SmrgWriteXKMCompatMap(FILE *file,XkbFileInfo *result,XkmInfo *info) 4168c9fbc29Smrg{ 4178c9fbc29Smrgregister unsigned i; 4188c9fbc29Smrgchar * name; 4198c9fbc29SmrgXkbDescPtr xkb; 4208c9fbc29SmrgXkbSymInterpretPtr interp; 4218c9fbc29SmrgxkmSymInterpretDesc wire; 4228c9fbc29SmrgDisplay * dpy; 4238c9fbc29Smrgunsigned tmp,size=0; 4248c9fbc29Smrg 4258c9fbc29Smrg xkb= result->xkb; 4268c9fbc29Smrg dpy= xkb->dpy; 4278c9fbc29Smrg if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->compat); 4288c9fbc29Smrg else name= NULL; 4298c9fbc29Smrg size+= xkmPutCountedString(file,name); 4308c9fbc29Smrg size+= xkmPutCARD16(file,xkb->compat->num_si); 4318c9fbc29Smrg size+= xkmPutCARD8(file,info->group_compat); 4328c9fbc29Smrg size+= xkmPutPadding(file,1); 4338c9fbc29Smrg interp= xkb->compat->sym_interpret; 4348c9fbc29Smrg for (i=0;i<xkb->compat->num_si;i++,interp++) { 4358c9fbc29Smrg wire.sym= interp->sym; 4368c9fbc29Smrg wire.mods= interp->mods; 4378c9fbc29Smrg wire.match= interp->match; 4388c9fbc29Smrg wire.virtualMod= interp->virtual_mod; 4398c9fbc29Smrg wire.flags= interp->flags; 4408c9fbc29Smrg wire.actionType= interp->act.type; 4418c9fbc29Smrg wire.actionData[0]= interp->act.data[0]; 4428c9fbc29Smrg wire.actionData[1]= interp->act.data[1]; 4438c9fbc29Smrg wire.actionData[2]= interp->act.data[2]; 4448c9fbc29Smrg wire.actionData[3]= interp->act.data[3]; 4458c9fbc29Smrg wire.actionData[4]= interp->act.data[4]; 4468c9fbc29Smrg wire.actionData[5]= interp->act.data[5]; 4478c9fbc29Smrg wire.actionData[6]= interp->act.data[6]; 4488c9fbc29Smrg tmp= fwrite(&wire,SIZEOF(xkmSymInterpretDesc),1,file); 4498c9fbc29Smrg size+= tmp*SIZEOF(xkmSymInterpretDesc); 4508c9fbc29Smrg } 4518c9fbc29Smrg if (info->group_compat) { 4528c9fbc29Smrg register unsigned bit; 4538c9fbc29Smrg xkmModsDesc modsWire; 4548c9fbc29Smrg for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 4558c9fbc29Smrg if (info->group_compat&bit) { 4568c9fbc29Smrg modsWire.realMods= xkb->compat->groups[i].real_mods; 4578c9fbc29Smrg modsWire.virtualMods= xkb->compat->groups[i].vmods; 4588c9fbc29Smrg fwrite(&modsWire,SIZEOF(xkmModsDesc),1,file); 4598c9fbc29Smrg size+= SIZEOF(xkmModsDesc); 4608c9fbc29Smrg } 4618c9fbc29Smrg } 4628c9fbc29Smrg } 4638c9fbc29Smrg return size; 4648c9fbc29Smrg} 4658c9fbc29Smrg 4668c9fbc29Smrg/***====================================================================***/ 4678c9fbc29Smrg 4688c9fbc29Smrgstatic unsigned 4698c9fbc29SmrgSizeXKMSymbols( XkbFileInfo * result, 4708c9fbc29Smrg XkmInfo * info, 4718c9fbc29Smrg xkmSectionInfo * toc, 4728c9fbc29Smrg int * offset_inout) 4738c9fbc29Smrg{ 4748c9fbc29SmrgDisplay * dpy; 4758c9fbc29SmrgXkbDescPtr xkb; 4768c9fbc29Smrgunsigned size; 4778c9fbc29Smrgregister int i,nSyms; 4788c9fbc29Smrgchar * name; 4798c9fbc29Smrg 4808c9fbc29Smrg xkb= result->xkb; 4818c9fbc29Smrg dpy= xkb->dpy; 4828c9fbc29Smrg if ((!xkb)||(!xkb->map)||((!xkb->map->syms))) { 4838c9fbc29Smrg _XkbLibError(_XkbErrMissingSymbols,"SizeXKMSymbols",0); 4848c9fbc29Smrg return 0; 4858c9fbc29Smrg } 4868c9fbc29Smrg if (xkb->names && (xkb->names->symbols!=None)) 4878c9fbc29Smrg name= XkbAtomGetString(dpy,xkb->names->symbols); 4888c9fbc29Smrg else name= NULL; 4898c9fbc29Smrg size= xkmSizeCountedString(name); 4908c9fbc29Smrg size+= 4; /* min and max keycode, group names mask */ 4918c9fbc29Smrg for (i=0;i<XkbNumKbdGroups;i++) { 4928c9fbc29Smrg if (xkb->names->groups[i]!=None) 4938c9fbc29Smrg size+= xkmSizeCountedAtomString(dpy,xkb->names->groups[i]); 4948c9fbc29Smrg } 4958c9fbc29Smrg info->total_vmodmaps= 0; 4968c9fbc29Smrg for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { 4978c9fbc29Smrg nSyms= XkbKeyNumSyms(xkb,i); 4988c9fbc29Smrg size+= SIZEOF(xkmKeySymMapDesc)+(nSyms*4); 4998c9fbc29Smrg if (xkb->server) { 5008c9fbc29Smrg if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) { 5018c9fbc29Smrg register int g; 5028c9fbc29Smrg for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) { 5038c9fbc29Smrg if (xkb->server->explicit[i]&(1<<g)) { 5048c9fbc29Smrg XkbKeyTypePtr type; 5058c9fbc29Smrg char * name; 5068c9fbc29Smrg type= XkbKeyKeyType(xkb,i,g); 5078c9fbc29Smrg name= XkbAtomGetString(dpy,type->name); 5088c9fbc29Smrg if (name!=NULL) 5098c9fbc29Smrg size+= xkmSizeCountedString(name); 5108c9fbc29Smrg } 5118c9fbc29Smrg } 5128c9fbc29Smrg } 5138c9fbc29Smrg if (XkbKeyHasActions(xkb,i)) 5148c9fbc29Smrg size+= nSyms*SIZEOF(xkmActionDesc); 5158c9fbc29Smrg if (xkb->server->behaviors[i].type!=XkbKB_Default) 5168c9fbc29Smrg size+= SIZEOF(xkmBehaviorDesc); 5178c9fbc29Smrg if (xkb->server->vmodmap && (xkb->server->vmodmap[i]!=0)) 5188c9fbc29Smrg info->total_vmodmaps++; 5198c9fbc29Smrg } 5208c9fbc29Smrg } 5218c9fbc29Smrg size+= info->total_vmodmaps*SIZEOF(xkmVModMapDesc); 5228c9fbc29Smrg toc->type= XkmSymbolsIndex; 5238c9fbc29Smrg toc->format= MSBFirst; 5248c9fbc29Smrg toc->size= size+SIZEOF(xkmSectionInfo); 5258c9fbc29Smrg toc->offset= (*offset_inout); 5268c9fbc29Smrg (*offset_inout)+= toc->size; 5278c9fbc29Smrg return 1; 5288c9fbc29Smrg} 5298c9fbc29Smrg 5308c9fbc29Smrgstatic unsigned 5318c9fbc29SmrgWriteXKMSymbols(FILE *file,XkbFileInfo *result,XkmInfo *info) 5328c9fbc29Smrg{ 5338c9fbc29SmrgDisplay * dpy; 5348c9fbc29SmrgXkbDescPtr xkb; 5358c9fbc29Smrgregister int i,n; 5368c9fbc29SmrgxkmKeySymMapDesc wireMap; 5378c9fbc29Smrgchar * name; 5388c9fbc29Smrgunsigned tmp,size= 0; 5398c9fbc29Smrg 5408c9fbc29Smrg xkb= result->xkb; 5418c9fbc29Smrg dpy= xkb->dpy; 5428c9fbc29Smrg if (xkb->names && (xkb->names->symbols!=None)) 5438c9fbc29Smrg name= XkbAtomGetString(dpy,xkb->names->symbols); 5448c9fbc29Smrg else name= NULL; 5458c9fbc29Smrg size+= xkmPutCountedString(file,name); 5468c9fbc29Smrg for (tmp=i=0;i<XkbNumKbdGroups;i++) { 5478c9fbc29Smrg if (xkb->names->groups[i]!=None) 5488c9fbc29Smrg tmp|= (1<<i); 5498c9fbc29Smrg } 5508c9fbc29Smrg size+= xkmPutCARD8(file,xkb->min_key_code); 5518c9fbc29Smrg size+= xkmPutCARD8(file,xkb->max_key_code); 5528c9fbc29Smrg size+= xkmPutCARD8(file,tmp); 5538c9fbc29Smrg size+= xkmPutCARD8(file,info->total_vmodmaps); 5548c9fbc29Smrg for (i=0,n=1;i<XkbNumKbdGroups;i++,n<<=1) { 5558c9fbc29Smrg if ((tmp&n)==0) 5568c9fbc29Smrg continue; 5578c9fbc29Smrg size+= xkmPutCountedAtomString(dpy,file,xkb->names->groups[i]); 5588c9fbc29Smrg } 5598c9fbc29Smrg for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { 5608c9fbc29Smrg char *typeName[XkbNumKbdGroups]; 5618c9fbc29Smrg wireMap.width= XkbKeyGroupsWidth(xkb,i); 5628c9fbc29Smrg wireMap.num_groups= XkbKeyGroupInfo(xkb,i); 5638c9fbc29Smrg if (xkb->map && xkb->map->modmap) 5648c9fbc29Smrg wireMap.modifier_map= xkb->map->modmap[i]; 5658c9fbc29Smrg else wireMap.modifier_map= 0; 5668c9fbc29Smrg wireMap.flags= 0; 5678c9fbc29Smrg bzero((char *)typeName,XkbNumKbdGroups*sizeof(char *)); 5688c9fbc29Smrg if (xkb->server) { 5698c9fbc29Smrg if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) { 5708c9fbc29Smrg register int g; 5718c9fbc29Smrg for (g=0;g<XkbKeyNumGroups(xkb,i);g++) { 5728c9fbc29Smrg if (xkb->server->explicit[i]&(1<<g)) { 5738c9fbc29Smrg XkbKeyTypePtr type; 5748c9fbc29Smrg type= XkbKeyKeyType(xkb,i,g); 5758c9fbc29Smrg typeName[g]= XkbAtomGetString(dpy,type->name); 5768c9fbc29Smrg if (typeName[g]!=NULL) 5778c9fbc29Smrg wireMap.flags|= (1<<g); 5788c9fbc29Smrg } 5798c9fbc29Smrg } 5808c9fbc29Smrg } 5818c9fbc29Smrg if (XkbKeyHasActions(xkb,i)) 5828c9fbc29Smrg wireMap.flags|= XkmKeyHasActions; 5838c9fbc29Smrg if (xkb->server->behaviors[i].type!=XkbKB_Default) 5848c9fbc29Smrg wireMap.flags|= XkmKeyHasBehavior; 5858c9fbc29Smrg if ((xkb->server->explicit[i]&XkbExplicitAutoRepeatMask)&& 5868c9fbc29Smrg (xkb->ctrls!=NULL)) { 5878c9fbc29Smrg if (xkb->ctrls->per_key_repeat[(i/8)]&(1<<(i%8))) 5888c9fbc29Smrg wireMap.flags|= XkmRepeatingKey; 5898c9fbc29Smrg else wireMap.flags|= XkmNonRepeatingKey; 5908c9fbc29Smrg } 5918c9fbc29Smrg } 5928c9fbc29Smrg tmp= fwrite(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file); 5938c9fbc29Smrg size+= tmp*SIZEOF(xkmKeySymMapDesc); 5948c9fbc29Smrg if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) { 5958c9fbc29Smrg register int g; 5968c9fbc29Smrg for (g=0;g<XkbNumKbdGroups;g++) { 5978c9fbc29Smrg if (typeName[g]!=NULL) 5988c9fbc29Smrg size+= xkmPutCountedString(file,typeName[g]); 5998c9fbc29Smrg } 6008c9fbc29Smrg } 6018c9fbc29Smrg if (XkbNumGroups(wireMap.num_groups)>0) { 6028c9fbc29Smrg KeySym *sym; 6038c9fbc29Smrg sym= XkbKeySymsPtr(xkb,i); 6048c9fbc29Smrg for (n=XkbKeyNumSyms(xkb,i);n>0;n--,sym++) { 6058c9fbc29Smrg size+= xkmPutCARD32(file,(CARD32)*sym); 6068c9fbc29Smrg } 6078c9fbc29Smrg if (wireMap.flags&XkmKeyHasActions) { 6088c9fbc29Smrg XkbAction * act; 6098c9fbc29Smrg act= XkbKeyActionsPtr(xkb,i); 6108c9fbc29Smrg for (n=XkbKeyNumActions(xkb,i);n>0;n--,act++) { 6118c9fbc29Smrg tmp= fwrite(act,SIZEOF(xkmActionDesc),1,file); 6128c9fbc29Smrg size+= tmp*SIZEOF(xkmActionDesc); 6138c9fbc29Smrg } 6148c9fbc29Smrg } 6158c9fbc29Smrg } 6168c9fbc29Smrg if (wireMap.flags&XkmKeyHasBehavior) { 6178c9fbc29Smrg xkmBehaviorDesc b; 6188c9fbc29Smrg b.type= xkb->server->behaviors[i].type; 6198c9fbc29Smrg b.data= xkb->server->behaviors[i].data; 6208c9fbc29Smrg tmp= fwrite(&b,SIZEOF(xkmBehaviorDesc),1,file); 6218c9fbc29Smrg size+= tmp*SIZEOF(xkmBehaviorDesc); 6228c9fbc29Smrg } 6238c9fbc29Smrg } 6248c9fbc29Smrg if (info->total_vmodmaps>0) { 6258c9fbc29Smrg xkmVModMapDesc v; 6268c9fbc29Smrg for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 6278c9fbc29Smrg if (xkb->server->vmodmap[i]!=0) { 6288c9fbc29Smrg v.key= i; 6298c9fbc29Smrg v.vmods= xkb->server->vmodmap[i]; 6308c9fbc29Smrg tmp= fwrite(&v,SIZEOF(xkmVModMapDesc),1,file); 6318c9fbc29Smrg size+= tmp*SIZEOF(xkmVModMapDesc); 6328c9fbc29Smrg } 6338c9fbc29Smrg } 6348c9fbc29Smrg } 6358c9fbc29Smrg return size; 6368c9fbc29Smrg} 6378c9fbc29Smrg 6388c9fbc29Smrg/***====================================================================***/ 6398c9fbc29Smrg 6408c9fbc29Smrgstatic unsigned 6418c9fbc29SmrgSizeXKMIndicators(XkbFileInfo *result,XkmInfo *info,xkmSectionInfo *toc, 6428c9fbc29Smrg int *offset_inout) 6438c9fbc29Smrg{ 6448c9fbc29SmrgDisplay * dpy; 6458c9fbc29SmrgXkbDescPtr xkb; 6468c9fbc29Smrgunsigned size; 6478c9fbc29Smrgregister unsigned i,nLEDs; 6488c9fbc29Smrg 6498c9fbc29Smrg xkb= result->xkb; 6508c9fbc29Smrg dpy= xkb->dpy; 6518c9fbc29Smrg if ((xkb==NULL)||(xkb->indicators==NULL)) { 6528c9fbc29Smrg/* _XkbLibError(_XkbErrMissingIndicators,"SizeXKMIndicators",0);*/ 6538c9fbc29Smrg return 0; 6548c9fbc29Smrg } 6558c9fbc29Smrg nLEDs=0; 6568c9fbc29Smrg size= 8; /* number of indicator maps/physical indicators */ 6578c9fbc29Smrg if (xkb->indicators!=NULL) { 6588c9fbc29Smrg for (i=0;i<XkbNumIndicators;i++) { 6598c9fbc29Smrg XkbIndicatorMapPtr map= &xkb->indicators->maps[i]; 6608c9fbc29Smrg if ((map->flags!=0)||(map->which_groups!=0)||(map->groups!=0)|| 6618c9fbc29Smrg (map->which_mods!=0)|| 6628c9fbc29Smrg (map->mods.real_mods!=0)||(map->mods.vmods!=0)|| 6634cd6a3aeSmrg (map->ctrls!=0) || 6648c9fbc29Smrg (xkb->names && (xkb->names->indicators[i]!=None))) { 6658c9fbc29Smrg char *name; 6668c9fbc29Smrg if (xkb->names && xkb->names->indicators[i]!=None) { 6678c9fbc29Smrg name= XkbAtomGetString(dpy,xkb->names->indicators[i]); 6688c9fbc29Smrg } 6698c9fbc29Smrg else name= NULL; 6708c9fbc29Smrg size+= xkmSizeCountedString(name); 6718c9fbc29Smrg size+= SIZEOF(xkmIndicatorMapDesc); 6728c9fbc29Smrg nLEDs++; 6738c9fbc29Smrg } 6748c9fbc29Smrg } 6758c9fbc29Smrg } 6768c9fbc29Smrg info->num_leds= nLEDs; 6778c9fbc29Smrg toc->type= XkmIndicatorsIndex; 6788c9fbc29Smrg toc->format= MSBFirst; 6798c9fbc29Smrg toc->size= size+SIZEOF(xkmSectionInfo); 6808c9fbc29Smrg toc->offset= (*offset_inout); 6818c9fbc29Smrg (*offset_inout)+= toc->size; 6828c9fbc29Smrg return 1; 6838c9fbc29Smrg} 6848c9fbc29Smrg 6858c9fbc29Smrgstatic unsigned 6868c9fbc29SmrgWriteXKMIndicators(FILE *file,XkbFileInfo *result,XkmInfo *info) 6878c9fbc29Smrg{ 6888c9fbc29SmrgDisplay * dpy; 6898c9fbc29SmrgXkbDescPtr xkb; 6908c9fbc29Smrgregister unsigned i; 6918c9fbc29SmrgxkmIndicatorMapDesc wire; 6928c9fbc29Smrgunsigned tmp,size= 0; 6938c9fbc29Smrg 6948c9fbc29Smrg xkb= result->xkb; 6958c9fbc29Smrg dpy= xkb->dpy; 6968c9fbc29Smrg size+= xkmPutCARD8(file,info->num_leds); 6978c9fbc29Smrg size+= xkmPutPadding(file,3); 6988c9fbc29Smrg size+= xkmPutCARD32(file,xkb->indicators->phys_indicators); 6998c9fbc29Smrg if (xkb->indicators!=NULL) { 7008c9fbc29Smrg for (i=0;i<XkbNumIndicators;i++) { 7018c9fbc29Smrg XkbIndicatorMapPtr map= &xkb->indicators->maps[i]; 7028c9fbc29Smrg if ((map->flags!=0)||(map->which_groups!=0)||(map->groups!=0)|| 7038c9fbc29Smrg (map->which_mods!=0)|| 7048c9fbc29Smrg (map->mods.real_mods!=0)||(map->mods.vmods!=0)|| 7058c9fbc29Smrg (map->ctrls!=0) || 7068c9fbc29Smrg (xkb->names && (xkb->names->indicators[i]!=None))) { 7078c9fbc29Smrg char *name; 7088c9fbc29Smrg if (xkb->names && xkb->names->indicators[i]!=None) { 7098c9fbc29Smrg name= XkbAtomGetString(dpy,xkb->names->indicators[i]); 7108c9fbc29Smrg } 7118c9fbc29Smrg else name= NULL; 7128c9fbc29Smrg size+= xkmPutCountedString(file,name); 7138c9fbc29Smrg wire.indicator= i+1; 7148c9fbc29Smrg wire.flags= map->flags; 7158c9fbc29Smrg wire.which_mods= map->which_mods; 7168c9fbc29Smrg wire.real_mods= map->mods.real_mods; 7178c9fbc29Smrg wire.vmods= map->mods.vmods; 7188c9fbc29Smrg wire.which_groups= map->which_groups; 7198c9fbc29Smrg wire.groups= map->groups; 7208c9fbc29Smrg wire.ctrls= map->ctrls; 7218c9fbc29Smrg tmp= fwrite(&wire,SIZEOF(xkmIndicatorMapDesc),1,file); 7228c9fbc29Smrg size+= tmp*SIZEOF(xkmIndicatorMapDesc); 7238c9fbc29Smrg } 7248c9fbc29Smrg } 7258c9fbc29Smrg } 7268c9fbc29Smrg return size; 7278c9fbc29Smrg} 7288c9fbc29Smrg 7298c9fbc29Smrg/***====================================================================***/ 7308c9fbc29Smrg 7318c9fbc29Smrgstatic unsigned 7328c9fbc29SmrgSizeXKMGeomDoodad(XkbFileInfo *result,XkbDoodadPtr doodad) 7338c9fbc29Smrg{ 7348c9fbc29Smrgunsigned size; 7358c9fbc29Smrg 7368c9fbc29Smrg size= SIZEOF(xkmAnyDoodadDesc); 7378c9fbc29Smrg size+= xkmSizeCountedAtomString(result->xkb->dpy,doodad->any.name); 7388c9fbc29Smrg if (doodad->any.type==XkbTextDoodad) { 7398c9fbc29Smrg size+= xkmSizeCountedString(doodad->text.text); 7408c9fbc29Smrg size+= xkmSizeCountedString(doodad->text.font); 7418c9fbc29Smrg } 7428c9fbc29Smrg else if (doodad->any.type==XkbLogoDoodad) { 7438c9fbc29Smrg size+= xkmSizeCountedString(doodad->logo.logo_name); 7448c9fbc29Smrg } 7458c9fbc29Smrg return size; 7468c9fbc29Smrg} 7478c9fbc29Smrg 7488c9fbc29Smrgstatic unsigned 7498c9fbc29SmrgSizeXKMGeomSection(XkbFileInfo *result,XkbSectionPtr section) 7508c9fbc29Smrg{ 7518c9fbc29Smrgregister int i; 7528c9fbc29Smrgunsigned size; 7538c9fbc29Smrg 7548c9fbc29Smrg size= SIZEOF(xkmSectionDesc); 7558c9fbc29Smrg size+= xkmSizeCountedAtomString(result->xkb->dpy,section->name); 7568c9fbc29Smrg if (section->rows) { 7578c9fbc29Smrg XkbRowPtr row; 7588c9fbc29Smrg for (row=section->rows,i=0;i<section->num_rows;i++,row++) { 7598c9fbc29Smrg size+= SIZEOF(xkmRowDesc); 7608c9fbc29Smrg size+= row->num_keys*SIZEOF(xkmKeyDesc); 7618c9fbc29Smrg } 7628c9fbc29Smrg } 7638c9fbc29Smrg if (section->doodads) { 7648c9fbc29Smrg XkbDoodadPtr doodad; 7658c9fbc29Smrg for (doodad=section->doodads,i=0;i<section->num_doodads;i++,doodad++) { 7668c9fbc29Smrg size+= SizeXKMGeomDoodad(result,doodad); 7678c9fbc29Smrg } 7688c9fbc29Smrg } 7698c9fbc29Smrg if (section->overlays) { 7708c9fbc29Smrg XkbOverlayPtr ol; 7718c9fbc29Smrg for (ol=section->overlays,i=0;i<section->num_overlays;i++,ol++) { 7728c9fbc29Smrg register int r; 7738c9fbc29Smrg XkbOverlayRowPtr row; 7748c9fbc29Smrg size+= xkmSizeCountedAtomString(result->xkb->dpy,ol->name); 7758c9fbc29Smrg size+= SIZEOF(xkmOverlayDesc); 7768c9fbc29Smrg for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { 7778c9fbc29Smrg size+= SIZEOF(xkmOverlayRowDesc); 7788c9fbc29Smrg size+= row->num_keys*SIZEOF(xkmOverlayKeyDesc); 7798c9fbc29Smrg } 7808c9fbc29Smrg } 7818c9fbc29Smrg } 7828c9fbc29Smrg return size; 7838c9fbc29Smrg} 7848c9fbc29Smrg 7858c9fbc29Smrgstatic unsigned 7868c9fbc29SmrgSizeXKMGeometry(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout) 7878c9fbc29Smrg{ 7888c9fbc29Smrgregister int i; 7898c9fbc29SmrgDisplay * dpy; 7908c9fbc29SmrgXkbDescPtr xkb; 7918c9fbc29SmrgXkbGeometryPtr geom; 7928c9fbc29Smrgunsigned size; 7938c9fbc29Smrg 7948c9fbc29Smrg xkb= result->xkb; 7958c9fbc29Smrg dpy= xkb->dpy; 7968c9fbc29Smrg if ((!xkb)||(!xkb->geom)) 7978c9fbc29Smrg return 0; 7988c9fbc29Smrg geom= xkb->geom; 7998c9fbc29Smrg size= xkmSizeCountedAtomString(dpy,geom->name); 8008c9fbc29Smrg size+= SIZEOF(xkmGeometryDesc); 8018c9fbc29Smrg size+= xkmSizeCountedString(geom->label_font); 8028c9fbc29Smrg if (geom->properties) { 8038c9fbc29Smrg XkbPropertyPtr prop; 8048c9fbc29Smrg for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { 8058c9fbc29Smrg size+= xkmSizeCountedString(prop->name); 8068c9fbc29Smrg size+= xkmSizeCountedString(prop->value); 8078c9fbc29Smrg } 8088c9fbc29Smrg } 8098c9fbc29Smrg if (geom->colors) { 8108c9fbc29Smrg XkbColorPtr color; 8118c9fbc29Smrg for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) { 8128c9fbc29Smrg size+= xkmSizeCountedString(color->spec); 8138c9fbc29Smrg } 8148c9fbc29Smrg } 8158c9fbc29Smrg if (geom->shapes) { 8168c9fbc29Smrg XkbShapePtr shape; 8178c9fbc29Smrg for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { 8188c9fbc29Smrg register int n; 8198c9fbc29Smrg register XkbOutlinePtr ol; 8208c9fbc29Smrg size+= xkmSizeCountedAtomString(dpy,shape->name); 8218c9fbc29Smrg size+= SIZEOF(xkmShapeDesc); 8228c9fbc29Smrg for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) { 8238c9fbc29Smrg size+= SIZEOF(xkmOutlineDesc); 8248c9fbc29Smrg size+= ol->num_points*SIZEOF(xkmPointDesc); 8258c9fbc29Smrg } 8268c9fbc29Smrg } 8278c9fbc29Smrg } 8288c9fbc29Smrg if (geom->sections) { 8298c9fbc29Smrg XkbSectionPtr section; 8308c9fbc29Smrg for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { 8318c9fbc29Smrg size+= SizeXKMGeomSection(result,section); 8328c9fbc29Smrg } 8338c9fbc29Smrg } 8348c9fbc29Smrg if (geom->doodads) { 8358c9fbc29Smrg XkbDoodadPtr doodad; 8368c9fbc29Smrg for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) { 8378c9fbc29Smrg size+= SizeXKMGeomDoodad(result,doodad); 8388c9fbc29Smrg } 8398c9fbc29Smrg } 8408c9fbc29Smrg if (geom->key_aliases) { 8418c9fbc29Smrg size+= geom->num_key_aliases*(XkbKeyNameLength*2); 8428c9fbc29Smrg } 8438c9fbc29Smrg toc->type= XkmGeometryIndex; 8448c9fbc29Smrg toc->format= MSBFirst; 8458c9fbc29Smrg toc->size= size+SIZEOF(xkmSectionInfo); 8468c9fbc29Smrg toc->offset= (*offset_inout); 8478c9fbc29Smrg (*offset_inout)+= toc->size; 8488c9fbc29Smrg return 1; 8498c9fbc29Smrg} 8508c9fbc29Smrg 8518c9fbc29Smrgstatic unsigned 8528c9fbc29SmrgWriteXKMGeomDoodad(FILE *file,XkbFileInfo *result,XkbDoodadPtr doodad) 8538c9fbc29Smrg{ 8548c9fbc29SmrgDisplay * dpy; 8558c9fbc29SmrgXkbDescPtr xkb; 8568c9fbc29SmrgxkmDoodadDesc doodadWire; 8578c9fbc29Smrgunsigned tmp,size= 0; 8588c9fbc29Smrg 8598c9fbc29Smrg xkb= result->xkb; 8608c9fbc29Smrg dpy= xkb->dpy; 8618c9fbc29Smrg bzero((char *)&doodadWire,sizeof(doodadWire)); 8628c9fbc29Smrg doodadWire.any.type= doodad->any.type; 8638c9fbc29Smrg doodadWire.any.priority= doodad->any.priority; 8648c9fbc29Smrg doodadWire.any.top= doodad->any.top; 8658c9fbc29Smrg doodadWire.any.left= doodad->any.left; 8668c9fbc29Smrg switch (doodad->any.type) { 8678c9fbc29Smrg case XkbOutlineDoodad: 8688c9fbc29Smrg case XkbSolidDoodad: 8698c9fbc29Smrg doodadWire.shape.angle= doodad->shape.angle; 8708c9fbc29Smrg doodadWire.shape.color_ndx= doodad->shape.color_ndx; 8718c9fbc29Smrg doodadWire.shape.shape_ndx= doodad->shape.shape_ndx; 8728c9fbc29Smrg break; 8738c9fbc29Smrg case XkbTextDoodad: 8748c9fbc29Smrg doodadWire.text.angle= doodad->text.angle; 8758c9fbc29Smrg doodadWire.text.width= doodad->text.width; 8768c9fbc29Smrg doodadWire.text.height= doodad->text.height; 8778c9fbc29Smrg doodadWire.text.color_ndx= doodad->text.color_ndx; 8788c9fbc29Smrg break; 8798c9fbc29Smrg case XkbIndicatorDoodad: 8808c9fbc29Smrg doodadWire.indicator.shape_ndx= doodad->indicator.shape_ndx; 8818c9fbc29Smrg doodadWire.indicator.on_color_ndx= doodad->indicator.on_color_ndx; 8828c9fbc29Smrg doodadWire.indicator.off_color_ndx= doodad->indicator.off_color_ndx; 8838c9fbc29Smrg break; 8848c9fbc29Smrg case XkbLogoDoodad: 8858c9fbc29Smrg doodadWire.logo.angle= doodad->logo.angle; 8868c9fbc29Smrg doodadWire.logo.color_ndx= doodad->logo.color_ndx; 8878c9fbc29Smrg doodadWire.logo.shape_ndx= doodad->logo.shape_ndx; 8888c9fbc29Smrg break; 8898c9fbc29Smrg default: 8908c9fbc29Smrg _XkbLibError(_XkbErrIllegalDoodad,"WriteXKMGeomDoodad", 8918c9fbc29Smrg doodad->any.type); 8928c9fbc29Smrg return 0; 8938c9fbc29Smrg } 8948c9fbc29Smrg size+= xkmPutCountedAtomString(dpy,file,doodad->any.name); 8958c9fbc29Smrg tmp= fwrite(&doodadWire,SIZEOF(xkmDoodadDesc),1,file); 8968c9fbc29Smrg size+= tmp*SIZEOF(xkmDoodadDesc); 8978c9fbc29Smrg if (doodad->any.type==XkbTextDoodad) { 8988c9fbc29Smrg size+= xkmPutCountedString(file,doodad->text.text); 8998c9fbc29Smrg size+= xkmPutCountedString(file,doodad->text.font); 9008c9fbc29Smrg } 9018c9fbc29Smrg else if (doodad->any.type==XkbLogoDoodad) { 9028c9fbc29Smrg size+= xkmPutCountedString(file,doodad->logo.logo_name); 9038c9fbc29Smrg } 9048c9fbc29Smrg return size; 9058c9fbc29Smrg} 9068c9fbc29Smrg 9078c9fbc29Smrgstatic unsigned 9088c9fbc29SmrgWriteXKMGeomOverlay(FILE *file,XkbFileInfo *result,XkbOverlayPtr ol) 9098c9fbc29Smrg{ 9108c9fbc29Smrgregister int r,k; 9118c9fbc29SmrgDisplay * dpy; 9128c9fbc29SmrgXkbDescPtr xkb; 9138c9fbc29SmrgXkbOverlayRowPtr row; 9148c9fbc29SmrgxkmOverlayDesc olWire; 9158c9fbc29SmrgxkmOverlayRowDesc rowWire; 9168c9fbc29SmrgxkmOverlayKeyDesc keyWire; 9178c9fbc29Smrgunsigned tmp,size= 0; 9188c9fbc29Smrg 9198c9fbc29Smrg xkb= result->xkb; 9208c9fbc29Smrg dpy= xkb->dpy; 9218c9fbc29Smrg bzero((char *)&olWire,sizeof(olWire)); 9228c9fbc29Smrg bzero((char *)&rowWire,sizeof(rowWire)); 9238c9fbc29Smrg bzero((char *)&keyWire,sizeof(keyWire)); 9248c9fbc29Smrg size+= xkmPutCountedAtomString(dpy,file,ol->name); 9258c9fbc29Smrg olWire.num_rows= ol->num_rows; 9268c9fbc29Smrg tmp= fwrite(&olWire,SIZEOF(xkmOverlayDesc),1,file); 9278c9fbc29Smrg size+= tmp*SIZEOF(xkmOverlayDesc); 9288c9fbc29Smrg for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { 9298c9fbc29Smrg XkbOverlayKeyPtr key; 9308c9fbc29Smrg rowWire.row_under= row->row_under; 9318c9fbc29Smrg rowWire.num_keys= row->num_keys; 9328c9fbc29Smrg tmp= fwrite(&rowWire,SIZEOF(xkmOverlayRowDesc),1,file); 9338c9fbc29Smrg size+= tmp*SIZEOF(xkmOverlayRowDesc); 9348c9fbc29Smrg for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 9358c9fbc29Smrg memcpy(keyWire.over,key->over.name,XkbKeyNameLength); 9368c9fbc29Smrg memcpy(keyWire.under,key->under.name,XkbKeyNameLength); 9378c9fbc29Smrg tmp= fwrite(&keyWire,SIZEOF(xkmOverlayKeyDesc),1,file); 9388c9fbc29Smrg size+= tmp*SIZEOF(xkmOverlayKeyDesc); 9398c9fbc29Smrg } 9408c9fbc29Smrg } 9414cd6a3aeSmrg return size; 9428c9fbc29Smrg} 9438c9fbc29Smrg 9448c9fbc29Smrgstatic unsigned 9458c9fbc29SmrgWriteXKMGeomSection(FILE *file,XkbFileInfo *result,XkbSectionPtr section) 9468c9fbc29Smrg{ 9478c9fbc29Smrgregister int i; 9488c9fbc29SmrgDisplay * dpy; 9498c9fbc29SmrgXkbDescPtr xkb; 9508c9fbc29SmrgxkmSectionDesc sectionWire; 9518c9fbc29Smrgunsigned tmp,size= 0; 9528c9fbc29Smrg 9538c9fbc29Smrg xkb= result->xkb; 9548c9fbc29Smrg dpy= xkb->dpy; 9558c9fbc29Smrg size+= xkmPutCountedAtomString(dpy,file,section->name); 9568c9fbc29Smrg sectionWire.top= section->top; 9578c9fbc29Smrg sectionWire.left= section->left; 9588c9fbc29Smrg sectionWire.width= section->width; 9598c9fbc29Smrg sectionWire.height= section->height; 9608c9fbc29Smrg sectionWire.angle= section->angle; 9618c9fbc29Smrg sectionWire.priority= section->priority; 9628c9fbc29Smrg sectionWire.num_rows= section->num_rows; 9638c9fbc29Smrg sectionWire.num_doodads= section->num_doodads; 9648c9fbc29Smrg sectionWire.num_overlays= section->num_overlays; 9658c9fbc29Smrg tmp= fwrite(§ionWire,SIZEOF(xkmSectionDesc),1,file); 9668c9fbc29Smrg size+= tmp*SIZEOF(xkmSectionDesc); 9678c9fbc29Smrg if (section->rows) { 9688c9fbc29Smrg register unsigned k; 9698c9fbc29Smrg XkbRowPtr row; 9708c9fbc29Smrg xkmRowDesc rowWire; 9718c9fbc29Smrg XkbKeyPtr key; 9728c9fbc29Smrg xkmKeyDesc keyWire; 9738c9fbc29Smrg for (i=0,row=section->rows;i<section->num_rows;i++,row++) { 9748c9fbc29Smrg rowWire.top= row->top; 9758c9fbc29Smrg rowWire.left= row->left; 9768c9fbc29Smrg rowWire.num_keys= row->num_keys; 9778c9fbc29Smrg rowWire.vertical= row->vertical; 9788c9fbc29Smrg tmp= fwrite(&rowWire,SIZEOF(xkmRowDesc),1,file); 9798c9fbc29Smrg size+= tmp*SIZEOF(xkmRowDesc); 9808c9fbc29Smrg for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 9818c9fbc29Smrg memcpy(keyWire.name,key->name.name,XkbKeyNameLength); 9828c9fbc29Smrg keyWire.gap= key->gap; 9838c9fbc29Smrg keyWire.shape_ndx= key->shape_ndx; 9848c9fbc29Smrg keyWire.color_ndx= key->color_ndx; 9858c9fbc29Smrg tmp= fwrite(&keyWire,SIZEOF(xkmKeyDesc),1,file); 9868c9fbc29Smrg size+= tmp*SIZEOF(xkmKeyDesc); 9878c9fbc29Smrg } 9888c9fbc29Smrg } 9898c9fbc29Smrg } 9908c9fbc29Smrg if (section->doodads) { 9918c9fbc29Smrg XkbDoodadPtr doodad; 9928c9fbc29Smrg for (i=0,doodad=section->doodads;i<section->num_doodads;i++,doodad++) { 9938c9fbc29Smrg size+= WriteXKMGeomDoodad(file,result,doodad); 9948c9fbc29Smrg } 9958c9fbc29Smrg } 9968c9fbc29Smrg if (section->overlays) { 9978c9fbc29Smrg XkbOverlayPtr ol; 9988c9fbc29Smrg for (i=0,ol=section->overlays;i<section->num_overlays;i++,ol++) { 9998c9fbc29Smrg size+= WriteXKMGeomOverlay(file,result,ol); 10008c9fbc29Smrg } 10018c9fbc29Smrg } 10028c9fbc29Smrg return size; 10038c9fbc29Smrg} 10048c9fbc29Smrg 10058c9fbc29Smrgstatic unsigned 10068c9fbc29SmrgWriteXKMGeometry(FILE *file,XkbFileInfo *result) 10078c9fbc29Smrg{ 10088c9fbc29Smrgregister int i; 10098c9fbc29SmrgDisplay * dpy; 10108c9fbc29SmrgXkbDescPtr xkb; 10118c9fbc29SmrgXkbGeometryPtr geom; 10128c9fbc29SmrgxkmGeometryDesc wire; 10138c9fbc29Smrgunsigned tmp,size= 0; 10148c9fbc29Smrg 10158c9fbc29Smrg xkb= result->xkb; 10168c9fbc29Smrg dpy= xkb->dpy; 10178c9fbc29Smrg if ((!xkb)||(!xkb->geom)) 10188c9fbc29Smrg return 0; 10198c9fbc29Smrg geom= xkb->geom; 10208c9fbc29Smrg wire.width_mm= geom->width_mm; 10218c9fbc29Smrg wire.height_mm= geom->height_mm; 10228c9fbc29Smrg wire.base_color_ndx= XkbGeomColorIndex(geom,geom->base_color); 10238c9fbc29Smrg wire.label_color_ndx= XkbGeomColorIndex(geom,geom->label_color); 10248c9fbc29Smrg wire.num_properties= geom->num_properties; 10258c9fbc29Smrg wire.num_colors= geom->num_colors; 10268c9fbc29Smrg wire.num_shapes= geom->num_shapes; 10278c9fbc29Smrg wire.num_sections= geom->num_sections; 10288c9fbc29Smrg wire.num_doodads= geom->num_doodads; 10298c9fbc29Smrg wire.num_key_aliases= geom->num_key_aliases; 10308c9fbc29Smrg size+= xkmPutCountedAtomString(dpy,file,geom->name); 10318c9fbc29Smrg tmp= fwrite(&wire,SIZEOF(xkmGeometryDesc),1,file); 10328c9fbc29Smrg size+= tmp*SIZEOF(xkmGeometryDesc); 10338c9fbc29Smrg size+= xkmPutCountedString(file,geom->label_font); 10348c9fbc29Smrg if (geom->properties) { 10358c9fbc29Smrg XkbPropertyPtr prop; 10368c9fbc29Smrg for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { 10378c9fbc29Smrg size+= xkmPutCountedString(file,prop->name); 10388c9fbc29Smrg size+= xkmPutCountedString(file,prop->value); 10398c9fbc29Smrg } 10408c9fbc29Smrg } 10418c9fbc29Smrg if (geom->colors) { 10428c9fbc29Smrg XkbColorPtr color; 10438c9fbc29Smrg for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) { 10448c9fbc29Smrg size+= xkmPutCountedString(file,color->spec); 10458c9fbc29Smrg } 10468c9fbc29Smrg } 10478c9fbc29Smrg if (geom->shapes) { 10488c9fbc29Smrg XkbShapePtr shape; 10498c9fbc29Smrg xkmShapeDesc shapeWire; 10508c9fbc29Smrg 10518c9fbc29Smrg for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { 10528c9fbc29Smrg register int n; 10538c9fbc29Smrg XkbOutlinePtr ol; 10548c9fbc29Smrg xkmOutlineDesc olWire; 10558c9fbc29Smrg bzero((char *)&shapeWire,sizeof(xkmShapeDesc)); 10568c9fbc29Smrg size+= xkmPutCountedAtomString(dpy,file,shape->name); 10578c9fbc29Smrg shapeWire.num_outlines= shape->num_outlines; 10588c9fbc29Smrg if (shape->primary!=NULL) 10598c9fbc29Smrg shapeWire.primary_ndx= XkbOutlineIndex(shape,shape->primary); 10608c9fbc29Smrg else shapeWire.primary_ndx= XkbNoShape; 10618c9fbc29Smrg if (shape->approx!=NULL) 10628c9fbc29Smrg shapeWire.approx_ndx= XkbOutlineIndex(shape,shape->approx); 10638c9fbc29Smrg else shapeWire.approx_ndx= XkbNoShape; 10648c9fbc29Smrg tmp= fwrite(&shapeWire,SIZEOF(xkmShapeDesc),1,file); 10658c9fbc29Smrg size+= tmp*SIZEOF(xkmShapeDesc); 10668c9fbc29Smrg for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) { 10678c9fbc29Smrg register int p; 10688c9fbc29Smrg XkbPointPtr pt; 10698c9fbc29Smrg xkmPointDesc ptWire; 10708c9fbc29Smrg olWire.num_points= ol->num_points; 10718c9fbc29Smrg olWire.corner_radius= ol->corner_radius; 10728c9fbc29Smrg tmp= fwrite(&olWire,SIZEOF(xkmOutlineDesc),1,file); 10738c9fbc29Smrg size+= tmp*SIZEOF(xkmOutlineDesc); 10748c9fbc29Smrg for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) { 10758c9fbc29Smrg ptWire.x= pt->x; 10768c9fbc29Smrg ptWire.y= pt->y; 10778c9fbc29Smrg tmp= fwrite(&ptWire,SIZEOF(xkmPointDesc),1,file); 10788c9fbc29Smrg size+= tmp*SIZEOF(xkmPointDesc); 10798c9fbc29Smrg } 10808c9fbc29Smrg } 10818c9fbc29Smrg } 10828c9fbc29Smrg } 10838c9fbc29Smrg if (geom->sections) { 10848c9fbc29Smrg XkbSectionPtr section; 10858c9fbc29Smrg for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { 10868c9fbc29Smrg size+= WriteXKMGeomSection(file,result,section); 10878c9fbc29Smrg } 10888c9fbc29Smrg } 10898c9fbc29Smrg if (geom->doodads) { 10908c9fbc29Smrg XkbDoodadPtr doodad; 10918c9fbc29Smrg for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) { 10928c9fbc29Smrg size+= WriteXKMGeomDoodad(file,result,doodad); 10938c9fbc29Smrg } 10948c9fbc29Smrg } 10958c9fbc29Smrg if (geom->key_aliases) { 10968c9fbc29Smrg tmp= fwrite(geom->key_aliases,2*XkbKeyNameLength,geom->num_key_aliases, 10978c9fbc29Smrg file); 10988c9fbc29Smrg size+= tmp*(2*XkbKeyNameLength); 10998c9fbc29Smrg } 11008c9fbc29Smrg return size; 11018c9fbc29Smrg} 11028c9fbc29Smrg 11038c9fbc29Smrg/***====================================================================***/ 11048c9fbc29Smrg 11058c9fbc29Smrg/*ARGSUSED*/ 11068c9fbc29Smrgstatic int 11078c9fbc29SmrgGetXKMKeyNamesTOC( XkbFileInfo * result, 11088c9fbc29Smrg XkmInfo * info, 11098c9fbc29Smrg int max_toc, 11108c9fbc29Smrg xkmSectionInfo *toc_rtrn) 11118c9fbc29Smrg{ 11128c9fbc29Smrgint num_toc; 11138c9fbc29Smrgint total_size; 11148c9fbc29Smrg 11158c9fbc29Smrg total_size= num_toc=0; 11168c9fbc29Smrg if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size)) 11178c9fbc29Smrg num_toc++; 11188c9fbc29Smrg if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) 11198c9fbc29Smrg num_toc++; 11208c9fbc29Smrg return num_toc; 11218c9fbc29Smrg} 11228c9fbc29Smrg 11238c9fbc29Smrg/*ARGSUSED*/ 11248c9fbc29Smrgstatic int 11258c9fbc29SmrgGetXKMTypesTOC( XkbFileInfo * result, 11268c9fbc29Smrg XkmInfo * info, 11278c9fbc29Smrg int max_toc, 11288c9fbc29Smrg xkmSectionInfo *toc_rtrn) 11298c9fbc29Smrg{ 11308c9fbc29Smrgint num_toc; 11318c9fbc29Smrgint total_size; 11328c9fbc29Smrg 11338c9fbc29Smrg total_size= num_toc=0; 11348c9fbc29Smrg if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) 11358c9fbc29Smrg num_toc++; 11368c9fbc29Smrg if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size)) 11378c9fbc29Smrg num_toc++; 11388c9fbc29Smrg return num_toc; 11398c9fbc29Smrg} 11408c9fbc29Smrg 11418c9fbc29Smrg/*ARGSUSED*/ 11428c9fbc29Smrgstatic int 11438c9fbc29SmrgGetXKMCompatMapTOC( XkbFileInfo * result, 11448c9fbc29Smrg XkmInfo * info, 11458c9fbc29Smrg int max_toc, 11468c9fbc29Smrg xkmSectionInfo *toc_rtrn) 11478c9fbc29Smrg{ 11488c9fbc29Smrgint num_toc; 11498c9fbc29Smrgint total_size; 11508c9fbc29Smrg 11518c9fbc29Smrg total_size= num_toc=0; 11528c9fbc29Smrg if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) 11538c9fbc29Smrg num_toc++; 11548c9fbc29Smrg if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size)) 11558c9fbc29Smrg num_toc++; 11568c9fbc29Smrg if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) 11578c9fbc29Smrg num_toc++; 11588c9fbc29Smrg return num_toc; 11598c9fbc29Smrg} 11608c9fbc29Smrg 11618c9fbc29Smrg/*ARGSUSED*/ 11628c9fbc29Smrgstatic int 11638c9fbc29SmrgGetXKMSemanticsTOC( XkbFileInfo * result, 11648c9fbc29Smrg XkmInfo * info, 11658c9fbc29Smrg int max_toc, 11668c9fbc29Smrg xkmSectionInfo *toc_rtrn) 11678c9fbc29Smrg{ 11688c9fbc29Smrgint num_toc; 11698c9fbc29Smrgint total_size; 11708c9fbc29Smrg 11718c9fbc29Smrg total_size= num_toc=0; 11728c9fbc29Smrg if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) 11738c9fbc29Smrg num_toc++; 11748c9fbc29Smrg if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size)) 11758c9fbc29Smrg num_toc++; 11768c9fbc29Smrg if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size)) 11778c9fbc29Smrg num_toc++; 11788c9fbc29Smrg if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) 11798c9fbc29Smrg num_toc++; 11808c9fbc29Smrg return num_toc; 11818c9fbc29Smrg} 11828c9fbc29Smrg 11838c9fbc29Smrg/*ARGSUSED*/ 11848c9fbc29Smrgstatic int 11858c9fbc29SmrgGetXKMLayoutTOC( XkbFileInfo * result, 11868c9fbc29Smrg XkmInfo * info, 11878c9fbc29Smrg int max_toc, 11888c9fbc29Smrg xkmSectionInfo *toc_rtrn) 11898c9fbc29Smrg{ 11908c9fbc29Smrgint num_toc; 11918c9fbc29Smrgint total_size; 11928c9fbc29Smrg 11938c9fbc29Smrg total_size= num_toc=0; 11948c9fbc29Smrg if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) 11958c9fbc29Smrg num_toc++; 11968c9fbc29Smrg if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size)) 11978c9fbc29Smrg num_toc++; 11988c9fbc29Smrg if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size)) 11998c9fbc29Smrg num_toc++; 12008c9fbc29Smrg if (SizeXKMSymbols(result,info,&toc_rtrn[num_toc],&total_size)) 12018c9fbc29Smrg num_toc++; 12028c9fbc29Smrg if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) 12038c9fbc29Smrg num_toc++; 12048c9fbc29Smrg if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size)) 12058c9fbc29Smrg num_toc++; 12068c9fbc29Smrg return num_toc; 12078c9fbc29Smrg} 12088c9fbc29Smrg 12098c9fbc29Smrg/*ARGSUSED*/ 12108c9fbc29Smrgstatic int 12118c9fbc29SmrgGetXKMKeymapTOC( XkbFileInfo * result, 12128c9fbc29Smrg XkmInfo * info, 12138c9fbc29Smrg int max_toc, 12148c9fbc29Smrg xkmSectionInfo *toc_rtrn) 12158c9fbc29Smrg{ 12168c9fbc29Smrgint num_toc; 12178c9fbc29Smrgint total_size; 12188c9fbc29Smrg 12198c9fbc29Smrg total_size= num_toc=0; 12208c9fbc29Smrg if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) 12218c9fbc29Smrg num_toc++; 12228c9fbc29Smrg if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size)) 12238c9fbc29Smrg num_toc++; 12248c9fbc29Smrg if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size)) 12258c9fbc29Smrg num_toc++; 12268c9fbc29Smrg if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size)) 12278c9fbc29Smrg num_toc++; 12288c9fbc29Smrg if (SizeXKMSymbols(result,info,&toc_rtrn[num_toc],&total_size)) 12298c9fbc29Smrg num_toc++; 12308c9fbc29Smrg if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) 12318c9fbc29Smrg num_toc++; 12328c9fbc29Smrg if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size)) 12338c9fbc29Smrg num_toc++; 12348c9fbc29Smrg return num_toc; 12358c9fbc29Smrg} 12368c9fbc29Smrg 12378c9fbc29Smrg/*ARGSUSED*/ 12388c9fbc29Smrgstatic int 12398c9fbc29SmrgGetXKMGeometryTOC( XkbFileInfo * result, 12408c9fbc29Smrg XkmInfo * info, 12418c9fbc29Smrg int max_toc, 12428c9fbc29Smrg xkmSectionInfo *toc_rtrn) 12438c9fbc29Smrg{ 12448c9fbc29Smrgint num_toc; 12458c9fbc29Smrgint total_size; 12468c9fbc29Smrg 12478c9fbc29Smrg total_size= num_toc=0; 12488c9fbc29Smrg if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size)) 12498c9fbc29Smrg num_toc++; 12508c9fbc29Smrg return num_toc; 12518c9fbc29Smrg} 12528c9fbc29Smrg 12538c9fbc29Smrgstatic Bool 12548c9fbc29SmrgWriteXKMFile( FILE * file, 12558c9fbc29Smrg XkbFileInfo * result, 12568c9fbc29Smrg int num_toc, 12578c9fbc29Smrg xkmSectionInfo *toc, 12588c9fbc29Smrg XkmInfo * info) 12598c9fbc29Smrg{ 12608c9fbc29Smrgregister int i; 12618c9fbc29Smrgunsigned tmp,size,total= 0; 12624cd6a3aeSmrg 12638c9fbc29Smrg for (i=0;i<num_toc;i++) { 12648c9fbc29Smrg tmp= fwrite(&toc[i],SIZEOF(xkmSectionInfo),1,file); 12658c9fbc29Smrg total+= tmp*SIZEOF(xkmSectionInfo); 12668c9fbc29Smrg switch (toc[i].type) { 12678c9fbc29Smrg case XkmTypesIndex: 12688c9fbc29Smrg size= WriteXKMKeyTypes(file,result); 12698c9fbc29Smrg break; 12708c9fbc29Smrg case XkmCompatMapIndex: 12718c9fbc29Smrg size= WriteXKMCompatMap(file,result,info); 12728c9fbc29Smrg break; 12738c9fbc29Smrg case XkmSymbolsIndex: 12748c9fbc29Smrg size= WriteXKMSymbols(file,result,info); 12758c9fbc29Smrg break; 12768c9fbc29Smrg case XkmIndicatorsIndex: 12778c9fbc29Smrg size= WriteXKMIndicators(file,result,info); 12788c9fbc29Smrg break; 12798c9fbc29Smrg case XkmKeyNamesIndex: 12808c9fbc29Smrg size= WriteXKMKeycodes(file,result); 12818c9fbc29Smrg break; 12828c9fbc29Smrg case XkmGeometryIndex: 12838c9fbc29Smrg size= WriteXKMGeometry(file,result); 12848c9fbc29Smrg break; 12858c9fbc29Smrg case XkmVirtualModsIndex: 12868c9fbc29Smrg size= WriteXKMVirtualMods(file,result,info); 12878c9fbc29Smrg break; 12888c9fbc29Smrg default: 12898c9fbc29Smrg _XkbLibError(_XkbErrIllegalTOCType,"WriteXKMFile",toc[i].type); 12908c9fbc29Smrg return False; 12918c9fbc29Smrg } 12928c9fbc29Smrg size+= SIZEOF(xkmSectionInfo); 12938c9fbc29Smrg if (size!=toc[i].size) { 12948c9fbc29Smrg _XkbLibError(_XkbErrBadLength,XkbConfigText(toc[i].type,XkbMessage), 12958c9fbc29Smrg size-toc[i].size); 12968c9fbc29Smrg return False; 12978c9fbc29Smrg } 12988c9fbc29Smrg } 12998c9fbc29Smrg return True; 13008c9fbc29Smrg} 13018c9fbc29Smrg 13028c9fbc29Smrg 13038c9fbc29Smrg#define MAX_TOC 16 13048c9fbc29Smrg 13058c9fbc29SmrgBool 13068c9fbc29SmrgXkbWriteXKMFile(FILE *out,XkbFileInfo *result) 13078c9fbc29Smrg{ 13088c9fbc29SmrgBool ok; 13098c9fbc29SmrgXkbDescPtr xkb; 13108c9fbc29SmrgXkmInfo info; 13118c9fbc29Smrgint size_toc,i; 13128c9fbc29Smrgunsigned hdr,present; 13138c9fbc29SmrgxkmFileInfo fileInfo; 13148c9fbc29SmrgxkmSectionInfo toc[MAX_TOC]; 13158c9fbc29Smrgint (*getTOC)( 13168c9fbc29Smrg XkbFileInfo * /* result */, 13178c9fbc29Smrg XkmInfo * /* info */, 13188c9fbc29Smrg int /* max_to */, 13198c9fbc29Smrg xkmSectionInfo */* toc_rtrn */ 13208c9fbc29Smrg); 13218c9fbc29Smrg 13228c9fbc29Smrg switch (result->type) { 13238c9fbc29Smrg case XkmKeyNamesIndex: 13248c9fbc29Smrg getTOC= GetXKMKeyNamesTOC; 13258c9fbc29Smrg break; 13268c9fbc29Smrg case XkmTypesIndex: 13278c9fbc29Smrg getTOC= GetXKMTypesTOC; 13288c9fbc29Smrg break; 13298c9fbc29Smrg case XkmCompatMapIndex: 13308c9fbc29Smrg getTOC= GetXKMCompatMapTOC; 13318c9fbc29Smrg break; 13328c9fbc29Smrg case XkmSemanticsFile: 13338c9fbc29Smrg getTOC= GetXKMSemanticsTOC; 13348c9fbc29Smrg break; 13358c9fbc29Smrg case XkmLayoutFile: 13368c9fbc29Smrg getTOC= GetXKMLayoutTOC; 13378c9fbc29Smrg break; 13388c9fbc29Smrg case XkmKeymapFile: 13398c9fbc29Smrg getTOC= GetXKMKeymapTOC; 13408c9fbc29Smrg break; 13418c9fbc29Smrg case XkmGeometryFile: 13428c9fbc29Smrg case XkmGeometryIndex: 13438c9fbc29Smrg getTOC= GetXKMGeometryTOC; 13448c9fbc29Smrg break; 13458c9fbc29Smrg default: 13468c9fbc29Smrg _XkbLibError(_XkbErrIllegalContents, 13478c9fbc29Smrg XkbConfigText(result->type,XkbMessage),0); 13488c9fbc29Smrg return False; 13498c9fbc29Smrg } 13508c9fbc29Smrg xkb= result->xkb; 13518c9fbc29Smrg 13528c9fbc29Smrg bzero((char *)&info,sizeof(XkmInfo)); 13538c9fbc29Smrg size_toc= (*getTOC)(result,&info,MAX_TOC,toc); 13548c9fbc29Smrg if (size_toc<1) { 13558c9fbc29Smrg _XkbLibError(_XkbErrEmptyFile,"XkbWriteXKMFile",0); 13568c9fbc29Smrg return False; 13578c9fbc29Smrg } 13588c9fbc29Smrg if (out==NULL) { 13598c9fbc29Smrg _XkbLibError(_XkbErrFileCannotOpen,"XkbWriteXKMFile",0); 13608c9fbc29Smrg return False; 13618c9fbc29Smrg } 13628c9fbc29Smrg for (i=present=0;i<size_toc;i++) { 13638c9fbc29Smrg toc[i].offset+= 4+SIZEOF(xkmFileInfo); 13648c9fbc29Smrg toc[i].offset+= (size_toc*SIZEOF(xkmSectionInfo)); 13658c9fbc29Smrg if (toc[i].type<=XkmLastIndex) { 13668c9fbc29Smrg present|= (1<<toc[i].type); 13678c9fbc29Smrg } 13688c9fbc29Smrg#ifdef DEBUG 13698c9fbc29Smrg else { 13708c9fbc29Smrg fprintf(stderr,"Illegal section type %d\n",toc[i].type); 13718c9fbc29Smrg fprintf(stderr,"Ignored\n"); 13728c9fbc29Smrg } 13738c9fbc29Smrg#endif 13748c9fbc29Smrg } 13758c9fbc29Smrg hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion); 13768c9fbc29Smrg xkmPutCARD32(out,(unsigned long)hdr); 13778c9fbc29Smrg fileInfo.type= result->type; 13788c9fbc29Smrg fileInfo.min_kc= xkb->min_key_code; 13798c9fbc29Smrg fileInfo.max_kc= xkb->max_key_code; 13808c9fbc29Smrg fileInfo.num_toc= size_toc; 13818c9fbc29Smrg fileInfo.present= present; 13828c9fbc29Smrg fileInfo.pad= 0; 13838c9fbc29Smrg fwrite(&fileInfo,SIZEOF(xkmFileInfo),1,out); 13848c9fbc29Smrg fwrite(toc,SIZEOF(xkmSectionInfo),size_toc,out); 13858c9fbc29Smrg ok= WriteXKMFile(out,result,size_toc,toc,&info); 13868c9fbc29Smrg return ok; 13878c9fbc29Smrg} 1388