cout.c revision 4e411241
1/* $Xorg: cout.c,v 1.3 2000/08/17 19:46:43 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/cout.c,v 3.8 2003/02/03 20:12:00 paulo Exp $ */
28
29#ifdef HAVE_CONFIG_H
30#include <config.h>
31#endif
32#include <stdio.h>
33#include <ctype.h>
34#include <stdlib.h>
35#include <X11/Xos.h>
36#include <X11/Xlib.h>
37#include <X11/XKBlib.h>
38#include <X11/extensions/XKBgeom.h>
39
40#include "XKMformat.h"
41#include "XKBfileInt.h"
42
43#define	lowbit(x)	((x) & (-(x)))
44
45static Bool
46WriteCHdrVMods(FILE *file,Display *dpy,XkbDescPtr xkb)
47{
48register int i,nOut;
49
50    if ((!xkb)||(!xkb->names)||(!xkb->names->vmods))
51	return False;
52    for (i=nOut=0;i<XkbNumVirtualMods;i++) {
53	if (xkb->names->vmods[i]!=None) {
54	    fprintf(file,"%s#define	vmod_%s	%d\n",(nOut<1?"\n":""),
55				XkbAtomText(dpy,xkb->names->vmods[i],XkbCFile),
56				i);
57	    nOut++;
58	}
59    }
60    for (i=nOut=0;i<XkbNumVirtualMods;i++) {
61	if (xkb->names->vmods[i]!=None) {
62	    fprintf(file,"%s#define	vmod_%sMask	(1<<%d)\n",
63				(nOut<1?"\n":""),
64				XkbAtomText(dpy,xkb->names->vmods[i],XkbCFile)
65				,i);
66	    nOut++;
67	}
68    }
69    if (nOut>0)
70	fprintf(file,"\n");
71    return True;
72}
73
74static Bool
75WriteCHdrKeycodes(FILE *file,XkbDescPtr xkb)
76{
77Atom			kcName;
78register unsigned 	i;
79char 			buf[8];
80
81    if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) {
82	_XkbLibError(_XkbErrMissingNames,"WriteCHdrKeycodes",0);
83	return False;
84    }
85    kcName= xkb->names->keycodes;
86    buf[4]= '\0';
87    if (xkb->names->keycodes!=None)
88	 fprintf(file,"/* keycodes name is \"%s\" */\n",
89 				XkbAtomText(xkb->dpy,kcName,XkbMessage));
90    fprintf(file,"static XkbKeyNameRec	keyNames[NUM_KEYS]= {\n");
91    for (i=0;i<=xkb->max_key_code;i++) {
92	sprintf(buf,"\"%s\"",XkbKeyNameText(xkb->names->keys[i].name,XkbCFile));
93	if (i!=xkb->max_key_code)  {
94	    fprintf(file,"    {  %6s  },",buf);
95	    if ((i&3)==3)
96		fprintf(file,"\n");
97	}
98	else {
99	    fprintf(file,"    {  %6s  }\n",buf);
100	}
101    }
102    fprintf(file,"};\n");
103    return True;
104}
105
106static void
107WriteTypePreserve(	FILE *		file,
108			Display *	dpy,
109			char *		prefix,
110			XkbDescPtr	xkb,
111			XkbKeyTypePtr	type)
112{
113register unsigned	i;
114XkbModsPtr		pre;
115
116    fprintf(file,"static XkbModsRec preserve_%s[%d]= {\n",prefix,
117							type->map_count);
118    for (i=0,pre=type->preserve;i<type->map_count;i++,pre++) {
119	if (i!=0)
120	    fprintf(file,",\n");
121	fprintf(file,"    {   %15s, ",XkbModMaskText(pre->mask,XkbCFile));
122	fprintf(file,"%15s, ",XkbModMaskText(pre->real_mods,XkbCFile));
123	fprintf(file,"%15s }",XkbVModMaskText(dpy,xkb,0,pre->vmods,XkbCFile));
124    }
125    fprintf(file,"\n};\n");
126    return;
127}
128
129static void
130WriteTypeInitFunc(FILE *file,Display *dpy,XkbDescPtr xkb)
131{
132register unsigned 	i,n;
133XkbKeyTypePtr		type;
134Atom *			names;
135char *			prefix = NULL;
136
137    fprintf(file,"\n\nstatic void\n");
138    fprintf(file,"initTypeNames(DPYTYPE dpy)\n");
139    fprintf(file,"{\n");
140    for (i=0,type=xkb->map->types;i<xkb->map->num_types;i++,type++) {
141	if (!(prefix = strdup(XkbAtomText(dpy,type->name,XkbCFile)))) {
142		_XkbLibError(_XkbErrBadAlloc,"WriteTypeInitFunc",0);
143		fprintf(file,"#error XkbErrBadAlloc WriteTypeInitFunc\n");
144		break;
145	}
146	if (type->name!=None)
147	    fprintf(file,"    dflt_types[%d].name= GET_ATOM(dpy,\"%s\");\n",i,
148					XkbAtomText(dpy,type->name,XkbCFile));
149	names= type->level_names;
150	if (names!=NULL) {
151	    char *tmp;
152	    for (n=0;n<type->num_levels;n++) {
153		if (names[n]==None)
154		    continue;
155		tmp= XkbAtomText(dpy,names[n],XkbCFile);
156		if (tmp==NULL)
157		    continue;
158		fprintf(file,"    lnames_%s[%d]=	",prefix,n);
159		fprintf(file,"GET_ATOM(dpy,\"%s\");\n",tmp);
160	    }
161	}
162	free(prefix);
163	prefix = NULL;
164    }
165    fprintf(file,"}\n");
166    return;
167}
168
169static Bool
170WriteCHdrKeyTypes(FILE *file,Display *dpy,XkbDescPtr xkb)
171{
172register unsigned	i,n;
173XkbClientMapPtr		map;
174XkbKeyTypePtr		type;
175char * 			prefix = NULL;
176
177    if ((!xkb)||(!xkb->map)||(!xkb->map->types)) {
178	_XkbLibError(_XkbErrMissingTypes,"WriteCHdrKeyTypes",0);
179	return False;
180    }
181    if (xkb->map->num_types<XkbNumRequiredTypes) {
182	_XkbLibError(_XkbErrMissingReqTypes,"WriteCHdrKeyTypes",0);
183	return 0;
184    }
185    map= xkb->map;
186    if ((xkb->names!=NULL)&&(xkb->names->types!=None)) {
187	fprintf(file,"/* types name is \"%s\" */\n",
188				XkbAtomText(dpy,xkb->names->types,XkbCFile));
189    }
190    for (i=0,type=map->types;i<map->num_types;i++,type++) {
191	if (!(prefix = strdup(XkbAtomText(dpy,type->name,XkbCFile)))) {
192		_XkbLibError(_XkbErrBadAlloc,"WriteCHdrKeyTypes",0);
193		return False;
194	}
195
196	if (type->map_count>0) {
197	    XkbKTMapEntryPtr	entry;
198	    entry= type->map;
199	    fprintf(file,"static XkbKTMapEntryRec map_%s[%d]= {\n",prefix,
200							type->map_count);
201	    for (n=0;n<(unsigned)type->map_count;n++,entry++) {
202		if (n!=0)
203		    fprintf(file,",\n");
204		fprintf(file,"    { %d, %6d, { %15s, %15s, %15s } }",
205			entry->active,
206			entry->level,
207			XkbModMaskText(entry->mods.mask,XkbCFile),
208			XkbModMaskText(entry->mods.real_mods,XkbCFile),
209			XkbVModMaskText(dpy,xkb,0,entry->mods.vmods,XkbCFile));
210	    }
211	    fprintf(file,"\n};\n");
212
213	    if (type->preserve)
214		WriteTypePreserve(file,dpy,prefix,xkb,type);
215	}
216	if (type->level_names!=NULL) {
217	    fprintf(file,"static Atom lnames_%s[%d];\n",prefix,
218							 type->num_levels);
219	}
220	fprintf(file,"\n");
221	free(prefix);
222	prefix = NULL;
223    }
224    fprintf(file,"static XkbKeyTypeRec dflt_types[]= {\n");
225    for (i=0,type=map->types;i<(unsigned)map->num_types;i++,type++) {
226	if (!(prefix = strdup(XkbAtomText(dpy,type->name,XkbCFile)))) {
227		_XkbLibError(_XkbErrBadAlloc,"WriteCHdrKeyTypes",0);
228		return False;
229	}
230	if (i!=0)	fprintf(file,",\n");
231	fprintf(file,"    {\n	{ %15s, %15s, %15s },\n",
232			XkbModMaskText(type->mods.mask,XkbCFile),
233			XkbModMaskText(type->mods.real_mods,XkbCFile),
234			XkbVModMaskText(dpy,xkb,0,type->mods.vmods,XkbCFile));
235	fprintf(file,"	%d,\n",type->num_levels);
236	fprintf(file,"	%d,",type->map_count);
237	if (type->map_count>0)
238	     fprintf(file,"	map_%s,",prefix);
239	else fprintf(file,"	NULL,");
240	if (type->preserve)
241	     fprintf(file,"	preserve_%s,\n",prefix);
242	else fprintf(file,"	NULL,\n");
243	if (type->level_names!=NULL)
244	     fprintf(file,"	None,	lnames_%s\n    }",prefix);
245	else fprintf(file,"	None,	NULL\n    }");
246	free(prefix);
247	prefix = NULL;
248    }
249    fprintf(file,"\n};\n");
250    fprintf(file,"#define num_dflt_types (sizeof(dflt_types)/sizeof(XkbKeyTypeRec))\n");
251    WriteTypeInitFunc(file,dpy,xkb);
252    return True;
253}
254
255static Bool
256WriteCHdrCompatMap(FILE *file,Display *dpy,XkbDescPtr xkb)
257{
258register unsigned	i;
259XkbCompatMapPtr		compat;
260XkbSymInterpretPtr	interp;
261
262    if ((!xkb)||(!xkb->compat)||(!xkb->compat->sym_interpret)) {
263	_XkbLibError(_XkbErrMissingSymInterps,"WriteCHdrInterp",0);
264	return False;
265    }
266    compat= xkb->compat;
267    if ((xkb->names!=NULL)&&(xkb->names->compat!=None)) {
268	fprintf(file,"/* compat name is \"%s\" */\n",
269				XkbAtomText(dpy,xkb->names->compat,XkbCFile));
270    }
271    fprintf(file,"static XkbSymInterpretRec dfltSI[%d]= {\n",
272						compat->num_si);
273    interp= compat->sym_interpret;
274    for (i=0;i<compat->num_si;i++,interp++) {
275	XkbAction *act;
276	act= (XkbAction *)&interp->act;
277	if (i!=0)	fprintf(file,",\n");
278	fprintf(file,"    {    %s, ",XkbKeysymText(interp->sym,XkbCFile));
279	fprintf(file,"0x%04x,\n",interp->flags);
280	fprintf(file,"         %s, ",XkbSIMatchText(interp->match,XkbCFile));
281	fprintf(file,"%s,\n",XkbModMaskText(interp->mods,XkbCFile));
282	fprintf(file,"         %d,\n",interp->virtual_mod);
283	fprintf(file,"       %s }",XkbActionText(dpy,xkb,act,XkbCFile));
284    }
285    fprintf(file,"\n};\n");
286    fprintf(file,
287	   "#define num_dfltSI (sizeof(dfltSI)/sizeof(XkbSymInterpretRec))\n");
288    fprintf(file,"\nstatic XkbCompatMapRec compatMap= {\n");
289    fprintf(file,"    dfltSI,\n");
290    fprintf(file,"    {   /* group compatibility */\n        ");
291    for (i=0;i<XkbNumKbdGroups;i++) {
292	XkbModsPtr gc;
293	gc= &xkb->compat->groups[i];
294	fprintf(file,"%s{ %12s, %12s, %12s }",
295			((i==0)?"":",\n        "),
296			XkbModMaskText(gc->mask,XkbCFile),
297			XkbModMaskText(gc->real_mods,XkbCFile),
298			XkbVModMaskText(xkb->dpy,xkb,0,gc->vmods,XkbCFile));
299    }
300    fprintf(file,"\n    },\n");
301    fprintf(file,"    num_dfltSI, num_dfltSI\n");
302    fprintf(file,"};\n\n");
303    return True;
304}
305
306static Bool
307WriteCHdrSymbols(FILE *file,XkbDescPtr xkb)
308{
309register unsigned i;
310
311    if ((!xkb)||(!xkb->map)||(!xkb->map->syms)||(!xkb->map->key_sym_map)) {
312	_XkbLibError(_XkbErrMissingSymbols,"WriteCHdrSymbols",0);
313	return False;
314    }
315    fprintf(file,"#define NUM_SYMBOLS	%d\n",xkb->map->num_syms);
316    if (xkb->map->num_syms>0) {
317	register KeySym *sym;
318	sym= xkb->map->syms;
319	fprintf(file,"static KeySym	symCache[NUM_SYMBOLS]= {\n");
320	for (i=0;i<xkb->map->num_syms;i++,sym++) {
321	    if (i==0)		fprintf(file,"    ");
322	    else if (i%4==0)	fprintf(file,",\n    ");
323	    else		fprintf(file,", ");
324	    fprintf(file,"%15s",XkbKeysymText(*sym,XkbCFile));
325	}
326	fprintf(file,"\n};\n");
327    }
328    if (xkb->max_key_code>0) {
329	register XkbSymMapPtr	map;
330	map= xkb->map->key_sym_map;
331	fprintf(file,"static XkbSymMapRec	symMap[NUM_KEYS]= {\n");
332	for (i=0;i<=xkb->max_key_code;i++,map++) {
333	    if (i==0)		fprintf(file,"    ");
334	    else if ((i&3)==0)	fprintf(file,",\n    ");
335	    else			fprintf(file,", ");
336	    fprintf(file, "{ %2d, 0x%x, %3d }",
337		    map->kt_index[0], map->group_info, map->offset);
338	}
339	fprintf(file,"\n};\n");
340    }
341    return True;
342}
343
344static Bool
345WriteCHdrClientMap(FILE *file,Display *dpy,XkbDescPtr xkb)
346{
347    if ((!xkb)||(!xkb->map)||(!xkb->map->syms)||(!xkb->map->key_sym_map)) {
348	_XkbLibError(_XkbErrMissingSymbols,"WriteCHdrClientMap",0);
349	return False;
350    }
351    if (!WriteCHdrKeyTypes(file,dpy,xkb))
352	return False;
353    if (!WriteCHdrSymbols(file,xkb))
354	return False;
355    fprintf(file,"static XkbClientMapRec clientMap= {\n");
356    fprintf(file,"    NUM_TYPES,   NUM_TYPES,   types, \n");
357    fprintf(file,"    NUM_SYMBOLS, NUM_SYMBOLS, symCache, symMap\n");
358    fprintf(file,"};\n\n");
359    return True;
360}
361
362static Bool
363WriteCHdrServerMap(FILE *file,Display *dpy,XkbDescPtr xkb)
364{
365register unsigned i;
366
367    if ((!xkb)||(!xkb->map)||(!xkb->map->syms)||(!xkb->map->key_sym_map)) {
368	_XkbLibError(_XkbErrMissingSymbols,"WriteCHdrServerMap",0);
369	return False;
370    }
371    if (xkb->server->num_acts>0) {
372	register XkbAnyAction *act;
373	act= (XkbAnyAction *)xkb->server->acts;
374	fprintf(file,"#define NUM_ACTIONS	%d\n",xkb->server->num_acts);
375	fprintf(file,"static XkbAnyAction 	actionCache[NUM_ACTIONS]= {\n");
376	for (i=0;i<xkb->server->num_acts;i++,act++) {
377	    if (i==0)	fprintf(file,"    ");
378	    else	fprintf(file,",\n    ");
379	    fprintf(file,"%s",XkbActionText(dpy,xkb,(XkbAction *)act,XkbCFile));
380	}
381	fprintf(file,"\n};\n");
382    }
383    fprintf(file,"static unsigned short	keyActions[NUM_KEYS]= {\n");
384    for (i=0;i<=xkb->max_key_code;i++) {
385	if (i==0)		fprintf(file,"    ");
386	else if ((i&0xf)==0)	fprintf(file,",\n    ");
387	else			fprintf(file,", ");
388	fprintf(file,"%2d",xkb->server->key_acts[i]);
389    }
390    fprintf(file,"\n};\n");
391    fprintf(file,"static XkbBehavior behaviors[NUM_KEYS]= {\n");
392    for (i=0;i<=xkb->max_key_code;i++) {
393	if (i==0)		fprintf(file,"    ");
394	else if ((i&0x3)==0)	fprintf(file,",\n    ");
395	else			fprintf(file,", ");
396	if (xkb->server->behaviors) {
397	     fprintf(file,"%s",
398		XkbBehaviorText(xkb,&xkb->server->behaviors[i],XkbCFile));
399	}
400	else fprintf(file,"{    0,    0 }");
401    }
402    fprintf(file,"\n};\n");
403    fprintf(file,"static unsigned char explicit_parts[NUM_KEYS]= {\n");
404    for (i=0;i<=xkb->max_key_code;i++) {
405	if (i==0)		fprintf(file,"    ");
406	else if ((i&0x7)==0)	fprintf(file,",\n    ");
407	else			fprintf(file,", ");
408	if ((xkb->server->explicit==NULL)||(xkb->server->explicit[i]==0))
409	     fprintf(file,"   0");
410	else fprintf(file,"0x%02x",xkb->server->explicit[i]);
411    }
412    fprintf(file,"\n};\n");
413    fprintf(file,"static unsigned short vmodmap[NUM_KEYS]= {\n");
414    for (i=0;i<xkb->max_key_code;i++) {
415	if (i==0)		fprintf(file,"    ");
416	else if ((i&0x7)==0)	fprintf(file,",\n    ");
417	else			fprintf(file,", ");
418	if ((xkb->server->vmodmap==NULL)||(xkb->server->vmodmap[i]==0))
419	     fprintf(file,"     0");
420	else fprintf(file,"0x%04x",xkb->server->vmodmap[i]);
421    }
422    fprintf(file,"};\n");
423    fprintf(file,"static XkbServerMapRec serverMap= {\n");
424    fprintf(file,"    %d, %d, (XkbAction *)actionCache,\n",
425				xkb->server->num_acts,xkb->server->num_acts);
426    fprintf(file,"    behaviors, keyActions, explicit_parts,\n");
427    for (i=0;i<XkbNumVirtualMods;i++) {
428	if (i==0)	fprintf(file,"    { ");
429	else if (i==8)	fprintf(file,",\n      ");
430	else		fprintf(file,", ");
431	fprintf(file,"%3d",xkb->server->vmods[i]);
432    }
433    fprintf(file," },\n");
434    fprintf(file,"    vmodmap\n");
435    fprintf(file,"};\n\n");
436    return True;
437}
438
439static Bool
440WriteCHdrIndicators(FILE *file,Display *dpy,XkbDescPtr xkb)
441{
442register int 		i,nNames;
443XkbIndicatorMapPtr	imap;
444
445    if (xkb->indicators==NULL)
446	return True;
447    fprintf(file, "static XkbIndicatorRec indicators= {\n");
448    fprintf(file, "    0x%lx,\n    {\n",
449	    (long)xkb->indicators->phys_indicators);
450    for (imap=xkb->indicators->maps,i=nNames=0;i<XkbNumIndicators;i++,imap++) {
451	fprintf(file,"%s        { 0x%02x, %s, 0x%02x, %s, { %s, ",
452			(i!=0?",\n":""),
453			imap->flags,
454			XkbIMWhichStateMaskText(imap->which_groups,XkbCFile),
455			imap->groups,
456			XkbIMWhichStateMaskText(imap->which_mods,XkbCFile),
457			XkbModMaskText(imap->mods.mask,XkbCFile));
458	fprintf(file," %s, %s }, %s }",
459			XkbModMaskText(imap->mods.real_mods,XkbCFile),
460			XkbVModMaskText(dpy,xkb,0,imap->mods.vmods,XkbCFile),
461			XkbControlsMaskText(imap->ctrls,XkbCFile));
462	if (xkb->names && (xkb->names->indicators[i]!=None))
463	    nNames++;
464    }
465    fprintf(file,"\n    }\n};\n");
466    if (nNames>0) {
467	fprintf(file,"static void\n");
468	fprintf(file,"initIndicatorNames(DPYTYPE dpy,XkbDescPtr xkb)\n");
469	fprintf(file,"{\n");
470	for (i=0;i<XkbNumIndicators;i++) {
471	    Atom name;
472	    if (xkb->names->indicators[i]==None)
473		continue;
474	    name= xkb->names->indicators[i];
475	    fprintf(file,"    xkb->names->indicators[%2d]=	",i);
476	    fprintf(file,"GET_ATOM(dpy,\"%s\");\n",
477						XkbAtomText(dpy,name,XkbCFile));
478	}
479	fprintf(file,"}\n");
480    }
481    return True;
482}
483
484static Bool
485WriteCHdrGeomProps(FILE *file,XkbDescPtr xkb,XkbGeometryPtr geom)
486{
487    if (geom->num_properties>0) {
488	register int i;
489	fprintf(file,"\nstatic XkbPropertyRec g_props[%d]= {\n",
490							geom->num_properties);
491	for (i=0;i<geom->num_properties;i++) {
492	    fprintf(file,"%s	{	\"%s\", \"%s\"	}",(i==0?"":",\n"),
493			XkbStringText(geom->properties[i].name,XkbCFile),
494			XkbStringText(geom->properties[i].value,XkbCFile));
495	}
496	fprintf(file,"\n};\n");
497    }
498    return True;
499}
500
501static Bool
502WriteCHdrGeomColors(FILE *file,XkbDescPtr xkb,XkbGeometryPtr geom)
503{
504    if (geom->num_colors>0) {
505	register int i;
506	fprintf(file,"\nstatic XkbColorRec g_colors[%d]= {\n",geom->num_colors);
507	for (i=0;i<geom->num_colors;i++) {
508	    fprintf(file,"%s	{	%3d, \"%s\"	}",(i==0?"":",\n"),
509			geom->colors[i].pixel,
510			XkbStringText(geom->colors[i].spec,XkbCFile));
511	}
512	fprintf(file,"\n};\n");
513    }
514    return True;
515}
516
517static Bool
518WriteCHdrGeomOutlines(FILE *file,int nOL,XkbOutlinePtr ol,int shapeNdx)
519{
520register int o,p;
521
522
523    for (o=0;o<nOL;o++) {
524	fprintf(file,"\nstatic XkbPointRec pts_sh%02do%02d[]= {\n",shapeNdx,o);
525	for (p=0;p<ol[o].num_points;p++) {
526	    if (p==0)			fprintf(file,"	");
527	    else if ((p&0x3)==0)	fprintf(file,",\n	");
528	    else 			fprintf(file,", ");
529	    fprintf(file,"{ %4d, %4d }",
530				ol[o].points[p].x,ol[o].points[p].y);
531	}
532	fprintf(file,"\n};");
533    }
534    fprintf(file,"\n\nstatic XkbOutlineRec ol_sh%02d[]= {\n",shapeNdx);
535    for (o=0;o<nOL;o++) {
536	fprintf(file,"%s	{ %d,	%d,	%d,	pts_sh%02do%02d	}",
537					(o==0?"":",\n"),
538					ol[o].num_points,ol[o].num_points,
539					ol[o].corner_radius,shapeNdx,o);
540    }
541    fprintf(file,"\n};\n");
542    return True;
543}
544
545static Bool
546WriteCHdrGeomShapes(FILE *file,XkbDescPtr xkb,XkbGeometryPtr geom)
547{
548register int 		s;
549register XkbShapePtr	shape;
550
551    for (s=0,shape=geom->shapes;s<geom->num_shapes;s++,shape++) {
552	WriteCHdrGeomOutlines(file,shape->num_outlines,shape->outlines,s);
553    }
554    fprintf(file,"\n\nstatic XkbShapeRec g_shapes[%d]= {\n",geom->num_shapes);
555    for (s=0,shape=geom->shapes;s<geom->num_shapes;s++,shape++) {
556	fprintf(file,"%s	{ None, %3d, %3d, ol_sh%02d, ",
557					(s==0?"":",\n"),shape->num_outlines,
558					shape->num_outlines,s);
559	if (shape->approx) {
560	    fprintf(file,"&ol_sh%02d[%2d],	",s,
561					XkbOutlineIndex(shape,shape->approx));
562	}
563	else fprintf(file,"        NULL,	");
564	if (shape->primary) {
565	    fprintf(file,"&ol_sh%02d[%2d],\n",s,
566					XkbOutlineIndex(shape,shape->primary));
567	}
568	else fprintf(file,"        NULL,\n");
569	fprintf(file,"					{ %4d, %4d, %4d, %4d } }",
570					shape->bounds.x1,shape->bounds.y1,
571					shape->bounds.x2,shape->bounds.y2);
572    }
573    fprintf(file,"\n};\n");
574    return True;
575}
576
577static Bool
578WriteCHdrGeomDoodads(	FILE *		file,
579			XkbDescPtr	xkb,
580			XkbGeometryPtr	geom,
581			XkbSectionPtr	section,
582			int		section_num)
583{
584int		nd,d;
585XkbDoodadPtr	doodad;
586Display *	dpy;
587
588    dpy= xkb->dpy;
589    if (section==NULL) {
590	if (geom->num_doodads>0) {
591	    fprintf(file,"static XkbDoodadRec g_doodads[%d];\n",
592							geom->num_doodads);
593	}
594	fprintf(file,"static void\n");
595	fprintf(file,"_InitGeomDoodads(DPYTYPE dpy,XkbGeometryPtr geom)\n");
596	fprintf(file,"{\n");
597	fprintf(file,"register XkbDoodadPtr doodads;\n\n");
598	fprintf(file,"    doodads= geom->doodads;\n");
599	nd= geom->num_doodads;
600	doodad= geom->doodads;
601    }
602    else {
603	if (section->num_doodads>0) {
604	    fprintf(file,"static XkbDoodadRec doodads_s%02d[%d];\n",
605					section_num,section->num_doodads);
606	}
607	fprintf(file,"static void\n");
608	fprintf(file,"_InitS%02dDoodads(",section_num);
609	fprintf(file,"    DPYTYPE		dpy,\n");
610	fprintf(file,"    XkbGeometryPtr 	geom,\n");
611	fprintf(file,"    XkbSectionPtr 	section)\n");
612	fprintf(file,"{\n");
613	fprintf(file,"register XkbDoodadPtr doodads;\n\n");
614	fprintf(file,"    doodads= section->doodads;\n");
615	nd= geom->num_doodads;
616	doodad= geom->doodads;
617    }
618    for (d=0;d<nd;d++,doodad++) {
619	if (d!=0)	fprintf(file,"\n");
620	fprintf(file,"    doodads[%d].any.name= GET_ATOM(dpy,\"%s\");\n",d,
621			XkbAtomText(dpy,doodad->any.name,XkbCFile));
622	fprintf(file,"    doodads[%d].any.type= %s;\n",d,
623			XkbDoodadTypeText(doodad->any.type,XkbCFile));
624	fprintf(file,"    doodads[%d].any.priority= %d;\n",d,
625			doodad->any.priority);
626	fprintf(file,"    doodads[%d].any.top= %d;\n",d,doodad->any.top);
627	fprintf(file,"    doodads[%d].any.left= %d;\n",d,doodad->any.left);
628	fprintf(file,"    doodads[%d].any.angle= %d;\n",d,doodad->any.angle);
629	switch (doodad->any.type) {
630	    case XkbOutlineDoodad:
631	    case XkbSolidDoodad:
632		fprintf(file,"    doodads[%d].shape.color_ndx= %d;\n",d,
633					doodad->shape.color_ndx);
634		fprintf(file,"    doodads[%d].shape.shape_ndx= %d;\n",d,
635					doodad->shape.shape_ndx);
636		break;
637	    case XkbTextDoodad:
638		fprintf(file,"    doodads[%d].text.width= %d;\n",d,
639					doodad->text.width);
640		fprintf(file,"    doodads[%d].text.height= %d;\n",d,
641					doodad->text.height);
642		fprintf(file,"    doodads[%d].text.color_ndx= %d;\n",d,
643					doodad->text.color_ndx);
644		fprintf(file,"    doodads[%d].text.text= \"%s\";\n",d,
645				XkbStringText(doodad->text.text,XkbCFile));
646		fprintf(file,"    doodads[%d].text.font= \"%s\";\n",d,
647				XkbStringText(doodad->text.font,XkbCFile));
648		break;
649	    case XkbIndicatorDoodad:
650		fprintf(file,"    doodads[%d].indicator.shape_ndx= %d;\n",d,
651					doodad->indicator.shape_ndx);
652		fprintf(file,"    doodads[%d].indicator.on_color_ndx= %d;\n",d,
653					doodad->indicator.on_color_ndx);
654		fprintf(file,"    doodads[%d].indicator.off_color_ndx= %d;\n",d,
655					doodad->indicator.off_color_ndx);
656		break;
657	    case XkbLogoDoodad:
658		fprintf(file,"    doodads[%d].logo.color_ndx= %d;\n",d,
659					doodad->logo.color_ndx);
660		fprintf(file,"    doodads[%d].logo.shape_ndx= %d;\n",d,
661					doodad->logo.shape_ndx);
662		fprintf(file,"    doodads[%d].logo.logo_name= \"%s\";\n",d,
663				XkbStringText(doodad->logo.logo_name,XkbCFile));
664		break;
665	}
666    }
667    fprintf(file,"}\n");
668    return True;
669}
670
671static Bool
672WriteCHdrGeomOverlays(	FILE *		file,
673			XkbDescPtr	xkb,
674			XkbSectionPtr	section,
675			int		section_num)
676{
677register int		o,r,k;
678XkbOverlayPtr		ol;
679XkbOverlayRowPtr	row;
680XkbOverlayKeyPtr	key;
681
682    if (section->num_overlays<1)
683	return True;
684    for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) {
685	for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
686	    fprintf(file,"static XkbOverlayKeyRec olkeys_s%02dr%02d[%d]= {\n",
687						section_num,r,row->num_keys);
688	    for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
689		fprintf(file,"%s	{ {\"%s\"},	{\"%s\"}	}",
690				(k==0?"":",\n"),
691				XkbKeyNameText(key->over.name,XkbCFile),
692				XkbKeyNameText(key->under.name,XkbCFile));
693	    }
694	    fprintf(file,"\n};\n");
695	}
696	fprintf(file,"static XkbOverlayRowRec olrows_s%02d[%d]= {\n",
697						section_num,section->num_rows);
698	for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
699	    fprintf(file,"%s	{ %4d, %4d, %4d, olkeys_s%02dr%02d }",
700				(r==0?"":",\n"),
701				row->row_under,row->num_keys,row->num_keys,
702				section_num,r);
703	}
704	fprintf(file,"\n};\n");
705    }
706    fprintf(file,"static XkbOverlayRec overlays_s%02d[%d]= {\n",section_num,
707							section->num_overlays);
708    for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) {
709	fprintf(file,"%s	{\n",(o==0?"":",\n"));
710	fprintf(file,"	    None, 	/* name */\n");
711	fprintf(file,"	    NULL,	/* section_under */\n");
712	fprintf(file,"	    %4d,	/* num_rows */\n",ol->num_rows);
713	fprintf(file,"	    %4d,	/* sz_rows */\n",ol->num_rows);
714	fprintf(file,"	    olrows_s%02d,\n",section_num);
715	fprintf(file,"	    NULL	/* bounds */\n");
716	fprintf(file,"	}");
717    }
718    fprintf(file,"\n};\n");
719    fprintf(file,"static void\n");
720    fprintf(file,"_InitS%02dOverlay(",section_num);
721    fprintf(file,"    DPYTYPE		dpy,\n");
722    fprintf(file,"    XkbGeometryPtr 	geom,\n");
723    fprintf(file,"    XkbSectionPtr 	section)\n");
724    fprintf(file,"{\n");
725    fprintf(file,"XkbOverlayPtr	ol;\n\n");
726    fprintf(file,"    ol= section->overlays;\n");
727    for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) {
728	fprintf(file,"    ol[%2d].name= GET_ATOM(dpy,\"%s\");\n",o,
729				XkbAtomText(xkb->dpy,ol->name,XkbCFile));
730	fprintf(file,"    ol[%2d].section_under= section;\n",o);
731    }
732    fprintf(file,"}\n");
733    return True;
734}
735
736static Bool
737WriteCHdrGeomRows(	FILE *		file,
738			XkbDescPtr	xkb,
739			XkbSectionPtr	section,
740			int		section_num)
741{
742register int 		k,r;
743register XkbRowPtr	row;
744register XkbKeyPtr	key;
745
746    for (r=0,row=section->rows;r<section->num_rows;r++,row++) {
747	fprintf(file,"static XkbKeyRec keys_s%02dr%02d[]= {\n",section_num,r);
748	for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
749	    fprintf(file,"%s	{ { \"%s\" },	%4d, %4d, %4d }",
750				(k==0?"":",\n"),
751				XkbKeyNameText(key->name.name,XkbCFile),
752				key->gap,key->shape_ndx,key->color_ndx);
753	}
754	fprintf(file,"\n};\n");
755    }
756    fprintf(file,"static XkbRowRec rows_s%02d[]= {\n",section_num);
757    for (r=0,row=section->rows;r<section->num_rows;r++,row++) {
758	fprintf(file,"%s	{ %4d, %4d, %2d, %2d, %1d, keys_s%02dr%02d, ",
759				(r==0?"":",\n"),
760				row->top,row->left,row->num_keys,row->num_keys,
761				(row->vertical!=0),
762				section_num,r);
763	fprintf(file," { %4d, %4d, %4d, %4d } }",
764				row->bounds.x1,row->bounds.y1,
765				row->bounds.x2,row->bounds.y2);
766    }
767    fprintf(file,"\n};\n");
768    return True;
769}
770
771static Bool
772WriteCHdrGeomSections(FILE *file,XkbDescPtr xkb,XkbGeometryPtr geom)
773{
774register int		s;
775register XkbSectionPtr	section;
776
777    for (s=0,section=geom->sections;s<geom->num_sections;s++,section++) {
778	WriteCHdrGeomRows(file,xkb,section,s);
779#ifdef NOTYET
780	if (section->num_doodads>0)
781	    WriteCHdrGeomDoodads(file,xkb,geom,section,s);
782#endif
783	if (section->num_overlays>0)
784	    WriteCHdrGeomOverlays(file,xkb,section,s);
785    }
786    fprintf(file,"\nstatic XkbSectionRec g_sections[%d]= {\n",
787							geom->num_sections);
788    for (s=0,section=geom->sections;s<geom->num_sections;s++,section++) {
789	if (s!=0) fprintf(file,",\n");
790	fprintf(file,"	{\n	    None, /* name */\n");
791	fprintf(file,"	    %4d, /* priority */\n",section->priority);
792	fprintf(file,"	    %4d, /* top */\n",section->top);
793	fprintf(file,"	    %4d, /* left */\n",section->left);
794	fprintf(file,"	    %4d, /* width */\n",section->width);
795	fprintf(file,"	    %4d, /* height */\n",section->height);
796	fprintf(file,"	    %4d, /* angle */\n",section->angle);
797	fprintf(file,"	    %4d, /* num_rows */\n",section->num_rows);
798	fprintf(file,"	    %4d, /* num_doodads */\n",section->num_doodads);
799	fprintf(file,"	    %4d, /* num_overlays */\n",section->num_overlays);
800	fprintf(file,"	    %4d, /* sz_rows */\n",section->num_rows);
801	fprintf(file,"	    %4d, /* sz_doodads */\n",section->num_doodads);
802	fprintf(file,"	    %4d, /* sz_overlays */\n",section->num_overlays);
803	if (section->num_rows>0)
804	     fprintf(file,"	    rows_s%02d,\n",s);
805	else fprintf(file,"	    NULL, /* rows */\n");
806	if (section->num_doodads>0)
807	     fprintf(file,"	    doodads_s%02d,\n",s);
808	else fprintf(file,"	    NULL, /* doodads */\n");
809	fprintf(file,"	    { %4d, %4d, %4d, %4d }, /* bounds */\n",
810					section->bounds.x1,section->bounds.y1,
811					section->bounds.x2,section->bounds.y2);
812	if (section->num_overlays>0)
813	     fprintf(file,"	    overlays_s%02d\n",s);
814	else fprintf(file,"	    NULL /* overlays */\n");
815	fprintf(file,"	}");
816    }
817    fprintf(file,"\n};\n");
818    fprintf(file,"\nstatic Bool\n");
819    fprintf(file,"_InitSections(DPYTYPE dpy,XkbGeometryPtr geom)\n");
820    fprintf(file,"{\nXkbSectionPtr	sections;\n\n");
821    fprintf(file,"    sections= geom->sections;\n");
822    for (s=0,section=geom->sections;s<geom->num_sections;s++,section++) {
823	if (section->num_doodads>0) {
824	    fprintf(file,"    _InitS%02dDoodads(dpy,geom,&sections[%d]);\n",
825									s,s);
826	}
827	if (section->num_overlays>0) {
828	    fprintf(file,"    _InitS%02dOverlays(dpy,geom,&sections[%d]);\n",
829									s,s);
830	}
831    }
832    fprintf(file,"}\n");
833    return True;
834}
835
836static Bool
837WriteCHdrGeomAliases(FILE *file,XkbDescPtr xkb,XkbGeometryPtr geom)
838{
839    if (geom->num_key_aliases>0) {
840	register int i;
841	fprintf(file,"\nstatic XkbKeyAliasRec g_aliases[%d]= {\n",
842						geom->num_key_aliases);
843	for (i=0;i<geom->num_key_aliases;i++) {
844	    fprintf(file,"%s	{	\"%s\", \"%s\"	}",(i==0?"":",\n"),
845			XkbKeyNameText(geom->key_aliases[i].real,XkbCFile),
846			XkbKeyNameText(geom->key_aliases[i].alias,XkbCFile));
847	}
848	fprintf(file,"\n};\n");
849    }
850    return True;
851}
852
853static Bool
854WriteCHdrGeometry(FILE *file,XkbDescPtr xkb)
855{
856XkbGeometryPtr	geom;
857register int	i;
858
859    if ((!xkb)||(!xkb->geom)) {
860	_XkbLibError(_XkbErrMissingGeometry,"WriteCHdrGeometry",0);
861	return False;
862    }
863    geom= xkb->geom;
864    WriteCHdrGeomProps(file,xkb,geom);
865    WriteCHdrGeomColors(file,xkb,geom);
866    WriteCHdrGeomShapes(file,xkb,geom);
867    WriteCHdrGeomSections(file,xkb,geom);
868    WriteCHdrGeomDoodads(file,xkb,geom,NULL,0);
869    WriteCHdrGeomAliases(file,xkb,geom);
870    fprintf(file,"\nstatic XkbGeometryRec	geom= {\n");
871    fprintf(file,"	None,			/* name */\n");
872    fprintf(file,"	%d, %d,		/* width, height */\n",geom->width_mm,
873							geom->height_mm);
874    if (geom->label_font) {
875	 fprintf(file,"	\"%s\",/* label font */\n",
876				XkbStringText(geom->label_font,XkbCFile));
877    }
878    else fprintf(file,"	NULL,		/* label font */\n");
879    if (geom->label_color) {
880	fprintf(file,"	&g_colors[%d],		/* label color */\n",
881				XkbGeomColorIndex(geom,geom->label_color));
882    }
883    else fprintf(file,"	NULL,			/* label color */\n");
884    if (geom->base_color) {
885	fprintf(file,"	&g_colors[%d],		/* base color */\n",
886				XkbGeomColorIndex(geom,geom->base_color));
887    }
888    else fprintf(file,"	NULL,			/* base color */\n");
889    fprintf(file,"	%d,	%d,	%d,	/*  sz: props, colors, shapes */\n",
890				geom->num_properties,geom->num_colors,
891				geom->num_shapes);
892    fprintf(file,"	%d,	%d,	%d,	/*  sz: sections, doodads, aliases */\n",
893				geom->num_sections,geom->num_doodads,
894				geom->num_key_aliases);
895    fprintf(file,"	%d,	%d,	%d,	/* num: props, colors, shapes */\n",
896				geom->num_properties,geom->num_colors,
897				geom->num_shapes);
898    fprintf(file,"	%d,	%d,	%d,	/* num: sections, doodads, aliases */\n",
899				geom->num_sections,geom->num_doodads,
900				geom->num_key_aliases);
901    fprintf(file,"	%s,	%s,	%s,\n",
902				(geom->num_properties>0?"g_props":"NULL"),
903				(geom->num_colors>0?"g_colors":"NULL"),
904				(geom->num_shapes>0?"g_shapes":"NULL"));
905    fprintf(file,"	%s,	%s,	%s\n",
906				(geom->num_sections>0?"g_sections":"NULL"),
907				(geom->num_doodads>0?"g_doodads":"NULL"),
908				(geom->num_key_aliases>0?"g_aliases":"NULL"));
909    fprintf(file,"};\n\n");
910    fprintf(file,"static Bool\n");
911    fprintf(file,"_InitHdrGeom(DPYTYPE dpy,XkbGeometryPtr geom)\n");
912    fprintf(file,"{\n");
913    if (geom->name!=None) {
914	fprintf(file,"    geom->name= GET_ATOM(dpy,\"%s\");\n",
915				XkbAtomText(xkb->dpy,geom->name,XkbCFile));
916    }
917    for (i=0;i<geom->num_shapes;i++) {
918	fprintf(file,"    geom->shapes[%2d].name= GET_ATOM(dpy,\"%s\");\n",i,
919			XkbAtomText(xkb->dpy,geom->shapes[i].name,XkbCFile));
920    }
921    if (geom->num_doodads>0)
922	fprintf(file,"    _InitGeomDoodads(dpy,geom);\n");
923    fprintf(file,"    _InitSections(dpy,geom);\n");
924    fprintf(file,"}\n\n");
925    return True;
926}
927
928static Bool
929WriteCHdrGeomFile(FILE *file,XkbFileInfo *result)
930{
931Bool		ok;
932
933    ok= WriteCHdrGeometry(file,result->xkb);
934    return ok;
935}
936
937static Bool
938WriteCHdrLayout(FILE *file,XkbFileInfo *result)
939{
940Bool		ok;
941XkbDescPtr	xkb;
942
943    xkb= result->xkb;
944    ok= WriteCHdrVMods(file,xkb->dpy,xkb);
945    ok= WriteCHdrKeycodes(file,xkb)&&ok;
946    ok= WriteCHdrSymbols(file,xkb)&&ok;
947    ok= WriteCHdrGeometry(file,xkb)&&ok;
948    return ok;
949}
950
951static Bool
952WriteCHdrSemantics(FILE *file,XkbFileInfo *result)
953{
954Bool		ok;
955XkbDescPtr	xkb;
956
957    xkb= result->xkb;
958    ok= WriteCHdrVMods(file,xkb->dpy,xkb);
959    ok= WriteCHdrKeyTypes(file,xkb->dpy,xkb)&&ok;
960    ok= WriteCHdrCompatMap(file,xkb->dpy,xkb)&&ok;
961    ok= WriteCHdrIndicators(file,xkb->dpy,xkb)&&ok;
962    return ok;
963}
964
965static Bool
966WriteCHdrKeymap(FILE *file,XkbFileInfo *result)
967{
968Bool		ok;
969XkbDescPtr	xkb;
970
971    xkb= result->xkb;
972    ok= WriteCHdrVMods(file,xkb->dpy,xkb);
973    ok= ok&&WriteCHdrKeycodes(file,xkb);
974    ok= ok&&WriteCHdrClientMap(file,xkb->dpy,xkb);
975    ok= ok&&WriteCHdrServerMap(file,xkb->dpy,xkb);
976    ok= ok&&WriteCHdrCompatMap(file,xkb->dpy,xkb);
977    ok= WriteCHdrIndicators(file,xkb->dpy,xkb)&&ok;
978    ok= ok&&WriteCHdrGeometry(file,xkb);
979    return ok;
980}
981
982Bool
983XkbWriteCFile(FILE *out,char *name,XkbFileInfo *result)
984{
985Bool	 		ok;
986XkbDescPtr		xkb;
987Bool			(*func)(
988	FILE *		/* file*/,
989	XkbFileInfo *	/* result */
990);
991
992    switch (result->type) {
993	case XkmSemanticsFile:
994	    func= WriteCHdrSemantics;
995	    break;
996	case XkmLayoutFile:
997	    func= WriteCHdrLayout;
998	    break;
999	case XkmKeymapFile:
1000	    func= WriteCHdrKeymap;
1001	    break;
1002        case XkmGeometryIndex:
1003        case XkmGeometryFile:
1004	    func= WriteCHdrGeomFile;
1005	    break;
1006	default:
1007	    _XkbLibError(_XkbErrIllegalContents,"XkbWriteCFile",result->type);
1008	    return False;
1009    }
1010    xkb= result->xkb;
1011    if (out==NULL) {
1012	_XkbLibError(_XkbErrFileCannotOpen,"XkbWriteCFile",0);
1013	ok= False;
1014    }
1015    else {
1016	char *tmp,*hdrdef;
1017	tmp= (char *)strrchr(name,'/');
1018	if (tmp==NULL)
1019	     tmp= name;
1020	else tmp++;
1021	hdrdef= (char *)_XkbCalloc(strlen(tmp)+1,sizeof(char));
1022	if (hdrdef) {
1023	    strcpy(hdrdef,tmp);
1024	    tmp= hdrdef;
1025	    while (*tmp) {
1026		if (islower(*tmp))		*tmp= toupper(*tmp);
1027		else if (!isalnum(*tmp))	*tmp= '_';
1028		tmp++;
1029	    }
1030	    fprintf(out,"/* This file generated automatically by xkbcomp */\n");
1031	    fprintf(out,"/* DO  NOT EDIT */\n");
1032	    fprintf(out,"#ifndef %s\n",hdrdef);
1033	    fprintf(out,"#define %s 1\n\n",hdrdef);
1034	}
1035	fprintf(out,"#ifndef XKB_IN_SERVER\n");
1036	fprintf(out,"#define GET_ATOM(d,s)	XInternAtom(d,s,0)\n");
1037	fprintf(out,"#define DPYTYPE	Display *\n");
1038	fprintf(out,"#else\n");
1039	fprintf(out,"#define GET_ATOM(d,s)	MakeAtom(s,strlen(s),1)\n");
1040	fprintf(out,"#define DPYTYPE	char *\n");
1041	fprintf(out,"#endif\n");
1042	fprintf(out,"#define NUM_KEYS	%d\n",xkb->max_key_code+1);
1043	ok= (*func)(out,result);
1044	if (hdrdef)
1045	    fprintf(out,"#endif /* %s */\n",hdrdef);
1046    }
1047
1048    if (!ok) {
1049	return False;
1050    }
1051    return True;
1052}
1053