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