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