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#include <X11/keysym.h> 38#include <X11/Xproto.h> 39#include <X11/extensions/XKMformat.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",NameForAtom(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 if (!xkb) { 357 _XkbLibError(_XkbErrMissingSymbols,"XkbWriteXKBSymbols",0); 358 return FALSE; 359 } 360 361 map= xkb->map; 362 if ((!map)||(!map->syms)||(!map->key_sym_map)) { 363 _XkbLibError(_XkbErrMissingSymbols,"XkbWriteXKBSymbols",0); 364 return FALSE; 365 } 366 if ((!xkb->names)||(!xkb->names->keys)) { 367 _XkbLibError(_XkbErrMissingNames,"XkbWriteXKBSymbols",0); 368 return FALSE; 369 } 370 if ((xkb->names==NULL)||(xkb->names->symbols==None)) 371 fprintf(file,"xkb_symbols {\n\n"); 372 else fprintf(file,"xkb_symbols \"%s\" {\n\n", 373 XkbAtomText(xkb->names->symbols,XkbXKBFile)); 374 for (tmp=i=0;i<XkbNumKbdGroups;i++) { 375 if (xkb->names->groups[i]!=None) { 376 fprintf(file," name[group%d]=\"%s\";\n",i+1, 377 XkbAtomText(xkb->names->groups[i],XkbXKBFile)); 378 tmp++; 379 } 380 } 381 if (tmp>0) 382 fprintf(file,"\n"); 383 srv= xkb->server; 384 for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 385 Bool simple; 386 if ((int)XkbKeyNumSyms(xkb,i)<1) 387 continue; 388 if (XkbFindKeycodeByName(xkb,xkb->names->keys[i].name,TRUE)!=i) 389 continue; 390 simple= TRUE; 391 fprintf(file," key %6s {", 392 XkbKeyNameText(xkb->names->keys[i].name,XkbXKBFile)); 393 if (srv->explicit) { 394 if (((srv->explicit[i]&XkbExplicitKeyTypesMask)!=0)|| 395 (showImplicit)) { 396 int typeNdx,g; 397 Bool multi; 398 char * comment=" "; 399 400 if ((srv->explicit[i]&XkbExplicitKeyTypesMask)==0) 401 comment= "//"; 402 multi= FALSE; 403 typeNdx= XkbKeyKeyTypeIndex(xkb,i,0); 404 for (g=1;(g<XkbKeyNumGroups(xkb,i))&&(!multi);g++) { 405 if (XkbKeyKeyTypeIndex(xkb,i,g)!=typeNdx) 406 multi= TRUE; 407 } 408 if (multi) { 409 for (g=0;g<XkbKeyNumGroups(xkb,i);g++) { 410 typeNdx= XkbKeyKeyTypeIndex(xkb,i,g); 411 if (srv->explicit[i]&(1<<g)) { 412 fprintf(file,"\n%s type[group%d]= \"%s\",", 413 comment,g+1, 414 XkbAtomText(map->types[typeNdx].name, 415 XkbXKBFile)); 416 } 417 else if (showImplicit) { 418 fprintf(file,"\n// type[group%d]= \"%s\",",g+1, 419 XkbAtomText(map->types[typeNdx].name, 420 XkbXKBFile)); 421 } 422 } 423 } 424 else { 425 fprintf(file,"\n%s type= \"%s\",",comment, 426 XkbAtomText(map->types[typeNdx].name, 427 XkbXKBFile)); 428 } 429 simple= FALSE; 430 } 431 if (((srv->explicit[i]&XkbExplicitAutoRepeatMask)!=0)&& 432 (xkb->ctrls!=NULL)) { 433 if (xkb->ctrls->per_key_repeat[i/8]&(1<<(i%8))) 434 fprintf(file,"\n repeat= Yes,"); 435 else fprintf(file,"\n repeat= No,"); 436 simple= FALSE; 437 } 438 if ((xkb->server!=NULL)&&(xkb->server->vmodmap!=NULL)&& 439 (xkb->server->vmodmap[i]!=0)) { 440 if ((srv->explicit[i]&XkbExplicitVModMapMask)!=0) { 441 fprintf(file,"\n virtualMods= %s,", 442 XkbVModMaskText(xkb,0, 443 xkb->server->vmodmap[i], 444 XkbXKBFile)); 445 } 446 else if (showImplicit) { 447 fprintf(file,"\n// virtualMods= %s,", 448 XkbVModMaskText(xkb,0, 449 xkb->server->vmodmap[i], 450 XkbXKBFile)); 451 } 452 } 453 } 454 switch (XkbOutOfRangeGroupAction(XkbKeyGroupInfo(xkb,i))) { 455 case XkbClampIntoRange: 456 fprintf(file,"\n groupsClamp,"); 457 break; 458 case XkbRedirectIntoRange: 459 fprintf(file,"\n groupsRedirect= Group%d,", 460 XkbOutOfRangeGroupNumber(XkbKeyGroupInfo(xkb,i))+1); 461 break; 462 } 463 if (srv->behaviors!=NULL) { 464 unsigned type; 465 type= srv->behaviors[i].type&XkbKB_OpMask; 466 467 if (type!=XkbKB_Default) { 468 simple= FALSE; 469 fprintf(file,"\n %s,", 470 XkbBehaviorText(xkb,&srv->behaviors[i],XkbXKBFile)); 471 } 472 } 473 if ((srv->explicit==NULL) || showImplicit || 474 ((srv->explicit[i]&XkbExplicitInterpretMask)!=0)) 475 showActions= XkbKeyHasActions(xkb,i); 476 else showActions= FALSE; 477 478 if (((unsigned)XkbKeyNumGroups(xkb,i)>1)||showActions) 479 simple= FALSE; 480 if (simple) { 481 KeySym *syms; 482 unsigned s; 483 484 syms= XkbKeySymsPtr(xkb,i); 485 fprintf(file," [ "); 486 for (s=0;s<XkbKeyGroupWidth(xkb,i,XkbGroup1Index);s++) { 487 if (s!=0) 488 fprintf(file,", "); 489 fprintf(file,"%15s",XkbKeysymText(*syms++,XkbXKBFile)); 490 } 491 fprintf(file," ] };\n"); 492 } 493 else { 494 unsigned g,s; 495 KeySym *syms; 496 XkbAction *acts; 497 syms= XkbKeySymsPtr(xkb,i); 498 acts= XkbKeyActionsPtr(xkb,i); 499 for (g=0;g<XkbKeyNumGroups(xkb,i);g++) { 500 if (g!=0) 501 fprintf(file,","); 502 fprintf(file,"\n symbols[Group%d]= [ ",g+1); 503 for (s=0;s<XkbKeyGroupWidth(xkb,i,g);s++) { 504 if (s!=0) 505 fprintf(file,", "); 506 fprintf(file,"%15s",XkbKeysymText(syms[s],XkbXKBFile)); 507 } 508 fprintf(file," ]"); 509 syms+= XkbKeyGroupsWidth(xkb,i); 510 if (showActions) { 511 fprintf(file,",\n actions[Group%d]= [ ",g+1); 512 for (s=0;s<XkbKeyGroupWidth(xkb,i,g);s++) { 513 if (s!=0) 514 fprintf(file,", "); 515 WriteXKBAction(file,xkb,(XkbAnyAction *)&acts[s]); 516 } 517 fprintf(file," ]"); 518 acts+= XkbKeyGroupsWidth(xkb,i); 519 } 520 } 521 fprintf(file,"\n };\n"); 522 } 523 } 524 if (map && map->modmap) { 525 for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 526 if (map->modmap[i]!=0) { 527 register int n,bit; 528 for (bit=1,n=0;n<XkbNumModifiers;n++,bit<<=1) { 529 if (map->modmap[i]&bit) { 530 char buf[5]; 531 memcpy(buf,xkb->names->keys[i].name,4); 532 buf[4]= '\0'; 533 fprintf(file," modifier_map %s { <%s> };\n", 534 XkbModIndexText(n,XkbXKBFile),buf); 535 } 536 } 537 } 538 } 539 } 540 if (addOn) 541 (*addOn)(file,xkb,topLevel,showImplicit,XkmSymbolsIndex,priv); 542 fprintf(file,"};\n\n"); 543 return TRUE; 544} 545 546static Bool 547WriteXKBOutline( FILE * file, 548 XkbShapePtr shape, 549 XkbOutlinePtr outline, 550 int lastRadius, 551 int first, 552 int indent) 553{ 554register int i; 555XkbPointPtr pt; 556char * iStr; 557 558 fprintf(file,"%s",iStr= XkbIndentText(first)); 559 if (first!=indent) 560 iStr= XkbIndentText(indent); 561 if (outline->corner_radius!=lastRadius) { 562 fprintf(file,"corner= %s,", 563 XkbGeomFPText(outline->corner_radius,XkbMessage)); 564 if (shape!=NULL) { 565 fprintf(file,"\n%s",iStr); 566 } 567 } 568 if (shape) { 569 if (outline==shape->approx) 570 fprintf(file,"approx= "); 571 else if (outline==shape->primary) 572 fprintf(file,"primary= "); 573 } 574 fprintf(file,"{"); 575 for (pt=outline->points,i=0;i<outline->num_points;i++,pt++) { 576 if (i==0) fprintf(file," "); 577 else if ((i%4)==0) fprintf(file,",\n%s ",iStr); 578 else fprintf(file,", "); 579 fprintf(file,"[ %3s, %3s ]",XkbGeomFPText(pt->x,XkbXKBFile), 580 XkbGeomFPText(pt->y,XkbXKBFile)); 581 } 582 fprintf(file," }"); 583 return TRUE; 584} 585 586static Bool 587WriteXKBDoodad( FILE * file, 588 unsigned indent, 589 XkbGeometryPtr geom, 590 XkbDoodadPtr doodad) 591{ 592register char * i_str; 593XkbShapePtr shape; 594XkbColorPtr color; 595 596 i_str= XkbIndentText(indent); 597 fprintf(file,"%s%s \"%s\" {\n",i_str, 598 XkbDoodadTypeText(doodad->any.type,XkbMessage), 599 XkbAtomText(doodad->any.name,XkbMessage)); 600 fprintf(file,"%s top= %s;\n",i_str, 601 XkbGeomFPText(doodad->any.top,XkbXKBFile)); 602 fprintf(file,"%s left= %s;\n",i_str, 603 XkbGeomFPText(doodad->any.left,XkbXKBFile)); 604 fprintf(file,"%s priority= %d;\n",i_str,doodad->any.priority); 605 switch (doodad->any.type) { 606 case XkbOutlineDoodad: 607 case XkbSolidDoodad: 608 if (doodad->shape.angle!=0) { 609 fprintf(file,"%s angle= %s;\n",i_str, 610 XkbGeomFPText(doodad->shape.angle,XkbXKBFile)); 611 } 612 if (doodad->shape.color_ndx!=0) { 613 fprintf(file,"%s color= \"%s\";\n",i_str, 614 XkbShapeDoodadColor(geom,&doodad->shape)->spec); 615 } 616 shape= XkbShapeDoodadShape(geom,&doodad->shape); 617 fprintf(file,"%s shape= \"%s\";\n",i_str, 618 XkbAtomText(shape->name,XkbXKBFile)); 619 break; 620 case XkbTextDoodad: 621 if (doodad->text.angle!=0) { 622 fprintf(file,"%s angle= %s;\n",i_str, 623 XkbGeomFPText(doodad->text.angle,XkbXKBFile)); 624 } 625 if (doodad->text.width!=0) { 626 fprintf(file,"%s width= %s;\n",i_str, 627 XkbGeomFPText(doodad->text.width,XkbXKBFile)); 628 629 } 630 if (doodad->text.height!=0) { 631 fprintf(file,"%s height= %s;\n",i_str, 632 XkbGeomFPText(doodad->text.height,XkbXKBFile)); 633 634 } 635 if (doodad->text.color_ndx!=0) { 636 color= XkbTextDoodadColor(geom,&doodad->text); 637 fprintf(file,"%s color= \"%s\";\n",i_str, 638 XkbStringText(color->spec,XkbXKBFile)); 639 } 640 fprintf(file,"%s XFont= \"%s\";\n",i_str, 641 XkbStringText(doodad->text.font,XkbXKBFile)); 642 fprintf(file,"%s text= \"%s\";\n",i_str, 643 XkbStringText(doodad->text.text,XkbXKBFile)); 644 break; 645 case XkbIndicatorDoodad: 646 shape= XkbIndicatorDoodadShape(geom,&doodad->indicator); 647 color= XkbIndicatorDoodadOnColor(geom,&doodad->indicator); 648 fprintf(file,"%s onColor= \"%s\";\n",i_str, 649 XkbStringText(color->spec,XkbXKBFile)); 650 color= XkbIndicatorDoodadOffColor(geom,&doodad->indicator); 651 fprintf(file,"%s offColor= \"%s\";\n",i_str, 652 XkbStringText(color->spec,XkbXKBFile)); 653 fprintf(file,"%s shape= \"%s\";\n",i_str, 654 XkbAtomText(shape->name,XkbXKBFile)); 655 break; 656 case XkbLogoDoodad: 657 fprintf(file,"%s logoName= \"%s\";\n",i_str, 658 XkbStringText(doodad->logo.logo_name,XkbXKBFile)); 659 if (doodad->shape.angle!=0) { 660 fprintf(file,"%s angle= %s;\n",i_str, 661 XkbGeomFPText(doodad->logo.angle,XkbXKBFile)); 662 } 663 if (doodad->shape.color_ndx!=0) { 664 fprintf(file,"%s color= \"%s\";\n",i_str, 665 XkbLogoDoodadColor(geom,&doodad->logo)->spec); 666 } 667 shape= XkbLogoDoodadShape(geom,&doodad->logo); 668 fprintf(file,"%s shape= \"%s\";\n",i_str, 669 XkbAtomText(shape->name,XkbXKBFile)); 670 break; 671 } 672 fprintf(file,"%s};\n",i_str); 673 return TRUE; 674} 675 676/*ARGSUSED*/ 677static Bool 678WriteXKBOverlay( FILE * file, 679 unsigned indent, 680 XkbGeometryPtr geom, 681 XkbOverlayPtr ol) 682{ 683register char * i_str; 684int r,k,nOut; 685XkbOverlayRowPtr row; 686XkbOverlayKeyPtr key; 687 688 i_str= XkbIndentText(indent); 689 if (ol->name!=None) { 690 fprintf(file,"%soverlay \"%s\" {\n",i_str, 691 XkbAtomText(ol->name,XkbMessage)); 692 } 693 else fprintf(file,"%soverlay {\n",i_str); 694 for (nOut=r=0,row=ol->rows;r<ol->num_rows;r++,row++) { 695 for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 696 char *over,*under; 697 over= XkbKeyNameText(key->over.name,XkbXKBFile); 698 under= XkbKeyNameText(key->under.name,XkbXKBFile); 699 if (nOut==0) 700 fprintf(file,"%s %6s=%6s",i_str,under,over); 701 else if ((nOut%4)==0) 702 fprintf(file,",\n%s %6s=%6s",i_str,under,over); 703 else fprintf(file,", %6s=%6s",under,over); 704 nOut++; 705 } 706 } 707 fprintf(file,"\n%s};\n",i_str); 708 return TRUE; 709} 710 711static Bool 712WriteXKBSection( FILE * file, 713 XkbSectionPtr s, 714 XkbGeometryPtr geom) 715{ 716register int i; 717XkbRowPtr row; 718int dfltKeyColor = 0; 719 720 fprintf(file," section \"%s\" {\n", 721 XkbAtomText(s->name,XkbXKBFile)); 722 if (s->rows&&(s->rows->num_keys>0)) { 723 dfltKeyColor= s->rows->keys[0].color_ndx; 724 fprintf(file," key.color= \"%s\";\n", 725 XkbStringText(geom->colors[dfltKeyColor].spec,XkbXKBFile)); 726 } 727 fprintf(file," priority= %d;\n",s->priority); 728 fprintf(file," top= %s;\n",XkbGeomFPText(s->top,XkbXKBFile)); 729 fprintf(file," left= %s;\n",XkbGeomFPText(s->left,XkbXKBFile)); 730 fprintf(file," width= %s;\n",XkbGeomFPText(s->width,XkbXKBFile)); 731 fprintf(file," height= %s;\n", 732 XkbGeomFPText(s->height,XkbXKBFile)); 733 if (s->angle!=0) { 734 fprintf(file," angle= %s;\n", 735 XkbGeomFPText(s->angle,XkbXKBFile)); 736 } 737 for (i=0,row=s->rows;i<s->num_rows;i++,row++) { 738 fprintf(file," row {\n"); 739 fprintf(file," top= %s;\n", 740 XkbGeomFPText(row->top,XkbXKBFile)); 741 fprintf(file," left= %s;\n", 742 XkbGeomFPText(row->left,XkbXKBFile)); 743 if (row->vertical) 744 fprintf(file," vertical;\n"); 745 if (row->num_keys>0) { 746 register int k; 747 register XkbKeyPtr key; 748 int forceNL=0; 749 int nThisLine= 0; 750 fprintf(file," keys {\n"); 751 for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 752 XkbShapePtr shape; 753 if (key->color_ndx!=dfltKeyColor) 754 forceNL= 1; 755 if (k==0) { 756 fprintf(file," "); 757 nThisLine= 0; 758 } 759 else if (((nThisLine%2)==1)||(forceNL)) { 760 fprintf(file,",\n "); 761 forceNL= nThisLine= 0; 762 } 763 else { 764 fprintf(file,", "); 765 nThisLine++; 766 } 767 shape= XkbKeyShape(geom,key); 768 fprintf(file,"{ %6s, \"%s\", %3s", 769 XkbKeyNameText(key->name.name,XkbXKBFile), 770 XkbAtomText(shape->name,XkbXKBFile), 771 XkbGeomFPText(key->gap,XkbXKBFile)); 772 if (key->color_ndx!=dfltKeyColor) { 773 fprintf(file,", color=\"%s\"",XkbKeyColor(geom,key)->spec); 774 forceNL= 1; 775 } 776 fprintf(file," }"); 777 } 778 fprintf(file,"\n };\n"); 779 } 780 fprintf(file," };\n"); 781 } 782 if (s->doodads!=NULL) { 783 XkbDoodadPtr doodad; 784 for (i=0,doodad=s->doodads;i<s->num_doodads;i++,doodad++) { 785 WriteXKBDoodad(file,8,geom,doodad); 786 } 787 } 788 if (s->overlays!=NULL) { 789 XkbOverlayPtr ol; 790 for (i=0,ol=s->overlays;i<s->num_overlays;i++,ol++) { 791 WriteXKBOverlay(file,8,geom,ol); 792 } 793 } 794 fprintf(file," }; // End of \"%s\" section\n\n", 795 XkbAtomText(s->name,XkbXKBFile)); 796 return TRUE; 797} 798 799Bool 800XkbWriteXKBGeometry( FILE * file, 801 XkbDescPtr xkb, 802 Bool topLevel, 803 Bool showImplicit, 804 XkbFileAddOnFunc addOn, 805 void * priv) 806{ 807register unsigned i,n; 808XkbGeometryPtr geom; 809 810 if ((!xkb)||(!xkb->geom)) { 811 _XkbLibError(_XkbErrMissingGeometry,"XkbWriteXKBGeometry",0); 812 return FALSE; 813 } 814 geom= xkb->geom; 815 if (geom->name==None) 816 fprintf(file,"xkb_geometry {\n\n"); 817 else fprintf(file,"xkb_geometry \"%s\" {\n\n", 818 XkbAtomText(geom->name,XkbXKBFile)); 819 fprintf(file," width= %s;\n", 820 XkbGeomFPText(geom->width_mm,XkbXKBFile)); 821 fprintf(file," height= %s;\n\n", 822 XkbGeomFPText(geom->height_mm,XkbXKBFile)); 823 824 if (geom->key_aliases!=NULL) { 825 XkbKeyAliasPtr pAl; 826 pAl= geom->key_aliases; 827 for (i=0;i<geom->num_key_aliases;i++,pAl++) { 828 fprintf(file," alias %6s = %6s;\n", 829 XkbKeyNameText(pAl->alias,XkbXKBFile), 830 XkbKeyNameText(pAl->real,XkbXKBFile)); 831 } 832 fprintf(file,"\n"); 833 } 834 835 if (geom->base_color!=NULL) 836 fprintf(file," baseColor= \"%s\";\n", 837 XkbStringText(geom->base_color->spec,XkbXKBFile)); 838 if (geom->label_color!=NULL) 839 fprintf(file," labelColor= \"%s\";\n", 840 XkbStringText(geom->label_color->spec,XkbXKBFile)); 841 if (geom->label_font!=NULL) 842 fprintf(file," xfont= \"%s\";\n", 843 XkbStringText(geom->label_font,XkbXKBFile)); 844 if ((geom->num_colors>0)&&(showImplicit)) { 845 XkbColorPtr color; 846 for (color=geom->colors,i=0;i<geom->num_colors;i++,color++) { 847 fprintf(file,"// color[%d]= \"%s\"\n",i, 848 XkbStringText(color->spec,XkbXKBFile)); 849 } 850 fprintf(file,"\n"); 851 } 852 if (geom->num_properties>0) { 853 XkbPropertyPtr prop; 854 for (prop=geom->properties,i=0;i<geom->num_properties;i++,prop++) { 855 fprintf(file," %s= \"%s\";\n",prop->name, 856 XkbStringText(prop->value,XkbXKBFile)); 857 } 858 fprintf(file,"\n"); 859 } 860 if (geom->num_shapes>0) { 861 XkbShapePtr shape; 862 XkbOutlinePtr outline; 863 int lastR; 864 for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) { 865 lastR=0; 866 fprintf(file," shape \"%s\" {", 867 XkbAtomText(shape->name,XkbXKBFile)); 868 outline= shape->outlines; 869 if (shape->num_outlines>1) { 870 for (n=0;n<shape->num_outlines;n++,outline++) { 871 if (n==0) fprintf(file,"\n"); 872 else fprintf(file,",\n"); 873 WriteXKBOutline(file,shape,outline,lastR,8,8); 874 lastR= outline->corner_radius; 875 } 876 fprintf(file,"\n };\n"); 877 } 878 else { 879 WriteXKBOutline(file,NULL,outline,lastR,1,8); 880 fprintf(file," };\n"); 881 } 882 } 883 } 884 if (geom->num_sections>0) { 885 XkbSectionPtr section; 886 for (section=geom->sections,i=0;i<geom->num_sections;i++,section++){ 887 WriteXKBSection(file,section,geom); 888 } 889 } 890 if (geom->num_doodads>0) { 891 XkbDoodadPtr doodad; 892 for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) { 893 WriteXKBDoodad(file,4,geom,doodad); 894 } 895 } 896 if (addOn) 897 (*addOn)(file,xkb,topLevel,showImplicit,XkmGeometryIndex,priv); 898 fprintf(file,"};\n\n"); 899 return TRUE; 900} 901