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

« back to all changes in this revision

Viewing changes to unix/xc/lib/xkbfile/xkbconfig.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: xkbconfig.c,v 1.4 2000/08/17 19:46:43 cpqbld Exp $ */
 
2
/************************************************************
 
3
 Copyright (c) 1995 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/xkbconfig.c,v 3.7 2001/11/30 12:11:51 eich Exp $ */
 
28
 
 
29
#include <stdio.h>
 
30
#include <ctype.h>
 
31
#include <stdlib.h>
 
32
 
 
33
#include <X11/Xfuncs.h>
 
34
 
 
35
#include <X11/Xfuncs.h>
 
36
 
 
37
#ifndef XKB_IN_SERVER
 
38
 
 
39
#include <X11/Xos.h>
 
40
#include <X11/Xlib.h>
 
41
#include <X11/keysym.h>
 
42
#include <X11/XKBlib.h>
 
43
#include "XKBfileInt.h"
 
44
 
 
45
#else
 
46
 
 
47
#include "X.h"
 
48
#define NEED_EVENTS
 
49
#include <X11/keysym.h>
 
50
#include "Xproto.h"
 
51
#include "misc.h"
 
52
#include "inputstr.h"
 
53
#include "dix.h"
 
54
#define XKBSRV_NEED_FILE_FUNCS
 
55
#include "XKBsrv.h"
 
56
#endif
 
57
 
 
58
#include <X11/extensions/XKBconfig.h>
 
59
 
 
60
/***====================================================================***/
 
61
 
 
62
#define XKBCF_MAX_STR_LEN       100
 
63
static char _XkbCF_rtrn[XKBCF_MAX_STR_LEN+1];
 
64
 
 
65
static int
 
66
#if NeedFunctionPrototypes
 
67
ScanIdent(FILE *file,int ch,XkbCFScanResultPtr val_rtrn)
 
68
#else
 
69
ScanIdent(file,ch,val_rtrn)
 
70
    FILE *              file;
 
71
    int                 ch;
 
72
    XkbCFScanResultPtr  val_rtrn;
 
73
#endif
 
74
{
 
75
register int    i;
 
76
char *          str;
 
77
 
 
78
    val_rtrn->str= str= _XkbCF_rtrn;
 
79
    for (i=0;(isalpha(ch)||isdigit(ch)||(ch=='_'));ch=getc(file)) {
 
80
        if (i<XKBCF_MAX_STR_LEN)
 
81
            str[i++]= ch;
 
82
    }
 
83
    if ((ch!=EOF)&&(ch!=' ')&&(ch!='\t'))
 
84
        ungetc(ch,file);
 
85
    str[i]= '\0';
 
86
    return XkbCF_Ident;
 
87
}
 
88
 
 
89
static int
 
90
#if NeedFunctionPrototypes
 
91
ScanString(FILE *file,int quote,XkbCFScanResultPtr val_rtrn)
 
92
#else
 
93
ScanString(file,quote,val_rtrn)
 
94
    FILE *              file;
 
95
    int                 quote;
 
96
    XkbCFScanResultPtr  val_rtrn;
 
97
#endif
 
98
{
 
99
int     ch,nInBuf;
 
100
 
 
101
    nInBuf = 0;
 
102
    while ( ((ch=getc(file))!=EOF) && (ch!='\n') && (ch!=quote) ) {
 
103
        if ( ch == '\\' ) {
 
104
            if ((ch = getc(file))!=EOF) {
 
105
                if ( ch=='n' )          ch = '\n';
 
106
                else if ( ch == 't' )   ch = '\t';
 
107
                else if ( ch == 'v' )   ch = '\v';
 
108
                else if ( ch == 'b' )   ch = '\b';
 
109
                else if ( ch == 'r' )   ch = '\r';
 
110
                else if ( ch == 'f' )   ch = '\f';
 
111
                else if ( ch == 'e' )   ch = '\033';
 
112
                else if ( ch == '0' ) {
 
113
                    int tmp,stop;
 
114
                    ch = stop = 0;
 
115
                    if (((tmp=getc(file))!=EOF) && (isdigit(tmp)) && 
 
116
                                                (tmp!='8') && (tmp!='9')) {
 
117
                        ch= (ch*8)+(tmp-'0');
 
118
                    }
 
119
                    else {
 
120
                        stop= 1;
 
121
                        ungetc(tmp,file);
 
122
                    }
 
123
                    if ((!stop) && ((tmp=getc(file))!=EOF) && (isdigit(tmp)) && 
 
124
                                                (tmp!='8') && (tmp!='9')) {
 
125
                        ch= (ch*8)+(tmp-'0');
 
126
                    }
 
127
                    else {
 
128
                        stop= 1;
 
129
                        ungetc(tmp,file);
 
130
                    }
 
131
                    if ((!stop) && ((tmp=getc(file))!=EOF) && (isdigit(tmp)) && 
 
132
                                                (tmp!='8') && (tmp!='9')) {
 
133
                        ch= (ch*8)+(tmp-'0');
 
134
                    }
 
135
                    else {
 
136
                        stop= 1;
 
137
                        ungetc(tmp,file);
 
138
                    }
 
139
                }
 
140
            }
 
141
            else return XkbCF_EOF;
 
142
        }
 
143
 
 
144
        if ( nInBuf < XKBCF_MAX_STR_LEN-1 ) 
 
145
            _XkbCF_rtrn[nInBuf++] = ch;
 
146
    }
 
147
    if ( ch == quote ) {
 
148
        _XkbCF_rtrn[nInBuf++] = '\0';
 
149
        val_rtrn->str= _XkbCF_rtrn;
 
150
        return XkbCF_String;
 
151
    }
 
152
    return XkbCF_UnterminatedString;
 
153
}
 
154
 
 
155
static int
 
156
#if NeedFunctionPrototypes
 
157
ScanInteger(FILE *file,int ch,XkbCFScanResultPtr val_rtrn)
 
158
#else
 
159
ScanInteger(file,ch,val_rtrn)
 
160
    FILE *              file;
 
161
    int                 ch;
 
162
    XkbCFScanResultPtr  val_rtrn;
 
163
#endif
 
164
{
 
165
int     i;
 
166
 
 
167
    if (isdigit(ch))
 
168
        ungetc(ch,file);
 
169
    if (fscanf(file,"%i",&i)==1) {
 
170
        val_rtrn->ival= i;
 
171
        return XkbCF_Integer;
 
172
    }
 
173
    return XkbCF_Unknown;
 
174
}
 
175
 
 
176
int 
 
177
#if NeedFunctionPrototypes
 
178
XkbCFScan(FILE *file,XkbCFScanResultPtr val_rtrn,XkbConfigRtrnPtr rtrn)
 
179
#else
 
180
XkbCFScan(file,val_rtrn,rtrn)
 
181
    FILE *              file;
 
182
    XkbCFScanResultPtr  val_rtrn;
 
183
    XkbConfigRtrnPtr    rtrn;
 
184
#endif
 
185
{
 
186
int     ch;
 
187
 
 
188
    do {
 
189
        ch= getc(file);
 
190
    } while ((ch=='\t')||(ch==' '));
 
191
    if (isalpha(ch))
 
192
         return ScanIdent(file,ch,val_rtrn);
 
193
    else if (isdigit(ch))
 
194
         return ScanInteger(file,ch,val_rtrn);
 
195
    else if (ch=='"')
 
196
         return ScanString(file,ch,val_rtrn);
 
197
    else if (ch=='\n') {
 
198
        rtrn->line++;
 
199
        return XkbCF_EOL;
 
200
    }
 
201
    else if (ch==';')
 
202
        return XkbCF_Semi;
 
203
    else if (ch=='=')
 
204
        return XkbCF_Equals;
 
205
    else if (ch=='+') {
 
206
        ch= getc(file);
 
207
        if (ch=='=')
 
208
            return XkbCF_PlusEquals;
 
209
        if ((ch!=EOF)&&(ch!=' ')&&(ch!='\t'))
 
210
            ungetc(ch,file);
 
211
        return XkbCF_Plus;
 
212
    }
 
213
    else if (ch=='-') {
 
214
        ch= getc(file);
 
215
        if (ch=='=')
 
216
            return XkbCF_MinusEquals;
 
217
        if ((ch!=EOF)&&(ch!=' ')&&(ch!='\t'))
 
218
            ungetc(ch,file);
 
219
        return XkbCF_Minus;
 
220
    }
 
221
    else if (ch==EOF)
 
222
        return XkbCF_EOF;
 
223
    else if ((ch=='#')||((ch=='/')&&(getc(file)=='/'))) {
 
224
        while ((ch!='\n')&&(ch!=EOF))
 
225
            ch= getc(file);
 
226
        rtrn->line++;
 
227
        return XkbCF_EOL;
 
228
    }
 
229
    return XkbCF_Unknown;
 
230
}
 
231
 
 
232
/***====================================================================***/
 
233
 
 
234
#define _XkbCF_Illegal                  0
 
235
#define _XkbCF_Keymap                   1
 
236
#define _XkbCF_Keycodes                 2
 
237
#define _XkbCF_Geometry                 3
 
238
#define _XkbCF_PhysSymbols              4
 
239
#define _XkbCF_Symbols                  5
 
240
#define _XkbCF_Types                    6
 
241
#define _XkbCF_CompatMap                7
 
242
 
 
243
#define _XkbCF_RulesFile                8
 
244
#define _XkbCF_Model                    9
 
245
#define _XkbCF_Layout                   10
 
246
#define _XkbCF_Variant                  11
 
247
#define _XkbCF_Options                  12
 
248
        
 
249
#define _XkbCF_InitialMods              13
 
250
#define _XkbCF_InitialCtrls             14
 
251
 
 
252
#define _XkbCF_ClickVolume              15
 
253
#define _XkbCF_BellVolume               16
 
254
#define _XkbCF_BellPitch                17
 
255
#define _XkbCF_BellDuration             18
 
256
#define _XkbCF_RepeatDelay              19
 
257
#define _XkbCF_RepeatInterval           20
 
258
#define _XkbCF_SlowKeysDelay            21
 
259
#define _XkbCF_DebounceDelay            22
 
260
#define _XkbCF_MouseKeysDelay           23
 
261
#define _XkbCF_MouseKeysInterval        24
 
262
#define _XkbCF_MouseKeysTimeToMax       25
 
263
#define _XkbCF_MouseKeysMaxSpeed        26
 
264
#define _XkbCF_MouseKeysCurve           27
 
265
#define _XkbCF_AccessXTimeout           28
 
266
#define _XkbCF_AccessXTimeoutCtrlsOn    29
 
267
#define _XkbCF_AccessXTimeoutCtrlsOff   30
 
268
#define _XkbCF_AccessXTimeoutOptsOn     31
 
269
#define _XkbCF_AccessXTimeoutOptsOff    32
 
270
 
 
271
#define _XkbCF_IgnoreLockMods           33
 
272
#define _XkbCF_IgnoreGroupLock          34
 
273
#define _XkbCF_InternalMods             35
 
274
 
 
275
#define _XkbCF_GroupsWrap               36
 
276
#define _XkbCF_InitialFeedback          37
 
277
 
 
278
static Bool
 
279
#if NeedFunctionPrototypes
 
280
AddCtrlByName(XkbConfigRtrnPtr rtrn,char *name,unsigned long *ctrls_rtrn)
 
281
#else
 
282
AddCtrlByName(rtrn,name,ctrls_rtrn)
 
283
    XkbConfigRtrnPtr    rtrn;
 
284
    char *              name;
 
285
    unsigned long *     ctrls_rtrn;
 
286
#endif
 
287
{
 
288
    if ((_XkbStrCaseCmp(name,"repeat")==0)||
 
289
        (_XkbStrCaseCmp(name,"repeatkeys")==0))
 
290
        *ctrls_rtrn= XkbRepeatKeysMask;
 
291
    else if (_XkbStrCaseCmp(name,"slowkeys")==0)
 
292
        *ctrls_rtrn= XkbSlowKeysMask;
 
293
    else if (_XkbStrCaseCmp(name,"bouncekeys")==0)
 
294
        *ctrls_rtrn= XkbBounceKeysMask;
 
295
    else if (_XkbStrCaseCmp(name,"stickykeys")==0)
 
296
        *ctrls_rtrn= XkbStickyKeysMask;
 
297
    else if (_XkbStrCaseCmp(name,"mousekeys")==0)
 
298
        *ctrls_rtrn= XkbMouseKeysMask;
 
299
    else if (_XkbStrCaseCmp(name,"mousekeysaccel")==0)
 
300
        *ctrls_rtrn= XkbMouseKeysAccelMask;
 
301
    else if (_XkbStrCaseCmp(name,"accessxkeys")==0)
 
302
        *ctrls_rtrn= XkbAccessXKeysMask;
 
303
    else if (_XkbStrCaseCmp(name,"accessxtimeout")==0)
 
304
        *ctrls_rtrn= XkbAccessXTimeoutMask;
 
305
    else if (_XkbStrCaseCmp(name,"accessxfeedback")==0)
 
306
        *ctrls_rtrn= XkbAccessXFeedbackMask;
 
307
    else if (_XkbStrCaseCmp(name,"audiblebell")==0)
 
308
        *ctrls_rtrn= XkbAudibleBellMask;
 
309
    else if (_XkbStrCaseCmp(name,"overlay1")==0)
 
310
        *ctrls_rtrn= XkbOverlay1Mask;
 
311
    else if (_XkbStrCaseCmp(name,"overlay2")==0)
 
312
        *ctrls_rtrn= XkbOverlay2Mask;
 
313
    else if (_XkbStrCaseCmp(name,"ignoregrouplock")==0)
 
314
        *ctrls_rtrn= XkbIgnoreGroupLockMask;
 
315
    else {
 
316
        rtrn->error= XkbCF_ExpectedControl;
 
317
        return False;
 
318
    }
 
319
    return True;
 
320
}
 
321
 
 
322
static Bool
 
323
#if NeedFunctionPrototypes
 
324
AddAXTimeoutOptByName(  XkbConfigRtrnPtr        rtrn,
 
325
                        char *                  name,
 
326
                        unsigned short *        opts_rtrn)
 
327
#else
 
328
AddAXTimeoutOptByName(rtrn,name,opts_rtrn)
 
329
    XkbConfigRtrnPtr    rtrn;
 
330
    char *              name;
 
331
    unsigned short *    opts_rtrn;
 
332
#endif
 
333
{
 
334
    if (_XkbStrCaseCmp(name,"slowkeyspress")==0)
 
335
        *opts_rtrn= XkbAX_SKPressFBMask;
 
336
    else if (_XkbStrCaseCmp(name,"slowkeysaccept")==0)
 
337
        *opts_rtrn= XkbAX_SKAcceptFBMask;
 
338
    else if (_XkbStrCaseCmp(name,"feature")==0)
 
339
        *opts_rtrn= XkbAX_FeatureFBMask;
 
340
    else if (_XkbStrCaseCmp(name,"slowwarn")==0)
 
341
        *opts_rtrn= XkbAX_SlowWarnFBMask;
 
342
    else if (_XkbStrCaseCmp(name,"indicator")==0)
 
343
        *opts_rtrn= XkbAX_IndicatorFBMask;
 
344
    else if (_XkbStrCaseCmp(name,"stickykeys")==0)
 
345
        *opts_rtrn= XkbAX_StickyKeysFBMask;
 
346
    else if (_XkbStrCaseCmp(name,"twokeys")==0)
 
347
        *opts_rtrn= XkbAX_TwoKeysMask;
 
348
    else if (_XkbStrCaseCmp(name,"latchtolock")==0)
 
349
        *opts_rtrn= XkbAX_LatchToLockMask;
 
350
    else if (_XkbStrCaseCmp(name,"slowkeysrelease")==0)
 
351
        *opts_rtrn= XkbAX_SKReleaseFBMask;
 
352
    else if (_XkbStrCaseCmp(name,"slowkeysreject")==0)
 
353
        *opts_rtrn= XkbAX_SKRejectFBMask;
 
354
    else if (_XkbStrCaseCmp(name,"bouncekeysreject")==0)
 
355
        *opts_rtrn= XkbAX_BKRejectFBMask;
 
356
    else if (_XkbStrCaseCmp(name,"dumbbell")==0)
 
357
        *opts_rtrn= XkbAX_DumbBellFBMask;
 
358
    else {
 
359
        rtrn->error= XkbCF_ExpectedControl;
 
360
        return False;
 
361
    }
 
362
    return True;
 
363
}
 
364
 
 
365
XkbConfigUnboundModPtr
 
366
#if NeedFunctionPrototypes
 
367
XkbCFAddModByName(      XkbConfigRtrnPtr        rtrn,
 
368
                        int                     what,
 
369
                        char *                  name,
 
370
                        Bool                    merge,
 
371
                        XkbConfigUnboundModPtr  last)
 
372
#else
 
373
XkbCFAddModByName(rtrn,what,name,merge,last)
 
374
    XkbConfigRtrnPtr            rtrn;
 
375
    int                         what;
 
376
    char *                      name;
 
377
    Bool                        merge;
 
378
    XkbConfigUnboundModPtr      last;
 
379
#endif
 
380
{
 
381
    if (rtrn->num_unbound_mods>=rtrn->sz_unbound_mods) {
 
382
        rtrn->sz_unbound_mods+= 5;
 
383
        rtrn->unbound_mods= _XkbTypedRealloc(rtrn->unbound_mods,
 
384
                                                  rtrn->sz_unbound_mods,
 
385
                                                  XkbConfigUnboundModRec);
 
386
        if (rtrn->unbound_mods==NULL) {
 
387
            rtrn->error= XkbCF_BadAlloc;
 
388
            return False;
 
389
        }
 
390
    }
 
391
    if (last==NULL) {
 
392
        last= &rtrn->unbound_mods[rtrn->num_unbound_mods++];
 
393
        last->what= what;
 
394
        last->mods= 0;
 
395
        last->vmods= 0;
 
396
        last->merge= merge;
 
397
        last->name= NULL;
 
398
    }
 
399
    if (_XkbStrCaseCmp(name,"shift")==0)
 
400
        last->mods|= ShiftMask;
 
401
    else if (_XkbStrCaseCmp(name,"lock")==0)
 
402
        last->mods|= LockMask;
 
403
    else if ((_XkbStrCaseCmp(name,"control")==0)||
 
404
                (_XkbStrCaseCmp(name,"ctrl")==0))
 
405
        last->mods|= ControlMask;
 
406
    else if (_XkbStrCaseCmp(name,"mod1")==0)
 
407
        last->mods|= Mod1Mask;
 
408
    else if (_XkbStrCaseCmp(name,"mod2")==0)
 
409
        last->mods|= Mod2Mask;
 
410
    else if (_XkbStrCaseCmp(name,"mod3")==0)
 
411
        last->mods|= Mod3Mask;
 
412
    else if (_XkbStrCaseCmp(name,"mod4")==0)
 
413
        last->mods|= Mod4Mask;
 
414
    else if (_XkbStrCaseCmp(name,"mod5")==0)
 
415
        last->mods|= Mod5Mask;
 
416
    else {
 
417
        if (last->name!=NULL) {
 
418
            last= &rtrn->unbound_mods[rtrn->num_unbound_mods++];
 
419
            last->what= what;
 
420
            last->mods= 0;
 
421
            last->vmods= 0;
 
422
            last->merge= merge;
 
423
            last->name= NULL;
 
424
        }
 
425
        last->name= _XkbDupString(name);
 
426
    }
 
427
    return last;
 
428
}
 
429
 
 
430
int
 
431
#if NeedFunctionPrototypes
 
432
XkbCFBindMods(XkbConfigRtrnPtr rtrn,XkbDescPtr xkb)
 
433
#else
 
434
XkbCFBindMods(rtrn,xkb)
 
435
    XkbConfigRtrnPtr    rtrn;
 
436
    XkbDescPtr          xkb;
 
437
#endif
 
438
{
 
439
register int            n,v;
 
440
Atom                    name;
 
441
XkbConfigUnboundModPtr  mod;
 
442
int                     missing;
 
443
 
 
444
    if (rtrn->num_unbound_mods<1)
 
445
        return 0;
 
446
    if ((xkb==NULL) || (xkb->names==NULL))
 
447
        return -1;
 
448
 
 
449
    missing= 0;
 
450
    for (n=0,mod=rtrn->unbound_mods;n<rtrn->num_unbound_mods;n++,mod++) {
 
451
        if (mod->name!=NULL) {
 
452
            name= XkbInternAtom(xkb->dpy,mod->name,True);
 
453
            if (name==None)
 
454
                continue;
 
455
            for (v=0;v<XkbNumVirtualMods;v++) {
 
456
                if (xkb->names->vmods[v]==name) {
 
457
                    mod->vmods= (1<<v);
 
458
                    _XkbFree(mod->name);
 
459
                    mod->name= NULL;
 
460
                    break;
 
461
                }
 
462
            }
 
463
            if (mod->name!=NULL)
 
464
                missing++;
 
465
        }
 
466
    }
 
467
    return missing;
 
468
}
 
469
 
 
470
Bool
 
471
#if NeedFunctionPrototypes
 
472
XkbCFApplyMods(XkbConfigRtrnPtr rtrn,int what,XkbConfigModInfoPtr info)
 
473
#else
 
474
XkbCFApplyMods(rtrn,what,info)
 
475
    XkbConfigRtrnPtr    rtrn;
 
476
    int                 what;
 
477
    XkbConfigModInfoPtr info;
 
478
#endif
 
479
{
 
480
register int            n;
 
481
XkbConfigUnboundModPtr  mod;
 
482
 
 
483
    if (rtrn->num_unbound_mods<1)
 
484
        return True;
 
485
 
 
486
    for (n=0,mod=rtrn->unbound_mods;n<rtrn->num_unbound_mods;n++,mod++) {
 
487
        if (mod->what!=what)
 
488
            continue;
 
489
        if (mod->merge==XkbCF_MergeRemove) {
 
490
            info->mods_clear|= mod->mods;
 
491
            info->vmods_clear|= mod->vmods;
 
492
        }
 
493
        else {
 
494
            if (mod->merge==XkbCF_MergeSet)
 
495
                info->replace= True;
 
496
            info->mods|= mod->mods;
 
497
            info->vmods|= mod->vmods;
 
498
        }
 
499
        if (mod->name==NULL) {
 
500
            mod->what= _XkbCF_Illegal;
 
501
        }
 
502
        else {
 
503
            mod->mods= 0;
 
504
            mod->vmods= 0;
 
505
        }
 
506
    }
 
507
    return True;
 
508
}
 
509
 
 
510
/*ARGSUSED*/
 
511
static Bool
 
512
#if NeedFunctionPrototypes
 
513
DefaultParser(  FILE *                  file,
 
514
                XkbConfigFieldsPtr      fields,
 
515
                XkbConfigFieldPtr       field,
 
516
                XkbDescPtr              xkb,
 
517
                XkbConfigRtrnPtr        rtrn)
 
518
#else
 
519
DefaultParser(file,fields,field,xkb,rtrn)
 
520
    FILE *              file;
 
521
    XkbConfigFieldsPtr  fields;
 
522
    XkbConfigFieldPtr   field;
 
523
    XkbDescPtr          xkb;
 
524
    XkbConfigRtrnPtr    rtrn;
 
525
#endif
 
526
{
 
527
int                     tok;
 
528
XkbCFScanResultRec      val;
 
529
char **                 str;
 
530
int                     merge;
 
531
unsigned long *         ctrls, ctrls_mask;
 
532
unsigned short *        opts, opts_mask;
 
533
int *                   pival, sign;
 
534
int                     onoff;
 
535
XkbConfigUnboundModPtr  last;
 
536
unsigned                what;
 
537
 
 
538
    tok= XkbCFScan(file,&val,rtrn);
 
539
    str= NULL;
 
540
    onoff= 0;
 
541
    pival= NULL;
 
542
    switch (field->field_id) {
 
543
        case _XkbCF_RulesFile:  if (!str)       str= &rtrn->rules_file;
 
544
        case _XkbCF_Model:      if (!str)       str= &rtrn->model;
 
545
        case _XkbCF_Layout:     if (!str)       str= &rtrn->layout;
 
546
        case _XkbCF_Variant:    if (!str)       str= &rtrn->variant;
 
547
        case _XkbCF_Options:    if (!str)       str= &rtrn->options;
 
548
        case _XkbCF_Keymap:     if (!str)       str= &rtrn->keymap;
 
549
        case _XkbCF_Keycodes:   if (!str)       str= &rtrn->keycodes;
 
550
        case _XkbCF_Geometry:   if (!str)       str= &rtrn->geometry;
 
551
        case _XkbCF_PhysSymbols:if (!str)       str= &rtrn->phys_symbols;
 
552
        case _XkbCF_Symbols:    if (!str)       str= &rtrn->symbols;
 
553
        case _XkbCF_Types:      if (!str)       str= &rtrn->types;
 
554
        case _XkbCF_CompatMap:  if (!str)       str= &rtrn->compat;
 
555
            if (tok!=XkbCF_Equals) {
 
556
                rtrn->error= XkbCF_MissingEquals;
 
557
                goto BAILOUT;
 
558
            }
 
559
            tok= XkbCFScan(file,&val,rtrn);
 
560
            if ((tok!=XkbCF_String)&&(tok!=XkbCF_Ident)) {
 
561
                rtrn->error= XkbCF_ExpectedString;
 
562
                return False;
 
563
            }
 
564
            tok= XkbCFScan(file,&val,rtrn);
 
565
            if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
 
566
                rtrn->error= XkbCF_ExpectedEOS;
 
567
                return False;
 
568
            }
 
569
            if (*str!=NULL)
 
570
                _XkbFree(*str);
 
571
            *str= _XkbDupString(val.str);
 
572
            break;
 
573
        case _XkbCF_InitialMods:
 
574
        case _XkbCF_IgnoreLockMods:
 
575
        case _XkbCF_InternalMods:
 
576
            what= XkbCF_InitialMods;
 
577
            if (field->field_id==_XkbCF_InitialMods)
 
578
                rtrn->defined|= (what=XkbCF_InitialMods);
 
579
            else if (field->field_id==_XkbCF_InternalMods)
 
580
                rtrn->defined|= (what=XkbCF_InternalMods);
 
581
            else if (field->field_id==_XkbCF_IgnoreLockMods)
 
582
                rtrn->defined|= (what=XkbCF_IgnoreLockMods);
 
583
            if (tok==XkbCF_Equals)              merge= XkbCF_MergeSet;
 
584
            else if (tok==XkbCF_MinusEquals)    merge= XkbCF_MergeRemove;
 
585
            else if (tok==XkbCF_PlusEquals)     merge= XkbCF_MergeAdd;
 
586
            else {
 
587
                rtrn->error= XkbCF_MissingEquals;
 
588
                goto BAILOUT;
 
589
            }
 
590
            tok= XkbCFScan(file,&val,rtrn);
 
591
            if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
 
592
                rtrn->error= XkbCF_ExpectedModifier;
 
593
                return False;
 
594
            }
 
595
            last= NULL;
 
596
            while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
 
597
                if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
 
598
                    rtrn->error= XkbCF_ExpectedModifier;
 
599
                    return False;
 
600
                }
 
601
                last=XkbCFAddModByName(rtrn,what,val.str,merge,last);
 
602
                if (last==NULL)
 
603
                    return False;
 
604
                if (merge==XkbCF_MergeSet)
 
605
                    merge= XkbCF_MergeAdd;
 
606
                tok= XkbCFScan(file,&val,rtrn);
 
607
                if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
 
608
                    if (tok!=XkbCF_Plus) {
 
609
                        rtrn->error= XkbCF_ExpectedOperator;
 
610
                        return False;
 
611
                    }
 
612
                    tok= XkbCFScan(file,&val,rtrn);
 
613
                }
 
614
            }
 
615
            break;
 
616
        case _XkbCF_InitialCtrls:
 
617
            rtrn->defined|= XkbCF_InitialCtrls;
 
618
            ctrls= NULL;
 
619
            if (tok==XkbCF_PlusEquals)
 
620
                ctrls= &rtrn->initial_ctrls;
 
621
            else if (tok==XkbCF_MinusEquals)
 
622
                ctrls= &rtrn->initial_ctrls_clear;
 
623
            else if (tok==XkbCF_Equals) {
 
624
                ctrls= &rtrn->initial_ctrls;
 
625
                rtrn->replace_initial_ctrls= True;
 
626
                *ctrls= 0;
 
627
            }
 
628
            else {
 
629
                rtrn->error= XkbCF_MissingEquals;
 
630
                goto BAILOUT;
 
631
            }
 
632
            tok= XkbCFScan(file,&val,rtrn);
 
633
            if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
 
634
                rtrn->error= XkbCF_ExpectedControl;
 
635
                return False;
 
636
            }
 
637
            while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
 
638
                if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
 
639
                    rtrn->error= XkbCF_ExpectedControl;
 
640
                    return False;
 
641
                }
 
642
                if (!AddCtrlByName(rtrn,val.str,&ctrls_mask)) {
 
643
                    return False;
 
644
                }
 
645
                *ctrls |= ctrls_mask;
 
646
                tok= XkbCFScan(file,&val,rtrn);
 
647
                if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
 
648
                    if (tok!=XkbCF_Plus) {
 
649
                        rtrn->error= XkbCF_ExpectedOperator;
 
650
                        return False;
 
651
                    }
 
652
                    tok= XkbCFScan(file,&val,rtrn);
 
653
                }
 
654
            }
 
655
            break;
 
656
        case _XkbCF_AccessXTimeoutCtrlsOn:
 
657
        case _XkbCF_AccessXTimeoutCtrlsOff:
 
658
            opts= NULL;
 
659
            if (tok==XkbCF_MinusEquals) {
 
660
                ctrls= &rtrn->axt_ctrls_ignore;
 
661
                opts= &rtrn->axt_opts_ignore;
 
662
            }
 
663
            else if ((tok==XkbCF_PlusEquals)||(tok==XkbCF_Equals)) {
 
664
                if (field->field_id==_XkbCF_AccessXTimeoutCtrlsOff) {
 
665
                    ctrls= &rtrn->axt_ctrls_off;
 
666
                    opts= &rtrn->axt_opts_off;
 
667
                    if (tok==XkbCF_Equals)
 
668
                        rtrn->replace_axt_ctrls_off= True;
 
669
                }
 
670
                else {
 
671
                    ctrls= &rtrn->axt_ctrls_on;
 
672
                    opts= &rtrn->axt_opts_on;
 
673
                    if (tok==XkbCF_Equals)
 
674
                        rtrn->replace_axt_ctrls_on= True;
 
675
                }
 
676
                *ctrls= 0;
 
677
            }
 
678
            else {
 
679
                rtrn->error= XkbCF_MissingEquals;
 
680
                goto BAILOUT;
 
681
            }
 
682
            tok= XkbCFScan(file,&val,rtrn);
 
683
            if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
 
684
                rtrn->error= XkbCF_ExpectedControl;
 
685
                return False;
 
686
            }
 
687
            while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
 
688
                if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
 
689
                    rtrn->error= XkbCF_ExpectedControl;
 
690
                    return False;
 
691
                }
 
692
                if (!AddCtrlByName(rtrn,val.str,&ctrls_mask)) {
 
693
                    if (!AddAXTimeoutOptByName(rtrn,val.str,&opts_mask))
 
694
                        return False;
 
695
                    *opts |= opts_mask;
 
696
                    if (field->field_id==_XkbCF_AccessXTimeoutCtrlsOff) {
 
697
                        rtrn->defined|= XkbCF_AccessXTimeoutOptsOff;
 
698
                        if (rtrn->replace_axt_ctrls_off)
 
699
                            rtrn->replace_axt_opts_off= True;
 
700
                    }
 
701
                    else {
 
702
                        rtrn->defined|= XkbCF_AccessXTimeoutOptsOn;
 
703
                        if (rtrn->replace_axt_ctrls_on)
 
704
                            rtrn->replace_axt_opts_on= True;
 
705
                    }
 
706
                }
 
707
                else
 
708
                    *ctrls |= ctrls_mask;
 
709
                tok= XkbCFScan(file,&val,rtrn);
 
710
                if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
 
711
                    if (tok!=XkbCF_Plus) {
 
712
                        rtrn->error= XkbCF_ExpectedOperator;
 
713
                        return False;
 
714
                    }
 
715
                    tok= XkbCFScan(file,&val,rtrn);
 
716
                }
 
717
            }
 
718
            break;
 
719
        case _XkbCF_InitialFeedback:
 
720
            rtrn->defined|= XkbCF_InitialOpts;
 
721
            opts= NULL;
 
722
            if (tok==XkbCF_PlusEquals)
 
723
                opts= &rtrn->initial_opts;
 
724
            else if (tok==XkbCF_MinusEquals)
 
725
                opts= &rtrn->initial_opts_clear;
 
726
            else if (tok==XkbCF_Equals) {
 
727
                opts= &rtrn->initial_opts;
 
728
                rtrn->replace_initial_opts= True;
 
729
                *opts= 0;
 
730
            }
 
731
            else {
 
732
                rtrn->error= XkbCF_MissingEquals;
 
733
                goto BAILOUT;
 
734
            }
 
735
            tok= XkbCFScan(file,&val,rtrn);
 
736
            if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
 
737
                rtrn->error= XkbCF_ExpectedAXOption;
 
738
                return False;
 
739
            }
 
740
            while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
 
741
                if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
 
742
                    rtrn->error= XkbCF_ExpectedAXOption;
 
743
                    return False;
 
744
                }
 
745
                if (!AddAXTimeoutOptByName(rtrn,val.str,&opts_mask)) {
 
746
                    return False;
 
747
                }
 
748
                *opts |= opts_mask;
 
749
                tok= XkbCFScan(file,&val,rtrn);
 
750
                if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
 
751
                    if (tok!=XkbCF_Plus) {
 
752
                        rtrn->error= XkbCF_ExpectedOperator;
 
753
                        return False;
 
754
                    }
 
755
                    tok= XkbCFScan(file,&val,rtrn);
 
756
                }
 
757
            }
 
758
            break;
 
759
        case _XkbCF_AccessXTimeoutOptsOff:
 
760
        case _XkbCF_AccessXTimeoutOptsOn:
 
761
            opts= NULL;
 
762
            if (tok==XkbCF_MinusEquals)
 
763
                opts= &rtrn->axt_opts_ignore;
 
764
            else if ((tok==XkbCF_PlusEquals)||(tok==XkbCF_Equals)) {
 
765
                if (field->field_id==_XkbCF_AccessXTimeoutOptsOff) {
 
766
                    opts= &rtrn->axt_opts_off;
 
767
                    if (tok==XkbCF_Equals)
 
768
                        rtrn->replace_axt_opts_off= True;
 
769
                }
 
770
                else {
 
771
                    opts= &rtrn->axt_opts_on;
 
772
                    if (tok==XkbCF_Equals)
 
773
                        rtrn->replace_axt_opts_on= True;
 
774
                }
 
775
                *opts = 0;
 
776
            }
 
777
            else {
 
778
                rtrn->error= XkbCF_MissingEquals;
 
779
                goto BAILOUT;
 
780
            }
 
781
            tok= XkbCFScan(file,&val,rtrn);
 
782
            if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
 
783
                rtrn->error= XkbCF_ExpectedControl;
 
784
                return False;
 
785
            }
 
786
            while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
 
787
                if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
 
788
                    rtrn->error= XkbCF_ExpectedControl;
 
789
                    return False;
 
790
                }
 
791
                if (!AddAXTimeoutOptByName(rtrn,val.str,&opts_mask))
 
792
                    return False;
 
793
                *opts |= opts_mask;
 
794
 
 
795
                tok= XkbCFScan(file,&val,rtrn);
 
796
                if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
 
797
                    if (tok!=XkbCF_Plus) {
 
798
                        rtrn->error= XkbCF_ExpectedOperator;
 
799
                        return False;
 
800
                    }
 
801
                    tok= XkbCFScan(file,&val,rtrn);
 
802
                }
 
803
            }
 
804
            break;
 
805
        case _XkbCF_ClickVolume:        
 
806
            if (!pival) {
 
807
                pival= &rtrn->click_volume;
 
808
                onoff= 100;
 
809
            }
 
810
        case _XkbCF_BellVolume:
 
811
            if (!pival) {
 
812
                pival= &rtrn->bell_volume;
 
813
                onoff= 100;
 
814
            }
 
815
        case _XkbCF_BellPitch:
 
816
            if (!pival)
 
817
                pival= &rtrn->bell_pitch;
 
818
        case _XkbCF_BellDuration:
 
819
            if (!pival)
 
820
                pival= &rtrn->bell_duration;
 
821
        case _XkbCF_RepeatDelay:
 
822
            if (!pival)
 
823
                pival= &rtrn->repeat_delay;
 
824
        case _XkbCF_RepeatInterval:
 
825
            if (!pival) 
 
826
                pival= &rtrn->repeat_interval;
 
827
        case _XkbCF_SlowKeysDelay:
 
828
            if (!pival) 
 
829
                pival= &rtrn->slow_keys_delay;
 
830
        case _XkbCF_DebounceDelay:
 
831
            if (!pival) 
 
832
                pival= &rtrn->debounce_delay;
 
833
        case _XkbCF_MouseKeysDelay:
 
834
            if (!pival) 
 
835
                pival= &rtrn->mk_delay;
 
836
        case _XkbCF_MouseKeysInterval:
 
837
            if (!pival) 
 
838
                pival= &rtrn->mk_interval;
 
839
        case _XkbCF_MouseKeysTimeToMax:
 
840
            if (!pival) 
 
841
                pival= &rtrn->mk_time_to_max;
 
842
        case _XkbCF_MouseKeysMaxSpeed:
 
843
            if (!pival) 
 
844
                pival= &rtrn->mk_max_speed;
 
845
        case _XkbCF_MouseKeysCurve:
 
846
            if (!pival) 
 
847
                pival= &rtrn->mk_curve;
 
848
        case _XkbCF_AccessXTimeout:
 
849
            if (!pival) 
 
850
                pival= &rtrn->ax_timeout;
 
851
            if (tok!=XkbCF_Equals) {
 
852
                rtrn->error= XkbCF_MissingEquals;
 
853
                goto BAILOUT;
 
854
            }
 
855
            tok= XkbCFScan(file,&val,rtrn);
 
856
            if (tok == XkbCF_Minus && field->field_id == _XkbCF_MouseKeysCurve) {
 
857
                /* This can be a negative value */
 
858
                tok = XkbCFScan(file,&val,rtrn);
 
859
                sign = -1;
 
860
            }
 
861
            else
 
862
                sign = 1;
 
863
            if (tok!=XkbCF_Integer) {
 
864
                Bool ok= False;
 
865
                if ((onoff)&&(tok==XkbCF_Ident)&&(val.str!=NULL)) {
 
866
                    if (_XkbStrCaseCmp(val.str,"on")) {
 
867
                        val.ival= onoff;
 
868
                        ok= True;
 
869
                    }
 
870
                    else if (_XkbStrCaseCmp(val.str,"off")) {
 
871
                        val.ival= 0;
 
872
                        ok= True;
 
873
                    }
 
874
                }
 
875
                if (!ok) {
 
876
                    rtrn->error= XkbCF_ExpectedInteger;
 
877
                    goto BAILOUT;
 
878
                }
 
879
            }
 
880
            *pival= val.ival * sign;
 
881
            if (field->field_id == _XkbCF_AccessXTimeout)
 
882
                rtrn->defined|=XkbCF_AccessXTimeout;
 
883
            tok= XkbCFScan(file,&val,rtrn);
 
884
            if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
 
885
                rtrn->error= XkbCF_ExpectedEOS;
 
886
                return False;
 
887
            }
 
888
            break;
 
889
        case _XkbCF_GroupsWrap:
 
890
            if (tok!=XkbCF_Equals) {
 
891
                rtrn->error= XkbCF_MissingEquals;
 
892
                goto BAILOUT;
 
893
            }
 
894
            tok= XkbCFScan(file,&val,rtrn);
 
895
            if (tok==XkbCF_Ident) {
 
896
                if (_XkbStrCaseCmp(val.str,"wrap")==0) {
 
897
                    rtrn->groups_wrap= XkbSetGroupInfo(0,XkbWrapIntoRange,0);
 
898
                }
 
899
                else if (_XkbStrCaseCmp(val.str,"clamp")==0) {
 
900
                    rtrn->groups_wrap= XkbSetGroupInfo(0,XkbClampIntoRange,0);
 
901
                }
 
902
                else {
 
903
                    rtrn->error= XkbCF_ExpectedOORGroupBehavior;
 
904
                    return False;
 
905
                }
 
906
            }
 
907
            else if ((tok==XkbCF_Integer)&&(XkbIsLegalGroup(val.ival-1))) {
 
908
                rtrn->groups_wrap= XkbSetGroupInfo(0,XkbRedirectIntoRange,
 
909
                                                                val.ival-1);
 
910
            }
 
911
            else {
 
912
                rtrn->error= XkbCF_ExpectedOORGroupBehavior;
 
913
                return False;
 
914
            }
 
915
            rtrn->defined|= XkbCF_GroupsWrap;
 
916
            tok= XkbCFScan(file,&val,rtrn);
 
917
            if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
 
918
                rtrn->error= XkbCF_ExpectedEOS;
 
919
                return False;
 
920
            }
 
921
            break;
 
922
        default:
 
923
            rtrn->error= XkbCF_ExpectedInteger;
 
924
            goto BAILOUT;
 
925
            
 
926
    }
 
927
    return True;
 
928
BAILOUT:
 
929
    return False;
 
930
}
 
931
 
 
932
static Bool
 
933
#if NeedFunctionPrototypes
 
934
DefaultCleanUp(XkbConfigRtrnPtr rtrn)
 
935
#else
 
936
DefaultCleanUp(rtrn)
 
937
    XkbConfigRtrnPtr    rtrn;
 
938
#endif
 
939
{
 
940
    if (rtrn->keymap)   _XkbFree(rtrn->keymap);
 
941
    if (rtrn->keycodes) _XkbFree(rtrn->keycodes);
 
942
    if (rtrn->geometry) _XkbFree(rtrn->geometry);
 
943
    if (rtrn->phys_symbols)     _XkbFree(rtrn->phys_symbols);
 
944
    if (rtrn->symbols)  _XkbFree(rtrn->symbols);
 
945
    if (rtrn->types)    _XkbFree(rtrn->types);
 
946
    if (rtrn->compat)   _XkbFree(rtrn->compat);
 
947
    rtrn->keycodes= rtrn->geometry= NULL;
 
948
    rtrn->symbols= rtrn->phys_symbols= NULL;
 
949
    rtrn->types= rtrn->compat= NULL;
 
950
    if ((rtrn->unbound_mods!=NULL)&&(rtrn->num_unbound_mods>0)) {
 
951
        register int i;
 
952
        for (i=0;i<rtrn->num_unbound_mods;i++) {
 
953
            if (rtrn->unbound_mods[i].name!=NULL) {
 
954
                _XkbFree(rtrn->unbound_mods[i].name);
 
955
                rtrn->unbound_mods[i].name= NULL;
 
956
            }
 
957
        }
 
958
        _XkbFree(rtrn->unbound_mods);
 
959
        rtrn->sz_unbound_mods= 0;
 
960
        rtrn->num_unbound_mods= 0;
 
961
        rtrn->unbound_mods= NULL;
 
962
    }
 
963
    return True;
 
964
}
 
965
 
 
966
static Bool
 
967
#if NeedFunctionPrototypes
 
968
DefaultApplyNames(XkbConfigRtrnPtr rtrn,XkbDescPtr xkb)
 
969
#else
 
970
DefaultApplyNames(rtrn,xkb)
 
971
    XkbConfigRtrnPtr    rtrn;
 
972
    XkbDescPtr          xkb;
 
973
#endif
 
974
{
 
975
char *str;
 
976
 
 
977
    if (XkbAllocNames(xkb,XkbComponentNamesMask,0,0)!=Success)
 
978
        return False;
 
979
    if ((str=rtrn->keycodes)!=NULL) {
 
980
        xkb->names->keycodes= XkbInternAtom(xkb->dpy,str,False);
 
981
        _XkbFree(str);
 
982
        rtrn->keycodes= NULL;
 
983
    }
 
984
    if ((str=rtrn->geometry)!=NULL) {
 
985
        xkb->names->geometry= XkbInternAtom(xkb->dpy,str,False);
 
986
        _XkbFree(str);
 
987
        rtrn->geometry= NULL;
 
988
    }
 
989
    if ((str=rtrn->symbols)!=NULL) {
 
990
        xkb->names->symbols= XkbInternAtom(xkb->dpy,str,False);
 
991
        _XkbFree(str);
 
992
        rtrn->symbols= NULL;
 
993
    }
 
994
    if ((str=rtrn->phys_symbols)!=NULL) {
 
995
        xkb->names->phys_symbols= XkbInternAtom(xkb->dpy,str,False);
 
996
        _XkbFree(str);
 
997
        rtrn->phys_symbols= NULL;
 
998
    }
 
999
    if ((str=rtrn->types)!=NULL) {
 
1000
        xkb->names->types= XkbInternAtom(xkb->dpy,str,False);
 
1001
        _XkbFree(str);
 
1002
        rtrn->types= NULL;
 
1003
    }
 
1004
    if ((str=rtrn->compat)!=NULL) {
 
1005
        xkb->names->compat= XkbInternAtom(xkb->dpy,str,False);
 
1006
        _XkbFree(str);
 
1007
        rtrn->compat= NULL;
 
1008
    }
 
1009
    return True;
 
1010
}
 
1011
 
 
1012
static Bool
 
1013
#if NeedFunctionPrototypes
 
1014
DefaultApplyControls(XkbConfigRtrnPtr rtrn,XkbDescPtr xkb)
 
1015
#else
 
1016
DefaultApplyControls(rtrn,xkb)
 
1017
    XkbConfigRtrnPtr    rtrn;
 
1018
    XkbDescPtr          xkb;
 
1019
#endif
 
1020
{
 
1021
unsigned        on,off;
 
1022
XkbControlsPtr  ctrls;
 
1023
unsigned int    mask;
 
1024
 
 
1025
    if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success)
 
1026
        return False;
 
1027
    ctrls= xkb->ctrls;
 
1028
    if (rtrn->replace_initial_ctrls)
 
1029
         ctrls->enabled_ctrls=  rtrn->initial_ctrls;
 
1030
    else ctrls->enabled_ctrls|= rtrn->initial_ctrls;
 
1031
    ctrls->enabled_ctrls&= ~rtrn->initial_ctrls_clear;
 
1032
    if (rtrn->internal_mods.replace) {
 
1033
        ctrls->internal.real_mods= rtrn->internal_mods.mods;
 
1034
        ctrls->internal.vmods= rtrn->internal_mods.vmods;
 
1035
    }
 
1036
    else {
 
1037
        ctrls->internal.real_mods&= ~rtrn->internal_mods.mods_clear;
 
1038
        ctrls->internal.vmods&= ~rtrn->internal_mods.vmods_clear;
 
1039
        ctrls->internal.real_mods|= rtrn->internal_mods.mods;
 
1040
        ctrls->internal.vmods|= rtrn->internal_mods.vmods;
 
1041
    }
 
1042
    mask= 0;
 
1043
    (void)XkbVirtualModsToReal(xkb,ctrls->internal.vmods,&mask);
 
1044
    ctrls->internal.mask= (ctrls->internal.real_mods|mask);
 
1045
 
 
1046
    if (rtrn->ignore_lock_mods.replace) {
 
1047
        ctrls->ignore_lock.real_mods= rtrn->ignore_lock_mods.mods;
 
1048
        ctrls->ignore_lock.vmods= rtrn->ignore_lock_mods.vmods;
 
1049
    }
 
1050
    else {
 
1051
        ctrls->ignore_lock.real_mods&= ~rtrn->ignore_lock_mods.mods_clear;
 
1052
        ctrls->ignore_lock.vmods&= ~rtrn->ignore_lock_mods.vmods_clear;
 
1053
        ctrls->ignore_lock.real_mods|= rtrn->ignore_lock_mods.mods;
 
1054
        ctrls->ignore_lock.vmods|= rtrn->ignore_lock_mods.vmods;
 
1055
    }
 
1056
    mask= 0;
 
1057
    (void)XkbVirtualModsToReal(xkb,ctrls->ignore_lock.vmods,&mask);
 
1058
    ctrls->ignore_lock.mask= (ctrls->ignore_lock.real_mods|mask);
 
1059
 
 
1060
    if (rtrn->repeat_delay>0)
 
1061
        ctrls->repeat_delay= rtrn->repeat_delay;
 
1062
    if (rtrn->repeat_interval>0)
 
1063
        ctrls->repeat_interval= rtrn->repeat_interval;
 
1064
    if (rtrn->slow_keys_delay>0)
 
1065
        ctrls->slow_keys_delay= rtrn->slow_keys_delay;
 
1066
    if (rtrn->debounce_delay>0)
 
1067
        ctrls->debounce_delay= rtrn->debounce_delay;
 
1068
    if (rtrn->mk_delay>0)
 
1069
        ctrls->mk_delay= rtrn->mk_delay;
 
1070
    if (rtrn->mk_interval>0)
 
1071
        ctrls->mk_interval= rtrn->mk_interval;
 
1072
    if (rtrn->mk_time_to_max>0)
 
1073
        ctrls->mk_time_to_max= rtrn->mk_time_to_max;
 
1074
    if (rtrn->mk_max_speed>0)
 
1075
        ctrls->mk_max_speed= rtrn->mk_max_speed;
 
1076
    if (rtrn->mk_curve>0)
 
1077
        ctrls->mk_curve= rtrn->mk_curve;
 
1078
    if (rtrn->defined&XkbCF_AccessXTimeout && rtrn->ax_timeout > 0)
 
1079
        ctrls->ax_timeout= rtrn->ax_timeout;
 
1080
 
 
1081
    /* any value set to both off and on is reset to ignore */
 
1082
    if ((off=(rtrn->axt_ctrls_on&rtrn->axt_ctrls_off))!=0)
 
1083
        rtrn->axt_ctrls_ignore|= off;
 
1084
 
 
1085
    /* ignore takes priority over on and off */
 
1086
    rtrn->axt_ctrls_on&= ~rtrn->axt_ctrls_ignore;
 
1087
    rtrn->axt_ctrls_off&= ~rtrn->axt_ctrls_ignore;
 
1088
 
 
1089
    if (!rtrn->replace_axt_ctrls_off) {
 
1090
         off= (ctrls->axt_ctrls_mask&(~ctrls->axt_ctrls_values));
 
1091
         off&= ~rtrn->axt_ctrls_on;
 
1092
         off|= rtrn->axt_ctrls_off;
 
1093
    }
 
1094
    else off= rtrn->axt_ctrls_off;
 
1095
    if (!rtrn->replace_axt_ctrls_on) {
 
1096
         on= (ctrls->axt_ctrls_mask&ctrls->axt_ctrls_values);
 
1097
         on&= ~rtrn->axt_ctrls_off;
 
1098
         on|= rtrn->axt_ctrls_on;
 
1099
    }
 
1100
    else on= rtrn->axt_ctrls_on;
 
1101
    ctrls->axt_ctrls_mask= (on|off)&~rtrn->axt_ctrls_ignore;
 
1102
    ctrls->axt_ctrls_values= on&~rtrn->axt_ctrls_ignore;
 
1103
 
 
1104
    /* any value set to both off and on is reset to ignore */
 
1105
    if ((off=(rtrn->axt_opts_on&rtrn->axt_opts_off))!=0)
 
1106
        rtrn->axt_opts_ignore|= off;
 
1107
 
 
1108
    /* ignore takes priority over on and off */
 
1109
    rtrn->axt_opts_on&= ~rtrn->axt_opts_ignore;
 
1110
    rtrn->axt_opts_off&= ~rtrn->axt_opts_ignore;
 
1111
 
 
1112
    if (rtrn->replace_axt_opts_off) {
 
1113
         off= (ctrls->axt_opts_mask&(~ctrls->axt_opts_values));
 
1114
         off&= ~rtrn->axt_opts_on;
 
1115
         off|= rtrn->axt_opts_off;
 
1116
    }
 
1117
    else off= rtrn->axt_opts_off;
 
1118
    if (!rtrn->replace_axt_opts_on) {
 
1119
         on= (ctrls->axt_opts_mask&ctrls->axt_opts_values);
 
1120
         on&= ~rtrn->axt_opts_off;
 
1121
         on|= rtrn->axt_opts_on;
 
1122
    }
 
1123
    else on= rtrn->axt_opts_on;
 
1124
    ctrls->axt_opts_mask= (unsigned short)((on|off)&~rtrn->axt_ctrls_ignore);
 
1125
    ctrls->axt_opts_values= (unsigned short)(on&~rtrn->axt_ctrls_ignore);
 
1126
 
 
1127
    if (rtrn->defined&XkbCF_GroupsWrap) {
 
1128
        int n;
 
1129
        n= XkbNumGroups(ctrls->groups_wrap);
 
1130
        rtrn->groups_wrap= XkbSetNumGroups(rtrn->groups_wrap,n);
 
1131
        ctrls->groups_wrap= rtrn->groups_wrap;
 
1132
    }
 
1133
    return True;
 
1134
}
 
1135
 
 
1136
/*ARGSUSED*/
 
1137
static Bool
 
1138
#if NeedFunctionPrototypes
 
1139
DefaultFinish(  XkbConfigFieldsPtr      fields,
 
1140
                XkbDescPtr              xkb,
 
1141
                XkbConfigRtrnPtr        rtrn,
 
1142
                int                     what)
 
1143
#else
 
1144
DefaultFinish(fields,xkb,rtrn,what)
 
1145
    XkbConfigFieldsPtr  fields;
 
1146
    XkbDescPtr          xkb;
 
1147
    XkbConfigRtrnPtr    rtrn;
 
1148
    int                 what;
 
1149
#endif
 
1150
{
 
1151
    if ((what==XkbCF_Destroy)||(what==XkbCF_CleanUp))
 
1152
        return DefaultCleanUp(rtrn);
 
1153
    if (what==XkbCF_Check) {
 
1154
        if ((rtrn->symbols==NULL)&&(rtrn->phys_symbols!=NULL))
 
1155
            rtrn->symbols= _XkbDupString(rtrn->phys_symbols);
 
1156
    }
 
1157
    if ((what==XkbCF_Apply)||(what==XkbCF_Check)) {
 
1158
        if (xkb && xkb->names && (rtrn->num_unbound_mods>0))
 
1159
            XkbCFBindMods(rtrn,xkb);
 
1160
        XkbCFApplyMods(rtrn,XkbCF_InitialMods,&rtrn->initial_mods);
 
1161
        XkbCFApplyMods(rtrn,XkbCF_InternalMods,&rtrn->internal_mods);
 
1162
        XkbCFApplyMods(rtrn,XkbCF_IgnoreLockMods,&rtrn->ignore_lock_mods);
 
1163
    }
 
1164
    if (what==XkbCF_Apply) {
 
1165
        if (xkb!=NULL) {
 
1166
            DefaultApplyNames(rtrn,xkb);
 
1167
            DefaultApplyControls(rtrn,xkb);
 
1168
            XkbCFBindMods(rtrn,xkb);
 
1169
        }
 
1170
    }
 
1171
    return True;
 
1172
}
 
1173
 
 
1174
static XkbConfigFieldRec _XkbCFDfltFields[] = {
 
1175
        { "rules",      _XkbCF_RulesFile },
 
1176
        { "model",      _XkbCF_Model },
 
1177
        { "layout",     _XkbCF_Layout },
 
1178
        { "variant",    _XkbCF_Variant },
 
1179
        { "options",    _XkbCF_Options },
 
1180
        { "keymap",     _XkbCF_Keymap },
 
1181
        { "keycodes",   _XkbCF_Keycodes },
 
1182
        { "geometry",   _XkbCF_Geometry },
 
1183
        { "realsymbols",_XkbCF_PhysSymbols },
 
1184
        { "actualsymbols",_XkbCF_PhysSymbols },
 
1185
        { "symbols",    _XkbCF_Symbols },
 
1186
        { "symbolstouse",_XkbCF_Symbols },
 
1187
        { "types",      _XkbCF_Types },
 
1188
        { "compat",     _XkbCF_CompatMap },
 
1189
        { "modifiers",  _XkbCF_InitialMods },
 
1190
        { "controls",   _XkbCF_InitialCtrls },
 
1191
        { "click",      _XkbCF_ClickVolume },
 
1192
        { "clickvolume",_XkbCF_ClickVolume },
 
1193
        { "bell",       _XkbCF_BellVolume },
 
1194
        { "bellvolume", _XkbCF_BellVolume },
 
1195
        { "bellpitch",  _XkbCF_BellPitch },
 
1196
        { "bellduration",_XkbCF_BellDuration },
 
1197
        { "repeatdelay",_XkbCF_RepeatDelay },
 
1198
        { "repeatinterval",_XkbCF_RepeatInterval },
 
1199
        { "slowkeysdelay",_XkbCF_SlowKeysDelay  },
 
1200
        { "debouncedelay",_XkbCF_DebounceDelay },
 
1201
        { "mousekeysdelay",_XkbCF_MouseKeysDelay },
 
1202
        { "mousekeysinterval",_XkbCF_MouseKeysInterval },
 
1203
        { "mousekeystimetomax",_XkbCF_MouseKeysTimeToMax },
 
1204
        { "mousekeysmaxspeed",_XkbCF_MouseKeysMaxSpeed },
 
1205
        { "mousekeyscurve",_XkbCF_MouseKeysCurve },
 
1206
        { "accessxtimeout",_XkbCF_AccessXTimeout },
 
1207
        { "axtimeout",_XkbCF_AccessXTimeout },
 
1208
        { "accessxtimeoutctrlson",_XkbCF_AccessXTimeoutCtrlsOn },
 
1209
        { "axtctrlson", _XkbCF_AccessXTimeoutCtrlsOn },
 
1210
        { "accessxtimeoutctrlsoff",_XkbCF_AccessXTimeoutCtrlsOff },
 
1211
        { "axtctrlsoff",_XkbCF_AccessXTimeoutCtrlsOff },
 
1212
        { "accessxtimeoutfeedbackon", _XkbCF_AccessXTimeoutOptsOn },
 
1213
        { "axtfeedbackon", _XkbCF_AccessXTimeoutOptsOn },
 
1214
        { "accessxtimeoutfeedbackoff", _XkbCF_AccessXTimeoutOptsOff },
 
1215
        { "axtfeedbackoff", _XkbCF_AccessXTimeoutOptsOff },
 
1216
        { "ignorelockmods",_XkbCF_IgnoreLockMods },
 
1217
        { "ignorelockmodifiers",_XkbCF_IgnoreLockMods },
 
1218
        { "ignoregrouplock",_XkbCF_IgnoreGroupLock },
 
1219
        { "internalmods",_XkbCF_InternalMods },
 
1220
        { "internalmodifiers",_XkbCF_InternalMods },
 
1221
        { "outofrangegroups",_XkbCF_GroupsWrap },
 
1222
        { "groups", _XkbCF_GroupsWrap },
 
1223
        { "feedback", _XkbCF_InitialFeedback },
 
1224
};
 
1225
#define _XkbCFNumDfltFields (sizeof(_XkbCFDfltFields)/sizeof(XkbConfigFieldRec))
 
1226
 
 
1227
static XkbConfigFieldsRec _XkbCFDflts = {
 
1228
        0,                      /* cfg_id */
 
1229
        _XkbCFNumDfltFields,    /* num_fields */
 
1230
        _XkbCFDfltFields,       /* fields */
 
1231
        DefaultParser,  /* parser */
 
1232
        DefaultFinish,  /* finish */
 
1233
        NULL,                   /* priv */
 
1234
        NULL                    /* next */
 
1235
};
 
1236
 
 
1237
XkbConfigFieldsPtr      XkbCFDflts= &_XkbCFDflts;
 
1238
 
 
1239
/***====================================================================***/
 
1240
 
 
1241
XkbConfigFieldsPtr
 
1242
#if NeedFunctionPrototypes
 
1243
XkbCFDup(XkbConfigFieldsPtr fields)
 
1244
#else
 
1245
XkbCFDup(fields)
 
1246
    XkbConfigFieldsPtr  fields;
 
1247
#endif
 
1248
{
 
1249
XkbConfigFieldsPtr      pNew;
 
1250
 
 
1251
    pNew= _XkbTypedAlloc(XkbConfigFieldsRec);
 
1252
    if (pNew!=NULL) {
 
1253
        memcpy(pNew,fields,sizeof(XkbConfigFieldsRec));
 
1254
        if ((pNew->fields!=NULL)&&(pNew->num_fields>0)) {
 
1255
            pNew->fields= _XkbTypedCalloc(pNew->num_fields,XkbConfigFieldRec);
 
1256
            if (pNew->fields) {
 
1257
                memcpy(fields->fields,pNew->fields,
 
1258
                                (pNew->num_fields*sizeof(XkbConfigFieldRec)));
 
1259
            }
 
1260
            else {
 
1261
                _XkbFree(pNew);
 
1262
                return NULL;
 
1263
            }
 
1264
        }
 
1265
        else {
 
1266
            pNew->num_fields= 0;
 
1267
            pNew->fields= NULL;
 
1268
        }
 
1269
        pNew->next= NULL;
 
1270
    }
 
1271
    return pNew;
 
1272
}
 
1273
 
 
1274
XkbConfigFieldsPtr 
 
1275
#if NeedFunctionPrototypes
 
1276
XkbCFFree(XkbConfigFieldsPtr fields,Bool all)
 
1277
#else
 
1278
XkbCFFree(fields,all)
 
1279
    XkbConfigFieldsPtr  fields;
 
1280
    Bool                all;
 
1281
#endif
 
1282
{
 
1283
XkbConfigFieldsPtr      next;
 
1284
 
 
1285
    next= NULL;
 
1286
    while (fields!=NULL) {
 
1287
        next= fields->next;
 
1288
        if (fields!=XkbCFDflts) {
 
1289
            if (fields->fields) {
 
1290
                _XkbFree(fields->fields);
 
1291
                fields->fields= NULL;
 
1292
                fields->num_fields= 0;
 
1293
            }
 
1294
            _XkbFree(fields);
 
1295
        }
 
1296
        fields= (all?next:NULL);
 
1297
    }
 
1298
    return next;
 
1299
}
 
1300
 
 
1301
Bool
 
1302
#if NeedFunctionPrototypes
 
1303
XkbCFApplyRtrnValues(   XkbConfigRtrnPtr        rtrn,
 
1304
                        XkbConfigFieldsPtr      fields,
 
1305
                        XkbDescPtr              xkb)
 
1306
#else
 
1307
XkbCFApplyRtrnValues(rtrn,fields,xkb)
 
1308
    XkbConfigRtrnPtr    rtrn;
 
1309
    XkbConfigFieldsPtr  fields;
 
1310
    XkbDescPtr          xkb;
 
1311
#endif
 
1312
{
 
1313
Bool                    ok;
 
1314
 
 
1315
    if ((fields==NULL)||(rtrn==NULL)||(xkb==NULL))
 
1316
        return False;
 
1317
    for (ok=True;fields!=NULL;fields=fields->next) {
 
1318
        if (fields->finish!=NULL)
 
1319
            ok= (*fields->finish)(fields,xkb,rtrn,XkbCF_Apply)&&ok;
 
1320
    }
 
1321
    return ok;
 
1322
}
 
1323
 
 
1324
XkbConfigRtrnPrivPtr
 
1325
#if NeedFunctionPrototypes
 
1326
XkbCFAddPrivate(        XkbConfigRtrnPtr        rtrn,
 
1327
                        XkbConfigFieldsPtr      fields,
 
1328
                        XPointer                ptr)
 
1329
#else
 
1330
XkbCFAddPrivate(rtrn,fields,ptr)
 
1331
    XkbConfigRtrnPtr    rtrn;
 
1332
    XkbConfigFieldsPtr  fields;
 
1333
    XPointer            ptr;
 
1334
#endif
 
1335
{
 
1336
XkbConfigRtrnPrivPtr    priv;
 
1337
 
 
1338
    if ((rtrn==NULL)||(fields==NULL))
 
1339
        return NULL;
 
1340
    priv= _XkbTypedAlloc(XkbConfigRtrnPrivRec);
 
1341
    if (priv!=NULL) {
 
1342
        priv->cfg_id=   fields->cfg_id;
 
1343
        priv->priv=     ptr;
 
1344
        priv->next=     rtrn->priv;
 
1345
        rtrn->priv=     priv;
 
1346
    }
 
1347
    return priv;
 
1348
}
 
1349
 
 
1350
void
 
1351
#if NeedFunctionPrototypes
 
1352
XkbCFFreeRtrn(  XkbConfigRtrnPtr        rtrn,
 
1353
                XkbConfigFieldsPtr      fields,
 
1354
                XkbDescPtr              xkb)
 
1355
#else
 
1356
XkbCFFreeRtrn(rtrn,fields,xkb)
 
1357
    XkbConfigRtrnPtr    rtrn;
 
1358
    XkbConfigFieldsPtr  fields;
 
1359
    XkbDescPtr          xkb;
 
1360
#endif
 
1361
{
 
1362
XkbConfigRtrnPrivPtr    tmp,next;
 
1363
 
 
1364
    if ((fields==NULL)||(rtrn==NULL))
 
1365
        return;
 
1366
    while (fields!=NULL) {
 
1367
        if (fields->finish!=NULL)
 
1368
            (*fields->finish)(fields,xkb,rtrn,XkbCF_Destroy);
 
1369
        fields= fields->next;
 
1370
    }
 
1371
    for (tmp=rtrn->priv;tmp!=NULL;tmp=next) {
 
1372
        next= tmp->next;
 
1373
        bzero((char *)tmp,sizeof(XkbConfigRtrnPrivRec));
 
1374
        _XkbFree(tmp);
 
1375
    }
 
1376
    bzero((char *)rtrn,sizeof(XkbConfigRtrnRec));
 
1377
    return;
 
1378
}
 
1379
 
 
1380
Bool
 
1381
#if NeedFunctionPrototypes
 
1382
XkbCFParse(     FILE *                  file,
 
1383
                XkbConfigFieldsPtr      fields,
 
1384
                XkbDescPtr              xkb,
 
1385
                XkbConfigRtrnPtr        rtrn)
 
1386
#else
 
1387
XkbCFParse(file,fields,xkb,rtrn)
 
1388
    FILE *              file;
 
1389
    XkbConfigFieldsPtr  fields;
 
1390
    XkbDescPtr          xkb;
 
1391
    XkbConfigRtrnPtr    rtrn;
 
1392
#endif
 
1393
{
 
1394
int                     tok;
 
1395
XkbCFScanResultRec      val;
 
1396
XkbConfigFieldsPtr      tmp;
 
1397
 
 
1398
    if ((file==NULL)||(fields==NULL)||(rtrn==NULL))
 
1399
        return False;
 
1400
    for (tok=0,tmp=fields;tmp!=NULL;tmp=tmp->next,tok++) {
 
1401
        fields->cfg_id= tok;
 
1402
    }
 
1403
    bzero((char *)rtrn,sizeof(XkbConfigRtrnRec));
 
1404
    rtrn->line= 1;
 
1405
    rtrn->click_volume= -1;
 
1406
    rtrn->bell_volume= -1;
 
1407
    while ((tok=XkbCFScan(file,&val,rtrn))!=XkbCF_EOF) {
 
1408
        if (tok==XkbCF_Ident) {
 
1409
            Bool                done;
 
1410
            for (tmp=fields,done=False;(tmp!=NULL)&&(!done);tmp=tmp->next) {
 
1411
                register int            i;
 
1412
                XkbConfigFieldPtr       f;
 
1413
 
 
1414
                for (i=0,f=tmp->fields;(i<tmp->num_fields)&&(!done);i++,f++) {
 
1415
                    if (_XkbStrCaseCmp(val.str,f->field)!=0)
 
1416
                        continue;
 
1417
                    if ((*tmp->parser)(file,tmp,f,xkb,rtrn))
 
1418
                         done= True;
 
1419
                    else goto BAILOUT;
 
1420
                }
 
1421
            }
 
1422
        }
 
1423
        else if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)) {
 
1424
            rtrn->error= XkbCF_MissingIdent;
 
1425
            goto BAILOUT;
 
1426
        }
 
1427
    }
 
1428
    for (tmp=fields;tmp!=NULL;tmp=tmp->next) {
 
1429
        if ((tmp->finish)&&(!(*tmp->finish)(tmp,xkb,rtrn,XkbCF_Check)))
 
1430
            goto BAILOUT;
 
1431
    }
 
1432
    return True;
 
1433
BAILOUT:
 
1434
    for (tmp=fields;tmp!=NULL;tmp=tmp->next) {
 
1435
        if (tmp->finish)
 
1436
            (*tmp->finish)(tmp,xkb,rtrn,XkbCF_CleanUp);
 
1437
    }
 
1438
    return False;
 
1439
}
 
1440
 
 
1441
/*ARGSUSED*/
 
1442
void
 
1443
#if NeedFunctionPrototypes
 
1444
XkbCFReportError(FILE *file,char *name,int error,int line)
 
1445
#else
 
1446
XkbCFReportError(file,name,error,line)
 
1447
    FILE *      file;
 
1448
    char *      name;
 
1449
    int         error;
 
1450
    int         line;
 
1451
#endif
 
1452
{
 
1453
char *  msg;
 
1454
 
 
1455
    switch(error) {
 
1456
        case XkbCF_BadAlloc:
 
1457
            msg= "allocation failed\n"; break;
 
1458
        case XkbCF_UnterminatedString:
 
1459
            msg= "unterminated string on line %d"; break;
 
1460
        case XkbCF_MissingIdent:
 
1461
            msg= "expected identifier on line %d"; break;
 
1462
        case XkbCF_MissingEquals:
 
1463
            msg= "expected '=' on line %d"; break;
 
1464
        case XkbCF_ExpectedEOS:
 
1465
            msg= "expected ';' or newline on line %d"; break;
 
1466
        case XkbCF_ExpectedBoolean:
 
1467
            msg= "expected a boolean value on line %d"; break;
 
1468
        case XkbCF_ExpectedInteger:
 
1469
            msg= "expected a numeric value on line %d"; break;
 
1470
        case XkbCF_ExpectedString:
 
1471
            msg= "expected a string on line %d"; break;
 
1472
        case XkbCF_ExpectedModifier:
 
1473
            msg= "expected a modifier name on line %d"; break;
 
1474
        case XkbCF_ExpectedControl:
 
1475
            msg= "expected a control name on line %d"; break;
 
1476
        case XkbCF_ExpectedAXOption:
 
1477
            msg= "expected an AccessX option on line %d"; break;
 
1478
        case XkbCF_ExpectedOperator:
 
1479
            msg= "expected '+' or '-' on line %d"; break;
 
1480
        case XkbCF_ExpectedOORGroupBehavior:
 
1481
            msg= "expected wrap, clamp or group number on line %d"; break;
 
1482
        default:
 
1483
            msg= "unknown error on line %d"; break;
 
1484
    }
 
1485
#ifndef XKB_IN_SERVER
 
1486
    fprintf(file,msg,line);
 
1487
    if (name)   fprintf(file," of %s\n",name);
 
1488
    else        fprintf(file,"\n");
 
1489
#else
 
1490
    ErrorF(msg,line);
 
1491
    if (name)   ErrorF(" of %s\n",name);
 
1492
    else        ErrorF("\n");
 
1493
#endif
 
1494
    return;
 
1495
}