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