xkmout.c revision 4cd6a3ae
1/************************************************************ 2 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. 3 4 Permission to use, copy, modify, and distribute this 5 software and its documentation for any purpose and without 6 fee is hereby granted, provided that the above copyright 7 notice appear in all copies and that both that copyright 8 notice and this permission notice appear in supporting 9 documentation, and that the name of Silicon Graphics not be 10 used in advertising or publicity pertaining to distribution 11 of the software without specific prior written permission. 12 Silicon Graphics makes no representation about the suitability 13 of this software for any purpose. It is provided "as is" 14 without any express or implied warranty. 15 16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23 THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 25 ********************************************************/ 26 27#ifdef HAVE_CONFIG_H 28#include <config.h> 29#endif 30#include <stdio.h> 31#include <ctype.h> 32#include <stdlib.h> 33#include <X11/Xfuncs.h> 34#include <X11/Xlib.h> 35#include <X11/XKBlib.h> 36#include <X11/extensions/XKBgeom.h> 37 38#include "XKMformat.h" 39#include "XKBfileInt.h" 40 41typedef struct _XkmInfo { 42 unsigned short bound_vmods; 43 unsigned short named_vmods; 44 unsigned char num_bound; 45 unsigned char group_compat; 46 unsigned short num_group_compat; 47 unsigned short num_leds; 48 int total_vmodmaps; 49} XkmInfo; 50 51/***====================================================================***/ 52 53#define xkmPutCARD8(f,v) (putc(v,f),1) 54 55static int 56xkmPutCARD16(FILE *file,unsigned val) 57{ 58CARD16 tmp= val; 59 60 fwrite(&tmp,2,1,file); 61 return 2; 62} 63 64static int 65xkmPutCARD32(FILE *file,unsigned long val) 66{ 67CARD32 tmp= val; 68 69 fwrite(&tmp,4,1,file); 70 return 4; 71} 72 73static int 74xkmPutPadding(FILE *file,unsigned pad) 75{ 76int i; 77 for (i=0;i<pad;i++) { 78 putc('\0',file); 79 } 80 return pad; 81} 82 83static int 84xkmPutCountedBytes(FILE *file,char *ptr,unsigned count) 85{ 86register int nOut; 87register unsigned pad; 88 89 if (count==0) 90 return xkmPutCARD32(file,(unsigned long)0); 91 92 xkmPutCARD16(file,count); 93 nOut= fwrite(ptr,1,count,file); 94 if (nOut<0) 95 return 2; 96 nOut= count+2; 97 pad= XkbPaddedSize(nOut)-nOut; 98 if (pad) 99 xkmPutPadding(file,pad); 100 return nOut+pad; 101} 102 103static unsigned 104xkmSizeCountedString(char *str) 105{ 106 if (str==NULL) 107 return 4; 108 return XkbPaddedSize(strlen(str)+2); 109} 110 111static int 112xkmPutCountedString(FILE *file,char *str) 113{ 114 if (str==NULL) 115 return xkmPutCARD32(file,(unsigned long)0); 116 return xkmPutCountedBytes(file,str,strlen(str)); 117} 118 119#define xkmSizeCountedAtomString(d,a) \ 120 xkmSizeCountedString(XkbAtomGetString((d),(a))) 121 122#define xkmPutCountedAtomString(d,f,a) \ 123 xkmPutCountedString((f),XkbAtomGetString((d),(a))) 124 125/***====================================================================***/ 126 127static unsigned 128SizeXKMVirtualMods( XkbFileInfo * result, 129 XkmInfo * info, 130 xkmSectionInfo * toc, 131 int * offset_inout) 132{ 133Display * dpy; 134XkbDescPtr xkb; 135unsigned nBound,bound; 136unsigned nNamed,named,szNames; 137register unsigned i,bit; 138 139 xkb= result->xkb; 140 dpy= xkb->dpy; 141 if ((!xkb)||(!xkb->names)||(!xkb->server)) { 142 _XkbLibError(_XkbErrMissingVMods,"SizeXKMVirtualMods",0); 143 return 0; 144 } 145 bound=named=0; 146 for (i=nBound=nNamed=szNames=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 147 if (xkb->server->vmods[i]!=XkbNoModifierMask) { 148 bound|= bit; 149 nBound++; 150 } 151 if (xkb->names->vmods[i]!=None) { 152 named|= bit; 153 szNames+= xkmSizeCountedAtomString(dpy,xkb->names->vmods[i]); 154 nNamed++; 155 } 156 } 157 info->num_bound= nBound; 158 info->bound_vmods= bound; 159 info->named_vmods= named; 160 if ((nBound==0)&&(nNamed==0)) 161 return 0; 162 toc->type= XkmVirtualModsIndex; 163 toc->format= MSBFirst; 164 toc->size= 4+XkbPaddedSize(nBound)+szNames+SIZEOF(xkmSectionInfo); 165 toc->offset= *offset_inout; 166 (*offset_inout)+= toc->size; 167 return 1; 168} 169 170static unsigned 171WriteXKMVirtualMods(FILE *file,XkbFileInfo *result,XkmInfo *info) 172{ 173register unsigned int i,bit; 174XkbDescPtr xkb; 175Display * dpy; 176unsigned size= 0; 177 178 xkb= result->xkb; 179 dpy= xkb->dpy; 180 size+= xkmPutCARD16(file,info->bound_vmods); 181 size+= xkmPutCARD16(file,info->named_vmods); 182 for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 183 if (info->bound_vmods&bit) 184 size+= xkmPutCARD8(file,xkb->server->vmods[i]); 185 } 186 if ((i= XkbPaddedSize(info->num_bound)-info->num_bound)>0) 187 size+= xkmPutPadding(file,i); 188 for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 189 if (info->named_vmods&bit) { 190 register char *name; 191 name= XkbAtomGetString(dpy,xkb->names->vmods[i]); 192 size+= xkmPutCountedString(file,name); 193 } 194 } 195 return size; 196} 197 198/***====================================================================***/ 199 200static unsigned 201SizeXKMKeycodes(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout) 202{ 203XkbDescPtr xkb; 204Atom kcName; 205int size=0; 206Display * dpy; 207 208 xkb= result->xkb; 209 dpy= xkb->dpy; 210 if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) { 211 _XkbLibError(_XkbErrMissingNames,"SizeXKMKeycodes",0); 212 return 0; 213 } 214 kcName= xkb->names->keycodes; 215 size+= 4; /* min and max keycode */ 216 size+= xkmSizeCountedAtomString(dpy,kcName); 217 size+= XkbNumKeys(xkb)*sizeof(XkbKeyNameRec); 218 if (xkb->names->num_key_aliases>0) { 219 if (xkb->names->key_aliases!=NULL) 220 size+= xkb->names->num_key_aliases*sizeof(XkbKeyAliasRec); 221 else xkb->names->num_key_aliases= 0; 222 } 223 toc->type= XkmKeyNamesIndex; 224 toc->format= MSBFirst; 225 toc->size= size+SIZEOF(xkmSectionInfo); 226 toc->offset= (*offset_inout); 227 (*offset_inout)+= toc->size; 228 return 1; 229} 230 231static unsigned 232WriteXKMKeycodes(FILE *file,XkbFileInfo *result) 233{ 234XkbDescPtr xkb; 235Atom kcName; 236char *start; 237Display * dpy; 238unsigned tmp,size= 0; 239 240 xkb= result->xkb; 241 dpy= xkb->dpy; 242 kcName= xkb->names->keycodes; 243 start= xkb->names->keys[xkb->min_key_code].name; 244 245 size+= xkmPutCountedString(file,XkbAtomGetString(dpy,kcName)); 246 size+= xkmPutCARD8(file,xkb->min_key_code); 247 size+= xkmPutCARD8(file,xkb->max_key_code); 248 size+= xkmPutCARD8(file,xkb->names->num_key_aliases); 249 size+= xkmPutPadding(file,1); 250 tmp= fwrite(start,sizeof(XkbKeyNameRec),XkbNumKeys(xkb),file); 251 size+= tmp*sizeof(XkbKeyNameRec); 252 if (xkb->names->num_key_aliases>0) { 253 tmp= fwrite((char *)xkb->names->key_aliases, 254 sizeof(XkbKeyAliasRec),xkb->names->num_key_aliases, 255 file); 256 size+= tmp*sizeof(XkbKeyAliasRec); 257 } 258 return size; 259} 260 261/***====================================================================***/ 262 263static unsigned 264SizeXKMKeyTypes(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout) 265{ 266register unsigned i,n,size; 267XkbKeyTypePtr type; 268XkbDescPtr xkb; 269Display * dpy; 270char * name; 271 272 xkb= result->xkb; 273 dpy= xkb->dpy; 274 if ((!xkb)||(!xkb->map)||(!xkb->map->types)) { 275 _XkbLibError(_XkbErrMissingTypes,"SizeXKBKeyTypes",0); 276 return 0; 277 } 278 if (xkb->map->num_types<XkbNumRequiredTypes) { 279 _XkbLibError(_XkbErrMissingReqTypes,"SizeXKBKeyTypes",0); 280 return 0; 281 } 282 if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->types); 283 else name= NULL; 284 size= xkmSizeCountedString(name); 285 size+= 4; /* room for # of key types + padding */ 286 for (i=0,type=xkb->map->types;i<xkb->map->num_types;i++,type++) { 287 size+= SIZEOF(xkmKeyTypeDesc); 288 size+= SIZEOF(xkmKTMapEntryDesc)*type->map_count; 289 size+= xkmSizeCountedAtomString(dpy,type->name); 290 if (type->preserve) 291 size+= SIZEOF(xkmModsDesc)*type->map_count; 292 if (type->level_names) { 293 Atom *names; 294 names= type->level_names; 295 for (n=0;n<(unsigned)type->num_levels;n++) { 296 size+= xkmSizeCountedAtomString(dpy,names[n]); 297 } 298 } 299 } 300 toc->type= XkmTypesIndex; 301 toc->format= MSBFirst; 302 toc->size= size+SIZEOF(xkmSectionInfo); 303 toc->offset= (*offset_inout); 304 (*offset_inout)+= toc->size; 305 return 1; 306} 307 308static unsigned 309WriteXKMKeyTypes(FILE *file,XkbFileInfo *result) 310{ 311register unsigned i,n; 312XkbDescPtr xkb; 313XkbKeyTypePtr type; 314xkmKeyTypeDesc wire; 315XkbKTMapEntryPtr entry; 316xkmKTMapEntryDesc wire_entry; 317Atom * names; 318Display * dpy; 319unsigned tmp,size= 0; 320char * name; 321 322 xkb= result->xkb; 323 dpy= xkb->dpy; 324 if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->types); 325 else name= NULL; 326 size+= xkmPutCountedString(file,name); 327 size+= xkmPutCARD16(file,xkb->map->num_types); 328 size+= xkmPutPadding(file,2); 329 type= xkb->map->types; 330 for (i=0;i<xkb->map->num_types;i++,type++) { 331 wire.realMods= type->mods.real_mods; 332 wire.virtualMods= type->mods.vmods; 333 wire.numLevels= type->num_levels; 334 wire.nMapEntries= type->map_count; 335 wire.preserve= (type->preserve!=NULL); 336 if (type->level_names!=NULL) 337 wire.nLevelNames= type->num_levels; 338 else wire.nLevelNames= 0; 339 tmp= fwrite(&wire,SIZEOF(xkmKeyTypeDesc),1,file); 340 size+= tmp*SIZEOF(xkmKeyTypeDesc); 341 for (n=0,entry= type->map;n<type->map_count;n++,entry++) { 342 wire_entry.level= entry->level; 343 wire_entry.realMods= entry->mods.real_mods; 344 wire_entry.virtualMods= entry->mods.vmods; 345 tmp= fwrite(&wire_entry,SIZEOF(xkmKTMapEntryDesc),1,file); 346 size+= tmp*SIZEOF(xkmKTMapEntryDesc); 347 } 348 size+= xkmPutCountedString(file,XkbAtomGetString(dpy,type->name)); 349 if (type->preserve) { 350 xkmModsDesc p_entry; 351 XkbModsPtr pre; 352 for (n=0,pre=type->preserve;n<type->map_count;n++,pre++) { 353 p_entry.realMods= pre->real_mods; 354 p_entry.virtualMods= pre->vmods; 355 tmp= fwrite(&p_entry,SIZEOF(xkmModsDesc),1,file); 356 size+= tmp*SIZEOF(xkmModsDesc); 357 } 358 } 359 if (type->level_names!=NULL) { 360 names= type->level_names; 361 for (n=0;n<wire.nLevelNames;n++) { 362 size+= xkmPutCountedString(file,XkbAtomGetString(dpy,names[n])); 363 } 364 } 365 } 366 return size; 367} 368 369/***====================================================================***/ 370 371static unsigned 372SizeXKMCompatMap( XkbFileInfo * result, 373 XkmInfo * info, 374 xkmSectionInfo * toc, 375 int * offset_inout) 376{ 377XkbDescPtr xkb; 378char * name; 379int size; 380register int i; 381unsigned groups,nGroups; 382Display * dpy; 383 384 xkb= result->xkb; 385 dpy= xkb->dpy; 386 if ((!xkb)||(!xkb->compat)||(!xkb->compat->sym_interpret)) { 387 _XkbLibError(_XkbErrMissingCompatMap,"SizeXKMCompatMap",0); 388 return 0; 389 } 390 if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->compat); 391 else name= NULL; 392 393 for (i=groups=nGroups=0;i<XkbNumKbdGroups;i++) { 394 if ((xkb->compat->groups[i].real_mods!=0)|| 395 (xkb->compat->groups[i].vmods!=0)) { 396 groups|= (1<<i); 397 nGroups++; 398 } 399 } 400 info->group_compat= groups; 401 info->num_group_compat= nGroups; 402 size= 4; /* room for num_si and group_compat mask */ 403 size+= xkmSizeCountedString(name); 404 size+= (SIZEOF(xkmSymInterpretDesc)*xkb->compat->num_si); 405 size+= (SIZEOF(xkmModsDesc)*nGroups); 406 toc->type= XkmCompatMapIndex; 407 toc->format= MSBFirst; 408 toc->size= size+SIZEOF(xkmSectionInfo); 409 toc->offset= (*offset_inout); 410 (*offset_inout)+= toc->size; 411 return 1; 412} 413 414static unsigned 415WriteXKMCompatMap(FILE *file,XkbFileInfo *result,XkmInfo *info) 416{ 417register unsigned i; 418char * name; 419XkbDescPtr xkb; 420XkbSymInterpretPtr interp; 421xkmSymInterpretDesc wire; 422Display * dpy; 423unsigned tmp,size=0; 424 425 xkb= result->xkb; 426 dpy= xkb->dpy; 427 if (xkb->names) name= XkbAtomGetString(dpy,xkb->names->compat); 428 else name= NULL; 429 size+= xkmPutCountedString(file,name); 430 size+= xkmPutCARD16(file,xkb->compat->num_si); 431 size+= xkmPutCARD8(file,info->group_compat); 432 size+= xkmPutPadding(file,1); 433 interp= xkb->compat->sym_interpret; 434 for (i=0;i<xkb->compat->num_si;i++,interp++) { 435 wire.sym= interp->sym; 436 wire.mods= interp->mods; 437 wire.match= interp->match; 438 wire.virtualMod= interp->virtual_mod; 439 wire.flags= interp->flags; 440 wire.actionType= interp->act.type; 441 wire.actionData[0]= interp->act.data[0]; 442 wire.actionData[1]= interp->act.data[1]; 443 wire.actionData[2]= interp->act.data[2]; 444 wire.actionData[3]= interp->act.data[3]; 445 wire.actionData[4]= interp->act.data[4]; 446 wire.actionData[5]= interp->act.data[5]; 447 wire.actionData[6]= interp->act.data[6]; 448 tmp= fwrite(&wire,SIZEOF(xkmSymInterpretDesc),1,file); 449 size+= tmp*SIZEOF(xkmSymInterpretDesc); 450 } 451 if (info->group_compat) { 452 register unsigned bit; 453 xkmModsDesc modsWire; 454 for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 455 if (info->group_compat&bit) { 456 modsWire.realMods= xkb->compat->groups[i].real_mods; 457 modsWire.virtualMods= xkb->compat->groups[i].vmods; 458 fwrite(&modsWire,SIZEOF(xkmModsDesc),1,file); 459 size+= SIZEOF(xkmModsDesc); 460 } 461 } 462 } 463 return size; 464} 465 466/***====================================================================***/ 467 468static unsigned 469SizeXKMSymbols( XkbFileInfo * result, 470 XkmInfo * info, 471 xkmSectionInfo * toc, 472 int * offset_inout) 473{ 474Display * dpy; 475XkbDescPtr xkb; 476unsigned size; 477register int i,nSyms; 478char * name; 479 480 xkb= result->xkb; 481 dpy= xkb->dpy; 482 if ((!xkb)||(!xkb->map)||((!xkb->map->syms))) { 483 _XkbLibError(_XkbErrMissingSymbols,"SizeXKMSymbols",0); 484 return 0; 485 } 486 if (xkb->names && (xkb->names->symbols!=None)) 487 name= XkbAtomGetString(dpy,xkb->names->symbols); 488 else name= NULL; 489 size= xkmSizeCountedString(name); 490 size+= 4; /* min and max keycode, group names mask */ 491 for (i=0;i<XkbNumKbdGroups;i++) { 492 if (xkb->names->groups[i]!=None) 493 size+= xkmSizeCountedAtomString(dpy,xkb->names->groups[i]); 494 } 495 info->total_vmodmaps= 0; 496 for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { 497 nSyms= XkbKeyNumSyms(xkb,i); 498 size+= SIZEOF(xkmKeySymMapDesc)+(nSyms*4); 499 if (xkb->server) { 500 if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) { 501 register int g; 502 for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) { 503 if (xkb->server->explicit[i]&(1<<g)) { 504 XkbKeyTypePtr type; 505 char * name; 506 type= XkbKeyKeyType(xkb,i,g); 507 name= XkbAtomGetString(dpy,type->name); 508 if (name!=NULL) 509 size+= xkmSizeCountedString(name); 510 } 511 } 512 } 513 if (XkbKeyHasActions(xkb,i)) 514 size+= nSyms*SIZEOF(xkmActionDesc); 515 if (xkb->server->behaviors[i].type!=XkbKB_Default) 516 size+= SIZEOF(xkmBehaviorDesc); 517 if (xkb->server->vmodmap && (xkb->server->vmodmap[i]!=0)) 518 info->total_vmodmaps++; 519 } 520 } 521 size+= info->total_vmodmaps*SIZEOF(xkmVModMapDesc); 522 toc->type= XkmSymbolsIndex; 523 toc->format= MSBFirst; 524 toc->size= size+SIZEOF(xkmSectionInfo); 525 toc->offset= (*offset_inout); 526 (*offset_inout)+= toc->size; 527 return 1; 528} 529 530static unsigned 531WriteXKMSymbols(FILE *file,XkbFileInfo *result,XkmInfo *info) 532{ 533Display * dpy; 534XkbDescPtr xkb; 535register int i,n; 536xkmKeySymMapDesc wireMap; 537char * name; 538unsigned tmp,size= 0; 539 540 xkb= result->xkb; 541 dpy= xkb->dpy; 542 if (xkb->names && (xkb->names->symbols!=None)) 543 name= XkbAtomGetString(dpy,xkb->names->symbols); 544 else name= NULL; 545 size+= xkmPutCountedString(file,name); 546 for (tmp=i=0;i<XkbNumKbdGroups;i++) { 547 if (xkb->names->groups[i]!=None) 548 tmp|= (1<<i); 549 } 550 size+= xkmPutCARD8(file,xkb->min_key_code); 551 size+= xkmPutCARD8(file,xkb->max_key_code); 552 size+= xkmPutCARD8(file,tmp); 553 size+= xkmPutCARD8(file,info->total_vmodmaps); 554 for (i=0,n=1;i<XkbNumKbdGroups;i++,n<<=1) { 555 if ((tmp&n)==0) 556 continue; 557 size+= xkmPutCountedAtomString(dpy,file,xkb->names->groups[i]); 558 } 559 for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) { 560 char *typeName[XkbNumKbdGroups]; 561 wireMap.width= XkbKeyGroupsWidth(xkb,i); 562 wireMap.num_groups= XkbKeyGroupInfo(xkb,i); 563 if (xkb->map && xkb->map->modmap) 564 wireMap.modifier_map= xkb->map->modmap[i]; 565 else wireMap.modifier_map= 0; 566 wireMap.flags= 0; 567 bzero((char *)typeName,XkbNumKbdGroups*sizeof(char *)); 568 if (xkb->server) { 569 if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) { 570 register int g; 571 for (g=0;g<XkbKeyNumGroups(xkb,i);g++) { 572 if (xkb->server->explicit[i]&(1<<g)) { 573 XkbKeyTypePtr type; 574 type= XkbKeyKeyType(xkb,i,g); 575 typeName[g]= XkbAtomGetString(dpy,type->name); 576 if (typeName[g]!=NULL) 577 wireMap.flags|= (1<<g); 578 } 579 } 580 } 581 if (XkbKeyHasActions(xkb,i)) 582 wireMap.flags|= XkmKeyHasActions; 583 if (xkb->server->behaviors[i].type!=XkbKB_Default) 584 wireMap.flags|= XkmKeyHasBehavior; 585 if ((xkb->server->explicit[i]&XkbExplicitAutoRepeatMask)&& 586 (xkb->ctrls!=NULL)) { 587 if (xkb->ctrls->per_key_repeat[(i/8)]&(1<<(i%8))) 588 wireMap.flags|= XkmRepeatingKey; 589 else wireMap.flags|= XkmNonRepeatingKey; 590 } 591 } 592 tmp= fwrite(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file); 593 size+= tmp*SIZEOF(xkmKeySymMapDesc); 594 if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) { 595 register int g; 596 for (g=0;g<XkbNumKbdGroups;g++) { 597 if (typeName[g]!=NULL) 598 size+= xkmPutCountedString(file,typeName[g]); 599 } 600 } 601 if (XkbNumGroups(wireMap.num_groups)>0) { 602 KeySym *sym; 603 sym= XkbKeySymsPtr(xkb,i); 604 for (n=XkbKeyNumSyms(xkb,i);n>0;n--,sym++) { 605 size+= xkmPutCARD32(file,(CARD32)*sym); 606 } 607 if (wireMap.flags&XkmKeyHasActions) { 608 XkbAction * act; 609 act= XkbKeyActionsPtr(xkb,i); 610 for (n=XkbKeyNumActions(xkb,i);n>0;n--,act++) { 611 tmp= fwrite(act,SIZEOF(xkmActionDesc),1,file); 612 size+= tmp*SIZEOF(xkmActionDesc); 613 } 614 } 615 } 616 if (wireMap.flags&XkmKeyHasBehavior) { 617 xkmBehaviorDesc b; 618 b.type= xkb->server->behaviors[i].type; 619 b.data= xkb->server->behaviors[i].data; 620 tmp= fwrite(&b,SIZEOF(xkmBehaviorDesc),1,file); 621 size+= tmp*SIZEOF(xkmBehaviorDesc); 622 } 623 } 624 if (info->total_vmodmaps>0) { 625 xkmVModMapDesc v; 626 for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 627 if (xkb->server->vmodmap[i]!=0) { 628 v.key= i; 629 v.vmods= xkb->server->vmodmap[i]; 630 tmp= fwrite(&v,SIZEOF(xkmVModMapDesc),1,file); 631 size+= tmp*SIZEOF(xkmVModMapDesc); 632 } 633 } 634 } 635 return size; 636} 637 638/***====================================================================***/ 639 640static unsigned 641SizeXKMIndicators(XkbFileInfo *result,XkmInfo *info,xkmSectionInfo *toc, 642 int *offset_inout) 643{ 644Display * dpy; 645XkbDescPtr xkb; 646unsigned size; 647register unsigned i,nLEDs; 648 649 xkb= result->xkb; 650 dpy= xkb->dpy; 651 if ((xkb==NULL)||(xkb->indicators==NULL)) { 652/* _XkbLibError(_XkbErrMissingIndicators,"SizeXKMIndicators",0);*/ 653 return 0; 654 } 655 nLEDs=0; 656 size= 8; /* number of indicator maps/physical indicators */ 657 if (xkb->indicators!=NULL) { 658 for (i=0;i<XkbNumIndicators;i++) { 659 XkbIndicatorMapPtr map= &xkb->indicators->maps[i]; 660 if ((map->flags!=0)||(map->which_groups!=0)||(map->groups!=0)|| 661 (map->which_mods!=0)|| 662 (map->mods.real_mods!=0)||(map->mods.vmods!=0)|| 663 (map->ctrls!=0) || 664 (xkb->names && (xkb->names->indicators[i]!=None))) { 665 char *name; 666 if (xkb->names && xkb->names->indicators[i]!=None) { 667 name= XkbAtomGetString(dpy,xkb->names->indicators[i]); 668 } 669 else name= NULL; 670 size+= xkmSizeCountedString(name); 671 size+= SIZEOF(xkmIndicatorMapDesc); 672 nLEDs++; 673 } 674 } 675 } 676 info->num_leds= nLEDs; 677 toc->type= XkmIndicatorsIndex; 678 toc->format= MSBFirst; 679 toc->size= size+SIZEOF(xkmSectionInfo); 680 toc->offset= (*offset_inout); 681 (*offset_inout)+= toc->size; 682 return 1; 683} 684 685static unsigned 686WriteXKMIndicators(FILE *file,XkbFileInfo *result,XkmInfo *info) 687{ 688Display * dpy; 689XkbDescPtr xkb; 690register unsigned i; 691xkmIndicatorMapDesc wire; 692unsigned tmp,size= 0; 693 694 xkb= result->xkb; 695 dpy= xkb->dpy; 696 size+= xkmPutCARD8(file,info->num_leds); 697 size+= xkmPutPadding(file,3); 698 size+= xkmPutCARD32(file,xkb->indicators->phys_indicators); 699 if (xkb->indicators!=NULL) { 700 for (i=0;i<XkbNumIndicators;i++) { 701 XkbIndicatorMapPtr map= &xkb->indicators->maps[i]; 702 if ((map->flags!=0)||(map->which_groups!=0)||(map->groups!=0)|| 703 (map->which_mods!=0)|| 704 (map->mods.real_mods!=0)||(map->mods.vmods!=0)|| 705 (map->ctrls!=0) || 706 (xkb->names && (xkb->names->indicators[i]!=None))) { 707 char *name; 708 if (xkb->names && xkb->names->indicators[i]!=None) { 709 name= XkbAtomGetString(dpy,xkb->names->indicators[i]); 710 } 711 else name= NULL; 712 size+= xkmPutCountedString(file,name); 713 wire.indicator= i+1; 714 wire.flags= map->flags; 715 wire.which_mods= map->which_mods; 716 wire.real_mods= map->mods.real_mods; 717 wire.vmods= map->mods.vmods; 718 wire.which_groups= map->which_groups; 719 wire.groups= map->groups; 720 wire.ctrls= map->ctrls; 721 tmp= fwrite(&wire,SIZEOF(xkmIndicatorMapDesc),1,file); 722 size+= tmp*SIZEOF(xkmIndicatorMapDesc); 723 } 724 } 725 } 726 return size; 727} 728 729/***====================================================================***/ 730 731static unsigned 732SizeXKMGeomDoodad(XkbFileInfo *result,XkbDoodadPtr doodad) 733{ 734unsigned size; 735 736 size= SIZEOF(xkmAnyDoodadDesc); 737 size+= xkmSizeCountedAtomString(result->xkb->dpy,doodad->any.name); 738 if (doodad->any.type==XkbTextDoodad) { 739 size+= xkmSizeCountedString(doodad->text.text); 740 size+= xkmSizeCountedString(doodad->text.font); 741 } 742 else if (doodad->any.type==XkbLogoDoodad) { 743 size+= xkmSizeCountedString(doodad->logo.logo_name); 744 } 745 return size; 746} 747 748static unsigned 749SizeXKMGeomSection(XkbFileInfo *result,XkbSectionPtr section) 750{ 751register int i; 752unsigned size; 753 754 size= SIZEOF(xkmSectionDesc); 755 size+= xkmSizeCountedAtomString(result->xkb->dpy,section->name); 756 if (section->rows) { 757 XkbRowPtr row; 758 for (row=section->rows,i=0;i<section->num_rows;i++,row++) { 759 size+= SIZEOF(xkmRowDesc); 760 size+= row->num_keys*SIZEOF(xkmKeyDesc); 761 } 762 } 763 if (section->doodads) { 764 XkbDoodadPtr doodad; 765 for (doodad=section->doodads,i=0;i<section->num_doodads;i++,doodad++) { 766 size+= SizeXKMGeomDoodad(result,doodad); 767 } 768 } 769 if (section->overlays) { 770 XkbOverlayPtr ol; 771 for (ol=section->overlays,i=0;i<section->num_overlays;i++,ol++) { 772 register int r; 773 XkbOverlayRowPtr row; 774 size+= xkmSizeCountedAtomString(result->xkb->dpy,ol->name); 775 size+= SIZEOF(xkmOverlayDesc); 776 for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { 777 size+= SIZEOF(xkmOverlayRowDesc); 778 size+= row->num_keys*SIZEOF(xkmOverlayKeyDesc); 779 } 780 } 781 } 782 return size; 783} 784 785static unsigned 786SizeXKMGeometry(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout) 787{ 788register int i; 789Display * dpy; 790XkbDescPtr xkb; 791XkbGeometryPtr geom; 792unsigned size; 793 794 xkb= result->xkb; 795 dpy= xkb->dpy; 796 if ((!xkb)||(!xkb->geom)) 797 return 0; 798 geom= xkb->geom; 799 size= xkmSizeCountedAtomString(dpy,geom->name); 800 size+= SIZEOF(xkmGeometryDesc); 801 size+= xkmSizeCountedString(geom->label_font); 802 if (geom->properties) { 803 XkbPropertyPtr prop; 804 for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { 805 size+= xkmSizeCountedString(prop->name); 806 size+= xkmSizeCountedString(prop->value); 807 } 808 } 809 if (geom->colors) { 810 XkbColorPtr color; 811 for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) { 812 size+= xkmSizeCountedString(color->spec); 813 } 814 } 815 if (geom->shapes) { 816 XkbShapePtr shape; 817 for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { 818 register int n; 819 register XkbOutlinePtr ol; 820 size+= xkmSizeCountedAtomString(dpy,shape->name); 821 size+= SIZEOF(xkmShapeDesc); 822 for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) { 823 size+= SIZEOF(xkmOutlineDesc); 824 size+= ol->num_points*SIZEOF(xkmPointDesc); 825 } 826 } 827 } 828 if (geom->sections) { 829 XkbSectionPtr section; 830 for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { 831 size+= SizeXKMGeomSection(result,section); 832 } 833 } 834 if (geom->doodads) { 835 XkbDoodadPtr doodad; 836 for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) { 837 size+= SizeXKMGeomDoodad(result,doodad); 838 } 839 } 840 if (geom->key_aliases) { 841 size+= geom->num_key_aliases*(XkbKeyNameLength*2); 842 } 843 toc->type= XkmGeometryIndex; 844 toc->format= MSBFirst; 845 toc->size= size+SIZEOF(xkmSectionInfo); 846 toc->offset= (*offset_inout); 847 (*offset_inout)+= toc->size; 848 return 1; 849} 850 851static unsigned 852WriteXKMGeomDoodad(FILE *file,XkbFileInfo *result,XkbDoodadPtr doodad) 853{ 854Display * dpy; 855XkbDescPtr xkb; 856xkmDoodadDesc doodadWire; 857unsigned tmp,size= 0; 858 859 xkb= result->xkb; 860 dpy= xkb->dpy; 861 bzero((char *)&doodadWire,sizeof(doodadWire)); 862 doodadWire.any.type= doodad->any.type; 863 doodadWire.any.priority= doodad->any.priority; 864 doodadWire.any.top= doodad->any.top; 865 doodadWire.any.left= doodad->any.left; 866 switch (doodad->any.type) { 867 case XkbOutlineDoodad: 868 case XkbSolidDoodad: 869 doodadWire.shape.angle= doodad->shape.angle; 870 doodadWire.shape.color_ndx= doodad->shape.color_ndx; 871 doodadWire.shape.shape_ndx= doodad->shape.shape_ndx; 872 break; 873 case XkbTextDoodad: 874 doodadWire.text.angle= doodad->text.angle; 875 doodadWire.text.width= doodad->text.width; 876 doodadWire.text.height= doodad->text.height; 877 doodadWire.text.color_ndx= doodad->text.color_ndx; 878 break; 879 case XkbIndicatorDoodad: 880 doodadWire.indicator.shape_ndx= doodad->indicator.shape_ndx; 881 doodadWire.indicator.on_color_ndx= doodad->indicator.on_color_ndx; 882 doodadWire.indicator.off_color_ndx= doodad->indicator.off_color_ndx; 883 break; 884 case XkbLogoDoodad: 885 doodadWire.logo.angle= doodad->logo.angle; 886 doodadWire.logo.color_ndx= doodad->logo.color_ndx; 887 doodadWire.logo.shape_ndx= doodad->logo.shape_ndx; 888 break; 889 default: 890 _XkbLibError(_XkbErrIllegalDoodad,"WriteXKMGeomDoodad", 891 doodad->any.type); 892 return 0; 893 } 894 size+= xkmPutCountedAtomString(dpy,file,doodad->any.name); 895 tmp= fwrite(&doodadWire,SIZEOF(xkmDoodadDesc),1,file); 896 size+= tmp*SIZEOF(xkmDoodadDesc); 897 if (doodad->any.type==XkbTextDoodad) { 898 size+= xkmPutCountedString(file,doodad->text.text); 899 size+= xkmPutCountedString(file,doodad->text.font); 900 } 901 else if (doodad->any.type==XkbLogoDoodad) { 902 size+= xkmPutCountedString(file,doodad->logo.logo_name); 903 } 904 return size; 905} 906 907static unsigned 908WriteXKMGeomOverlay(FILE *file,XkbFileInfo *result,XkbOverlayPtr ol) 909{ 910register int r,k; 911Display * dpy; 912XkbDescPtr xkb; 913XkbOverlayRowPtr row; 914xkmOverlayDesc olWire; 915xkmOverlayRowDesc rowWire; 916xkmOverlayKeyDesc keyWire; 917unsigned tmp,size= 0; 918 919 xkb= result->xkb; 920 dpy= xkb->dpy; 921 bzero((char *)&olWire,sizeof(olWire)); 922 bzero((char *)&rowWire,sizeof(rowWire)); 923 bzero((char *)&keyWire,sizeof(keyWire)); 924 size+= xkmPutCountedAtomString(dpy,file,ol->name); 925 olWire.num_rows= ol->num_rows; 926 tmp= fwrite(&olWire,SIZEOF(xkmOverlayDesc),1,file); 927 size+= tmp*SIZEOF(xkmOverlayDesc); 928 for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { 929 XkbOverlayKeyPtr key; 930 rowWire.row_under= row->row_under; 931 rowWire.num_keys= row->num_keys; 932 tmp= fwrite(&rowWire,SIZEOF(xkmOverlayRowDesc),1,file); 933 size+= tmp*SIZEOF(xkmOverlayRowDesc); 934 for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 935 memcpy(keyWire.over,key->over.name,XkbKeyNameLength); 936 memcpy(keyWire.under,key->under.name,XkbKeyNameLength); 937 tmp= fwrite(&keyWire,SIZEOF(xkmOverlayKeyDesc),1,file); 938 size+= tmp*SIZEOF(xkmOverlayKeyDesc); 939 } 940 } 941 return size; 942} 943 944static unsigned 945WriteXKMGeomSection(FILE *file,XkbFileInfo *result,XkbSectionPtr section) 946{ 947register int i; 948Display * dpy; 949XkbDescPtr xkb; 950xkmSectionDesc sectionWire; 951unsigned tmp,size= 0; 952 953 xkb= result->xkb; 954 dpy= xkb->dpy; 955 size+= xkmPutCountedAtomString(dpy,file,section->name); 956 sectionWire.top= section->top; 957 sectionWire.left= section->left; 958 sectionWire.width= section->width; 959 sectionWire.height= section->height; 960 sectionWire.angle= section->angle; 961 sectionWire.priority= section->priority; 962 sectionWire.num_rows= section->num_rows; 963 sectionWire.num_doodads= section->num_doodads; 964 sectionWire.num_overlays= section->num_overlays; 965 tmp= fwrite(§ionWire,SIZEOF(xkmSectionDesc),1,file); 966 size+= tmp*SIZEOF(xkmSectionDesc); 967 if (section->rows) { 968 register unsigned k; 969 XkbRowPtr row; 970 xkmRowDesc rowWire; 971 XkbKeyPtr key; 972 xkmKeyDesc keyWire; 973 for (i=0,row=section->rows;i<section->num_rows;i++,row++) { 974 rowWire.top= row->top; 975 rowWire.left= row->left; 976 rowWire.num_keys= row->num_keys; 977 rowWire.vertical= row->vertical; 978 tmp= fwrite(&rowWire,SIZEOF(xkmRowDesc),1,file); 979 size+= tmp*SIZEOF(xkmRowDesc); 980 for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 981 memcpy(keyWire.name,key->name.name,XkbKeyNameLength); 982 keyWire.gap= key->gap; 983 keyWire.shape_ndx= key->shape_ndx; 984 keyWire.color_ndx= key->color_ndx; 985 tmp= fwrite(&keyWire,SIZEOF(xkmKeyDesc),1,file); 986 size+= tmp*SIZEOF(xkmKeyDesc); 987 } 988 } 989 } 990 if (section->doodads) { 991 XkbDoodadPtr doodad; 992 for (i=0,doodad=section->doodads;i<section->num_doodads;i++,doodad++) { 993 size+= WriteXKMGeomDoodad(file,result,doodad); 994 } 995 } 996 if (section->overlays) { 997 XkbOverlayPtr ol; 998 for (i=0,ol=section->overlays;i<section->num_overlays;i++,ol++) { 999 size+= WriteXKMGeomOverlay(file,result,ol); 1000 } 1001 } 1002 return size; 1003} 1004 1005static unsigned 1006WriteXKMGeometry(FILE *file,XkbFileInfo *result) 1007{ 1008register int i; 1009Display * dpy; 1010XkbDescPtr xkb; 1011XkbGeometryPtr geom; 1012xkmGeometryDesc wire; 1013unsigned tmp,size= 0; 1014 1015 xkb= result->xkb; 1016 dpy= xkb->dpy; 1017 if ((!xkb)||(!xkb->geom)) 1018 return 0; 1019 geom= xkb->geom; 1020 wire.width_mm= geom->width_mm; 1021 wire.height_mm= geom->height_mm; 1022 wire.base_color_ndx= XkbGeomColorIndex(geom,geom->base_color); 1023 wire.label_color_ndx= XkbGeomColorIndex(geom,geom->label_color); 1024 wire.num_properties= geom->num_properties; 1025 wire.num_colors= geom->num_colors; 1026 wire.num_shapes= geom->num_shapes; 1027 wire.num_sections= geom->num_sections; 1028 wire.num_doodads= geom->num_doodads; 1029 wire.num_key_aliases= geom->num_key_aliases; 1030 size+= xkmPutCountedAtomString(dpy,file,geom->name); 1031 tmp= fwrite(&wire,SIZEOF(xkmGeometryDesc),1,file); 1032 size+= tmp*SIZEOF(xkmGeometryDesc); 1033 size+= xkmPutCountedString(file,geom->label_font); 1034 if (geom->properties) { 1035 XkbPropertyPtr prop; 1036 for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { 1037 size+= xkmPutCountedString(file,prop->name); 1038 size+= xkmPutCountedString(file,prop->value); 1039 } 1040 } 1041 if (geom->colors) { 1042 XkbColorPtr color; 1043 for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) { 1044 size+= xkmPutCountedString(file,color->spec); 1045 } 1046 } 1047 if (geom->shapes) { 1048 XkbShapePtr shape; 1049 xkmShapeDesc shapeWire; 1050 1051 for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { 1052 register int n; 1053 XkbOutlinePtr ol; 1054 xkmOutlineDesc olWire; 1055 bzero((char *)&shapeWire,sizeof(xkmShapeDesc)); 1056 size+= xkmPutCountedAtomString(dpy,file,shape->name); 1057 shapeWire.num_outlines= shape->num_outlines; 1058 if (shape->primary!=NULL) 1059 shapeWire.primary_ndx= XkbOutlineIndex(shape,shape->primary); 1060 else shapeWire.primary_ndx= XkbNoShape; 1061 if (shape->approx!=NULL) 1062 shapeWire.approx_ndx= XkbOutlineIndex(shape,shape->approx); 1063 else shapeWire.approx_ndx= XkbNoShape; 1064 tmp= fwrite(&shapeWire,SIZEOF(xkmShapeDesc),1,file); 1065 size+= tmp*SIZEOF(xkmShapeDesc); 1066 for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) { 1067 register int p; 1068 XkbPointPtr pt; 1069 xkmPointDesc ptWire; 1070 olWire.num_points= ol->num_points; 1071 olWire.corner_radius= ol->corner_radius; 1072 tmp= fwrite(&olWire,SIZEOF(xkmOutlineDesc),1,file); 1073 size+= tmp*SIZEOF(xkmOutlineDesc); 1074 for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) { 1075 ptWire.x= pt->x; 1076 ptWire.y= pt->y; 1077 tmp= fwrite(&ptWire,SIZEOF(xkmPointDesc),1,file); 1078 size+= tmp*SIZEOF(xkmPointDesc); 1079 } 1080 } 1081 } 1082 } 1083 if (geom->sections) { 1084 XkbSectionPtr section; 1085 for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { 1086 size+= WriteXKMGeomSection(file,result,section); 1087 } 1088 } 1089 if (geom->doodads) { 1090 XkbDoodadPtr doodad; 1091 for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) { 1092 size+= WriteXKMGeomDoodad(file,result,doodad); 1093 } 1094 } 1095 if (geom->key_aliases) { 1096 tmp= fwrite(geom->key_aliases,2*XkbKeyNameLength,geom->num_key_aliases, 1097 file); 1098 size+= tmp*(2*XkbKeyNameLength); 1099 } 1100 return size; 1101} 1102 1103/***====================================================================***/ 1104 1105/*ARGSUSED*/ 1106static int 1107GetXKMKeyNamesTOC( XkbFileInfo * result, 1108 XkmInfo * info, 1109 int max_toc, 1110 xkmSectionInfo *toc_rtrn) 1111{ 1112int num_toc; 1113int total_size; 1114 1115 total_size= num_toc=0; 1116 if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size)) 1117 num_toc++; 1118 if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) 1119 num_toc++; 1120 return num_toc; 1121} 1122 1123/*ARGSUSED*/ 1124static int 1125GetXKMTypesTOC( XkbFileInfo * result, 1126 XkmInfo * info, 1127 int max_toc, 1128 xkmSectionInfo *toc_rtrn) 1129{ 1130int num_toc; 1131int total_size; 1132 1133 total_size= num_toc=0; 1134 if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) 1135 num_toc++; 1136 if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size)) 1137 num_toc++; 1138 return num_toc; 1139} 1140 1141/*ARGSUSED*/ 1142static int 1143GetXKMCompatMapTOC( XkbFileInfo * result, 1144 XkmInfo * info, 1145 int max_toc, 1146 xkmSectionInfo *toc_rtrn) 1147{ 1148int num_toc; 1149int total_size; 1150 1151 total_size= num_toc=0; 1152 if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) 1153 num_toc++; 1154 if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size)) 1155 num_toc++; 1156 if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) 1157 num_toc++; 1158 return num_toc; 1159} 1160 1161/*ARGSUSED*/ 1162static int 1163GetXKMSemanticsTOC( XkbFileInfo * result, 1164 XkmInfo * info, 1165 int max_toc, 1166 xkmSectionInfo *toc_rtrn) 1167{ 1168int num_toc; 1169int total_size; 1170 1171 total_size= num_toc=0; 1172 if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) 1173 num_toc++; 1174 if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size)) 1175 num_toc++; 1176 if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size)) 1177 num_toc++; 1178 if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) 1179 num_toc++; 1180 return num_toc; 1181} 1182 1183/*ARGSUSED*/ 1184static int 1185GetXKMLayoutTOC( XkbFileInfo * result, 1186 XkmInfo * info, 1187 int max_toc, 1188 xkmSectionInfo *toc_rtrn) 1189{ 1190int num_toc; 1191int total_size; 1192 1193 total_size= num_toc=0; 1194 if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) 1195 num_toc++; 1196 if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size)) 1197 num_toc++; 1198 if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size)) 1199 num_toc++; 1200 if (SizeXKMSymbols(result,info,&toc_rtrn[num_toc],&total_size)) 1201 num_toc++; 1202 if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) 1203 num_toc++; 1204 if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size)) 1205 num_toc++; 1206 return num_toc; 1207} 1208 1209/*ARGSUSED*/ 1210static int 1211GetXKMKeymapTOC( XkbFileInfo * result, 1212 XkmInfo * info, 1213 int max_toc, 1214 xkmSectionInfo *toc_rtrn) 1215{ 1216int num_toc; 1217int total_size; 1218 1219 total_size= num_toc=0; 1220 if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size)) 1221 num_toc++; 1222 if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size)) 1223 num_toc++; 1224 if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size)) 1225 num_toc++; 1226 if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size)) 1227 num_toc++; 1228 if (SizeXKMSymbols(result,info,&toc_rtrn[num_toc],&total_size)) 1229 num_toc++; 1230 if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size)) 1231 num_toc++; 1232 if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size)) 1233 num_toc++; 1234 return num_toc; 1235} 1236 1237/*ARGSUSED*/ 1238static int 1239GetXKMGeometryTOC( XkbFileInfo * result, 1240 XkmInfo * info, 1241 int max_toc, 1242 xkmSectionInfo *toc_rtrn) 1243{ 1244int num_toc; 1245int total_size; 1246 1247 total_size= num_toc=0; 1248 if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size)) 1249 num_toc++; 1250 return num_toc; 1251} 1252 1253static Bool 1254WriteXKMFile( FILE * file, 1255 XkbFileInfo * result, 1256 int num_toc, 1257 xkmSectionInfo *toc, 1258 XkmInfo * info) 1259{ 1260register int i; 1261unsigned tmp,size,total= 0; 1262 1263 for (i=0;i<num_toc;i++) { 1264 tmp= fwrite(&toc[i],SIZEOF(xkmSectionInfo),1,file); 1265 total+= tmp*SIZEOF(xkmSectionInfo); 1266 switch (toc[i].type) { 1267 case XkmTypesIndex: 1268 size= WriteXKMKeyTypes(file,result); 1269 break; 1270 case XkmCompatMapIndex: 1271 size= WriteXKMCompatMap(file,result,info); 1272 break; 1273 case XkmSymbolsIndex: 1274 size= WriteXKMSymbols(file,result,info); 1275 break; 1276 case XkmIndicatorsIndex: 1277 size= WriteXKMIndicators(file,result,info); 1278 break; 1279 case XkmKeyNamesIndex: 1280 size= WriteXKMKeycodes(file,result); 1281 break; 1282 case XkmGeometryIndex: 1283 size= WriteXKMGeometry(file,result); 1284 break; 1285 case XkmVirtualModsIndex: 1286 size= WriteXKMVirtualMods(file,result,info); 1287 break; 1288 default: 1289 _XkbLibError(_XkbErrIllegalTOCType,"WriteXKMFile",toc[i].type); 1290 return False; 1291 } 1292 size+= SIZEOF(xkmSectionInfo); 1293 if (size!=toc[i].size) { 1294 _XkbLibError(_XkbErrBadLength,XkbConfigText(toc[i].type,XkbMessage), 1295 size-toc[i].size); 1296 return False; 1297 } 1298 } 1299 return True; 1300} 1301 1302 1303#define MAX_TOC 16 1304 1305Bool 1306XkbWriteXKMFile(FILE *out,XkbFileInfo *result) 1307{ 1308Bool ok; 1309XkbDescPtr xkb; 1310XkmInfo info; 1311int size_toc,i; 1312unsigned hdr,present; 1313xkmFileInfo fileInfo; 1314xkmSectionInfo toc[MAX_TOC]; 1315int (*getTOC)( 1316 XkbFileInfo * /* result */, 1317 XkmInfo * /* info */, 1318 int /* max_to */, 1319 xkmSectionInfo */* toc_rtrn */ 1320); 1321 1322 switch (result->type) { 1323 case XkmKeyNamesIndex: 1324 getTOC= GetXKMKeyNamesTOC; 1325 break; 1326 case XkmTypesIndex: 1327 getTOC= GetXKMTypesTOC; 1328 break; 1329 case XkmCompatMapIndex: 1330 getTOC= GetXKMCompatMapTOC; 1331 break; 1332 case XkmSemanticsFile: 1333 getTOC= GetXKMSemanticsTOC; 1334 break; 1335 case XkmLayoutFile: 1336 getTOC= GetXKMLayoutTOC; 1337 break; 1338 case XkmKeymapFile: 1339 getTOC= GetXKMKeymapTOC; 1340 break; 1341 case XkmGeometryFile: 1342 case XkmGeometryIndex: 1343 getTOC= GetXKMGeometryTOC; 1344 break; 1345 default: 1346 _XkbLibError(_XkbErrIllegalContents, 1347 XkbConfigText(result->type,XkbMessage),0); 1348 return False; 1349 } 1350 xkb= result->xkb; 1351 1352 bzero((char *)&info,sizeof(XkmInfo)); 1353 size_toc= (*getTOC)(result,&info,MAX_TOC,toc); 1354 if (size_toc<1) { 1355 _XkbLibError(_XkbErrEmptyFile,"XkbWriteXKMFile",0); 1356 return False; 1357 } 1358 if (out==NULL) { 1359 _XkbLibError(_XkbErrFileCannotOpen,"XkbWriteXKMFile",0); 1360 return False; 1361 } 1362 for (i=present=0;i<size_toc;i++) { 1363 toc[i].offset+= 4+SIZEOF(xkmFileInfo); 1364 toc[i].offset+= (size_toc*SIZEOF(xkmSectionInfo)); 1365 if (toc[i].type<=XkmLastIndex) { 1366 present|= (1<<toc[i].type); 1367 } 1368#ifdef DEBUG 1369 else { 1370 fprintf(stderr,"Illegal section type %d\n",toc[i].type); 1371 fprintf(stderr,"Ignored\n"); 1372 } 1373#endif 1374 } 1375 hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion); 1376 xkmPutCARD32(out,(unsigned long)hdr); 1377 fileInfo.type= result->type; 1378 fileInfo.min_kc= xkb->min_key_code; 1379 fileInfo.max_kc= xkb->max_key_code; 1380 fileInfo.num_toc= size_toc; 1381 fileInfo.present= present; 1382 fileInfo.pad= 0; 1383 fwrite(&fileInfo,SIZEOF(xkmFileInfo),1,out); 1384 fwrite(toc,SIZEOF(xkmSectionInfo),size_toc,out); 1385 ok= WriteXKMFile(out,result,size_toc,toc,&info); 1386 return ok; 1387} 1388