xkbout.c revision 4642e01f
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_DIX_CONFIG_H 28#include <dix-config.h> 29#endif 30 31#include <stdio.h> 32#include <ctype.h> 33#include <stdlib.h> 34#include <X11/Xfuncs.h> 35 36#include <X11/X.h> 37#define NEED_EVENTS 38#include <X11/keysym.h> 39#include <X11/Xproto.h> 40#include "misc.h" 41#include "inputstr.h" 42#include "dix.h" 43#include "xkbstr.h" 44#define XKBSRV_NEED_FILE_FUNCS 1 45#include <xkbsrv.h> 46 47#include "xkbgeom.h" 48#include "xkbfile.h" 49 50#define VMOD_HIDE_VALUE 0 51#define VMOD_SHOW_VALUE 1 52#define VMOD_COMMENT_VALUE 2 53 54static Bool 55WriteXKBVModDecl(FILE *file,XkbDescPtr xkb,int showValue) 56{ 57register int i,nMods; 58Atom * vmodNames; 59 60 if (xkb==NULL) 61 return False; 62 if (xkb->names!=NULL) 63 vmodNames= xkb->names->vmods; 64 else vmodNames= NULL; 65 66 for (i=nMods=0;i<XkbNumVirtualMods;i++) { 67 if ((vmodNames!=NULL)&&(vmodNames[i]!=None)) { 68 if (nMods==0) fprintf(file," virtual_modifiers "); 69 else fprintf(file,","); 70 fprintf(file,"%s",XkbAtomText(vmodNames[i],XkbXKBFile)); 71 if ((showValue!=VMOD_HIDE_VALUE)&& 72 (xkb->server)&&(xkb->server->vmods[i]!=XkbNoModifierMask)) { 73 if (showValue==VMOD_COMMENT_VALUE) { 74 fprintf(file,"/* = %s */", 75 XkbModMaskText(xkb->server->vmods[i],XkbXKBFile)); 76 } 77 else { 78 fprintf(file,"= %s", 79 XkbModMaskText(xkb->server->vmods[i],XkbXKBFile)); 80 } 81 } 82 nMods++; 83 } 84 } 85 if (nMods>0) 86 fprintf(file,";\n\n"); 87 return True; 88} 89 90/***====================================================================***/ 91 92static Bool 93WriteXKBAction(FILE *file,XkbDescPtr xkb,XkbAnyAction *action) 94{ 95 fprintf(file,"%s",XkbActionText(xkb,(XkbAction *)action,XkbXKBFile)); 96 return True; 97} 98 99/***====================================================================***/ 100 101Bool 102XkbWriteXKBKeycodes( FILE * file, 103 XkbDescPtr xkb, 104 Bool topLevel, 105 Bool showImplicit, 106 XkbFileAddOnFunc addOn, 107 void * priv) 108{ 109Atom kcName; 110register unsigned i; 111char * alternate; 112 113 if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) { 114 _XkbLibError(_XkbErrMissingNames,"XkbWriteXKBKeycodes",0); 115 return False; 116 } 117 kcName= xkb->names->keycodes; 118 if (kcName!=None) 119 fprintf(file,"xkb_keycodes \"%s\" {\n", 120 XkbAtomText(kcName,XkbXKBFile)); 121 else fprintf(file,"xkb_keycodes {\n"); 122 fprintf(file," minimum = %d;\n",xkb->min_key_code); 123 fprintf(file," maximum = %d;\n",xkb->max_key_code); 124 for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 125 if (xkb->names->keys[i].name[0]!='\0') { 126 if (XkbFindKeycodeByName(xkb,xkb->names->keys[i].name,True)!=i) 127 alternate= "alternate "; 128 else alternate= ""; 129 fprintf(file," %s%6s = %d;\n",alternate, 130 XkbKeyNameText(xkb->names->keys[i].name,XkbXKBFile), 131 i); 132 } 133 } 134 if (xkb->indicators!=NULL) { 135 for (i=0;i<XkbNumIndicators;i++) { 136 char *type; 137 if (xkb->indicators->phys_indicators&(1<<i)) 138 type= " "; 139 else type= " virtual "; 140 if (xkb->names->indicators[i]!=None) { 141 fprintf(file,"%sindicator %d = \"%s\";\n",type,i+1, 142 XkbAtomText(xkb->names->indicators[i],XkbXKBFile)); 143 } 144 } 145 } 146 if (xkb->names->key_aliases!=NULL) { 147 XkbKeyAliasPtr pAl; 148 pAl= xkb->names->key_aliases; 149 for (i=0;i<xkb->names->num_key_aliases;i++,pAl++) { 150 fprintf(file," alias %6s = %6s;\n", 151 XkbKeyNameText(pAl->alias,XkbXKBFile), 152 XkbKeyNameText(pAl->real,XkbXKBFile)); 153 } 154 } 155 if (addOn) 156 (*addOn)(file,xkb,topLevel,showImplicit,XkmKeyNamesIndex,priv); 157 fprintf(file,"};\n\n"); 158 return True; 159} 160 161Bool 162XkbWriteXKBKeyTypes( FILE * file, 163 XkbDescPtr xkb, 164 Bool topLevel, 165 Bool showImplicit, 166 XkbFileAddOnFunc addOn, 167 void * priv) 168{ 169register unsigned i,n; 170XkbKeyTypePtr type; 171XkbKTMapEntryPtr entry; 172 173 if ((!xkb)||(!xkb->map)||(!xkb->map->types)) { 174 _XkbLibError(_XkbErrMissingTypes,"XkbWriteXKBKeyTypes",0); 175 return False; 176 } 177 if (xkb->map->num_types<XkbNumRequiredTypes) { 178 _XkbLibError(_XkbErrMissingReqTypes,"XkbWriteXKBKeyTypes",0); 179 return 0; 180 } 181 if ((xkb->names==NULL)||(xkb->names->types==None)) 182 fprintf(file,"xkb_types {\n\n"); 183 else fprintf(file,"xkb_types \"%s\" {\n\n", 184 XkbAtomText(xkb->names->types,XkbXKBFile)); 185 WriteXKBVModDecl(file,xkb, 186 (showImplicit?VMOD_COMMENT_VALUE:VMOD_HIDE_VALUE)); 187 188 type= xkb->map->types; 189 for (i=0;i<xkb->map->num_types;i++,type++) { 190 fprintf(file," type \"%s\" {\n", 191 XkbAtomText(type->name,XkbXKBFile)); 192 fprintf(file," modifiers= %s;\n", 193 XkbVModMaskText(xkb,type->mods.real_mods,type->mods.vmods, 194 XkbXKBFile)); 195 entry= type->map; 196 for (n=0;n<type->map_count;n++,entry++) { 197 char *str; 198 str=XkbVModMaskText(xkb,entry->mods.real_mods,entry->mods.vmods, 199 XkbXKBFile); 200 fprintf(file," map[%s]= Level%d;\n",str,entry->level+1); 201 if ((type->preserve)&&((type->preserve[n].real_mods)|| 202 (type->preserve[n].vmods))) { 203 fprintf(file," preserve[%s]= ",str); 204 fprintf(file,"%s;\n",XkbVModMaskText(xkb, 205 type->preserve[n].real_mods, 206 type->preserve[n].vmods, 207 XkbXKBFile)); 208 } 209 } 210 if (type->level_names!=NULL) { 211 Atom *name= type->level_names; 212 for (n=0;n<type->num_levels;n++,name++) { 213 if ((*name)==None) 214 continue; 215 fprintf(file," level_name[Level%d]= \"%s\";\n",n+1, 216 XkbAtomText(*name,XkbXKBFile)); 217 } 218 } 219 fprintf(file," };\n"); 220 } 221 if (addOn) 222 (*addOn)(file,xkb,topLevel,showImplicit,XkmTypesIndex,priv); 223 fprintf(file,"};\n\n"); 224 return True; 225} 226 227static Bool 228WriteXKBIndicatorMap( FILE * file, 229 XkbDescPtr xkb, 230 Atom name, 231 XkbIndicatorMapPtr led, 232 XkbFileAddOnFunc addOn, 233 void * priv) 234{ 235 236 fprintf(file," indicator \"%s\" {\n",XkbAtomGetString(name)); 237 if (led->flags&XkbIM_NoExplicit) 238 fprintf(file," !allowExplicit;\n"); 239 if (led->flags&XkbIM_LEDDrivesKB) 240 fprintf(file," indicatorDrivesKeyboard;\n"); 241 if (led->which_groups!=0) { 242 if (led->which_groups!=XkbIM_UseEffective) { 243 fprintf(file," whichGroupState= %s;\n", 244 XkbIMWhichStateMaskText(led->which_groups,XkbXKBFile)); 245 } 246 fprintf(file," groups= 0x%02x;\n",led->groups); 247 } 248 if (led->which_mods!=0) { 249 if (led->which_mods!=XkbIM_UseEffective) { 250 fprintf(file," whichModState= %s;\n", 251 XkbIMWhichStateMaskText(led->which_mods,XkbXKBFile)); 252 } 253 fprintf(file," modifiers= %s;\n", 254 XkbVModMaskText(xkb, 255 led->mods.real_mods,led->mods.vmods, 256 XkbXKBFile)); 257 } 258 if (led->ctrls!=0) { 259 fprintf(file," controls= %s;\n", 260 XkbControlsMaskText(led->ctrls,XkbXKBFile)); 261 } 262 if (addOn) 263 (*addOn)(file,xkb,False,True,XkmIndicatorsIndex,priv); 264 fprintf(file," };\n"); 265 return True; 266} 267 268Bool 269XkbWriteXKBCompatMap( FILE * file, 270 XkbDescPtr xkb, 271 Bool topLevel, 272 Bool showImplicit, 273 XkbFileAddOnFunc addOn, 274 void * priv) 275{ 276register unsigned i; 277XkbSymInterpretPtr interp; 278 279 if ((!xkb)||(!xkb->compat)||(!xkb->compat->sym_interpret)) { 280 _XkbLibError(_XkbErrMissingCompatMap,"XkbWriteXKBCompatMap",0); 281 return False; 282 } 283 if ((xkb->names==NULL)||(xkb->names->compat==None)) 284 fprintf(file,"xkb_compatibility {\n\n"); 285 else fprintf(file,"xkb_compatibility \"%s\" {\n\n", 286 XkbAtomText(xkb->names->compat,XkbXKBFile)); 287 WriteXKBVModDecl(file,xkb, 288 (showImplicit?VMOD_COMMENT_VALUE:VMOD_HIDE_VALUE)); 289 290 fprintf(file," interpret.useModMapMods= AnyLevel;\n"); 291 fprintf(file," interpret.repeat= False;\n"); 292 fprintf(file," interpret.locking= False;\n"); 293 interp= xkb->compat->sym_interpret; 294 for (i=0;i<xkb->compat->num_si;i++,interp++) { 295 fprintf(file," interpret %s+%s(%s) {\n", 296 ((interp->sym==NoSymbol)?"Any": 297 XkbKeysymText(interp->sym,XkbXKBFile)), 298 XkbSIMatchText(interp->match,XkbXKBFile), 299 XkbModMaskText(interp->mods,XkbXKBFile)); 300 if (interp->virtual_mod!=XkbNoModifier) { 301 fprintf(file," virtualModifier= %s;\n", 302 XkbVModIndexText(xkb,interp->virtual_mod,XkbXKBFile)); 303 } 304 if (interp->match&XkbSI_LevelOneOnly) 305 fprintf(file," useModMapMods=level1;\n"); 306 if (interp->flags&XkbSI_LockingKey) 307 fprintf(file," locking= True;\n"); 308 if (interp->flags&XkbSI_AutoRepeat) 309 fprintf(file," repeat= True;\n"); 310 fprintf(file," action= "); 311 WriteXKBAction(file,xkb,&interp->act); 312 fprintf(file,";\n"); 313 fprintf(file," };\n"); 314 } 315 for (i=0;i<XkbNumKbdGroups;i++) { 316 XkbModsPtr gc; 317 318 gc= &xkb->compat->groups[i]; 319 if ((gc->real_mods==0)&&(gc->vmods==0)) 320 continue; 321 fprintf(file," group %d = %s;\n",i+1,XkbVModMaskText(xkb, 322 gc->real_mods,gc->vmods, 323 XkbXKBFile)); 324 } 325 if (xkb->indicators) { 326 for (i=0;i<XkbNumIndicators;i++) { 327 XkbIndicatorMapPtr map= &xkb->indicators->maps[i]; 328 if ((map->flags!=0)||(map->which_groups!=0)||(map->groups!=0)|| 329 (map->which_mods!=0)|| 330 (map->mods.real_mods!=0)||(map->mods.vmods!=0)|| 331 (map->ctrls!=0)) { 332 WriteXKBIndicatorMap(file,xkb,xkb->names->indicators[i],map, 333 addOn,priv); 334 } 335 } 336 } 337 if (addOn) 338 (*addOn)(file,xkb,topLevel,showImplicit,XkmCompatMapIndex,priv); 339 fprintf(file,"};\n\n"); 340 return True; 341} 342 343Bool 344XkbWriteXKBSymbols( FILE * file, 345 XkbDescPtr xkb, 346 Bool topLevel, 347 Bool showImplicit, 348 XkbFileAddOnFunc addOn, 349 void * priv) 350{ 351register unsigned i,tmp; 352XkbClientMapPtr map; 353XkbServerMapPtr srv; 354Bool showActions; 355 356 map= xkb->map; 357 srv= xkb->server; 358 if ((!xkb)||(!map)||(!map->syms)||(!map->key_sym_map)) { 359 _XkbLibError(_XkbErrMissingSymbols,"XkbWriteXKBSymbols",0); 360 return False; 361 } 362 if ((!xkb->names)||(!xkb->names->keys)) { 363 _XkbLibError(_XkbErrMissingNames,"XkbWriteXKBSymbols",0); 364 return False; 365 } 366 if ((xkb->names==NULL)||(xkb->names->symbols==None)) 367 fprintf(file,"xkb_symbols {\n\n"); 368 else fprintf(file,"xkb_symbols \"%s\" {\n\n", 369 XkbAtomText(xkb->names->symbols,XkbXKBFile)); 370 for (tmp=i=0;i<XkbNumKbdGroups;i++) { 371 if (xkb->names->groups[i]!=None) { 372 fprintf(file," name[group%d]=\"%s\";\n",i+1, 373 XkbAtomText(xkb->names->groups[i],XkbXKBFile)); 374 tmp++; 375 } 376 } 377 if (tmp>0) 378 fprintf(file,"\n"); 379 for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 380 Bool simple; 381 if ((int)XkbKeyNumSyms(xkb,i)<1) 382 continue; 383 if (XkbFindKeycodeByName(xkb,xkb->names->keys[i].name,True)!=i) 384 continue; 385 simple= True; 386 fprintf(file," key %6s {", 387 XkbKeyNameText(xkb->names->keys[i].name,XkbXKBFile)); 388 if (srv->explicit) { 389 if (((srv->explicit[i]&XkbExplicitKeyTypesMask)!=0)|| 390 (showImplicit)) { 391 int typeNdx,g; 392 Bool multi; 393 char * comment=" "; 394 395 if ((srv->explicit[i]&XkbExplicitKeyTypesMask)==0) 396 comment= "//"; 397 multi= False; 398 typeNdx= XkbKeyKeyTypeIndex(xkb,i,0); 399 for (g=1;(g<XkbKeyNumGroups(xkb,i))&&(!multi);g++) { 400 if (XkbKeyKeyTypeIndex(xkb,i,g)!=typeNdx) 401 multi= True; 402 } 403 if (multi) { 404 for (g=0;g<XkbKeyNumGroups(xkb,i);g++) { 405 typeNdx= XkbKeyKeyTypeIndex(xkb,i,g); 406 if (srv->explicit[i]&(1<<g)) { 407 fprintf(file,"\n%s type[group%d]= \"%s\",", 408 comment,g+1, 409 XkbAtomText(map->types[typeNdx].name, 410 XkbXKBFile)); 411 } 412 else if (showImplicit) { 413 fprintf(file,"\n// type[group%d]= \"%s\",",g+1, 414 XkbAtomText(map->types[typeNdx].name, 415 XkbXKBFile)); 416 } 417 } 418 } 419 else { 420 fprintf(file,"\n%s type= \"%s\",",comment, 421 XkbAtomText(map->types[typeNdx].name, 422 XkbXKBFile)); 423 } 424 simple= False; 425 } 426 if (((srv->explicit[i]&XkbExplicitAutoRepeatMask)!=0)&& 427 (xkb->ctrls!=NULL)) { 428 if (xkb->ctrls->per_key_repeat[i/8]&(1<<(i%8))) 429 fprintf(file,"\n repeat= Yes,"); 430 else fprintf(file,"\n repeat= No,"); 431 simple= False; 432 } 433 if ((xkb->server!=NULL)&&(xkb->server->vmodmap!=NULL)&& 434 (xkb->server->vmodmap[i]!=0)) { 435 if ((srv->explicit[i]&XkbExplicitVModMapMask)!=0) { 436 fprintf(file,"\n virtualMods= %s,", 437 XkbVModMaskText(xkb,0, 438 xkb->server->vmodmap[i], 439 XkbXKBFile)); 440 } 441 else if (showImplicit) { 442 fprintf(file,"\n// virtualMods= %s,", 443 XkbVModMaskText(xkb,0, 444 xkb->server->vmodmap[i], 445 XkbXKBFile)); 446 } 447 } 448 } 449 switch (XkbOutOfRangeGroupAction(XkbKeyGroupInfo(xkb,i))) { 450 case XkbClampIntoRange: 451 fprintf(file,"\n groupsClamp,"); 452 break; 453 case XkbRedirectIntoRange: 454 fprintf(file,"\n groupsRedirect= Group%d,", 455 XkbOutOfRangeGroupNumber(XkbKeyGroupInfo(xkb,i))+1); 456 break; 457 } 458 if (srv->behaviors!=NULL) { 459 unsigned type; 460 type= srv->behaviors[i].type&XkbKB_OpMask; 461 462 if (type!=XkbKB_Default) { 463 simple= False; 464 fprintf(file,"\n %s,", 465 XkbBehaviorText(xkb,&srv->behaviors[i],XkbXKBFile)); 466 } 467 } 468 if ((srv->explicit==NULL) || showImplicit || 469 ((srv->explicit[i]&XkbExplicitInterpretMask)!=0)) 470 showActions= XkbKeyHasActions(xkb,i); 471 else showActions= False; 472 473 if (((unsigned)XkbKeyNumGroups(xkb,i)>1)||showActions) 474 simple= False; 475 if (simple) { 476 KeySym *syms; 477 unsigned s; 478 479 syms= XkbKeySymsPtr(xkb,i); 480 fprintf(file," [ "); 481 for (s=0;s<XkbKeyGroupWidth(xkb,i,XkbGroup1Index);s++) { 482 if (s!=0) 483 fprintf(file,", "); 484 fprintf(file,"%15s",XkbKeysymText(*syms++,XkbXKBFile)); 485 } 486 fprintf(file," ] };\n"); 487 } 488 else { 489 unsigned g,s; 490 KeySym *syms; 491 XkbAction *acts; 492 syms= XkbKeySymsPtr(xkb,i); 493 acts= XkbKeyActionsPtr(xkb,i); 494 for (g=0;g<XkbKeyNumGroups(xkb,i);g++) { 495 if (g!=0) 496 fprintf(file,","); 497 fprintf(file,"\n symbols[Group%d]= [ ",g+1); 498 for (s=0;s<XkbKeyGroupWidth(xkb,i,g);s++) { 499 if (s!=0) 500 fprintf(file,", "); 501 fprintf(file,"%15s",XkbKeysymText(syms[s],XkbXKBFile)); 502 } 503 fprintf(file," ]"); 504 syms+= XkbKeyGroupsWidth(xkb,i); 505 if (showActions) { 506 fprintf(file,",\n actions[Group%d]= [ ",g+1); 507 for (s=0;s<XkbKeyGroupWidth(xkb,i,g);s++) { 508 if (s!=0) 509 fprintf(file,", "); 510 WriteXKBAction(file,xkb,(XkbAnyAction *)&acts[s]); 511 } 512 fprintf(file," ]"); 513 acts+= XkbKeyGroupsWidth(xkb,i); 514 } 515 } 516 fprintf(file,"\n };\n"); 517 } 518 } 519 if (map && map->modmap) { 520 for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 521 if (map->modmap[i]!=0) { 522 register int n,bit; 523 for (bit=1,n=0;n<XkbNumModifiers;n++,bit<<=1) { 524 if (map->modmap[i]&bit) { 525 char buf[5]; 526 memcpy(buf,xkb->names->keys[i].name,4); 527 buf[4]= '\0'; 528 fprintf(file," modifier_map %s { <%s> };\n", 529 XkbModIndexText(n,XkbXKBFile),buf); 530 } 531 } 532 } 533 } 534 } 535 if (addOn) 536 (*addOn)(file,xkb,topLevel,showImplicit,XkmSymbolsIndex,priv); 537 fprintf(file,"};\n\n"); 538 return True; 539} 540 541static Bool 542WriteXKBOutline( FILE * file, 543 XkbShapePtr shape, 544 XkbOutlinePtr outline, 545 int lastRadius, 546 int first, 547 int indent) 548{ 549register int i; 550XkbPointPtr pt; 551char * iStr; 552 553 fprintf(file,"%s",iStr= XkbIndentText(first)); 554 if (first!=indent) 555 iStr= XkbIndentText(indent); 556 if (outline->corner_radius!=lastRadius) { 557 fprintf(file,"corner= %s,", 558 XkbGeomFPText(outline->corner_radius,XkbMessage)); 559 if (shape!=NULL) { 560 fprintf(file,"\n%s",iStr); 561 } 562 } 563 if (shape) { 564 if (outline==shape->approx) 565 fprintf(file,"approx= "); 566 else if (outline==shape->primary) 567 fprintf(file,"primary= "); 568 } 569 fprintf(file,"{"); 570 for (pt=outline->points,i=0;i<outline->num_points;i++,pt++) { 571 if (i==0) fprintf(file," "); 572 else if ((i%4)==0) fprintf(file,",\n%s ",iStr); 573 else fprintf(file,", "); 574 fprintf(file,"[ %3s, %3s ]",XkbGeomFPText(pt->x,XkbXKBFile), 575 XkbGeomFPText(pt->y,XkbXKBFile)); 576 } 577 fprintf(file," }"); 578 return True; 579} 580 581static Bool 582WriteXKBDoodad( FILE * file, 583 unsigned indent, 584 XkbGeometryPtr geom, 585 XkbDoodadPtr doodad) 586{ 587register char * i_str; 588XkbShapePtr shape; 589XkbColorPtr color; 590 591 i_str= XkbIndentText(indent); 592 fprintf(file,"%s%s \"%s\" {\n",i_str, 593 XkbDoodadTypeText(doodad->any.type,XkbMessage), 594 XkbAtomText(doodad->any.name,XkbMessage)); 595 fprintf(file,"%s top= %s;\n",i_str, 596 XkbGeomFPText(doodad->any.top,XkbXKBFile)); 597 fprintf(file,"%s left= %s;\n",i_str, 598 XkbGeomFPText(doodad->any.left,XkbXKBFile)); 599 fprintf(file,"%s priority= %d;\n",i_str,doodad->any.priority); 600 switch (doodad->any.type) { 601 case XkbOutlineDoodad: 602 case XkbSolidDoodad: 603 if (doodad->shape.angle!=0) { 604 fprintf(file,"%s angle= %s;\n",i_str, 605 XkbGeomFPText(doodad->shape.angle,XkbXKBFile)); 606 } 607 if (doodad->shape.color_ndx!=0) { 608 fprintf(file,"%s color= \"%s\";\n",i_str, 609 XkbShapeDoodadColor(geom,&doodad->shape)->spec); 610 } 611 shape= XkbShapeDoodadShape(geom,&doodad->shape); 612 fprintf(file,"%s shape= \"%s\";\n",i_str, 613 XkbAtomText(shape->name,XkbXKBFile)); 614 break; 615 case XkbTextDoodad: 616 if (doodad->text.angle!=0) { 617 fprintf(file,"%s angle= %s;\n",i_str, 618 XkbGeomFPText(doodad->text.angle,XkbXKBFile)); 619 } 620 if (doodad->text.width!=0) { 621 fprintf(file,"%s width= %s;\n",i_str, 622 XkbGeomFPText(doodad->text.width,XkbXKBFile)); 623 624 } 625 if (doodad->text.height!=0) { 626 fprintf(file,"%s height= %s;\n",i_str, 627 XkbGeomFPText(doodad->text.height,XkbXKBFile)); 628 629 } 630 if (doodad->text.color_ndx!=0) { 631 color= XkbTextDoodadColor(geom,&doodad->text); 632 fprintf(file,"%s color= \"%s\";\n",i_str, 633 XkbStringText(color->spec,XkbXKBFile)); 634 } 635 fprintf(file,"%s XFont= \"%s\";\n",i_str, 636 XkbStringText(doodad->text.font,XkbXKBFile)); 637 fprintf(file,"%s text= \"%s\";\n",i_str, 638 XkbStringText(doodad->text.text,XkbXKBFile)); 639 break; 640 case XkbIndicatorDoodad: 641 shape= XkbIndicatorDoodadShape(geom,&doodad->indicator); 642 color= XkbIndicatorDoodadOnColor(geom,&doodad->indicator); 643 fprintf(file,"%s onColor= \"%s\";\n",i_str, 644 XkbStringText(color->spec,XkbXKBFile)); 645 color= XkbIndicatorDoodadOffColor(geom,&doodad->indicator); 646 fprintf(file,"%s offColor= \"%s\";\n",i_str, 647 XkbStringText(color->spec,XkbXKBFile)); 648 fprintf(file,"%s shape= \"%s\";\n",i_str, 649 XkbAtomText(shape->name,XkbXKBFile)); 650 break; 651 case XkbLogoDoodad: 652 fprintf(file,"%s logoName= \"%s\";\n",i_str, 653 XkbStringText(doodad->logo.logo_name,XkbXKBFile)); 654 if (doodad->shape.angle!=0) { 655 fprintf(file,"%s angle= %s;\n",i_str, 656 XkbGeomFPText(doodad->logo.angle,XkbXKBFile)); 657 } 658 if (doodad->shape.color_ndx!=0) { 659 fprintf(file,"%s color= \"%s\";\n",i_str, 660 XkbLogoDoodadColor(geom,&doodad->logo)->spec); 661 } 662 shape= XkbLogoDoodadShape(geom,&doodad->logo); 663 fprintf(file,"%s shape= \"%s\";\n",i_str, 664 XkbAtomText(shape->name,XkbXKBFile)); 665 break; 666 } 667 fprintf(file,"%s};\n",i_str); 668 return True; 669} 670 671/*ARGSUSED*/ 672static Bool 673WriteXKBOverlay( FILE * file, 674 unsigned indent, 675 XkbGeometryPtr geom, 676 XkbOverlayPtr ol) 677{ 678register char * i_str; 679int r,k,nOut; 680XkbOverlayRowPtr row; 681XkbOverlayKeyPtr key; 682 683 i_str= XkbIndentText(indent); 684 if (ol->name!=None) { 685 fprintf(file,"%soverlay \"%s\" {\n",i_str, 686 XkbAtomText(ol->name,XkbMessage)); 687 } 688 else fprintf(file,"%soverlay {\n",i_str); 689 for (nOut=r=0,row=ol->rows;r<ol->num_rows;r++,row++) { 690 for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 691 char *over,*under; 692 over= XkbKeyNameText(key->over.name,XkbXKBFile); 693 under= XkbKeyNameText(key->under.name,XkbXKBFile); 694 if (nOut==0) 695 fprintf(file,"%s %6s=%6s",i_str,under,over); 696 else if ((nOut%4)==0) 697 fprintf(file,",\n%s %6s=%6s",i_str,under,over); 698 else fprintf(file,", %6s=%6s",under,over); 699 nOut++; 700 } 701 } 702 fprintf(file,"\n%s};\n",i_str); 703 return True; 704} 705 706static Bool 707WriteXKBSection( FILE * file, 708 XkbSectionPtr s, 709 XkbGeometryPtr geom) 710{ 711register int i; 712XkbRowPtr row; 713int dfltKeyColor = 0; 714 715 fprintf(file," section \"%s\" {\n", 716 XkbAtomText(s->name,XkbXKBFile)); 717 if (s->rows&&(s->rows->num_keys>0)) { 718 dfltKeyColor= s->rows->keys[0].color_ndx; 719 fprintf(file," key.color= \"%s\";\n", 720 XkbStringText(geom->colors[dfltKeyColor].spec,XkbXKBFile)); 721 } 722 fprintf(file," priority= %d;\n",s->priority); 723 fprintf(file," top= %s;\n",XkbGeomFPText(s->top,XkbXKBFile)); 724 fprintf(file," left= %s;\n",XkbGeomFPText(s->left,XkbXKBFile)); 725 fprintf(file," width= %s;\n",XkbGeomFPText(s->width,XkbXKBFile)); 726 fprintf(file," height= %s;\n", 727 XkbGeomFPText(s->height,XkbXKBFile)); 728 if (s->angle!=0) { 729 fprintf(file," angle= %s;\n", 730 XkbGeomFPText(s->angle,XkbXKBFile)); 731 } 732 for (i=0,row=s->rows;i<s->num_rows;i++,row++) { 733 fprintf(file," row {\n"); 734 fprintf(file," top= %s;\n", 735 XkbGeomFPText(row->top,XkbXKBFile)); 736 fprintf(file," left= %s;\n", 737 XkbGeomFPText(row->left,XkbXKBFile)); 738 if (row->vertical) 739 fprintf(file," vertical;\n"); 740 if (row->num_keys>0) { 741 register int k; 742 register XkbKeyPtr key; 743 int forceNL=0; 744 int nThisLine= 0; 745 fprintf(file," keys {\n"); 746 for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 747 XkbShapePtr shape; 748 if (key->color_ndx!=dfltKeyColor) 749 forceNL= 1; 750 if (k==0) { 751 fprintf(file," "); 752 nThisLine= 0; 753 } 754 else if (((nThisLine%2)==1)||(forceNL)) { 755 fprintf(file,",\n "); 756 forceNL= nThisLine= 0; 757 } 758 else { 759 fprintf(file,", "); 760 nThisLine++; 761 } 762 shape= XkbKeyShape(geom,key); 763 fprintf(file,"{ %6s, \"%s\", %3s", 764 XkbKeyNameText(key->name.name,XkbXKBFile), 765 XkbAtomText(shape->name,XkbXKBFile), 766 XkbGeomFPText(key->gap,XkbXKBFile)); 767 if (key->color_ndx!=dfltKeyColor) { 768 fprintf(file,", color=\"%s\"",XkbKeyColor(geom,key)->spec); 769 forceNL= 1; 770 } 771 fprintf(file," }"); 772 } 773 fprintf(file,"\n };\n"); 774 } 775 fprintf(file," };\n"); 776 } 777 if (s->doodads!=NULL) { 778 XkbDoodadPtr doodad; 779 for (i=0,doodad=s->doodads;i<s->num_doodads;i++,doodad++) { 780 WriteXKBDoodad(file,8,geom,doodad); 781 } 782 } 783 if (s->overlays!=NULL) { 784 XkbOverlayPtr ol; 785 for (i=0,ol=s->overlays;i<s->num_overlays;i++,ol++) { 786 WriteXKBOverlay(file,8,geom,ol); 787 } 788 } 789 fprintf(file," }; // End of \"%s\" section\n\n", 790 XkbAtomText(s->name,XkbXKBFile)); 791 return True; 792} 793 794Bool 795XkbWriteXKBGeometry( FILE * file, 796 XkbDescPtr xkb, 797 Bool topLevel, 798 Bool showImplicit, 799 XkbFileAddOnFunc addOn, 800 void * priv) 801{ 802register unsigned i,n; 803XkbGeometryPtr geom; 804 805 if ((!xkb)||(!xkb->geom)) { 806 _XkbLibError(_XkbErrMissingGeometry,"XkbWriteXKBGeometry",0); 807 return False; 808 } 809 geom= xkb->geom; 810 if (geom->name==None) 811 fprintf(file,"xkb_geometry {\n\n"); 812 else fprintf(file,"xkb_geometry \"%s\" {\n\n", 813 XkbAtomText(geom->name,XkbXKBFile)); 814 fprintf(file," width= %s;\n", 815 XkbGeomFPText(geom->width_mm,XkbXKBFile)); 816 fprintf(file," height= %s;\n\n", 817 XkbGeomFPText(geom->height_mm,XkbXKBFile)); 818 819 if (geom->key_aliases!=NULL) { 820 XkbKeyAliasPtr pAl; 821 pAl= geom->key_aliases; 822 for (i=0;i<geom->num_key_aliases;i++,pAl++) { 823 fprintf(file," alias %6s = %6s;\n", 824 XkbKeyNameText(pAl->alias,XkbXKBFile), 825 XkbKeyNameText(pAl->real,XkbXKBFile)); 826 } 827 fprintf(file,"\n"); 828 } 829 830 if (geom->base_color!=NULL) 831 fprintf(file," baseColor= \"%s\";\n", 832 XkbStringText(geom->base_color->spec,XkbXKBFile)); 833 if (geom->label_color!=NULL) 834 fprintf(file," labelColor= \"%s\";\n", 835 XkbStringText(geom->label_color->spec,XkbXKBFile)); 836 if (geom->label_font!=NULL) 837 fprintf(file," xfont= \"%s\";\n", 838 XkbStringText(geom->label_font,XkbXKBFile)); 839 if ((geom->num_colors>0)&&(showImplicit)) { 840 XkbColorPtr color; 841 for (color=geom->colors,i=0;i<geom->num_colors;i++,color++) { 842 fprintf(file,"// color[%d]= \"%s\"\n",i, 843 XkbStringText(color->spec,XkbXKBFile)); 844 } 845 fprintf(file,"\n"); 846 } 847 if (geom->num_properties>0) { 848 XkbPropertyPtr prop; 849 for (prop=geom->properties,i=0;i<geom->num_properties;i++,prop++) { 850 fprintf(file," %s= \"%s\";\n",prop->name, 851 XkbStringText(prop->value,XkbXKBFile)); 852 } 853 fprintf(file,"\n"); 854 } 855 if (geom->num_shapes>0) { 856 XkbShapePtr shape; 857 XkbOutlinePtr outline; 858 int lastR; 859 for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) { 860 lastR=0; 861 fprintf(file," shape \"%s\" {", 862 XkbAtomText(shape->name,XkbXKBFile)); 863 outline= shape->outlines; 864 if (shape->num_outlines>1) { 865 for (n=0;n<shape->num_outlines;n++,outline++) { 866 if (n==0) fprintf(file,"\n"); 867 else fprintf(file,",\n"); 868 WriteXKBOutline(file,shape,outline,lastR,8,8); 869 lastR= outline->corner_radius; 870 } 871 fprintf(file,"\n };\n"); 872 } 873 else { 874 WriteXKBOutline(file,NULL,outline,lastR,1,8); 875 fprintf(file," };\n"); 876 } 877 } 878 } 879 if (geom->num_sections>0) { 880 XkbSectionPtr section; 881 for (section=geom->sections,i=0;i<geom->num_sections;i++,section++){ 882 WriteXKBSection(file,section,geom); 883 } 884 } 885 if (geom->num_doodads>0) { 886 XkbDoodadPtr doodad; 887 for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) { 888 WriteXKBDoodad(file,4,geom,doodad); 889 } 890 } 891 if (addOn) 892 (*addOn)(file,xkb,topLevel,showImplicit,XkmGeometryIndex,priv); 893 fprintf(file,"};\n\n"); 894 return True; 895} 896