cout.c revision 87c518e6
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#ifdef NOTYET
830        if (section->num_doodads > 0)
831            WriteCHdrGeomDoodads(file, xkb, geom, section, s);
832#endif
833        if (section->num_overlays > 0)
834            WriteCHdrGeomOverlays(file, xkb, section, s);
835    }
836    fprintf(file, "\nstatic XkbSectionRec g_sections[%d]= {\n",
837            geom->num_sections);
838    for (s = 0, section = geom->sections; s < geom->num_sections;
839         s++, section++) {
840        if (s != 0)
841            fprintf(file, ",\n");
842        fprintf(file, "	{\n	    None, /* name */\n");
843        fprintf(file, "	    %4d, /* priority */\n", section->priority);
844        fprintf(file, "	    %4d, /* top */\n", section->top);
845        fprintf(file, "	    %4d, /* left */\n", section->left);
846        fprintf(file, "	    %4d, /* width */\n", section->width);
847        fprintf(file, "	    %4d, /* height */\n", section->height);
848        fprintf(file, "	    %4d, /* angle */\n", section->angle);
849        fprintf(file, "	    %4d, /* num_rows */\n", section->num_rows);
850        fprintf(file, "	    %4d, /* num_doodads */\n", section->num_doodads);
851        fprintf(file, "	    %4d, /* num_overlays */\n", section->num_overlays);
852        fprintf(file, "	    %4d, /* sz_rows */\n", section->num_rows);
853        fprintf(file, "	    %4d, /* sz_doodads */\n", section->num_doodads);
854        fprintf(file, "	    %4d, /* sz_overlays */\n", section->num_overlays);
855        if (section->num_rows > 0)
856            fprintf(file, "	    rows_s%02d,\n", s);
857        else
858            fprintf(file, "	    NULL, /* rows */\n");
859        if (section->num_doodads > 0)
860            fprintf(file, "	    doodads_s%02d,\n", s);
861        else
862            fprintf(file, "	    NULL, /* doodads */\n");
863        fprintf(file, "	    { %4d, %4d, %4d, %4d }, /* bounds */\n",
864                section->bounds.x1, section->bounds.y1,
865                section->bounds.x2, section->bounds.y2);
866        if (section->num_overlays > 0)
867            fprintf(file, "	    overlays_s%02d\n", s);
868        else
869            fprintf(file, "	    NULL /* overlays */\n");
870        fprintf(file, "	}");
871    }
872    fprintf(file, "\n};\n");
873    fprintf(file, "\nstatic Bool\n");
874    fprintf(file, "_InitSections(DPYTYPE dpy,XkbGeometryPtr geom)\n");
875    fprintf(file, "{\nXkbSectionPtr	sections;\n\n");
876    fprintf(file, "    sections= geom->sections;\n");
877    for (s = 0, section = geom->sections; s < geom->num_sections;
878         s++, section++) {
879        if (section->num_doodads > 0) {
880            fprintf(file, "    _InitS%02dDoodads(dpy,geom,&sections[%d]);\n",
881                    s, s);
882        }
883        if (section->num_overlays > 0) {
884            fprintf(file, "    _InitS%02dOverlays(dpy,geom,&sections[%d]);\n",
885                    s, s);
886        }
887    }
888    fprintf(file, "}\n");
889    return True;
890}
891
892static Bool
893WriteCHdrGeomAliases(FILE *file, XkbDescPtr xkb, XkbGeometryPtr geom)
894{
895    if (geom->num_key_aliases > 0) {
896        register int i;
897
898        fprintf(file, "\nstatic XkbKeyAliasRec g_aliases[%d]= {\n",
899                geom->num_key_aliases);
900        for (i = 0; i < geom->num_key_aliases; i++) {
901            fprintf(file, "%s	{	\"%s\", \"%s\"	}",
902                    (i == 0 ? "" : ",\n"),
903                    XkbKeyNameText(geom->key_aliases[i].real, XkbCFile),
904                    XkbKeyNameText(geom->key_aliases[i].alias, XkbCFile));
905        }
906        fprintf(file, "\n};\n");
907    }
908    return True;
909}
910
911static Bool
912WriteCHdrGeometry(FILE *file, XkbDescPtr xkb)
913{
914    XkbGeometryPtr geom;
915    register int i;
916
917    if ((!xkb) || (!xkb->geom)) {
918        _XkbLibError(_XkbErrMissingGeometry, "WriteCHdrGeometry", 0);
919        return False;
920    }
921    geom = xkb->geom;
922    WriteCHdrGeomProps(file, xkb, geom);
923    WriteCHdrGeomColors(file, xkb, geom);
924    WriteCHdrGeomShapes(file, xkb, geom);
925    WriteCHdrGeomSections(file, xkb, geom);
926    WriteCHdrGeomDoodads(file, xkb, geom, NULL, 0);
927    WriteCHdrGeomAliases(file, xkb, geom);
928    fprintf(file, "\nstatic XkbGeometryRec	geom= {\n");
929    fprintf(file, "	None,			/* name */\n");
930    fprintf(file, "	%d, %d,		/* width, height */\n",
931            geom->width_mm, geom->height_mm);
932    if (geom->label_font)
933        fprintf(file, "	\"%s\",/* label font */\n",
934                XkbStringText(geom->label_font, XkbCFile));
935    else
936        fprintf(file, "	NULL,		/* label font */\n");
937    if (geom->label_color)
938        fprintf(file, "	&g_colors[%d],		/* label color */\n",
939                XkbGeomColorIndex(geom, geom->label_color));
940    else
941        fprintf(file, "	NULL,			/* label color */\n");
942    if (geom->base_color)
943        fprintf(file, "	&g_colors[%d],		/* base color */\n",
944                XkbGeomColorIndex(geom, geom->base_color));
945    else
946        fprintf(file, "	NULL,			/* base color */\n");
947    fprintf(file,
948            "	%d,	%d,	%d,	/*  sz: props, colors, shapes */\n",
949            geom->num_properties, geom->num_colors, geom->num_shapes);
950    fprintf(file,
951            "	%d,	%d,	%d,	/*  sz: sections, doodads, aliases */\n",
952            geom->num_sections, geom->num_doodads, geom->num_key_aliases);
953    fprintf(file,
954            "	%d,	%d,	%d,	/* num: props, colors, shapes */\n",
955            geom->num_properties, geom->num_colors, geom->num_shapes);
956    fprintf(file,
957            "	%d,	%d,	%d,	/* num: sections, doodads, aliases */\n",
958            geom->num_sections, geom->num_doodads, geom->num_key_aliases);
959    fprintf(file, "	%s,	%s,	%s,\n",
960            (geom->num_properties > 0 ? "g_props" : "NULL"),
961            (geom->num_colors > 0 ? "g_colors" : "NULL"),
962            (geom->num_shapes > 0 ? "g_shapes" : "NULL"));
963    fprintf(file, "	%s,	%s,	%s\n",
964            (geom->num_sections > 0 ? "g_sections" : "NULL"),
965            (geom->num_doodads > 0 ? "g_doodads" : "NULL"),
966            (geom->num_key_aliases > 0 ? "g_aliases" : "NULL"));
967    fprintf(file, "};\n\n");
968    fprintf(file, "static Bool\n");
969    fprintf(file, "_InitHdrGeom(DPYTYPE dpy,XkbGeometryPtr geom)\n");
970    fprintf(file, "{\n");
971    if (geom->name != None) {
972        fprintf(file, "    geom->name= GET_ATOM(dpy,\"%s\");\n",
973                XkbAtomText(xkb->dpy, geom->name, XkbCFile));
974    }
975    for (i = 0; i < geom->num_shapes; i++) {
976        fprintf(file, "    geom->shapes[%2d].name= GET_ATOM(dpy,\"%s\");\n", i,
977                XkbAtomText(xkb->dpy, geom->shapes[i].name, XkbCFile));
978    }
979    if (geom->num_doodads > 0)
980        fprintf(file, "    _InitGeomDoodads(dpy,geom);\n");
981    fprintf(file, "    _InitSections(dpy,geom);\n");
982    fprintf(file, "}\n\n");
983    return True;
984}
985
986static Bool
987WriteCHdrGeomFile(FILE *file, XkbFileInfo *result)
988{
989    Bool ok;
990
991    ok = WriteCHdrGeometry(file, result->xkb);
992    return ok;
993}
994
995static Bool
996WriteCHdrLayout(FILE *file, XkbFileInfo *result)
997{
998    Bool ok;
999    XkbDescPtr xkb;
1000
1001    xkb = result->xkb;
1002    ok = WriteCHdrVMods(file, xkb->dpy, xkb);
1003    ok = WriteCHdrKeycodes(file, xkb) && ok;
1004    ok = WriteCHdrSymbols(file, xkb) && ok;
1005    ok = WriteCHdrGeometry(file, xkb) && ok;
1006    return ok;
1007}
1008
1009static Bool
1010WriteCHdrSemantics(FILE *file, XkbFileInfo *result)
1011{
1012    Bool ok;
1013    XkbDescPtr xkb;
1014
1015    xkb = result->xkb;
1016    ok = WriteCHdrVMods(file, xkb->dpy, xkb);
1017    ok = WriteCHdrKeyTypes(file, xkb->dpy, xkb) && ok;
1018    ok = WriteCHdrCompatMap(file, xkb->dpy, xkb) && ok;
1019    ok = WriteCHdrIndicators(file, xkb->dpy, xkb) && ok;
1020    return ok;
1021}
1022
1023static Bool
1024WriteCHdrKeymap(FILE *file, XkbFileInfo *result)
1025{
1026    Bool ok;
1027    XkbDescPtr xkb;
1028
1029    xkb = result->xkb;
1030    ok = WriteCHdrVMods(file, xkb->dpy, xkb);
1031    ok = ok && WriteCHdrKeycodes(file, xkb);
1032    ok = ok && WriteCHdrClientMap(file, xkb->dpy, xkb);
1033    ok = ok && WriteCHdrServerMap(file, xkb->dpy, xkb);
1034    ok = ok && WriteCHdrCompatMap(file, xkb->dpy, xkb);
1035    ok = WriteCHdrIndicators(file, xkb->dpy, xkb) && ok;
1036    ok = ok && WriteCHdrGeometry(file, xkb);
1037    return ok;
1038}
1039
1040Bool
1041XkbWriteCFile(FILE *out, char *name, XkbFileInfo *result)
1042{
1043    Bool ok;
1044    XkbDescPtr xkb;
1045
1046    Bool (*func) (FILE *        /* file */,
1047                  XkbFileInfo * /* result */
1048        );
1049
1050    switch (result->type) {
1051    case XkmSemanticsFile:
1052        func = WriteCHdrSemantics;
1053        break;
1054    case XkmLayoutFile:
1055        func = WriteCHdrLayout;
1056        break;
1057    case XkmKeymapFile:
1058        func = WriteCHdrKeymap;
1059        break;
1060    case XkmGeometryIndex:
1061    case XkmGeometryFile:
1062        func = WriteCHdrGeomFile;
1063        break;
1064    default:
1065        _XkbLibError(_XkbErrIllegalContents, "XkbWriteCFile", result->type);
1066        return False;
1067    }
1068    xkb = result->xkb;
1069    if (out == NULL) {
1070        _XkbLibError(_XkbErrFileCannotOpen, "XkbWriteCFile", 0);
1071        ok = False;
1072    }
1073    else {
1074        char *tmp, *hdrdef;
1075
1076        tmp = (char *) strrchr(name, '/');
1077        if (tmp == NULL)
1078            tmp = name;
1079        else
1080            tmp++;
1081        hdrdef = (char *) _XkbCalloc(strlen(tmp) + 1, sizeof(char));
1082        if (hdrdef) {
1083            strcpy(hdrdef, tmp);
1084            tmp = hdrdef;
1085            while (*tmp) {
1086                if (islower(*tmp))
1087                    *tmp = toupper(*tmp);
1088                else if (!isalnum(*tmp))
1089                    *tmp = '_';
1090                tmp++;
1091            }
1092            fprintf(out, "/* This file generated automatically by xkbcomp */\n");
1093            fprintf(out, "/* DO  NOT EDIT */\n");
1094            fprintf(out, "#ifndef %s\n", hdrdef);
1095            fprintf(out, "#define %s 1\n\n", hdrdef);
1096        }
1097        fprintf(out, "#ifndef XKB_IN_SERVER\n");
1098        fprintf(out, "#define GET_ATOM(d,s)	XInternAtom(d,s,0)\n");
1099        fprintf(out, "#define DPYTYPE	Display *\n");
1100        fprintf(out, "#else\n");
1101        fprintf(out, "#define GET_ATOM(d,s)	MakeAtom(s,strlen(s),1)\n");
1102        fprintf(out, "#define DPYTYPE	char *\n");
1103        fprintf(out, "#endif\n");
1104        fprintf(out, "#define NUM_KEYS	%d\n", xkb->max_key_code + 1);
1105        ok = (*func) (out, result);
1106        if (hdrdef)
1107            fprintf(out, "#endif /* %s */\n", hdrdef);
1108    }
1109
1110    if (!ok) {
1111        return False;
1112    }
1113    return True;
1114}
1115