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