1 /************************************************************
2 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
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.
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.
25 ********************************************************/
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
29 #endif
31 #include <stdio.h>
32 #include <ctype.h>
33 #include <stdlib.h>
34 #include <X11/Xfuncs.h>
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>
47 #include "xkbgeom.h"
48 #include "xkbfile.h"
50 #define VMOD_HIDE_VALUE 0
51 #define VMOD_SHOW_VALUE 1
52 #define VMOD_COMMENT_VALUE 2
54 static Bool
55 WriteXKBVModDecl(FILE *file,XkbDescPtr xkb,int showValue)
56 {
57 register int i,nMods;
58 Atom * vmodNames;
60 if (xkb==NULL)
61 return FALSE;
62 if (xkb->names!=NULL)
63 vmodNames= xkb->names->vmods;
64 else vmodNames= NULL;
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 }
90 /***====================================================================***/
92 static Bool
93 WriteXKBAction(FILE *file,XkbDescPtr xkb,XkbAnyAction *action)
94 {
95 fprintf(file,"%s",XkbActionText(xkb,(XkbAction *)action,XkbXKBFile));
96 return TRUE;
97 }
99 /***====================================================================***/
101 Bool
102 XkbWriteXKBKeycodes( FILE * file,
103 XkbDescPtr xkb,
104 Bool topLevel,
105 Bool showImplicit,
106 XkbFileAddOnFunc addOn,
107 void * priv)
108 {
109 Atom kcName;
110 register unsigned i;
111 char * alternate;
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 }
161 Bool
162 XkbWriteXKBKeyTypes( FILE * file,
163 XkbDescPtr xkb,
164 Bool topLevel,
165 Bool showImplicit,
166 XkbFileAddOnFunc addOn,
167 void * priv)
168 {
169 register unsigned i,n;
170 XkbKeyTypePtr type;
171 XkbKTMapEntryPtr entry;
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));
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 }
227 static Bool
228 WriteXKBIndicatorMap( FILE * file,
229 XkbDescPtr xkb,
230 Atom name,
231 XkbIndicatorMapPtr led,
232 XkbFileAddOnFunc addOn,
233 void * priv)
234 {
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 }
268 Bool
269 XkbWriteXKBCompatMap( FILE * file,
270 XkbDescPtr xkb,
271 Bool topLevel,
272 Bool showImplicit,
273 XkbFileAddOnFunc addOn,
274 void * priv)
275 {
276 register unsigned i;
277 XkbSymInterpretPtr interp;
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));
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;
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 }
343 Bool
344 XkbWriteXKBSymbols( FILE * file,
345 XkbDescPtr xkb,
346 Bool topLevel,
347 Bool showImplicit,
348 XkbFileAddOnFunc addOn,
349 void * priv)
350 {
351 register unsigned i,tmp;
352 XkbClientMapPtr map;
353 XkbServerMapPtr srv;
354 Bool showActions;
356 if (!xkb) {
357 _XkbLibError(_XkbErrMissingSymbols,"XkbWriteXKBSymbols",0);
358 return FALSE;
359 }
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=" ";
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;
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;
478 if (((unsigned)XkbKeyNumGroups(xkb,i)>1)||showActions)
479 simple= FALSE;
480 if (simple) {
481 KeySym *syms;
482 unsigned s;
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 }
546 static Bool
547 WriteXKBOutline( FILE * file,
548 XkbShapePtr shape,
549 XkbOutlinePtr outline,
550 int lastRadius,
551 int first,
552 int indent)
553 {
554 register int i;
555 XkbPointPtr pt;
556 char * iStr;
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 }
586 static Bool
587 WriteXKBDoodad( FILE * file,
588 unsigned indent,
589 XkbGeometryPtr geom,
590 XkbDoodadPtr doodad)
591 {
592 register char * i_str;
593 XkbShapePtr shape;
594 XkbColorPtr color;
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));
629 }
630 if (doodad->text.height!=0) {
631 fprintf(file,"%s height= %s;\n",i_str,
632 XkbGeomFPText(doodad->text.height,XkbXKBFile));
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 }
676 /*ARGSUSED*/
677 static Bool
678 WriteXKBOverlay( FILE * file,
679 unsigned indent,
680 XkbGeometryPtr geom,
681 XkbOverlayPtr ol)
682 {
683 register char * i_str;
684 int r,k,nOut;
685 XkbOverlayRowPtr row;
686 XkbOverlayKeyPtr key;
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 }
711 static Bool
712 WriteXKBSection( FILE * file,
713 XkbSectionPtr s,
714 XkbGeometryPtr geom)
715 {
716 register int i;
717 XkbRowPtr row;
718 int dfltKeyColor = 0;
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 }
799 Bool
800 XkbWriteXKBGeometry( FILE * file,
801 XkbDescPtr xkb,
802 Bool topLevel,
803 Bool showImplicit,
804 XkbFileAddOnFunc addOn,
805 void * priv)
806 {
807 register unsigned i,n;
808 XkbGeometryPtr geom;
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));
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 }
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 }