~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/lib/xkbfile/xkmout.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Xorg: xkmout.c,v 1.3 2000/08/17 19:46:44 cpqbld Exp $ */
 
2
/************************************************************
 
3
 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
 
4
 
 
5
 Permission to use, copy, modify, and distribute this
 
6
 software and its documentation for any purpose and without
 
7
 fee is hereby granted, provided that the above copyright
 
8
 notice appear in all copies and that both that copyright
 
9
 notice and this permission notice appear in supporting
 
10
 documentation, and that the name of Silicon Graphics not be 
 
11
 used in advertising or publicity pertaining to distribution 
 
12
 of the software without specific prior written permission.
 
13
 Silicon Graphics makes no representation about the suitability 
 
14
 of this software for any purpose. It is provided "as is"
 
15
 without any express or implied warranty.
 
16
 
 
17
 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 
 
18
 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 
 
19
 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
 
20
 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 
 
21
 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 
 
22
 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 
 
23
 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
 
24
 THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
25
 
 
26
 ********************************************************/
 
27
/* $XFree86: xc/lib/xkbfile/xkmout.c,v 1.5 2001/07/25 15:04:58 dawes Exp $ */
 
28
 
 
29
#include <stdio.h>
 
30
#include <ctype.h>
 
31
#include <stdlib.h>
 
32
#include <X11/Xfuncs.h>
 
33
#include <X11/Xlib.h>
 
34
#include <X11/XKBlib.h>
 
35
#include <X11/extensions/XKBgeom.h>
 
36
 
 
37
#include "XKMformat.h"
 
38
#include "XKBfileInt.h"
 
39
 
 
40
typedef struct _XkmInfo {
 
41
     unsigned short     bound_vmods;
 
42
     unsigned short     named_vmods;
 
43
     unsigned char      num_bound;
 
44
     unsigned char      group_compat;
 
45
     unsigned short     num_group_compat;
 
46
     unsigned short     num_leds;
 
47
     int                total_vmodmaps;
 
48
} XkmInfo;
 
49
 
 
50
/***====================================================================***/
 
51
 
 
52
#define xkmPutCARD8(f,v)        (putc(v,f),1)
 
53
 
 
54
static int
 
55
#if NeedFunctionPrototypes
 
56
xkmPutCARD16(FILE *file,unsigned val)
 
57
#else
 
58
xkmPutCARD16(file,val)
 
59
    FILE *              file;
 
60
    unsigned            val;
 
61
#endif
 
62
{
 
63
CARD16  tmp= val;
 
64
 
 
65
    fwrite(&tmp,2,1,file);
 
66
    return 2;
 
67
}
 
68
 
 
69
static int
 
70
#if NeedFunctionPrototypes
 
71
xkmPutCARD32(FILE *file,unsigned long val)
 
72
#else
 
73
xkmPutCARD32(file,val)
 
74
    FILE *              file;
 
75
    unsigned long       val;
 
76
#endif
 
77
{
 
78
CARD32 tmp= val;
 
79
 
 
80
    fwrite(&tmp,4,1,file);
 
81
    return 4;
 
82
}
 
83
 
 
84
static int
 
85
#if NeedFunctionPrototypes
 
86
xkmPutPadding(FILE *file,unsigned pad)
 
87
#else
 
88
xkmPutPadding(file,pad)
 
89
    FILE *              file;
 
90
    unsigned            pad;
 
91
#endif
 
92
{
 
93
int     i;
 
94
    for (i=0;i<pad;i++) {
 
95
        putc('\0',file);
 
96
    }
 
97
    return pad;
 
98
}
 
99
 
 
100
static int
 
101
#if NeedFunctionPrototypes
 
102
xkmPutCountedBytes(FILE *file,char *ptr,unsigned count)
 
103
#else
 
104
xkmPutCountedBytes(file,ptr,count)
 
105
    FILE *              file;
 
106
    char *              ptr;
 
107
    unsigned            count;
 
108
#endif
 
109
{
 
110
register int nOut;
 
111
register unsigned pad;
 
112
 
 
113
    if (count==0)
 
114
        return xkmPutCARD32(file,(unsigned long)0);
 
115
 
 
116
    xkmPutCARD16(file,count);
 
117
    nOut= fwrite(ptr,1,count,file);
 
118
    if (nOut<0)
 
119
        return 2;
 
120
    nOut= count+2;
 
121
    pad= XkbPaddedSize(nOut)-nOut;
 
122
    if (pad)
 
123
        xkmPutPadding(file,pad);
 
124
    return nOut+pad;
 
125
}
 
126
 
 
127
static unsigned
 
128
#if NeedFunctionPrototypes
 
129
xkmSizeCountedString(char *str)
 
130
#else
 
131
xkmSizeCountedString(str)
 
132
    char *      str;
 
133
#endif
 
134
{
 
135
    if (str==NULL)
 
136
        return 4;
 
137
    return XkbPaddedSize(strlen(str)+2);
 
138
}
 
139
 
 
140
static int
 
141
#if NeedFunctionPrototypes
 
142
xkmPutCountedString(FILE *file,char *str)
 
143
#else
 
144
xkmPutCountedString(file,str)
 
145
    FILE *      file;
 
146
    char *      str;
 
147
#endif
 
148
{
 
149
    if (str==NULL)
 
150
         return xkmPutCARD32(file,(unsigned long)0);
 
151
    return xkmPutCountedBytes(file,str,strlen(str));
 
152
}
 
153
 
 
154
#define xkmSizeCountedAtomString(d,a)   \
 
155
        xkmSizeCountedString(XkbAtomGetString((d),(a)))
 
156
 
 
157
#define xkmPutCountedAtomString(d,f,a)  \
 
158
        xkmPutCountedString((f),XkbAtomGetString((d),(a)))
 
159
 
 
160
/***====================================================================***/
 
161
 
 
162
static unsigned
 
163
#if NeedFunctionPrototypes
 
164
SizeXKMVirtualMods(     XkbFileInfo *           result,
 
165
                        XkmInfo *               info,
 
166
                        xkmSectionInfo *        toc,
 
167
                        int *                   offset_inout)
 
168
#else
 
169
SizeXKMVirtualMods(result,info,toc,offset_inout)
 
170
    XkbFileInfo *       result;
 
171
    XkmInfo *           info;
 
172
    xkmSectionInfo *    toc;
 
173
    int *               offset_inout;
 
174
#endif
 
175
{
 
176
Display *       dpy;
 
177
XkbDescPtr      xkb;
 
178
unsigned        nBound,bound;
 
179
unsigned        nNamed,named,szNames;
 
180
register unsigned       i,bit;
 
181
 
 
182
    xkb= result->xkb;
 
183
    dpy= xkb->dpy;
 
184
    if ((!xkb)||(!xkb->names)||(!xkb->server)) {
 
185
        _XkbLibError(_XkbErrMissingVMods,"SizeXKMVirtualMods",0);
 
186
        return 0;
 
187
    }
 
188
    bound=named=0;
 
189
    for (i=nBound=nNamed=szNames=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
 
190
        if (xkb->server->vmods[i]!=XkbNoModifierMask) {
 
191
            bound|= bit;
 
192
            nBound++;
 
193
        }
 
194
        if (xkb->names->vmods[i]!=None) {
 
195
            named|= bit;
 
196
            szNames+= xkmSizeCountedAtomString(dpy,xkb->names->vmods[i]);
 
197
            nNamed++;
 
198
        }
 
199
    }
 
200
    info->num_bound= nBound;
 
201
    info->bound_vmods= bound;
 
202
    info->named_vmods= named;
 
203
    if ((nBound==0)&&(nNamed==0))
 
204
        return 0;
 
205
    toc->type=          XkmVirtualModsIndex;
 
206
    toc->format=        MSBFirst;
 
207
    toc->size=          4+XkbPaddedSize(nBound)+szNames+SIZEOF(xkmSectionInfo);
 
208
    toc->offset=        *offset_inout;
 
209
    (*offset_inout)+=   toc->size;
 
210
    return 1;
 
211
}
 
212
 
 
213
static unsigned
 
214
#if NeedFunctionPrototypes
 
215
WriteXKMVirtualMods(FILE *file,XkbFileInfo *result,XkmInfo *info)
 
216
#else
 
217
WriteXKMVirtualMods(file,result,info)
 
218
    FILE *              file;
 
219
    XkbFileInfo *       result;
 
220
    XkmInfo *           info;
 
221
#endif
 
222
{
 
223
register unsigned int i,bit;
 
224
XkbDescPtr      xkb;
 
225
Display *       dpy;
 
226
unsigned        size= 0;
 
227
 
 
228
    xkb= result->xkb;
 
229
    dpy= xkb->dpy;
 
230
    size+= xkmPutCARD16(file,info->bound_vmods);
 
231
    size+= xkmPutCARD16(file,info->named_vmods);
 
232
    for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
 
233
        if (info->bound_vmods&bit)
 
234
            size+= xkmPutCARD8(file,xkb->server->vmods[i]);
 
235
    }
 
236
    if ((i= XkbPaddedSize(info->num_bound)-info->num_bound)>0)
 
237
        size+= xkmPutPadding(file,i);
 
238
    for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
 
239
        if (info->named_vmods&bit) {
 
240
            register char *name;
 
241
            name= XkbAtomGetString(dpy,xkb->names->vmods[i]);
 
242
            size+= xkmPutCountedString(file,name);
 
243
        }
 
244
    }
 
245
    return size;
 
246
}
 
247
 
 
248
/***====================================================================***/
 
249
 
 
250
static unsigned
 
251
#if NeedFunctionPrototypes
 
252
SizeXKMKeycodes(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout)
 
253
#else
 
254
SizeXKMKeycodes(result,toc,offset_inout)
 
255
    XkbFileInfo *       result;
 
256
    xkmSectionInfo *    toc;
 
257
    int *               offset_inout;
 
258
#endif
 
259
{
 
260
XkbDescPtr      xkb;
 
261
Atom            kcName;
 
262
int             size=0;
 
263
Display *       dpy;
 
264
 
 
265
    xkb= result->xkb;
 
266
    dpy= xkb->dpy;
 
267
    if ((!xkb)||(!xkb->names)||(!xkb->names->keys)) {
 
268
        _XkbLibError(_XkbErrMissingNames,"SizeXKMKeycodes",0);
 
269
        return 0;
 
270
    }
 
271
    kcName= xkb->names->keycodes;
 
272
    size+= 4;   /* min and max keycode */
 
273
    size+= xkmSizeCountedAtomString(dpy,kcName);
 
274
    size+= XkbNumKeys(xkb)*sizeof(XkbKeyNameRec);
 
275
    if (xkb->names->num_key_aliases>0) {
 
276
        if (xkb->names->key_aliases!=NULL)
 
277
             size+= xkb->names->num_key_aliases*sizeof(XkbKeyAliasRec);
 
278
        else xkb->names->num_key_aliases= 0;
 
279
    }
 
280
    toc->type=          XkmKeyNamesIndex;
 
281
    toc->format=        MSBFirst;
 
282
    toc->size=          size+SIZEOF(xkmSectionInfo);
 
283
    toc->offset=        (*offset_inout);
 
284
    (*offset_inout)+=   toc->size;
 
285
    return 1;
 
286
}
 
287
 
 
288
static unsigned
 
289
#if NeedFunctionPrototypes
 
290
WriteXKMKeycodes(FILE *file,XkbFileInfo *result)
 
291
#else
 
292
WriteXKMKeycodes(file,result)
 
293
    FILE *              file;
 
294
    XkbFileInfo *       result;
 
295
#endif
 
296
{
 
297
XkbDescPtr      xkb;
 
298
Atom            kcName;
 
299
char            *start;
 
300
Display *       dpy;
 
301
unsigned        tmp,size= 0;
 
302
 
 
303
    xkb= result->xkb;
 
304
    dpy= xkb->dpy;
 
305
    kcName= xkb->names->keycodes;
 
306
    start= xkb->names->keys[xkb->min_key_code].name;
 
307
    
 
308
    size+= xkmPutCountedString(file,XkbAtomGetString(dpy,kcName));
 
309
    size+= xkmPutCARD8(file,xkb->min_key_code);
 
310
    size+= xkmPutCARD8(file,xkb->max_key_code);
 
311
    size+= xkmPutCARD8(file,xkb->names->num_key_aliases);
 
312
    size+= xkmPutPadding(file,1);
 
313
    tmp= fwrite(start,sizeof(XkbKeyNameRec),XkbNumKeys(xkb),file);
 
314
    size+= tmp*sizeof(XkbKeyNameRec);
 
315
    if (xkb->names->num_key_aliases>0) {
 
316
        tmp= fwrite((char *)xkb->names->key_aliases,
 
317
                        sizeof(XkbKeyAliasRec),xkb->names->num_key_aliases,
 
318
                        file);
 
319
        size+= tmp*sizeof(XkbKeyAliasRec);
 
320
    }
 
321
    return size;
 
322
}
 
323
 
 
324
/***====================================================================***/
 
325
 
 
326
static unsigned
 
327
#if NeedFunctionPrototypes
 
328
SizeXKMKeyTypes(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout)
 
329
#else
 
330
SizeXKMKeyTypes(result,toc,offset_inout)
 
331
    XkbFileInfo *       result;
 
332
    xkmSectionInfo *    toc;
 
333
    int *               offset_inout;
 
334
#endif
 
335
{
 
336
register unsigned       i,n,size;
 
337
XkbKeyTypePtr           type;
 
338
XkbDescPtr              xkb;
 
339
Display *               dpy;
 
340
char *                  name;
 
341
 
 
342
    xkb= result->xkb;
 
343
    dpy= xkb->dpy;
 
344
    if ((!xkb)||(!xkb->map)||(!xkb->map->types)) {
 
345
        _XkbLibError(_XkbErrMissingTypes,"SizeXKBKeyTypes",0);
 
346
        return 0;
 
347
    }
 
348
    if (xkb->map->num_types<XkbNumRequiredTypes) {
 
349
        _XkbLibError(_XkbErrMissingReqTypes,"SizeXKBKeyTypes",0);
 
350
        return 0;
 
351
    }
 
352
    if (xkb->names)     name= XkbAtomGetString(dpy,xkb->names->types);
 
353
    else                name= NULL;
 
354
    size= xkmSizeCountedString(name);
 
355
    size+= 4;   /* room for # of key types + padding */
 
356
    for (i=0,type=xkb->map->types;i<xkb->map->num_types;i++,type++) {
 
357
        size+= SIZEOF(xkmKeyTypeDesc);
 
358
        size+= SIZEOF(xkmKTMapEntryDesc)*type->map_count;
 
359
        size+= xkmSizeCountedAtomString(dpy,type->name);
 
360
        if (type->preserve)
 
361
            size+= SIZEOF(xkmModsDesc)*type->map_count;
 
362
        if (type->level_names) {
 
363
            Atom *names;
 
364
            names= type->level_names;
 
365
            for (n=0;n<(unsigned)type->num_levels;n++) {
 
366
                size+= xkmSizeCountedAtomString(dpy,names[n]);
 
367
            }
 
368
        }
 
369
    }
 
370
    toc->type=          XkmTypesIndex;
 
371
    toc->format=        MSBFirst;
 
372
    toc->size=          size+SIZEOF(xkmSectionInfo);
 
373
    toc->offset=        (*offset_inout);
 
374
    (*offset_inout)+=   toc->size;
 
375
    return 1;
 
376
}
 
377
 
 
378
static unsigned
 
379
#if NeedFunctionPrototypes
 
380
WriteXKMKeyTypes(FILE *file,XkbFileInfo *result)
 
381
#else
 
382
WriteXKMKeyTypes(file,result)
 
383
    FILE *      file;
 
384
    XkbFileInfo *       result;
 
385
#endif
 
386
{
 
387
register unsigned       i,n;
 
388
XkbDescPtr              xkb;
 
389
XkbKeyTypePtr           type;
 
390
xkmKeyTypeDesc          wire;
 
391
XkbKTMapEntryPtr        entry;
 
392
xkmKTMapEntryDesc       wire_entry;
 
393
Atom *                  names;
 
394
Display *               dpy;
 
395
unsigned                tmp,size= 0;
 
396
char *                  name;
 
397
 
 
398
    xkb= result->xkb;
 
399
    dpy= xkb->dpy;
 
400
    if (xkb->names)     name= XkbAtomGetString(dpy,xkb->names->types);
 
401
    else                name= NULL;
 
402
    size+= xkmPutCountedString(file,name);
 
403
    size+= xkmPutCARD16(file,xkb->map->num_types);
 
404
    size+= xkmPutPadding(file,2);
 
405
    type= xkb->map->types;
 
406
    for (i=0;i<xkb->map->num_types;i++,type++) {
 
407
        wire.realMods= type->mods.real_mods;
 
408
        wire.virtualMods= type->mods.vmods;
 
409
        wire.numLevels= type->num_levels;
 
410
        wire.nMapEntries= type->map_count;
 
411
        wire.preserve= (type->preserve!=NULL);
 
412
        if (type->level_names!=NULL)
 
413
             wire.nLevelNames= type->num_levels;
 
414
        else wire.nLevelNames= 0;
 
415
        tmp= fwrite(&wire,SIZEOF(xkmKeyTypeDesc),1,file);
 
416
        size+= tmp*SIZEOF(xkmKeyTypeDesc);
 
417
        for (n=0,entry= type->map;n<type->map_count;n++,entry++) {
 
418
            wire_entry.level= entry->level;
 
419
            wire_entry.realMods= entry->mods.real_mods;
 
420
            wire_entry.virtualMods= entry->mods.vmods;
 
421
            tmp= fwrite(&wire_entry,SIZEOF(xkmKTMapEntryDesc),1,file);
 
422
            size+= tmp*SIZEOF(xkmKTMapEntryDesc);
 
423
        }
 
424
        size+= xkmPutCountedString(file,XkbAtomGetString(dpy,type->name));
 
425
        if (type->preserve) {
 
426
            xkmModsDesc p_entry;
 
427
            XkbModsPtr  pre;
 
428
            for (n=0,pre=type->preserve;n<type->map_count;n++,pre++) {
 
429
                p_entry.realMods= pre->real_mods;
 
430
                p_entry.virtualMods= pre->vmods;
 
431
                tmp= fwrite(&p_entry,SIZEOF(xkmModsDesc),1,file);
 
432
                size+= tmp*SIZEOF(xkmModsDesc);
 
433
            }
 
434
        }
 
435
        if (type->level_names!=NULL) {
 
436
            names= type->level_names;
 
437
            for (n=0;n<wire.nLevelNames;n++) {
 
438
                size+= xkmPutCountedString(file,XkbAtomGetString(dpy,names[n]));
 
439
            }
 
440
        }
 
441
    }
 
442
    return size;
 
443
}
 
444
 
 
445
/***====================================================================***/
 
446
 
 
447
static unsigned
 
448
#if NeedFunctionPrototypes
 
449
SizeXKMCompatMap(       XkbFileInfo *           result,
 
450
                        XkmInfo *               info,
 
451
                        xkmSectionInfo *        toc,
 
452
                        int *                   offset_inout)
 
453
#else
 
454
SizeXKMCompatMap(result,info,toc,offset_inout)
 
455
    XkbFileInfo *       result;
 
456
    XkmInfo *           info;
 
457
    xkmSectionInfo *    toc;
 
458
    int *               offset_inout;
 
459
#endif
 
460
{
 
461
XkbDescPtr      xkb;
 
462
char *          name;
 
463
int             size;
 
464
register int    i;
 
465
unsigned        groups,nGroups;
 
466
Display *       dpy;
 
467
 
 
468
    xkb= result->xkb;
 
469
    dpy= xkb->dpy;
 
470
    if ((!xkb)||(!xkb->compat)||(!xkb->compat->sym_interpret)) {
 
471
        _XkbLibError(_XkbErrMissingCompatMap,"SizeXKMCompatMap",0);
 
472
        return 0;
 
473
    }
 
474
    if (xkb->names)     name= XkbAtomGetString(dpy,xkb->names->compat);
 
475
    else                name= NULL;
 
476
 
 
477
    for (i=groups=nGroups=0;i<XkbNumKbdGroups;i++) {
 
478
        if ((xkb->compat->groups[i].real_mods!=0)||
 
479
                        (xkb->compat->groups[i].vmods!=0)) {
 
480
            groups|= (1<<i);
 
481
            nGroups++;
 
482
        }
 
483
    }
 
484
    info->group_compat= groups;
 
485
    info->num_group_compat= nGroups;
 
486
    size= 4; /* room for num_si and group_compat mask */
 
487
    size+= xkmSizeCountedString(name);
 
488
    size+= (SIZEOF(xkmSymInterpretDesc)*xkb->compat->num_si);
 
489
    size+= (SIZEOF(xkmModsDesc)*nGroups);
 
490
    toc->type=          XkmCompatMapIndex;
 
491
    toc->format=        MSBFirst;
 
492
    toc->size=          size+SIZEOF(xkmSectionInfo);
 
493
    toc->offset=        (*offset_inout);
 
494
    (*offset_inout)+=   toc->size;
 
495
    return 1;
 
496
}
 
497
 
 
498
static unsigned
 
499
#if NeedFunctionPrototypes
 
500
WriteXKMCompatMap(FILE *file,XkbFileInfo *result,XkmInfo *info)
 
501
#else
 
502
WriteXKMCompatMap(file,result,info)
 
503
    FILE *      file;
 
504
    XkbFileInfo *       result;
 
505
    XkmInfo *   info;
 
506
#endif
 
507
{
 
508
register unsigned       i;
 
509
char *                  name;
 
510
XkbDescPtr              xkb;
 
511
XkbSymInterpretPtr      interp;
 
512
xkmSymInterpretDesc     wire;
 
513
Display *               dpy;
 
514
unsigned                tmp,size=0;
 
515
 
 
516
    xkb= result->xkb;
 
517
    dpy= xkb->dpy;
 
518
    if (xkb->names)     name= XkbAtomGetString(dpy,xkb->names->compat);
 
519
    else                name= NULL;
 
520
    size+= xkmPutCountedString(file,name);
 
521
    size+= xkmPutCARD16(file,xkb->compat->num_si);
 
522
    size+= xkmPutCARD8(file,info->group_compat);
 
523
    size+= xkmPutPadding(file,1);
 
524
    interp= xkb->compat->sym_interpret;
 
525
    for (i=0;i<xkb->compat->num_si;i++,interp++) {
 
526
        wire.sym= interp->sym;
 
527
        wire.mods= interp->mods;
 
528
        wire.match= interp->match;
 
529
        wire.virtualMod= interp->virtual_mod;
 
530
        wire.flags= interp->flags;
 
531
        wire.actionType= interp->act.type;
 
532
        wire.actionData[0]= interp->act.data[0];
 
533
        wire.actionData[1]= interp->act.data[1];
 
534
        wire.actionData[2]= interp->act.data[2];
 
535
        wire.actionData[3]= interp->act.data[3];
 
536
        wire.actionData[4]= interp->act.data[4];
 
537
        wire.actionData[5]= interp->act.data[5];
 
538
        wire.actionData[6]= interp->act.data[6];
 
539
        tmp= fwrite(&wire,SIZEOF(xkmSymInterpretDesc),1,file);
 
540
        size+= tmp*SIZEOF(xkmSymInterpretDesc);
 
541
    }
 
542
    if (info->group_compat) {
 
543
        register unsigned       bit;
 
544
        xkmModsDesc             modsWire;
 
545
        for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
 
546
            if (info->group_compat&bit) {
 
547
                modsWire.realMods= xkb->compat->groups[i].real_mods;
 
548
                modsWire.virtualMods= xkb->compat->groups[i].vmods;
 
549
                fwrite(&modsWire,SIZEOF(xkmModsDesc),1,file);
 
550
                size+= SIZEOF(xkmModsDesc);
 
551
            }
 
552
        }
 
553
    }
 
554
    return size;
 
555
}
 
556
 
 
557
/***====================================================================***/
 
558
 
 
559
static unsigned
 
560
#if NeedFunctionPrototypes
 
561
SizeXKMSymbols( XkbFileInfo *           result,
 
562
                XkmInfo *               info,
 
563
                xkmSectionInfo *        toc,
 
564
                int *                   offset_inout)
 
565
#else
 
566
SizeXKMSymbols(result,info,toc,offset_inout)
 
567
    XkbFileInfo *       result;
 
568
    XkmInfo *           info;
 
569
    xkmSectionInfo *    toc;
 
570
    int *               offset_inout;
 
571
#endif
 
572
{
 
573
Display *       dpy;
 
574
XkbDescPtr      xkb;
 
575
unsigned        size;
 
576
register int    i,nSyms;
 
577
char *          name;
 
578
 
 
579
    xkb= result->xkb;
 
580
    dpy= xkb->dpy;
 
581
    if ((!xkb)||(!xkb->map)||((!xkb->map->syms))) {
 
582
        _XkbLibError(_XkbErrMissingSymbols,"SizeXKMSymbols",0);
 
583
        return 0;
 
584
    }
 
585
    if (xkb->names && (xkb->names->symbols!=None))
 
586
         name= XkbAtomGetString(dpy,xkb->names->symbols);
 
587
    else name= NULL;
 
588
    size= xkmSizeCountedString(name);
 
589
    size+= 4;   /* min and max keycode, group names mask */
 
590
    for (i=0;i<XkbNumKbdGroups;i++) {
 
591
        if (xkb->names->groups[i]!=None)
 
592
            size+= xkmSizeCountedAtomString(dpy,xkb->names->groups[i]);
 
593
    }
 
594
    info->total_vmodmaps= 0;
 
595
    for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++) {
 
596
        nSyms= XkbKeyNumSyms(xkb,i);
 
597
        size+= SIZEOF(xkmKeySymMapDesc)+(nSyms*4);
 
598
        if (xkb->server) {
 
599
            if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) {
 
600
                register int g;
 
601
                for (g=XkbKeyNumGroups(xkb,i)-1;g>=0;g--) {
 
602
                    if (xkb->server->explicit[i]&(1<<g)) {
 
603
                        XkbKeyTypePtr   type;
 
604
                        char *          name;
 
605
                        type= XkbKeyKeyType(xkb,i,g);
 
606
                        name= XkbAtomGetString(dpy,type->name);
 
607
                        if (name!=NULL)
 
608
                            size+= xkmSizeCountedString(name);
 
609
                    }
 
610
                }
 
611
            }
 
612
            if (XkbKeyHasActions(xkb,i))
 
613
                size+= nSyms*SIZEOF(xkmActionDesc);
 
614
            if (xkb->server->behaviors[i].type!=XkbKB_Default)
 
615
                size+= SIZEOF(xkmBehaviorDesc);
 
616
            if (xkb->server->vmodmap && (xkb->server->vmodmap[i]!=0))
 
617
                info->total_vmodmaps++;
 
618
        }
 
619
    }
 
620
    size+= info->total_vmodmaps*SIZEOF(xkmVModMapDesc);
 
621
    toc->type=          XkmSymbolsIndex;
 
622
    toc->format=        MSBFirst;
 
623
    toc->size=          size+SIZEOF(xkmSectionInfo);
 
624
    toc->offset=        (*offset_inout);
 
625
    (*offset_inout)+=   toc->size;
 
626
    return 1;
 
627
}
 
628
 
 
629
static unsigned
 
630
#if NeedFunctionPrototypes
 
631
WriteXKMSymbols(FILE *file,XkbFileInfo *result,XkmInfo *info)
 
632
#else
 
633
WriteXKMSymbols(file,result,info)
 
634
    FILE *              file;
 
635
    XkbFileInfo *       result;
 
636
    XkmInfo *           info;
 
637
#endif
 
638
{
 
639
Display *               dpy;
 
640
XkbDescPtr              xkb;
 
641
register int            i,n;
 
642
xkmKeySymMapDesc        wireMap;
 
643
char *                  name;
 
644
unsigned                tmp,size= 0;
 
645
 
 
646
    xkb= result->xkb;
 
647
    dpy= xkb->dpy;
 
648
    if (xkb->names && (xkb->names->symbols!=None))
 
649
         name= XkbAtomGetString(dpy,xkb->names->symbols);
 
650
    else name= NULL;
 
651
    size+= xkmPutCountedString(file,name);
 
652
    for (tmp=i=0;i<XkbNumKbdGroups;i++) {
 
653
        if (xkb->names->groups[i]!=None)
 
654
            tmp|= (1<<i);
 
655
    }
 
656
    size+= xkmPutCARD8(file,xkb->min_key_code);
 
657
    size+= xkmPutCARD8(file,xkb->max_key_code);
 
658
    size+= xkmPutCARD8(file,tmp);
 
659
    size+= xkmPutCARD8(file,info->total_vmodmaps);
 
660
    for (i=0,n=1;i<XkbNumKbdGroups;i++,n<<=1) {
 
661
        if ((tmp&n)==0)
 
662
            continue;
 
663
        size+= xkmPutCountedAtomString(dpy,file,xkb->names->groups[i]);
 
664
    }
 
665
    for (i=xkb->min_key_code;i<=(int)xkb->max_key_code;i++)  {
 
666
        char *typeName[XkbNumKbdGroups];
 
667
        wireMap.width= XkbKeyGroupsWidth(xkb,i);
 
668
        wireMap.num_groups= XkbKeyGroupInfo(xkb,i);
 
669
        if (xkb->map && xkb->map->modmap)
 
670
             wireMap.modifier_map= xkb->map->modmap[i];
 
671
        else wireMap.modifier_map= 0;
 
672
        wireMap.flags= 0;
 
673
        bzero((char *)typeName,XkbNumKbdGroups*sizeof(char *));
 
674
        if (xkb->server) {
 
675
            if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) {
 
676
                register int g;
 
677
                for (g=0;g<XkbKeyNumGroups(xkb,i);g++) {
 
678
                    if (xkb->server->explicit[i]&(1<<g)) {
 
679
                        XkbKeyTypePtr   type;
 
680
                        type= XkbKeyKeyType(xkb,i,g);
 
681
                        typeName[g]= XkbAtomGetString(dpy,type->name);
 
682
                        if (typeName[g]!=NULL)
 
683
                            wireMap.flags|= (1<<g);
 
684
                    }
 
685
                }
 
686
            }
 
687
            if (XkbKeyHasActions(xkb,i))
 
688
                wireMap.flags|= XkmKeyHasActions;
 
689
            if (xkb->server->behaviors[i].type!=XkbKB_Default)
 
690
                wireMap.flags|= XkmKeyHasBehavior;
 
691
            if ((xkb->server->explicit[i]&XkbExplicitAutoRepeatMask)&&
 
692
                (xkb->ctrls!=NULL)) {
 
693
                if (xkb->ctrls->per_key_repeat[(i/8)]&(1<<(i%8)))
 
694
                     wireMap.flags|= XkmRepeatingKey;
 
695
                else wireMap.flags|= XkmNonRepeatingKey;
 
696
            }
 
697
        }
 
698
        tmp= fwrite(&wireMap,SIZEOF(xkmKeySymMapDesc),1,file);
 
699
        size+= tmp*SIZEOF(xkmKeySymMapDesc);
 
700
        if (xkb->server->explicit[i]&XkbExplicitKeyTypesMask) {
 
701
            register int g;
 
702
            for (g=0;g<XkbNumKbdGroups;g++) {
 
703
                if (typeName[g]!=NULL)
 
704
                    size+= xkmPutCountedString(file,typeName[g]);
 
705
            }
 
706
        }
 
707
        if (XkbNumGroups(wireMap.num_groups)>0) {
 
708
            KeySym      *sym;
 
709
            sym= XkbKeySymsPtr(xkb,i);
 
710
            for (n=XkbKeyNumSyms(xkb,i);n>0;n--,sym++) {
 
711
                size+= xkmPutCARD32(file,(CARD32)*sym);
 
712
            }
 
713
            if (wireMap.flags&XkmKeyHasActions) {
 
714
                XkbAction *     act;
 
715
                act= XkbKeyActionsPtr(xkb,i);
 
716
                for (n=XkbKeyNumActions(xkb,i);n>0;n--,act++) {
 
717
                    tmp= fwrite(act,SIZEOF(xkmActionDesc),1,file);
 
718
                    size+= tmp*SIZEOF(xkmActionDesc);
 
719
                }
 
720
            }
 
721
        }
 
722
        if (wireMap.flags&XkmKeyHasBehavior) {
 
723
            xkmBehaviorDesc     b;
 
724
            b.type= xkb->server->behaviors[i].type;
 
725
            b.data= xkb->server->behaviors[i].data;
 
726
            tmp= fwrite(&b,SIZEOF(xkmBehaviorDesc),1,file);
 
727
            size+= tmp*SIZEOF(xkmBehaviorDesc);
 
728
        }
 
729
    }
 
730
    if (info->total_vmodmaps>0) {
 
731
        xkmVModMapDesc  v;
 
732
        for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
 
733
            if (xkb->server->vmodmap[i]!=0) {
 
734
                v.key= i;
 
735
                v.vmods= xkb->server->vmodmap[i];
 
736
                tmp= fwrite(&v,SIZEOF(xkmVModMapDesc),1,file);
 
737
                size+= tmp*SIZEOF(xkmVModMapDesc);
 
738
            }
 
739
        }
 
740
    }
 
741
    return size;
 
742
}
 
743
 
 
744
/***====================================================================***/
 
745
 
 
746
static unsigned
 
747
#if NeedFunctionPrototypes
 
748
SizeXKMIndicators(XkbFileInfo *result,XkmInfo *info,xkmSectionInfo *toc,
 
749
                                                        int *offset_inout)
 
750
#else
 
751
SizeXKMIndicators(result,info,toc,offset_inout)
 
752
    XkbFileInfo *       result;
 
753
    XkmInfo *           info;
 
754
    xkmSectionInfo *    toc;
 
755
    int *               offset_inout;
 
756
#endif
 
757
{
 
758
Display *               dpy;
 
759
XkbDescPtr              xkb;
 
760
unsigned                size;
 
761
register unsigned       i,nLEDs;
 
762
 
 
763
    xkb= result->xkb;
 
764
    dpy= xkb->dpy;
 
765
    if ((xkb==NULL)||(xkb->indicators==NULL)) {
 
766
/*      _XkbLibError(_XkbErrMissingIndicators,"SizeXKMIndicators",0);*/
 
767
        return 0;
 
768
    }
 
769
    nLEDs=0;
 
770
    size= 8;    /* number of indicator maps/physical indicators */
 
771
    if (xkb->indicators!=NULL) {
 
772
        for (i=0;i<XkbNumIndicators;i++) {
 
773
            XkbIndicatorMapPtr map= &xkb->indicators->maps[i];
 
774
            if ((map->flags!=0)||(map->which_groups!=0)||(map->groups!=0)||
 
775
                (map->which_mods!=0)||
 
776
                (map->mods.real_mods!=0)||(map->mods.vmods!=0)||
 
777
                (map->ctrls!=0) || 
 
778
                (xkb->names && (xkb->names->indicators[i]!=None))) {
 
779
                char *name;
 
780
                if (xkb->names && xkb->names->indicators[i]!=None) {
 
781
                     name= XkbAtomGetString(dpy,xkb->names->indicators[i]);
 
782
                }
 
783
                else name= NULL;
 
784
                size+= xkmSizeCountedString(name);
 
785
                size+= SIZEOF(xkmIndicatorMapDesc);
 
786
                nLEDs++;
 
787
            }
 
788
        }
 
789
    }
 
790
    info->num_leds= nLEDs;
 
791
    toc->type=          XkmIndicatorsIndex;
 
792
    toc->format=        MSBFirst;
 
793
    toc->size=          size+SIZEOF(xkmSectionInfo);
 
794
    toc->offset=        (*offset_inout);
 
795
    (*offset_inout)+=   toc->size;
 
796
    return 1;
 
797
}
 
798
 
 
799
static unsigned
 
800
#if NeedFunctionPrototypes
 
801
WriteXKMIndicators(FILE *file,XkbFileInfo *result,XkmInfo *info)
 
802
#else
 
803
WriteXKMIndicators(file,result,info)
 
804
    FILE *              file;
 
805
    XkbFileInfo *       result;
 
806
    XkmInfo *           info;
 
807
#endif
 
808
{
 
809
Display *               dpy;
 
810
XkbDescPtr              xkb;
 
811
register unsigned       i;
 
812
xkmIndicatorMapDesc     wire;
 
813
unsigned                tmp,size= 0;
 
814
 
 
815
    xkb= result->xkb;
 
816
    dpy= xkb->dpy;
 
817
    size+= xkmPutCARD8(file,info->num_leds);
 
818
    size+= xkmPutPadding(file,3);
 
819
    size+= xkmPutCARD32(file,xkb->indicators->phys_indicators);
 
820
    if (xkb->indicators!=NULL) {
 
821
        for (i=0;i<XkbNumIndicators;i++) {
 
822
            XkbIndicatorMapPtr map= &xkb->indicators->maps[i];
 
823
            if ((map->flags!=0)||(map->which_groups!=0)||(map->groups!=0)||
 
824
                (map->which_mods!=0)||
 
825
                (map->mods.real_mods!=0)||(map->mods.vmods!=0)||
 
826
                (map->ctrls!=0) ||
 
827
                (xkb->names && (xkb->names->indicators[i]!=None))) {
 
828
                char *name;
 
829
                if (xkb->names && xkb->names->indicators[i]!=None) {
 
830
                     name= XkbAtomGetString(dpy,xkb->names->indicators[i]);
 
831
                }
 
832
                else name= NULL;
 
833
                size+= xkmPutCountedString(file,name);
 
834
                wire.indicator= i+1;
 
835
                wire.flags= map->flags;
 
836
                wire.which_mods= map->which_mods;
 
837
                wire.real_mods= map->mods.real_mods;
 
838
                wire.vmods= map->mods.vmods;
 
839
                wire.which_groups= map->which_groups;
 
840
                wire.groups= map->groups;
 
841
                wire.ctrls= map->ctrls;
 
842
                tmp= fwrite(&wire,SIZEOF(xkmIndicatorMapDesc),1,file);
 
843
                size+= tmp*SIZEOF(xkmIndicatorMapDesc);
 
844
            }
 
845
        }
 
846
    }
 
847
    return size;
 
848
}
 
849
 
 
850
/***====================================================================***/
 
851
 
 
852
static unsigned
 
853
#if NeedFunctionPrototypes
 
854
SizeXKMGeomDoodad(XkbFileInfo *result,XkbDoodadPtr doodad)
 
855
#else
 
856
SizeXKMGeomDoodad(result,doodad)
 
857
    XkbFileInfo *       result;
 
858
    XkbDoodadPtr        doodad;
 
859
#endif
 
860
{
 
861
unsigned        size;
 
862
 
 
863
    size= SIZEOF(xkmAnyDoodadDesc);
 
864
    size+= xkmSizeCountedAtomString(result->xkb->dpy,doodad->any.name);
 
865
    if (doodad->any.type==XkbTextDoodad) {
 
866
        size+= xkmSizeCountedString(doodad->text.text);
 
867
        size+= xkmSizeCountedString(doodad->text.font);
 
868
    }
 
869
    else if (doodad->any.type==XkbLogoDoodad) {
 
870
        size+= xkmSizeCountedString(doodad->logo.logo_name);
 
871
    }
 
872
    return size;
 
873
}
 
874
 
 
875
static unsigned
 
876
#if NeedFunctionPrototypes
 
877
SizeXKMGeomSection(XkbFileInfo *result,XkbSectionPtr section)
 
878
#else
 
879
SizeXKMGeomSection(result,section)
 
880
    XkbFileInfo *       result;
 
881
    XkbSectionPtr       section;
 
882
#endif
 
883
{
 
884
register int i;
 
885
unsigned size;
 
886
 
 
887
    size= SIZEOF(xkmSectionDesc);
 
888
    size+= xkmSizeCountedAtomString(result->xkb->dpy,section->name);
 
889
    if (section->rows) {
 
890
        XkbRowPtr       row;
 
891
        for (row=section->rows,i=0;i<section->num_rows;i++,row++) {
 
892
            size+= SIZEOF(xkmRowDesc);
 
893
            size+= row->num_keys*SIZEOF(xkmKeyDesc);
 
894
        }
 
895
    }
 
896
    if (section->doodads) {
 
897
        XkbDoodadPtr    doodad;
 
898
        for (doodad=section->doodads,i=0;i<section->num_doodads;i++,doodad++) {
 
899
            size+= SizeXKMGeomDoodad(result,doodad);
 
900
        }
 
901
    }
 
902
    if (section->overlays) {
 
903
        XkbOverlayPtr   ol;
 
904
        for (ol=section->overlays,i=0;i<section->num_overlays;i++,ol++) {
 
905
            register int r;
 
906
            XkbOverlayRowPtr    row;
 
907
            size+= xkmSizeCountedAtomString(result->xkb->dpy,ol->name);
 
908
            size+= SIZEOF(xkmOverlayDesc);
 
909
            for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
 
910
                size+= SIZEOF(xkmOverlayRowDesc);
 
911
                size+= row->num_keys*SIZEOF(xkmOverlayKeyDesc);
 
912
            }
 
913
        }
 
914
    }
 
915
    return size;
 
916
}
 
917
 
 
918
static unsigned
 
919
#if NeedFunctionPrototypes
 
920
SizeXKMGeometry(XkbFileInfo *result,xkmSectionInfo *toc,int *offset_inout)
 
921
#else
 
922
SizeXKMGeometry(result,toc,offset_inout)
 
923
    XkbFileInfo *       result;
 
924
    xkmSectionInfo *    toc;
 
925
    int *               offset_inout;
 
926
#endif
 
927
{
 
928
register int    i;
 
929
Display *       dpy;
 
930
XkbDescPtr      xkb;
 
931
XkbGeometryPtr  geom;
 
932
unsigned        size;
 
933
 
 
934
    xkb= result->xkb;
 
935
    dpy= xkb->dpy;
 
936
    if ((!xkb)||(!xkb->geom))
 
937
        return 0;
 
938
    geom= xkb->geom;
 
939
    size= xkmSizeCountedAtomString(dpy,geom->name);
 
940
    size+= SIZEOF(xkmGeometryDesc);
 
941
    size+= xkmSizeCountedString(geom->label_font);
 
942
    if (geom->properties) {
 
943
        XkbPropertyPtr  prop;
 
944
        for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
 
945
            size+= xkmSizeCountedString(prop->name);
 
946
            size+= xkmSizeCountedString(prop->value);
 
947
        }
 
948
    }
 
949
    if (geom->colors) {
 
950
        XkbColorPtr     color;
 
951
        for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
 
952
            size+= xkmSizeCountedString(color->spec);
 
953
        }
 
954
    }
 
955
    if (geom->shapes) {
 
956
        XkbShapePtr     shape;
 
957
        for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
 
958
            register int n;
 
959
            register XkbOutlinePtr      ol;
 
960
            size+= xkmSizeCountedAtomString(dpy,shape->name);
 
961
            size+= SIZEOF(xkmShapeDesc);
 
962
            for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) {
 
963
                size+= SIZEOF(xkmOutlineDesc);
 
964
                size+= ol->num_points*SIZEOF(xkmPointDesc);
 
965
            }
 
966
        }
 
967
    }
 
968
    if (geom->sections) {
 
969
        XkbSectionPtr   section;
 
970
        for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
 
971
            size+= SizeXKMGeomSection(result,section);
 
972
        }
 
973
    }
 
974
    if  (geom->doodads) {
 
975
        XkbDoodadPtr    doodad;
 
976
        for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) {
 
977
            size+= SizeXKMGeomDoodad(result,doodad);
 
978
        }
 
979
    }
 
980
    if (geom->key_aliases) {
 
981
        size+= geom->num_key_aliases*(XkbKeyNameLength*2);
 
982
    }
 
983
    toc->type=          XkmGeometryIndex;
 
984
    toc->format=        MSBFirst;
 
985
    toc->size=          size+SIZEOF(xkmSectionInfo);
 
986
    toc->offset=        (*offset_inout);
 
987
    (*offset_inout)+=   toc->size;
 
988
    return 1;
 
989
}
 
990
 
 
991
static unsigned
 
992
#if NeedFunctionPrototypes
 
993
WriteXKMGeomDoodad(FILE *file,XkbFileInfo *result,XkbDoodadPtr doodad)
 
994
#else
 
995
WriteXKMGeomDoodad(file,result,doodad)
 
996
    FILE *              file;
 
997
    XkbFileInfo *       result;
 
998
    XkbDoodadPtr        doodad;
 
999
#endif
 
1000
{
 
1001
Display *       dpy;
 
1002
XkbDescPtr      xkb;
 
1003
xkmDoodadDesc   doodadWire;
 
1004
unsigned        tmp,size= 0;
 
1005
 
 
1006
    xkb= result->xkb;
 
1007
    dpy= xkb->dpy;
 
1008
    bzero((char *)&doodadWire,sizeof(doodadWire));
 
1009
    doodadWire.any.type= doodad->any.type;
 
1010
    doodadWire.any.priority= doodad->any.priority;
 
1011
    doodadWire.any.top= doodad->any.top;
 
1012
    doodadWire.any.left= doodad->any.left;
 
1013
    switch (doodad->any.type) {
 
1014
        case XkbOutlineDoodad:
 
1015
        case XkbSolidDoodad:
 
1016
            doodadWire.shape.angle= doodad->shape.angle;
 
1017
            doodadWire.shape.color_ndx= doodad->shape.color_ndx;
 
1018
            doodadWire.shape.shape_ndx= doodad->shape.shape_ndx;
 
1019
            break;
 
1020
        case XkbTextDoodad:
 
1021
            doodadWire.text.angle= doodad->text.angle;
 
1022
            doodadWire.text.width= doodad->text.width;
 
1023
            doodadWire.text.height= doodad->text.height;
 
1024
            doodadWire.text.color_ndx= doodad->text.color_ndx;
 
1025
            break;
 
1026
        case XkbIndicatorDoodad:
 
1027
            doodadWire.indicator.shape_ndx= doodad->indicator.shape_ndx;
 
1028
            doodadWire.indicator.on_color_ndx= doodad->indicator.on_color_ndx;
 
1029
            doodadWire.indicator.off_color_ndx= doodad->indicator.off_color_ndx;
 
1030
            break;
 
1031
        case XkbLogoDoodad:
 
1032
            doodadWire.logo.angle= doodad->logo.angle;
 
1033
            doodadWire.logo.color_ndx= doodad->logo.color_ndx;
 
1034
            doodadWire.logo.shape_ndx= doodad->logo.shape_ndx;
 
1035
            break;
 
1036
        default:
 
1037
            _XkbLibError(_XkbErrIllegalDoodad,"WriteXKMGeomDoodad",
 
1038
                                                        doodad->any.type);
 
1039
            return 0;
 
1040
    }
 
1041
    size+= xkmPutCountedAtomString(dpy,file,doodad->any.name);
 
1042
    tmp= fwrite(&doodadWire,SIZEOF(xkmDoodadDesc),1,file);
 
1043
    size+= tmp*SIZEOF(xkmDoodadDesc);
 
1044
    if (doodad->any.type==XkbTextDoodad) {
 
1045
        size+= xkmPutCountedString(file,doodad->text.text);
 
1046
        size+= xkmPutCountedString(file,doodad->text.font);
 
1047
    }
 
1048
    else if (doodad->any.type==XkbLogoDoodad) {
 
1049
        size+= xkmPutCountedString(file,doodad->logo.logo_name);
 
1050
    }
 
1051
    return size;
 
1052
}
 
1053
 
 
1054
static unsigned
 
1055
#if NeedFunctionPrototypes
 
1056
WriteXKMGeomOverlay(FILE *file,XkbFileInfo *result,XkbOverlayPtr ol)
 
1057
#else
 
1058
WriteXKMGeomOverlay(file,result,ol)
 
1059
    FILE *              file;
 
1060
    XkbFileInfo *       result;
 
1061
    XkbOverlayPtr       ol;
 
1062
#endif
 
1063
{
 
1064
register int            r,k;
 
1065
Display *               dpy;
 
1066
XkbDescPtr              xkb;
 
1067
XkbOverlayRowPtr        row;
 
1068
xkmOverlayDesc          olWire;
 
1069
xkmOverlayRowDesc       rowWire;
 
1070
xkmOverlayKeyDesc       keyWire;
 
1071
unsigned                tmp,size= 0;
 
1072
 
 
1073
    xkb= result->xkb;
 
1074
    dpy= xkb->dpy;
 
1075
    bzero((char *)&olWire,sizeof(olWire));
 
1076
    bzero((char *)&rowWire,sizeof(rowWire));
 
1077
    bzero((char *)&keyWire,sizeof(keyWire));
 
1078
    size+= xkmPutCountedAtomString(dpy,file,ol->name);
 
1079
    olWire.num_rows= ol->num_rows;
 
1080
    tmp= fwrite(&olWire,SIZEOF(xkmOverlayDesc),1,file);
 
1081
    size+= tmp*SIZEOF(xkmOverlayDesc);
 
1082
    for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
 
1083
        XkbOverlayKeyPtr        key;
 
1084
        rowWire.row_under= row->row_under;
 
1085
        rowWire.num_keys= row->num_keys;
 
1086
        tmp= fwrite(&rowWire,SIZEOF(xkmOverlayRowDesc),1,file);
 
1087
        size+= tmp*SIZEOF(xkmOverlayRowDesc);
 
1088
        for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
 
1089
            memcpy(keyWire.over,key->over.name,XkbKeyNameLength);
 
1090
            memcpy(keyWire.under,key->under.name,XkbKeyNameLength);
 
1091
            tmp= fwrite(&keyWire,SIZEOF(xkmOverlayKeyDesc),1,file);
 
1092
            size+= tmp*SIZEOF(xkmOverlayKeyDesc);
 
1093
        }
 
1094
    }
 
1095
    return size;    
 
1096
}
 
1097
 
 
1098
static unsigned
 
1099
#if NeedFunctionPrototypes
 
1100
WriteXKMGeomSection(FILE *file,XkbFileInfo *result,XkbSectionPtr section)
 
1101
#else
 
1102
WriteXKMGeomSection(file,result,section)
 
1103
    FILE *              file;
 
1104
    XkbFileInfo *       result;
 
1105
    XkbSectionPtr       section;
 
1106
#endif
 
1107
{
 
1108
register int    i;
 
1109
Display *       dpy;
 
1110
XkbDescPtr      xkb;
 
1111
xkmSectionDesc  sectionWire;
 
1112
unsigned        tmp,size= 0;
 
1113
 
 
1114
    xkb= result->xkb;
 
1115
    dpy= xkb->dpy;
 
1116
    size+= xkmPutCountedAtomString(dpy,file,section->name);
 
1117
    sectionWire.top= section->top;
 
1118
    sectionWire.left= section->left;
 
1119
    sectionWire.width= section->width;
 
1120
    sectionWire.height= section->height;
 
1121
    sectionWire.angle= section->angle;
 
1122
    sectionWire.priority= section->priority;
 
1123
    sectionWire.num_rows= section->num_rows;
 
1124
    sectionWire.num_doodads= section->num_doodads;
 
1125
    sectionWire.num_overlays= section->num_overlays;
 
1126
    tmp= fwrite(&sectionWire,SIZEOF(xkmSectionDesc),1,file);
 
1127
    size+= tmp*SIZEOF(xkmSectionDesc);
 
1128
    if (section->rows) {
 
1129
        register unsigned k;
 
1130
        XkbRowPtr       row;
 
1131
        xkmRowDesc      rowWire;
 
1132
        XkbKeyPtr       key;
 
1133
        xkmKeyDesc      keyWire;
 
1134
        for (i=0,row=section->rows;i<section->num_rows;i++,row++) {
 
1135
            rowWire.top= row->top;
 
1136
            rowWire.left= row->left;
 
1137
            rowWire.num_keys= row->num_keys;
 
1138
            rowWire.vertical= row->vertical;
 
1139
            tmp= fwrite(&rowWire,SIZEOF(xkmRowDesc),1,file);
 
1140
            size+= tmp*SIZEOF(xkmRowDesc);
 
1141
            for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
 
1142
                memcpy(keyWire.name,key->name.name,XkbKeyNameLength);
 
1143
                keyWire.gap= key->gap;
 
1144
                keyWire.shape_ndx= key->shape_ndx;
 
1145
                keyWire.color_ndx= key->color_ndx;
 
1146
                tmp= fwrite(&keyWire,SIZEOF(xkmKeyDesc),1,file);
 
1147
                size+= tmp*SIZEOF(xkmKeyDesc);
 
1148
            }
 
1149
        }
 
1150
    }
 
1151
    if (section->doodads) {
 
1152
        XkbDoodadPtr    doodad;
 
1153
        for (i=0,doodad=section->doodads;i<section->num_doodads;i++,doodad++) {
 
1154
            size+= WriteXKMGeomDoodad(file,result,doodad);
 
1155
        }
 
1156
    }
 
1157
    if (section->overlays) {
 
1158
        XkbOverlayPtr   ol;
 
1159
        for (i=0,ol=section->overlays;i<section->num_overlays;i++,ol++) {
 
1160
            size+= WriteXKMGeomOverlay(file,result,ol);
 
1161
        }
 
1162
    }
 
1163
    return size;
 
1164
}
 
1165
 
 
1166
static unsigned
 
1167
#if NeedFunctionPrototypes
 
1168
WriteXKMGeometry(FILE *file,XkbFileInfo *result)
 
1169
#else
 
1170
WriteXKMGeometry(file,result)
 
1171
    FILE *              file;
 
1172
    XkbFileInfo *       result;
 
1173
#endif
 
1174
{
 
1175
register int    i;
 
1176
Display *       dpy;
 
1177
XkbDescPtr      xkb;
 
1178
XkbGeometryPtr  geom;
 
1179
xkmGeometryDesc wire;
 
1180
unsigned        tmp,size= 0;
 
1181
 
 
1182
    xkb= result->xkb;
 
1183
    dpy= xkb->dpy;
 
1184
    if ((!xkb)||(!xkb->geom))
 
1185
        return 0;
 
1186
    geom= xkb->geom;
 
1187
    wire.width_mm= geom->width_mm;
 
1188
    wire.height_mm= geom->height_mm;
 
1189
    wire.base_color_ndx= XkbGeomColorIndex(geom,geom->base_color);
 
1190
    wire.label_color_ndx= XkbGeomColorIndex(geom,geom->label_color);
 
1191
    wire.num_properties= geom->num_properties;
 
1192
    wire.num_colors= geom->num_colors;
 
1193
    wire.num_shapes= geom->num_shapes;
 
1194
    wire.num_sections= geom->num_sections;
 
1195
    wire.num_doodads= geom->num_doodads;
 
1196
    wire.num_key_aliases= geom->num_key_aliases;
 
1197
    size+= xkmPutCountedAtomString(dpy,file,geom->name);
 
1198
    tmp= fwrite(&wire,SIZEOF(xkmGeometryDesc),1,file);
 
1199
    size+= tmp*SIZEOF(xkmGeometryDesc);
 
1200
    size+= xkmPutCountedString(file,geom->label_font);
 
1201
    if (geom->properties) {
 
1202
        XkbPropertyPtr  prop;
 
1203
        for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
 
1204
            size+= xkmPutCountedString(file,prop->name);
 
1205
            size+= xkmPutCountedString(file,prop->value);
 
1206
        }
 
1207
    }
 
1208
    if (geom->colors) {
 
1209
        XkbColorPtr     color;
 
1210
        for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
 
1211
            size+= xkmPutCountedString(file,color->spec);
 
1212
        }
 
1213
    }
 
1214
    if (geom->shapes) {
 
1215
        XkbShapePtr     shape;
 
1216
        xkmShapeDesc    shapeWire;
 
1217
 
 
1218
        for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
 
1219
            register int        n;
 
1220
            XkbOutlinePtr       ol;
 
1221
            xkmOutlineDesc      olWire;
 
1222
            bzero((char *)&shapeWire,sizeof(xkmShapeDesc));
 
1223
            size+= xkmPutCountedAtomString(dpy,file,shape->name);
 
1224
            shapeWire.num_outlines= shape->num_outlines;
 
1225
            if (shape->primary!=NULL)
 
1226
                 shapeWire.primary_ndx= XkbOutlineIndex(shape,shape->primary);
 
1227
            else shapeWire.primary_ndx= XkbNoShape;
 
1228
            if (shape->approx!=NULL)
 
1229
                 shapeWire.approx_ndx= XkbOutlineIndex(shape,shape->approx);
 
1230
            else shapeWire.approx_ndx= XkbNoShape;
 
1231
            tmp= fwrite(&shapeWire,SIZEOF(xkmShapeDesc),1,file);
 
1232
            size+= tmp*SIZEOF(xkmShapeDesc);
 
1233
            for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) {
 
1234
                register int    p;
 
1235
                XkbPointPtr     pt;
 
1236
                xkmPointDesc    ptWire;
 
1237
                olWire.num_points= ol->num_points;
 
1238
                olWire.corner_radius= ol->corner_radius;
 
1239
                tmp= fwrite(&olWire,SIZEOF(xkmOutlineDesc),1,file);
 
1240
                size+= tmp*SIZEOF(xkmOutlineDesc);
 
1241
                for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) {
 
1242
                    ptWire.x= pt->x;
 
1243
                    ptWire.y= pt->y;
 
1244
                    tmp= fwrite(&ptWire,SIZEOF(xkmPointDesc),1,file);
 
1245
                    size+= tmp*SIZEOF(xkmPointDesc);
 
1246
                }
 
1247
            }
 
1248
        }
 
1249
    }
 
1250
    if (geom->sections) {
 
1251
        XkbSectionPtr   section;
 
1252
        for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
 
1253
            size+= WriteXKMGeomSection(file,result,section);
 
1254
        }
 
1255
    }
 
1256
    if (geom->doodads) {
 
1257
        XkbDoodadPtr    doodad;
 
1258
        for (i=0,doodad=geom->doodads;i<geom->num_doodads;i++,doodad++) {
 
1259
            size+= WriteXKMGeomDoodad(file,result,doodad);
 
1260
        }
 
1261
    }
 
1262
    if (geom->key_aliases) {
 
1263
        tmp= fwrite(geom->key_aliases,2*XkbKeyNameLength,geom->num_key_aliases,
 
1264
                                                                        file);
 
1265
        size+= tmp*(2*XkbKeyNameLength);
 
1266
    }
 
1267
    return size;
 
1268
}
 
1269
 
 
1270
/***====================================================================***/
 
1271
 
 
1272
/*ARGSUSED*/
 
1273
static int
 
1274
#if NeedFunctionPrototypes
 
1275
GetXKMKeyNamesTOC(      XkbFileInfo *   result,
 
1276
                        XkmInfo *       info,
 
1277
                        int             max_toc,
 
1278
                        xkmSectionInfo *toc_rtrn)
 
1279
#else
 
1280
GetXKMKeyNamesTOC(result,info,max_toc,toc_rtrn)
 
1281
    XkbFileInfo *       result;
 
1282
    XkmInfo *           info;
 
1283
    int                 max_toc;
 
1284
    xkmSectionInfo *    toc_rtrn;
 
1285
#endif
 
1286
{
 
1287
int     num_toc;
 
1288
int     total_size;
 
1289
 
 
1290
    total_size= num_toc=0;
 
1291
    if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size))
 
1292
        num_toc++;
 
1293
    if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size))
 
1294
        num_toc++;
 
1295
    return num_toc;
 
1296
}
 
1297
 
 
1298
/*ARGSUSED*/
 
1299
static int
 
1300
#if NeedFunctionPrototypes
 
1301
GetXKMTypesTOC( XkbFileInfo *   result,
 
1302
                XkmInfo *       info,
 
1303
                int             max_toc,
 
1304
                xkmSectionInfo *toc_rtrn)
 
1305
#else
 
1306
GetXKMTypesTOC(result,info,max_toc,toc_rtrn)
 
1307
    XkbFileInfo *       result;
 
1308
    XkmInfo *           info;
 
1309
    int                 max_toc;
 
1310
    xkmSectionInfo *    toc_rtrn;
 
1311
#endif
 
1312
{
 
1313
int     num_toc;
 
1314
int     total_size;
 
1315
 
 
1316
    total_size= num_toc=0;
 
1317
    if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size))
 
1318
        num_toc++;
 
1319
    if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size))
 
1320
        num_toc++;
 
1321
    return num_toc;
 
1322
}
 
1323
 
 
1324
/*ARGSUSED*/
 
1325
static int
 
1326
#if NeedFunctionPrototypes
 
1327
GetXKMCompatMapTOC(     XkbFileInfo *   result,
 
1328
                        XkmInfo *       info,
 
1329
                        int             max_toc,
 
1330
                        xkmSectionInfo *toc_rtrn)
 
1331
#else
 
1332
GetXKMCompatMapTOC(result,info,max_toc,toc_rtrn)
 
1333
    XkbFileInfo *       result;
 
1334
    XkmInfo *           info;
 
1335
    int                 max_toc;
 
1336
    xkmSectionInfo *    toc_rtrn;
 
1337
#endif
 
1338
{
 
1339
int     num_toc;
 
1340
int     total_size;
 
1341
 
 
1342
    total_size= num_toc=0;
 
1343
    if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size))
 
1344
        num_toc++;
 
1345
    if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size))
 
1346
        num_toc++;
 
1347
    if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size))
 
1348
        num_toc++;
 
1349
    return num_toc;
 
1350
}
 
1351
 
 
1352
/*ARGSUSED*/
 
1353
static int
 
1354
#if NeedFunctionPrototypes
 
1355
GetXKMSemanticsTOC(     XkbFileInfo *   result,
 
1356
                        XkmInfo *       info,
 
1357
                        int             max_toc,
 
1358
                        xkmSectionInfo *toc_rtrn)
 
1359
#else
 
1360
GetXKMSemanticsTOC(result,info,max_toc,toc_rtrn)
 
1361
    XkbFileInfo *       result;
 
1362
    XkmInfo *           info;
 
1363
    int                 max_toc;
 
1364
    xkmSectionInfo *    toc_rtrn;
 
1365
#endif
 
1366
{
 
1367
int     num_toc;
 
1368
int     total_size;
 
1369
 
 
1370
    total_size= num_toc=0;
 
1371
    if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size))
 
1372
        num_toc++;
 
1373
    if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size))
 
1374
        num_toc++;
 
1375
    if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size))
 
1376
        num_toc++;
 
1377
    if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size))
 
1378
        num_toc++;
 
1379
    return num_toc;
 
1380
}
 
1381
 
 
1382
/*ARGSUSED*/
 
1383
static int
 
1384
#if NeedFunctionPrototypes
 
1385
GetXKMLayoutTOC(        XkbFileInfo *   result,
 
1386
                        XkmInfo *       info,
 
1387
                        int             max_toc,
 
1388
                        xkmSectionInfo *toc_rtrn)
 
1389
#else
 
1390
GetXKMLayoutTOC(result,info,max_toc,toc_rtrn)
 
1391
    XkbFileInfo *       result;
 
1392
    XkmInfo *           info;
 
1393
    int                 max_toc;
 
1394
    xkmSectionInfo *    toc_rtrn;
 
1395
#endif
 
1396
{
 
1397
int     num_toc;
 
1398
int     total_size;
 
1399
 
 
1400
    total_size= num_toc=0;
 
1401
    if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size))
 
1402
        num_toc++;
 
1403
    if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size))
 
1404
        num_toc++;
 
1405
    if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size))
 
1406
        num_toc++;
 
1407
    if (SizeXKMSymbols(result,info,&toc_rtrn[num_toc],&total_size))
 
1408
        num_toc++;
 
1409
    if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size))
 
1410
        num_toc++;
 
1411
    if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size))
 
1412
        num_toc++;
 
1413
    return num_toc;
 
1414
}
 
1415
 
 
1416
/*ARGSUSED*/
 
1417
static int
 
1418
#if NeedFunctionPrototypes
 
1419
GetXKMKeymapTOC(        XkbFileInfo *   result,
 
1420
                        XkmInfo *       info,
 
1421
                        int             max_toc,
 
1422
                        xkmSectionInfo *toc_rtrn)
 
1423
#else
 
1424
GetXKMKeymapTOC(result,info,max_toc,toc_rtrn)
 
1425
    XkbFileInfo *       result;
 
1426
    XkmInfo *           info;
 
1427
    int                 max_toc;
 
1428
    xkmSectionInfo *    toc_rtrn;
 
1429
#endif
 
1430
{
 
1431
int     num_toc;
 
1432
int     total_size;
 
1433
 
 
1434
    total_size= num_toc=0;
 
1435
    if (SizeXKMVirtualMods(result,info,&toc_rtrn[num_toc],&total_size))
 
1436
        num_toc++;
 
1437
    if (SizeXKMKeycodes(result,&toc_rtrn[num_toc],&total_size))
 
1438
        num_toc++;
 
1439
    if (SizeXKMKeyTypes(result,&toc_rtrn[num_toc],&total_size))
 
1440
        num_toc++;
 
1441
    if (SizeXKMCompatMap(result,info,&toc_rtrn[num_toc],&total_size))
 
1442
        num_toc++;
 
1443
    if (SizeXKMSymbols(result,info,&toc_rtrn[num_toc],&total_size))
 
1444
        num_toc++;
 
1445
    if (SizeXKMIndicators(result,info,&toc_rtrn[num_toc],&total_size))
 
1446
        num_toc++;
 
1447
    if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size))
 
1448
        num_toc++;
 
1449
    return num_toc;
 
1450
}
 
1451
 
 
1452
/*ARGSUSED*/
 
1453
static int
 
1454
#if NeedFunctionPrototypes
 
1455
GetXKMGeometryTOC(      XkbFileInfo *   result,
 
1456
                        XkmInfo *       info,
 
1457
                        int             max_toc,
 
1458
                        xkmSectionInfo *toc_rtrn)
 
1459
#else
 
1460
GetXKMGeometryTOC(result,info,max_toc,toc_rtrn)
 
1461
    XkbFileInfo *       result;
 
1462
    XkmInfo *           info;
 
1463
    int                 max_toc;
 
1464
    xkmSectionInfo *    toc_rtrn;
 
1465
#endif
 
1466
{
 
1467
int     num_toc;
 
1468
int     total_size;
 
1469
 
 
1470
    total_size= num_toc=0;
 
1471
    if (SizeXKMGeometry(result,&toc_rtrn[num_toc],&total_size))
 
1472
        num_toc++;
 
1473
    return num_toc;
 
1474
}
 
1475
 
 
1476
static Bool
 
1477
#if NeedFunctionPrototypes
 
1478
WriteXKMFile(   FILE *          file,
 
1479
                XkbFileInfo *   result,
 
1480
                int             num_toc,
 
1481
                xkmSectionInfo *toc,
 
1482
                XkmInfo *       info)
 
1483
#else
 
1484
WriteXKMFile(file,result,num_toc,toc,info)
 
1485
    FILE *              file;
 
1486
    XkbFileInfo *       result;
 
1487
    int                 num_toc;
 
1488
    xkmSectionInfo *    toc;
 
1489
    XkmInfo *           info;
 
1490
#endif
 
1491
{
 
1492
register int    i;
 
1493
unsigned        tmp,size,total= 0;
 
1494
    
 
1495
    for (i=0;i<num_toc;i++) {
 
1496
        tmp= fwrite(&toc[i],SIZEOF(xkmSectionInfo),1,file);
 
1497
        total+= tmp*SIZEOF(xkmSectionInfo);
 
1498
        switch (toc[i].type) {
 
1499
            case XkmTypesIndex:
 
1500
                size= WriteXKMKeyTypes(file,result);
 
1501
                break;
 
1502
            case XkmCompatMapIndex:
 
1503
                size= WriteXKMCompatMap(file,result,info);
 
1504
                break;
 
1505
            case XkmSymbolsIndex:
 
1506
                size= WriteXKMSymbols(file,result,info);
 
1507
                break;
 
1508
            case XkmIndicatorsIndex:
 
1509
                size= WriteXKMIndicators(file,result,info);
 
1510
                break;
 
1511
            case XkmKeyNamesIndex:
 
1512
                size= WriteXKMKeycodes(file,result);
 
1513
                break;
 
1514
            case XkmGeometryIndex:
 
1515
                size= WriteXKMGeometry(file,result);
 
1516
                break;
 
1517
            case XkmVirtualModsIndex:
 
1518
                size= WriteXKMVirtualMods(file,result,info);
 
1519
                break;
 
1520
            default:
 
1521
                _XkbLibError(_XkbErrIllegalTOCType,"WriteXKMFile",toc[i].type);
 
1522
                return False;
 
1523
        }
 
1524
        size+= SIZEOF(xkmSectionInfo);
 
1525
        if (size!=toc[i].size) {
 
1526
            _XkbLibError(_XkbErrBadLength,XkbConfigText(toc[i].type,XkbMessage),
 
1527
                                                        size-toc[i].size);
 
1528
            return False;
 
1529
        }
 
1530
    }
 
1531
    return True;
 
1532
}
 
1533
 
 
1534
 
 
1535
#define MAX_TOC 16
 
1536
 
 
1537
Bool
 
1538
#if NeedFunctionPrototypes
 
1539
XkbWriteXKMFile(FILE *out,XkbFileInfo *result)
 
1540
#else
 
1541
XkbWriteXKMFile(out,result)
 
1542
    FILE *              out;
 
1543
    XkbFileInfo *       result;
 
1544
#endif
 
1545
{
 
1546
Bool                    ok;
 
1547
XkbDescPtr              xkb;
 
1548
XkmInfo                 info;
 
1549
int                     size_toc,i;
 
1550
unsigned                hdr,present;
 
1551
xkmFileInfo             fileInfo;
 
1552
xkmSectionInfo          toc[MAX_TOC];
 
1553
int                     (*getTOC)(
 
1554
#if NeedFunctionPrototypes
 
1555
        XkbFileInfo *   /* result */,
 
1556
        XkmInfo *       /* info */,
 
1557
        int             /* max_to */,
 
1558
        xkmSectionInfo */* toc_rtrn */
 
1559
#endif
 
1560
);
 
1561
 
 
1562
    switch (result->type) {
 
1563
        case XkmKeyNamesIndex:
 
1564
            getTOC= GetXKMKeyNamesTOC;
 
1565
            break;
 
1566
        case XkmTypesIndex:
 
1567
            getTOC= GetXKMTypesTOC;
 
1568
            break;
 
1569
        case XkmCompatMapIndex:
 
1570
            getTOC= GetXKMCompatMapTOC;
 
1571
            break;
 
1572
        case XkmSemanticsFile:
 
1573
            getTOC= GetXKMSemanticsTOC;
 
1574
            break;
 
1575
        case XkmLayoutFile:
 
1576
            getTOC= GetXKMLayoutTOC;
 
1577
            break;
 
1578
        case XkmKeymapFile:
 
1579
            getTOC= GetXKMKeymapTOC;
 
1580
            break;
 
1581
        case XkmGeometryFile:
 
1582
        case XkmGeometryIndex:
 
1583
            getTOC= GetXKMGeometryTOC;
 
1584
            break;
 
1585
        default:
 
1586
            _XkbLibError(_XkbErrIllegalContents,
 
1587
                                XkbConfigText(result->type,XkbMessage),0);
 
1588
            return False;
 
1589
    }
 
1590
    xkb= result->xkb;
 
1591
 
 
1592
    bzero((char *)&info,sizeof(XkmInfo));
 
1593
    size_toc= (*getTOC)(result,&info,MAX_TOC,toc);
 
1594
    if (size_toc<1) {
 
1595
        _XkbLibError(_XkbErrEmptyFile,"XkbWriteXKMFile",0);
 
1596
        return False;
 
1597
    }
 
1598
    if (out==NULL) {
 
1599
        _XkbLibError(_XkbErrFileCannotOpen,"XkbWriteXKMFile",0);
 
1600
        return False;
 
1601
    }
 
1602
    for (i=present=0;i<size_toc;i++) {
 
1603
        toc[i].offset+= 4+SIZEOF(xkmFileInfo);
 
1604
        toc[i].offset+= (size_toc*SIZEOF(xkmSectionInfo));
 
1605
        if (toc[i].type<=XkmLastIndex) {
 
1606
            present|= (1<<toc[i].type);
 
1607
        }
 
1608
#ifdef DEBUG
 
1609
        else {
 
1610
            fprintf(stderr,"Illegal section type %d\n",toc[i].type);
 
1611
            fprintf(stderr,"Ignored\n");
 
1612
        }
 
1613
#endif
 
1614
    }
 
1615
    hdr= (('x'<<24)|('k'<<16)|('m'<<8)|XkmFileVersion);
 
1616
    xkmPutCARD32(out,(unsigned long)hdr);
 
1617
    fileInfo.type= result->type;
 
1618
    fileInfo.min_kc= xkb->min_key_code;
 
1619
    fileInfo.max_kc= xkb->max_key_code;
 
1620
    fileInfo.num_toc= size_toc;
 
1621
    fileInfo.present= present;
 
1622
    fileInfo.pad= 0;
 
1623
    fwrite(&fileInfo,SIZEOF(xkmFileInfo),1,out);
 
1624
    fwrite(toc,SIZEOF(xkmSectionInfo),size_toc,out);
 
1625
    ok= WriteXKMFile(out,result,size_toc,toc,&info);
 
1626
    return ok;
 
1627
}