xkbout.c revision 8c9fbc29
1/* $Xorg: xkbout.c,v 1.3 2000/08/17 19:46:44 cpqbld Exp $ */ 2/************************************************************ 3 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. 4 5 Permission to use, copy, modify, and distribute this 6 software and its documentation for any purpose and without 7 fee is hereby granted, provided that the above copyright 8 notice appear in all copies and that both that copyright 9 notice and this permission notice appear in supporting 10 documentation, and that the name of Silicon Graphics not be 11 used in advertising or publicity pertaining to distribution 12 of the software without specific prior written permission. 13 Silicon Graphics makes no representation about the suitability 14 of this software for any purpose. It is provided "as is" 15 without any express or implied warranty. 16 17 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 18 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 19 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 20 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 21 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 22 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 23 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 24 THE USE OR PERFORMANCE OF THIS SOFTWARE. 25 26 ********************************************************/ 27/* $XFree86: xc/lib/xkbfile/xkbout.c,v 3.9 2001/10/28 03:32:47 tsi Exp $ */ 28 29#ifdef HAVE_DIX_CONFIG_H 30#include <dix-config.h> 31#elif defined(HAVE_CONFIG_H) 32#include <config.h> 33#endif 34 35#include <stdio.h> 36#include <ctype.h> 37#include <stdlib.h> 38#include <X11/Xfuncs.h> 39 40#ifndef XKB_IN_SERVER 41 42#include <X11/Xlib.h> 43#include <X11/XKBlib.h> 44#include <X11/extensions/XKBgeom.h> 45 46#include "XKMformat.h" 47#include "XKBfileInt.h" 48 49#else 50 51#include <X11/X.h> 52#define NEED_EVENTS 53#include <X11/keysym.h> 54#include <X11/Xproto.h> 55#include "misc.h" 56#include "inputstr.h" 57#include "dix.h" 58#include <X11/extensions/XKBstr.h> 59#define XKBSRV_NEED_FILE_FUNCS 1 60#include <X11/extensions/XKBsrv.h> 61 62#include <X11/extensions/XKBgeom.h> 63#include <X11/extensions/XKBfile.h> 64 65#endif 66 67#define VMOD_HIDE_VALUE 0 68#define VMOD_SHOW_VALUE 1 69#define VMOD_COMMENT_VALUE 2 70 71static Bool 72WriteXKBVModDecl(FILE *file,Display *dpy,XkbDescPtr xkb,int showValue) 73{ 74register int i,nMods; 75Atom * vmodNames; 76 77 if (xkb==NULL) 78 return False; 79 if (xkb->names!=NULL) 80 vmodNames= xkb->names->vmods; 81 else vmodNames= NULL; 82 83 for (i=nMods=0;i<XkbNumVirtualMods;i++) { 84 if ((vmodNames!=NULL)&&(vmodNames[i]!=None)) { 85 if (nMods==0) fprintf(file," virtual_modifiers "); 86 else fprintf(file,","); 87 fprintf(file,"%s",XkbAtomText(dpy,vmodNames[i],XkbXKBFile)); 88 if ((showValue!=VMOD_HIDE_VALUE)&& 89 (xkb->server)&&(xkb->server->vmods[i]!=XkbNoModifierMask)) { 90 if (showValue==VMOD_COMMENT_VALUE) { 91 fprintf(file,"/* = %s */", 92 XkbModMaskText(xkb->server->vmods[i],XkbXKBFile)); 93 } 94 else { 95 fprintf(file,"= %s", 96 XkbModMaskText(xkb->server->vmods[i],XkbXKBFile)); 97 } 98 } 99 nMods++; 100 } 101 } 102 if (nMods>0) 103 fprintf(file,";\n\n"); 104 return True; 105} 106 107/***====================================================================***/ 108 109static Bool 110WriteXKBAction(FILE *file,XkbFileInfo *result,XkbAnyAction *action) 111{ 112XkbDescPtr xkb; 113Display * dpy; 114 115 xkb= result->xkb; 116 dpy= xkb->dpy; 117 fprintf(file,"%s",XkbActionText(dpy,xkb,(XkbAction *)action,XkbXKBFile)); 118 return True; 119} 120 121/***====================================================================***/ 122 123Bool 124XkbWriteXKBKeycodes( FILE * file, 125 XkbFileInfo * result, 126 Bool topLevel, 127 Bool showImplicit, 128 XkbFileAddOnFunc addOn, 129 void * priv) 130{ 131Atom kcName; 132register unsigned i; 133XkbDescPtr xkb; 134Display * dpy; 135char * alternate; 136 137 xkb= result->xkb; 138 if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) { 139 _XkbLibError(_XkbErrMissingNames,"XkbWriteXKBKeycodes",0); 140 return False; 141 } 142 dpy= xkb->dpy; 143 kcName= xkb->names->keycodes; 144 if (kcName!=None) 145 fprintf(file,"xkb_keycodes \"%s\" {\n", 146 XkbAtomText(dpy,kcName,XkbXKBFile)); 147 else fprintf(file,"xkb_keycodes {\n"); 148 fprintf(file," minimum = %d;\n",xkb->min_key_code); 149 fprintf(file," maximum = %d;\n",xkb->max_key_code); 150 for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 151 if (xkb->names->keys[i].name[0]!='\0') { 152 if (XkbFindKeycodeByName(xkb,xkb->names->keys[i].name,True)!=i) 153 alternate= "alternate "; 154 else alternate= ""; 155 fprintf(file," %s%6s = %d;\n",alternate, 156 XkbKeyNameText(xkb->names->keys[i].name,XkbXKBFile), 157 i); 158 } 159 } 160 if (xkb->indicators!=NULL) { 161 for (i=0;i<XkbNumIndicators;i++) { 162 char *type; 163 if (xkb->indicators->phys_indicators&(1<<i)) 164 type= " "; 165 else type= " virtual "; 166 if (xkb->names->indicators[i]!=None) { 167 fprintf(file,"%sindicator %d = \"%s\";\n",type,i+1, 168 XkbAtomText(dpy,xkb->names->indicators[i],XkbXKBFile)); 169 } 170 } 171 } 172 if (xkb->names->key_aliases!=NULL) { 173 XkbKeyAliasPtr pAl; 174 pAl= xkb->names->key_aliases; 175 for (i=0;i<xkb->names->num_key_aliases;i++,pAl++) { 176 fprintf(file," alias %6s = %6s;\n", 177 XkbKeyNameText(pAl->alias,XkbXKBFile), 178 XkbKeyNameText(pAl->real,XkbXKBFile)); 179 } 180 } 181 if (addOn) 182 (*addOn)(file,result,topLevel,showImplicit,XkmKeyNamesIndex,priv); 183 fprintf(file,"};\n\n"); 184 return True; 185} 186 187Bool 188XkbWriteXKBKeyTypes( FILE * file, 189 XkbFileInfo * result, 190 Bool topLevel, 191 Bool showImplicit, 192 XkbFileAddOnFunc addOn, 193 void * priv) 194{ 195Display * dpy; 196register unsigned i,n; 197XkbKeyTypePtr type; 198XkbKTMapEntryPtr entry; 199XkbDescPtr xkb; 200 201 xkb= result->xkb; 202 if ((!xkb)||(!xkb->map)||(!xkb->map->types)) { 203 _XkbLibError(_XkbErrMissingTypes,"XkbWriteXKBKeyTypes",0); 204 return False; 205 } 206 dpy= xkb->dpy; 207 if (xkb->map->num_types<XkbNumRequiredTypes) { 208 _XkbLibError(_XkbErrMissingReqTypes,"XkbWriteXKBKeyTypes",0); 209 return 0; 210 } 211 if ((xkb->names==NULL)||(xkb->names->types==None)) 212 fprintf(file,"xkb_types {\n\n"); 213 else fprintf(file,"xkb_types \"%s\" {\n\n", 214 XkbAtomText(dpy,xkb->names->types,XkbXKBFile)); 215 WriteXKBVModDecl(file,dpy,xkb, 216 (showImplicit?VMOD_COMMENT_VALUE:VMOD_HIDE_VALUE)); 217 218 type= xkb->map->types; 219 for (i=0;i<xkb->map->num_types;i++,type++) { 220 fprintf(file," type \"%s\" {\n", 221 XkbAtomText(dpy,type->name,XkbXKBFile)); 222 fprintf(file," modifiers= %s;\n", 223 XkbVModMaskText(dpy,xkb,type->mods.real_mods,type->mods.vmods, 224 XkbXKBFile)); 225 entry= type->map; 226 for (n=0;n<type->map_count;n++,entry++) { 227 char *str; 228 str=XkbVModMaskText(dpy,xkb,entry->mods.real_mods,entry->mods.vmods, 229 XkbXKBFile); 230 fprintf(file," map[%s]= Level%d;\n",str,entry->level+1); 231 if ((type->preserve)&&((type->preserve[n].real_mods)|| 232 (type->preserve[n].vmods))) { 233 fprintf(file," preserve[%s]= ",str); 234 fprintf(file,"%s;\n",XkbVModMaskText(dpy,xkb, 235 type->preserve[n].real_mods, 236 type->preserve[n].vmods, 237 XkbXKBFile)); 238 } 239 } 240 if (type->level_names!=NULL) { 241 Atom *name= type->level_names; 242 for (n=0;n<type->num_levels;n++,name++) { 243 if ((*name)==None) 244 continue; 245 fprintf(file," level_name[Level%d]= \"%s\";\n",n+1, 246 XkbAtomText(dpy,*name,XkbXKBFile)); 247 } 248 } 249 fprintf(file," };\n"); 250 } 251 if (addOn) 252 (*addOn)(file,result,topLevel,showImplicit,XkmTypesIndex,priv); 253 fprintf(file,"};\n\n"); 254 return True; 255} 256 257static Bool 258WriteXKBIndicatorMap( FILE * file, 259 XkbFileInfo * result, 260 Atom name, 261 XkbIndicatorMapPtr led, 262 XkbFileAddOnFunc addOn, 263 void * priv) 264{ 265XkbDescPtr xkb; 266char *tmp; 267 268 xkb= result->xkb; 269 tmp = XkbAtomGetString(xkb->dpy, name); 270 fprintf(file," indicator \"%s\" {\n",tmp); 271 _XkbFree(tmp); 272 if (led->flags&XkbIM_NoExplicit) 273 fprintf(file," !allowExplicit;\n"); 274 if (led->flags&XkbIM_LEDDrivesKB) 275 fprintf(file," indicatorDrivesKeyboard;\n"); 276 if (led->which_groups!=0) { 277 if (led->which_groups!=XkbIM_UseEffective) { 278 fprintf(file," whichGroupState= %s;\n", 279 XkbIMWhichStateMaskText(led->which_groups,XkbXKBFile)); 280 } 281 fprintf(file," groups= 0x%02x;\n",led->groups); 282 } 283 if (led->which_mods!=0) { 284 if (led->which_mods!=XkbIM_UseEffective) { 285 fprintf(file," whichModState= %s;\n", 286 XkbIMWhichStateMaskText(led->which_mods,XkbXKBFile)); 287 } 288 fprintf(file," modifiers= %s;\n", 289 XkbVModMaskText(xkb->dpy,xkb, 290 led->mods.real_mods,led->mods.vmods, 291 XkbXKBFile)); 292 } 293 if (led->ctrls!=0) { 294 fprintf(file," controls= %s;\n", 295 XkbControlsMaskText(led->ctrls,XkbXKBFile)); 296 } 297 if (addOn) 298 (*addOn)(file,result,False,True,XkmIndicatorsIndex,priv); 299 fprintf(file," };\n"); 300 return True; 301} 302 303Bool 304XkbWriteXKBCompatMap( FILE * file, 305 XkbFileInfo * result, 306 Bool topLevel, 307 Bool showImplicit, 308 XkbFileAddOnFunc addOn, 309 void * priv) 310{ 311Display * dpy; 312register unsigned i; 313XkbSymInterpretPtr interp; 314XkbDescPtr xkb; 315 316 xkb= result->xkb; 317 if ((!xkb)||(!xkb->compat)||(!xkb->compat->sym_interpret)) { 318 _XkbLibError(_XkbErrMissingCompatMap,"XkbWriteXKBCompatMap",0); 319 return False; 320 } 321 dpy= xkb->dpy; 322 if ((xkb->names==NULL)||(xkb->names->compat==None)) 323 fprintf(file,"xkb_compatibility {\n\n"); 324 else fprintf(file,"xkb_compatibility \"%s\" {\n\n", 325 XkbAtomText(dpy,xkb->names->compat,XkbXKBFile)); 326 WriteXKBVModDecl(file,dpy,xkb, 327 (showImplicit?VMOD_COMMENT_VALUE:VMOD_HIDE_VALUE)); 328 329 fprintf(file," interpret.useModMapMods= AnyLevel;\n"); 330 fprintf(file," interpret.repeat= False;\n"); 331 fprintf(file," interpret.locking= False;\n"); 332 interp= xkb->compat->sym_interpret; 333 for (i=0;i<xkb->compat->num_si;i++,interp++) { 334 fprintf(file," interpret %s+%s(%s) {\n", 335 ((interp->sym==NoSymbol)?"Any": 336 XkbKeysymText(interp->sym,XkbXKBFile)), 337 XkbSIMatchText(interp->match,XkbXKBFile), 338 XkbModMaskText(interp->mods,XkbXKBFile)); 339 if (interp->virtual_mod!=XkbNoModifier) { 340 fprintf(file," virtualModifier= %s;\n", 341 XkbVModIndexText(dpy,xkb,interp->virtual_mod,XkbXKBFile)); 342 } 343 if (interp->match&XkbSI_LevelOneOnly) 344 fprintf(file," useModMapMods=level1;\n"); 345 if (interp->flags&XkbSI_LockingKey) 346 fprintf(file," locking= True;\n"); 347 if (interp->flags&XkbSI_AutoRepeat) 348 fprintf(file," repeat= True;\n"); 349 fprintf(file," action= "); 350 WriteXKBAction(file,result,&interp->act); 351 fprintf(file,";\n"); 352 fprintf(file," };\n"); 353 } 354 for (i=0;i<XkbNumKbdGroups;i++) { 355 XkbModsPtr gc; 356 357 gc= &xkb->compat->groups[i]; 358 if ((gc->real_mods==0)&&(gc->vmods==0)) 359 continue; 360 fprintf(file," group %d = %s;\n",i+1,XkbVModMaskText(xkb->dpy,xkb, 361 gc->real_mods,gc->vmods, 362 XkbXKBFile)); 363 } 364 if (xkb->indicators) { 365 for (i=0;i<XkbNumIndicators;i++) { 366 XkbIndicatorMapPtr map= &xkb->indicators->maps[i]; 367 if ((map->flags!=0)||(map->which_groups!=0)||(map->groups!=0)|| 368 (map->which_mods!=0)|| 369 (map->mods.real_mods!=0)||(map->mods.vmods!=0)|| 370 (map->ctrls!=0)) { 371 WriteXKBIndicatorMap(file,result,xkb->names->indicators[i],map, 372 addOn,priv); 373 } 374 } 375 } 376 if (addOn) 377 (*addOn)(file,result,topLevel,showImplicit,XkmCompatMapIndex,priv); 378 fprintf(file,"};\n\n"); 379 return True; 380} 381 382Bool 383XkbWriteXKBSymbols( FILE * file, 384 XkbFileInfo * result, 385 Bool topLevel, 386 Bool showImplicit, 387 XkbFileAddOnFunc addOn, 388 void * priv) 389{ 390Display * dpy; 391register unsigned i,tmp; 392XkbDescPtr xkb; 393XkbClientMapPtr map; 394XkbServerMapPtr srv; 395Bool showActions; 396 397 xkb= result->xkb; 398 399 if ((!xkb)||(!xkb->map)||(!xkb->map->syms)||(!xkb->map->key_sym_map)) { 400 _XkbLibError(_XkbErrMissingSymbols,"XkbWriteXKBSymbols",0); 401 return False; 402 } 403 if ((!xkb->names)||(!xkb->names->keys)) { 404 _XkbLibError(_XkbErrMissingNames,"XkbWriteXKBSymbols",0); 405 return False; 406 } 407 408 map= xkb->map; 409 srv= xkb->server; 410 dpy= xkb->dpy; 411 412 if ((xkb->names==NULL)||(xkb->names->symbols==None)) 413 fprintf(file,"xkb_symbols {\n\n"); 414 else fprintf(file,"xkb_symbols \"%s\" {\n\n", 415 XkbAtomText(dpy,xkb->names->symbols,XkbXKBFile)); 416 for (tmp=i=0;i<XkbNumKbdGroups;i++) { 417 if (xkb->names->groups[i]!=None) { 418 fprintf(file," name[group%d]=\"%s\";\n",i+1, 419 XkbAtomText(dpy,xkb->names->groups[i],XkbXKBFile)); 420 tmp++; 421 } 422 } 423 if (tmp>0) 424 fprintf(file,"\n"); 425 for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 426 Bool simple; 427 if ((int)XkbKeyNumSyms(xkb,i)<1) 428 continue; 429 if (XkbFindKeycodeByName(xkb,xkb->names->keys[i].name,True)!=i) 430 continue; 431 simple= True; 432 fprintf(file," key %6s {", 433 XkbKeyNameText(xkb->names->keys[i].name,XkbXKBFile)); 434 if (srv->explicit) { 435 if (((srv->explicit[i]&XkbExplicitKeyTypesMask)!=0)|| 436 (showImplicit)) { 437 int typeNdx,g; 438 Bool multi; 439 char * comment=" "; 440 441 if ((srv->explicit[i]&XkbExplicitKeyTypesMask)==0) 442 comment= "//"; 443 multi= False; 444 typeNdx= XkbKeyKeyTypeIndex(xkb,i,0); 445 for (g=1;(g<XkbKeyNumGroups(xkb,i))&&(!multi);g++) { 446 if (XkbKeyKeyTypeIndex(xkb,i,g)!=typeNdx) 447 multi= True; 448 } 449 if (multi) { 450 for (g=0;g<XkbKeyNumGroups(xkb,i);g++) { 451 typeNdx= XkbKeyKeyTypeIndex(xkb,i,g); 452 if (srv->explicit[i]&(1<<g)) { 453 fprintf(file,"\n%s type[group%d]= \"%s\",", 454 comment,g+1, 455 XkbAtomText(dpy,map->types[typeNdx].name, 456 XkbXKBFile)); 457 } 458 else if (showImplicit) { 459 fprintf(file,"\n// type[group%d]= \"%s\",",g+1, 460 XkbAtomText(dpy,map->types[typeNdx].name, 461 XkbXKBFile)); 462 } 463 } 464 } 465 else { 466 fprintf(file,"\n%s type= \"%s\",",comment, 467 XkbAtomText(dpy,map->types[typeNdx].name, 468 XkbXKBFile)); 469 } 470 simple= False; 471 } 472 if (((srv->explicit[i]&XkbExplicitAutoRepeatMask)!=0)&& 473 (xkb->ctrls!=NULL)) { 474 if (xkb->ctrls->per_key_repeat[i/8]&(1<<(i%8))) 475 fprintf(file,"\n repeat= Yes,"); 476 else fprintf(file,"\n repeat= No,"); 477 simple= False; 478 } 479 if ((xkb->server!=NULL)&&(xkb->server->vmodmap!=NULL)&& 480 (xkb->server->vmodmap[i]!=0)) { 481 if ((srv->explicit[i]&XkbExplicitVModMapMask)!=0) { 482 fprintf(file,"\n virtualMods= %s,", 483 XkbVModMaskText(dpy,xkb,0, 484 xkb->server->vmodmap[i], 485 XkbXKBFile)); 486 } 487 else if (showImplicit) { 488 fprintf(file,"\n// virtualMods= %s,", 489 XkbVModMaskText(dpy,xkb,0, 490 xkb->server->vmodmap[i], 491 XkbXKBFile)); 492 } 493 } 494 } 495 switch (XkbOutOfRangeGroupAction(XkbKeyGroupInfo(xkb,i))) { 496 case XkbClampIntoRange: 497 fprintf(file,"\n groupsClamp,"); 498 break; 499 case XkbRedirectIntoRange: 500 fprintf(file,"\n groupsRedirect= Group%d,", 501 XkbOutOfRangeGroupNumber(XkbKeyGroupInfo(xkb,i))+1); 502 break; 503 } 504 if (srv->behaviors!=NULL) { 505 unsigned type; 506 type= srv->behaviors[i].type&XkbKB_OpMask; 507 508 if (type!=XkbKB_Default) { 509 simple= False; 510 fprintf(file,"\n %s,", 511 XkbBehaviorText(xkb,&srv->behaviors[i],XkbXKBFile)); 512 } 513 } 514 if ((srv->explicit==NULL) || showImplicit || 515 ((srv->explicit[i]&XkbExplicitInterpretMask)!=0)) 516 showActions= XkbKeyHasActions(xkb,i); 517 else showActions= False; 518 519 if (((unsigned)XkbKeyNumGroups(xkb,i)>1)||showActions) 520 simple= False; 521 if (simple) { 522 KeySym *syms; 523 unsigned s; 524 525 syms= XkbKeySymsPtr(xkb,i); 526 fprintf(file," [ "); 527 for (s=0;s<XkbKeyGroupWidth(xkb,i,XkbGroup1Index);s++) { 528 if (s!=0) 529 fprintf(file,", "); 530 fprintf(file,"%15s",XkbKeysymText(*syms++,XkbXKBFile)); 531 } 532 fprintf(file," ] };\n"); 533 } 534 else { 535 unsigned g,s; 536 KeySym *syms; 537 XkbAction *acts; 538 syms= XkbKeySymsPtr(xkb,i); 539 acts= XkbKeyActionsPtr(xkb,i); 540 for (g=0;g<XkbKeyNumGroups(xkb,i);g++) { 541 if (g!=0) 542 fprintf(file,","); 543 fprintf(file,"\n symbols[Group%d]= [ ",g+1); 544 for (s=0;s<XkbKeyGroupWidth(xkb,i,g);s++) { 545 if (s!=0) 546 fprintf(file,", "); 547 fprintf(file,"%15s",XkbKeysymText(syms[s],XkbXKBFile)); 548 } 549 fprintf(file," ]"); 550 syms+= XkbKeyGroupsWidth(xkb,i); 551 if (showActions) { 552 fprintf(file,",\n actions[Group%d]= [ ",g+1); 553 for (s=0;s<XkbKeyGroupWidth(xkb,i,g);s++) { 554 if (s!=0) 555 fprintf(file,", "); 556 WriteXKBAction(file,result,(XkbAnyAction *)&acts[s]); 557 } 558 fprintf(file," ]"); 559 acts+= XkbKeyGroupsWidth(xkb,i); 560 } 561 } 562 fprintf(file,"\n };\n"); 563 } 564 } 565 if (map && map->modmap) { 566 for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 567 if (map->modmap[i]!=0) { 568 register int n,bit; 569 for (bit=1,n=0;n<XkbNumModifiers;n++,bit<<=1) { 570 if (map->modmap[i]&bit) { 571 char buf[5]; 572 memcpy(buf,xkb->names->keys[i].name,4); 573 buf[4]= '\0'; 574 fprintf(file," modifier_map %s { <%s> };\n", 575 XkbModIndexText(n,XkbXKBFile),buf); 576 } 577 } 578 } 579 } 580 } 581 if (addOn) 582 (*addOn)(file,result,topLevel,showImplicit,XkmSymbolsIndex,priv); 583 fprintf(file,"};\n\n"); 584 return True; 585} 586 587static Bool 588WriteXKBOutline( FILE * file, 589 XkbShapePtr shape, 590 XkbOutlinePtr outline, 591 int lastRadius, 592 int first, 593 int indent) 594{ 595register int i; 596XkbPointPtr pt; 597char * iStr; 598 599 fprintf(file,"%s",iStr= XkbIndentText(first)); 600 if (first!=indent) 601 iStr= XkbIndentText(indent); 602 if (outline->corner_radius!=lastRadius) { 603 fprintf(file,"corner= %s,", 604 XkbGeomFPText(outline->corner_radius,XkbMessage)); 605 if (shape!=NULL) { 606 fprintf(file,"\n%s",iStr); 607 } 608 } 609 if (shape) { 610 if (outline==shape->approx) 611 fprintf(file,"approx= "); 612 else if (outline==shape->primary) 613 fprintf(file,"primary= "); 614 } 615 fprintf(file,"{"); 616 for (pt=outline->points,i=0;i<outline->num_points;i++,pt++) { 617 if (i==0) fprintf(file," "); 618 else if ((i%4)==0) fprintf(file,",\n%s ",iStr); 619 else fprintf(file,", "); 620 fprintf(file,"[ %3s, %3s ]",XkbGeomFPText(pt->x,XkbXKBFile), 621 XkbGeomFPText(pt->y,XkbXKBFile)); 622 } 623 fprintf(file," }"); 624 return True; 625} 626 627static Bool 628WriteXKBDoodad( FILE * file, 629 Display * dpy, 630 unsigned indent, 631 XkbGeometryPtr geom, 632 XkbDoodadPtr doodad) 633{ 634register char * i_str; 635XkbShapePtr shape; 636XkbColorPtr color; 637 638 i_str= XkbIndentText(indent); 639 fprintf(file,"%s%s \"%s\" {\n",i_str, 640 XkbDoodadTypeText(doodad->any.type,XkbMessage), 641 XkbAtomText(dpy,doodad->any.name,XkbMessage)); 642 fprintf(file,"%s top= %s;\n",i_str, 643 XkbGeomFPText(doodad->any.top,XkbXKBFile)); 644 fprintf(file,"%s left= %s;\n",i_str, 645 XkbGeomFPText(doodad->any.left,XkbXKBFile)); 646 fprintf(file,"%s priority= %d;\n",i_str,doodad->any.priority); 647 switch (doodad->any.type) { 648 case XkbOutlineDoodad: 649 case XkbSolidDoodad: 650 if (doodad->shape.angle!=0) { 651 fprintf(file,"%s angle= %s;\n",i_str, 652 XkbGeomFPText(doodad->shape.angle,XkbXKBFile)); 653 } 654 if (doodad->shape.color_ndx!=0) { 655 fprintf(file,"%s color= \"%s\";\n",i_str, 656 XkbShapeDoodadColor(geom,&doodad->shape)->spec); 657 } 658 shape= XkbShapeDoodadShape(geom,&doodad->shape); 659 fprintf(file,"%s shape= \"%s\";\n",i_str, 660 XkbAtomText(dpy,shape->name,XkbXKBFile)); 661 break; 662 case XkbTextDoodad: 663 if (doodad->text.angle!=0) { 664 fprintf(file,"%s angle= %s;\n",i_str, 665 XkbGeomFPText(doodad->text.angle,XkbXKBFile)); 666 } 667 if (doodad->text.width!=0) { 668 fprintf(file,"%s width= %s;\n",i_str, 669 XkbGeomFPText(doodad->text.width,XkbXKBFile)); 670 671 } 672 if (doodad->text.height!=0) { 673 fprintf(file,"%s height= %s;\n",i_str, 674 XkbGeomFPText(doodad->text.height,XkbXKBFile)); 675 676 } 677 if (doodad->text.color_ndx!=0) { 678 color= XkbTextDoodadColor(geom,&doodad->text); 679 fprintf(file,"%s color= \"%s\";\n",i_str, 680 XkbStringText(color->spec,XkbXKBFile)); 681 } 682 fprintf(file,"%s XFont= \"%s\";\n",i_str, 683 XkbStringText(doodad->text.font,XkbXKBFile)); 684 fprintf(file,"%s text= \"%s\";\n",i_str, 685 XkbStringText(doodad->text.text,XkbXKBFile)); 686 break; 687 case XkbIndicatorDoodad: 688 shape= XkbIndicatorDoodadShape(geom,&doodad->indicator); 689 color= XkbIndicatorDoodadOnColor(geom,&doodad->indicator); 690 fprintf(file,"%s onColor= \"%s\";\n",i_str, 691 XkbStringText(color->spec,XkbXKBFile)); 692 color= XkbIndicatorDoodadOffColor(geom,&doodad->indicator); 693 fprintf(file,"%s offColor= \"%s\";\n",i_str, 694 XkbStringText(color->spec,XkbXKBFile)); 695 fprintf(file,"%s shape= \"%s\";\n",i_str, 696 XkbAtomText(dpy,shape->name,XkbXKBFile)); 697 break; 698 case XkbLogoDoodad: 699 fprintf(file,"%s logoName= \"%s\";\n",i_str, 700 XkbStringText(doodad->logo.logo_name,XkbXKBFile)); 701 if (doodad->shape.angle!=0) { 702 fprintf(file,"%s angle= %s;\n",i_str, 703 XkbGeomFPText(doodad->logo.angle,XkbXKBFile)); 704 } 705 if (doodad->shape.color_ndx!=0) { 706 fprintf(file,"%s color= \"%s\";\n",i_str, 707 XkbLogoDoodadColor(geom,&doodad->logo)->spec); 708 } 709 shape= XkbLogoDoodadShape(geom,&doodad->logo); 710 fprintf(file,"%s shape= \"%s\";\n",i_str, 711 XkbAtomText(dpy,shape->name,XkbXKBFile)); 712 break; 713 } 714 fprintf(file,"%s};\n",i_str); 715 return True; 716} 717 718/*ARGSUSED*/ 719static Bool 720WriteXKBOverlay( FILE * file, 721 Display * dpy, 722 unsigned indent, 723 XkbGeometryPtr geom, 724 XkbOverlayPtr ol) 725{ 726register char * i_str; 727int r,k,nOut; 728XkbOverlayRowPtr row; 729XkbOverlayKeyPtr key; 730 731 i_str= XkbIndentText(indent); 732 if (ol->name!=None) { 733 fprintf(file,"%soverlay \"%s\" {\n",i_str, 734 XkbAtomText(dpy,ol->name,XkbMessage)); 735 } 736 else fprintf(file,"%soverlay {\n",i_str); 737 for (nOut=r=0,row=ol->rows;r<ol->num_rows;r++,row++) { 738 for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 739 char *over,*under; 740 over= XkbKeyNameText(key->over.name,XkbXKBFile); 741 under= XkbKeyNameText(key->under.name,XkbXKBFile); 742 if (nOut==0) 743 fprintf(file,"%s %6s=%6s",i_str,under,over); 744 else if ((nOut%4)==0) 745 fprintf(file,",\n%s %6s=%6s",i_str,under,over); 746 else fprintf(file,", %6s=%6s",under,over); 747 nOut++; 748 } 749 } 750 fprintf(file,"\n%s};\n",i_str); 751 return True; 752} 753 754static Bool 755WriteXKBSection( FILE * file, 756 Display * dpy, 757 XkbSectionPtr s, 758 XkbGeometryPtr geom) 759{ 760register int i; 761XkbRowPtr row; 762int dfltKeyColor = 0; 763 764 fprintf(file," section \"%s\" {\n", 765 XkbAtomText(dpy,s->name,XkbXKBFile)); 766 if (s->rows&&(s->rows->num_keys>0)) { 767 dfltKeyColor= s->rows->keys[0].color_ndx; 768 fprintf(file," key.color= \"%s\";\n", 769 XkbStringText(geom->colors[dfltKeyColor].spec,XkbXKBFile)); 770 } 771 fprintf(file," priority= %d;\n",s->priority); 772 fprintf(file," top= %s;\n",XkbGeomFPText(s->top,XkbXKBFile)); 773 fprintf(file," left= %s;\n",XkbGeomFPText(s->left,XkbXKBFile)); 774 fprintf(file," width= %s;\n",XkbGeomFPText(s->width,XkbXKBFile)); 775 fprintf(file," height= %s;\n", 776 XkbGeomFPText(s->height,XkbXKBFile)); 777 if (s->angle!=0) { 778 fprintf(file," angle= %s;\n", 779 XkbGeomFPText(s->angle,XkbXKBFile)); 780 } 781 for (i=0,row=s->rows;row&&i<s->num_rows;i++,row++) { 782 fprintf(file," row {\n"); 783 fprintf(file," top= %s;\n", 784 XkbGeomFPText(row->top,XkbXKBFile)); 785 fprintf(file," left= %s;\n", 786 XkbGeomFPText(row->left,XkbXKBFile)); 787 if (row->vertical) 788 fprintf(file," vertical;\n"); 789 if (row->num_keys>0) { 790 register int k; 791 register XkbKeyPtr key; 792 int forceNL=0; 793 int nThisLine= 0; 794 fprintf(file," keys {\n"); 795 for (k=0,key=row->keys;k<row->num_keys;k++,key++) { 796 XkbShapePtr shape; 797 if (key->color_ndx!=dfltKeyColor) 798 forceNL= 1; 799 if (k==0) { 800 fprintf(file," "); 801 nThisLine= 0; 802 } 803 else if (((nThisLine%2)==1)||(forceNL)) { 804 fprintf(file,",\n "); 805 forceNL= nThisLine= 0; 806 } 807 else { 808 fprintf(file,", "); 809 nThisLine++; 810 } 811 shape= XkbKeyShape(geom,key); 812 fprintf(file,"{ %6s, \"%s\", %3s", 813 XkbKeyNameText(key->name.name,XkbXKBFile), 814 XkbAtomText(dpy,shape->name,XkbXKBFile), 815 XkbGeomFPText(key->gap,XkbXKBFile)); 816 if (key->color_ndx!=dfltKeyColor) { 817 fprintf(file,", color=\"%s\"",XkbKeyColor(geom,key)->spec); 818 forceNL= 1; 819 } 820 fprintf(file," }"); 821 } 822 fprintf(file,"\n };\n"); 823 } 824 fprintf(file," };\n"); 825 } 826 if (s->doodads!=NULL) { 827 XkbDoodadPtr doodad; 828 for (i=0,doodad=s->doodads;i<s->num_doodads;i++,doodad++) { 829 WriteXKBDoodad(file,dpy,8,geom,doodad); 830 } 831 } 832 if (s->overlays!=NULL) { 833 XkbOverlayPtr ol; 834 for (i=0,ol=s->overlays;i<s->num_overlays;i++,ol++) { 835 WriteXKBOverlay(file,dpy,8,geom,ol); 836 } 837 } 838 fprintf(file," }; // End of \"%s\" section\n\n", 839 XkbAtomText(dpy,s->name,XkbXKBFile)); 840 return True; 841} 842 843Bool 844XkbWriteXKBGeometry( FILE * file, 845 XkbFileInfo * result, 846 Bool topLevel, 847 Bool showImplicit, 848 XkbFileAddOnFunc addOn, 849 void * priv) 850{ 851Display * dpy; 852register unsigned i,n; 853XkbDescPtr xkb; 854XkbGeometryPtr geom; 855 856 xkb= result->xkb; 857 if ((!xkb)||(!xkb->geom)) { 858 _XkbLibError(_XkbErrMissingGeometry,"XkbWriteXKBGeometry",0); 859 return False; 860 } 861 dpy= xkb->dpy; 862 geom= xkb->geom; 863 if (geom->name==None) 864 fprintf(file,"xkb_geometry {\n\n"); 865 else fprintf(file,"xkb_geometry \"%s\" {\n\n", 866 XkbAtomText(dpy,geom->name,XkbXKBFile)); 867 fprintf(file," width= %s;\n", 868 XkbGeomFPText(geom->width_mm,XkbXKBFile)); 869 fprintf(file," height= %s;\n\n", 870 XkbGeomFPText(geom->height_mm,XkbXKBFile)); 871 872 if (geom->key_aliases!=NULL) { 873 XkbKeyAliasPtr pAl; 874 pAl= geom->key_aliases; 875 for (i=0;i<geom->num_key_aliases;i++,pAl++) { 876 fprintf(file," alias %6s = %6s;\n", 877 XkbKeyNameText(pAl->alias,XkbXKBFile), 878 XkbKeyNameText(pAl->real,XkbXKBFile)); 879 } 880 fprintf(file,"\n"); 881 } 882 883 if (geom->base_color!=NULL) 884 fprintf(file," baseColor= \"%s\";\n", 885 XkbStringText(geom->base_color->spec,XkbXKBFile)); 886 if (geom->label_color!=NULL) 887 fprintf(file," labelColor= \"%s\";\n", 888 XkbStringText(geom->label_color->spec,XkbXKBFile)); 889 if (geom->label_font!=NULL) 890 fprintf(file," xfont= \"%s\";\n", 891 XkbStringText(geom->label_font,XkbXKBFile)); 892 if ((geom->num_colors>0)&&(showImplicit)) { 893 XkbColorPtr color; 894 for (color=geom->colors,i=0;i<geom->num_colors;i++,color++) { 895 fprintf(file,"// color[%d]= \"%s\"\n",i, 896 XkbStringText(color->spec,XkbXKBFile)); 897 } 898 fprintf(file,"\n"); 899 } 900 if (geom->num_properties>0) { 901 XkbPropertyPtr prop; 902 for (prop=geom->properties,i=0;i<geom->num_properties;i++,prop++) { 903 fprintf(file," %s= \"%s\";\n",prop->name, 904 XkbStringText(prop->value,XkbXKBFile)); 905 } 906 fprintf(file,"\n"); 907 } 908 if (geom->num_shapes>0) { 909 XkbShapePtr shape; 910 XkbOutlinePtr outline; 911 int lastR; 912 for (shape=geom->shapes,i=0;i<geom->num_shapes;i++,shape++) { 913 lastR=0; 914 fprintf(file," shape \"%s\" {", 915 XkbAtomText(dpy,shape->name,XkbXKBFile)); 916 outline= shape->outlines; 917 if (shape->num_outlines>1) { 918 for (n=0;n<shape->num_outlines;n++,outline++) { 919 if (n==0) fprintf(file,"\n"); 920 else fprintf(file,",\n"); 921 WriteXKBOutline(file,shape,outline,lastR,8,8); 922 lastR= outline->corner_radius; 923 } 924 fprintf(file,"\n };\n"); 925 } 926 else { 927 WriteXKBOutline(file,NULL,outline,lastR,1,8); 928 fprintf(file," };\n"); 929 } 930 } 931 } 932 if (geom->num_sections>0) { 933 XkbSectionPtr section; 934 for (section=geom->sections,i=0;i<geom->num_sections;i++,section++){ 935 WriteXKBSection(file,dpy,section,geom); 936 } 937 } 938 if (geom->num_doodads>0) { 939 XkbDoodadPtr doodad; 940 for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) { 941 WriteXKBDoodad(file,dpy,4,geom,doodad); 942 } 943 } 944 if (addOn) 945 (*addOn)(file,result,topLevel,showImplicit,XkmGeometryIndex,priv); 946 fprintf(file,"};\n\n"); 947 return True; 948} 949 950/*ARGSUSED*/ 951Bool 952XkbWriteXKBSemantics( FILE * file, 953 XkbFileInfo * result, 954 Bool topLevel, 955 Bool showImplicit, 956 XkbFileAddOnFunc addOn, 957 void * priv) 958{ 959Bool ok; 960 961 fprintf(file,"xkb_semantics {\n"); 962 ok= XkbWriteXKBKeyTypes(file,result,False,False,addOn,priv); 963 ok= ok&&XkbWriteXKBCompatMap(file,result,False,False,addOn,priv); 964 fprintf(file,"};\n"); 965 return ok; 966} 967 968/*ARGSUSED*/ 969Bool 970XkbWriteXKBLayout( FILE * file, 971 XkbFileInfo * result, 972 Bool topLevel, 973 Bool showImplicit, 974 XkbFileAddOnFunc addOn, 975 void * priv) 976{ 977Bool ok; 978XkbDescPtr xkb; 979 980 xkb= result->xkb; 981 fprintf(file,"xkb_layout {\n"); 982 ok= XkbWriteXKBKeycodes(file,result,False,showImplicit,addOn,priv); 983 ok= ok&&XkbWriteXKBKeyTypes(file,result,False,showImplicit,addOn,priv); 984 ok= ok&&XkbWriteXKBSymbols(file,result,False,showImplicit,addOn,priv); 985 if (xkb->geom) 986 ok= ok&&XkbWriteXKBGeometry(file,result,False,showImplicit,addOn,priv); 987 fprintf(file,"};\n"); 988 return ok; 989} 990 991/*ARGSUSED*/ 992Bool 993XkbWriteXKBKeymap( FILE * file, 994 XkbFileInfo * result, 995 Bool topLevel, 996 Bool showImplicit, 997 XkbFileAddOnFunc addOn, 998 void * priv) 999{ 1000Bool ok; 1001XkbDescPtr xkb; 1002 1003 xkb= result->xkb; 1004 fprintf(file,"xkb_keymap {\n"); 1005 ok= XkbWriteXKBKeycodes(file,result,False,showImplicit,addOn,priv); 1006 ok= ok&&XkbWriteXKBKeyTypes(file,result,False,showImplicit,addOn,priv); 1007 ok= ok&&XkbWriteXKBCompatMap(file,result,False,showImplicit,addOn,priv); 1008 ok= ok&&XkbWriteXKBSymbols(file,result,False,showImplicit,addOn,priv); 1009 if (xkb->geom) 1010 ok= ok&&XkbWriteXKBGeometry(file,result,False,showImplicit,addOn,priv); 1011 fprintf(file,"};\n"); 1012 return ok; 1013} 1014 1015Bool 1016XkbWriteXKBFile( FILE * out, 1017 XkbFileInfo * result, 1018 Bool showImplicit, 1019 XkbFileAddOnFunc addOn, 1020 void * priv) 1021{ 1022Bool ok = False; 1023Bool (*func)( 1024 FILE * /* file */, 1025 XkbFileInfo * /* result */, 1026 Bool /* topLevel */, 1027 Bool /* showImplicit */, 1028 XkbFileAddOnFunc /* addOn */, 1029 void * /* priv */ 1030) = NULL; 1031 1032 switch (result->type) { 1033 case XkmSemanticsFile: 1034 func= XkbWriteXKBSemantics; 1035 break; 1036 case XkmLayoutFile: 1037 func= XkbWriteXKBLayout; 1038 break; 1039 case XkmKeymapFile: 1040 func= XkbWriteXKBKeymap; 1041 break; 1042 case XkmTypesIndex: 1043 func= XkbWriteXKBKeyTypes; 1044 break; 1045 case XkmCompatMapIndex: 1046 func= XkbWriteXKBCompatMap; 1047 break; 1048 case XkmSymbolsIndex: 1049 func= XkbWriteXKBSymbols; 1050 break; 1051 case XkmKeyNamesIndex: 1052 func= XkbWriteXKBKeycodes; 1053 break; 1054 case XkmGeometryFile: 1055 case XkmGeometryIndex: 1056 func= XkbWriteXKBGeometry; 1057 break; 1058 case XkmVirtualModsIndex: 1059 case XkmIndicatorsIndex: 1060 _XkbLibError(_XkbErrBadImplementation, 1061 XkbConfigText(result->type,XkbMessage),0); 1062 return False; 1063 } 1064 if (out==NULL) { 1065 _XkbLibError(_XkbErrFileCannotOpen,"XkbWriteXkbFile",0); 1066 ok= False; 1067 } 1068 else if (func) { 1069 ok= (*func)(out,result,True,showImplicit,addOn,priv); 1070 } 1071 return ok; 1072} 1073