1 /************************************************************
2 Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 ********************************************************/
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
29 #elif defined(HAVE_CONFIG_H)
37 #include <X11/Xfuncs.h>
39 #include <X11/Xfuncs.h>
45 #include <X11/keysym.h>
46 #include <X11/XKBlib.h>
47 #include "XKBfileInt.h"
52 #include <X11/keysym.h>
53 #include <X11/Xproto.h>
57 #define XKBSRV_NEED_FILE_FUNCS
58 #include <X11/extensions/XKBsrv.h>
61 #include <X11/extensions/XKBconfig.h>
63 /***====================================================================***/
65 #define XKBCF_MAX_STR_LEN 100
66 static char _XkbCF_rtrn[XKBCF_MAX_STR_LEN+1];
69 ScanIdent(FILE *file,int ch,XkbCFScanResultPtr val_rtrn)
74 val_rtrn->str= str= _XkbCF_rtrn;
75 for (i=0;(isalpha(ch)||isdigit(ch)||(ch=='_'));ch=getc(file)) {
76 if (i<XKBCF_MAX_STR_LEN)
79 if ((ch!=EOF)&&(ch!=' ')&&(ch!='\t'))
86 ScanString(FILE *file,int quote,XkbCFScanResultPtr val_rtrn)
91 while ( ((ch=getc(file))!=EOF) && (ch!='\n') && (ch!=quote) ) {
93 if ((ch = getc(file))!=EOF) {
94 if ( ch=='n' ) ch = '\n';
95 else if ( ch == 't' ) ch = '\t';
96 else if ( ch == 'v' ) ch = '\v';
97 else if ( ch == 'b' ) ch = '\b';
98 else if ( ch == 'r' ) ch = '\r';
99 else if ( ch == 'f' ) ch = '\f';
100 else if ( ch == 'e' ) ch = '\033';
101 else if ( ch == '0' ) {
104 if (((tmp=getc(file))!=EOF) && (isdigit(tmp)) &&
105 (tmp!='8') && (tmp!='9')) {
106 ch= (ch*8)+(tmp-'0');
112 if ((!stop) && ((tmp=getc(file))!=EOF) && (isdigit(tmp)) &&
113 (tmp!='8') && (tmp!='9')) {
114 ch= (ch*8)+(tmp-'0');
120 if ((!stop) && ((tmp=getc(file))!=EOF) && (isdigit(tmp)) &&
121 (tmp!='8') && (tmp!='9')) {
122 ch= (ch*8)+(tmp-'0');
130 else return XkbCF_EOF;
133 if ( nInBuf < XKBCF_MAX_STR_LEN-1 )
134 _XkbCF_rtrn[nInBuf++] = ch;
137 _XkbCF_rtrn[nInBuf++] = '\0';
138 val_rtrn->str= _XkbCF_rtrn;
141 return XkbCF_UnterminatedString;
145 ScanInteger(FILE *file,int ch,XkbCFScanResultPtr val_rtrn)
151 if (fscanf(file,"%i",&i)==1) {
153 return XkbCF_Integer;
155 return XkbCF_Unknown;
159 XkbCFScan(FILE *file,XkbCFScanResultPtr val_rtrn,XkbConfigRtrnPtr rtrn)
165 } while ((ch=='\t')||(ch==' '));
167 return ScanIdent(file,ch,val_rtrn);
168 else if (isdigit(ch))
169 return ScanInteger(file,ch,val_rtrn);
171 return ScanString(file,ch,val_rtrn);
183 return XkbCF_PlusEquals;
184 if ((ch!=EOF)&&(ch!=' ')&&(ch!='\t'))
191 return XkbCF_MinusEquals;
192 if ((ch!=EOF)&&(ch!=' ')&&(ch!='\t'))
198 else if ((ch=='#')||((ch=='/')&&(getc(file)=='/'))) {
199 while ((ch!='\n')&&(ch!=EOF))
204 return XkbCF_Unknown;
207 /***====================================================================***/
209 #define _XkbCF_Illegal 0
210 #define _XkbCF_Keymap 1
211 #define _XkbCF_Keycodes 2
212 #define _XkbCF_Geometry 3
213 #define _XkbCF_PhysSymbols 4
214 #define _XkbCF_Symbols 5
215 #define _XkbCF_Types 6
216 #define _XkbCF_CompatMap 7
218 #define _XkbCF_RulesFile 8
219 #define _XkbCF_Model 9
220 #define _XkbCF_Layout 10
221 #define _XkbCF_Variant 11
222 #define _XkbCF_Options 12
224 #define _XkbCF_InitialMods 13
225 #define _XkbCF_InitialCtrls 14
227 #define _XkbCF_ClickVolume 15
228 #define _XkbCF_BellVolume 16
229 #define _XkbCF_BellPitch 17
230 #define _XkbCF_BellDuration 18
231 #define _XkbCF_RepeatDelay 19
232 #define _XkbCF_RepeatInterval 20
233 #define _XkbCF_SlowKeysDelay 21
234 #define _XkbCF_DebounceDelay 22
235 #define _XkbCF_MouseKeysDelay 23
236 #define _XkbCF_MouseKeysInterval 24
237 #define _XkbCF_MouseKeysTimeToMax 25
238 #define _XkbCF_MouseKeysMaxSpeed 26
239 #define _XkbCF_MouseKeysCurve 27
240 #define _XkbCF_AccessXTimeout 28
241 #define _XkbCF_AccessXTimeoutCtrlsOn 29
242 #define _XkbCF_AccessXTimeoutCtrlsOff 30
243 #define _XkbCF_AccessXTimeoutOptsOn 31
244 #define _XkbCF_AccessXTimeoutOptsOff 32
246 #define _XkbCF_IgnoreLockMods 33
247 #define _XkbCF_IgnoreGroupLock 34
248 #define _XkbCF_InternalMods 35
250 #define _XkbCF_GroupsWrap 36
251 #define _XkbCF_InitialFeedback 37
254 AddCtrlByName(XkbConfigRtrnPtr rtrn,char *name,unsigned long *ctrls_rtrn)
256 if ((_XkbStrCaseCmp(name,"repeat")==0)||
257 (_XkbStrCaseCmp(name,"repeatkeys")==0))
258 *ctrls_rtrn= XkbRepeatKeysMask;
259 else if (_XkbStrCaseCmp(name,"slowkeys")==0)
260 *ctrls_rtrn= XkbSlowKeysMask;
261 else if (_XkbStrCaseCmp(name,"bouncekeys")==0)
262 *ctrls_rtrn= XkbBounceKeysMask;
263 else if (_XkbStrCaseCmp(name,"stickykeys")==0)
264 *ctrls_rtrn= XkbStickyKeysMask;
265 else if (_XkbStrCaseCmp(name,"mousekeys")==0)
266 *ctrls_rtrn= XkbMouseKeysMask;
267 else if (_XkbStrCaseCmp(name,"mousekeysaccel")==0)
268 *ctrls_rtrn= XkbMouseKeysAccelMask;
269 else if (_XkbStrCaseCmp(name,"accessxkeys")==0)
270 *ctrls_rtrn= XkbAccessXKeysMask;
271 else if (_XkbStrCaseCmp(name,"accessxtimeout")==0)
272 *ctrls_rtrn= XkbAccessXTimeoutMask;
273 else if (_XkbStrCaseCmp(name,"accessxfeedback")==0)
274 *ctrls_rtrn= XkbAccessXFeedbackMask;
275 else if (_XkbStrCaseCmp(name,"audiblebell")==0)
276 *ctrls_rtrn= XkbAudibleBellMask;
277 else if (_XkbStrCaseCmp(name,"overlay1")==0)
278 *ctrls_rtrn= XkbOverlay1Mask;
279 else if (_XkbStrCaseCmp(name,"overlay2")==0)
280 *ctrls_rtrn= XkbOverlay2Mask;
281 else if (_XkbStrCaseCmp(name,"ignoregrouplock")==0)
282 *ctrls_rtrn= XkbIgnoreGroupLockMask;
284 rtrn->error= XkbCF_ExpectedControl;
291 AddAXTimeoutOptByName( XkbConfigRtrnPtr rtrn,
293 unsigned short * opts_rtrn)
295 if (_XkbStrCaseCmp(name,"slowkeyspress")==0)
296 *opts_rtrn= XkbAX_SKPressFBMask;
297 else if (_XkbStrCaseCmp(name,"slowkeysaccept")==0)
298 *opts_rtrn= XkbAX_SKAcceptFBMask;
299 else if (_XkbStrCaseCmp(name,"feature")==0)
300 *opts_rtrn= XkbAX_FeatureFBMask;
301 else if (_XkbStrCaseCmp(name,"slowwarn")==0)
302 *opts_rtrn= XkbAX_SlowWarnFBMask;
303 else if (_XkbStrCaseCmp(name,"indicator")==0)
304 *opts_rtrn= XkbAX_IndicatorFBMask;
305 else if (_XkbStrCaseCmp(name,"stickykeys")==0)
306 *opts_rtrn= XkbAX_StickyKeysFBMask;
307 else if (_XkbStrCaseCmp(name,"twokeys")==0)
308 *opts_rtrn= XkbAX_TwoKeysMask;
309 else if (_XkbStrCaseCmp(name,"latchtolock")==0)
310 *opts_rtrn= XkbAX_LatchToLockMask;
311 else if (_XkbStrCaseCmp(name,"slowkeysrelease")==0)
312 *opts_rtrn= XkbAX_SKReleaseFBMask;
313 else if (_XkbStrCaseCmp(name,"slowkeysreject")==0)
314 *opts_rtrn= XkbAX_SKRejectFBMask;
315 else if (_XkbStrCaseCmp(name,"bouncekeysreject")==0)
316 *opts_rtrn= XkbAX_BKRejectFBMask;
317 else if (_XkbStrCaseCmp(name,"dumbbell")==0)
318 *opts_rtrn= XkbAX_DumbBellFBMask;
320 rtrn->error= XkbCF_ExpectedControl;
326 XkbConfigUnboundModPtr
327 XkbCFAddModByName( XkbConfigRtrnPtr rtrn,
331 XkbConfigUnboundModPtr last)
333 if (rtrn->num_unbound_mods>=rtrn->sz_unbound_mods) {
334 rtrn->sz_unbound_mods+= 5;
335 rtrn->unbound_mods= _XkbTypedRealloc(rtrn->unbound_mods,
336 rtrn->sz_unbound_mods,
337 XkbConfigUnboundModRec);
338 if (rtrn->unbound_mods==NULL) {
339 rtrn->error= XkbCF_BadAlloc;
344 last= &rtrn->unbound_mods[rtrn->num_unbound_mods++];
351 if (_XkbStrCaseCmp(name,"shift")==0)
352 last->mods|= ShiftMask;
353 else if (_XkbStrCaseCmp(name,"lock")==0)
354 last->mods|= LockMask;
355 else if ((_XkbStrCaseCmp(name,"control")==0)||
356 (_XkbStrCaseCmp(name,"ctrl")==0))
357 last->mods|= ControlMask;
358 else if (_XkbStrCaseCmp(name,"mod1")==0)
359 last->mods|= Mod1Mask;
360 else if (_XkbStrCaseCmp(name,"mod2")==0)
361 last->mods|= Mod2Mask;
362 else if (_XkbStrCaseCmp(name,"mod3")==0)
363 last->mods|= Mod3Mask;
364 else if (_XkbStrCaseCmp(name,"mod4")==0)
365 last->mods|= Mod4Mask;
366 else if (_XkbStrCaseCmp(name,"mod5")==0)
367 last->mods|= Mod5Mask;
369 if (last->name!=NULL) {
370 last= &rtrn->unbound_mods[rtrn->num_unbound_mods++];
377 last->name= _XkbDupString(name);
383 XkbCFBindMods(XkbConfigRtrnPtr rtrn,XkbDescPtr xkb)
387 XkbConfigUnboundModPtr mod;
390 if (rtrn->num_unbound_mods<1)
392 if ((xkb==NULL) || (xkb->names==NULL))
396 for (n=0,mod=rtrn->unbound_mods;n<rtrn->num_unbound_mods;n++,mod++) {
397 if (mod->name!=NULL) {
398 name= XkbInternAtom(xkb->dpy,mod->name,True);
401 for (v=0;v<XkbNumVirtualMods;v++) {
402 if (xkb->names->vmods[v]==name) {
417 XkbCFApplyMods(XkbConfigRtrnPtr rtrn,int what,XkbConfigModInfoPtr info)
420 XkbConfigUnboundModPtr mod;
422 if (rtrn->num_unbound_mods<1)
425 for (n=0,mod=rtrn->unbound_mods;n<rtrn->num_unbound_mods;n++,mod++) {
428 if (mod->merge==XkbCF_MergeRemove) {
429 info->mods_clear|= mod->mods;
430 info->vmods_clear|= mod->vmods;
433 if (mod->merge==XkbCF_MergeSet)
435 info->mods|= mod->mods;
436 info->vmods|= mod->vmods;
438 if (mod->name==NULL) {
439 mod->what= _XkbCF_Illegal;
451 DefaultParser( FILE * file,
452 XkbConfigFieldsPtr fields,
453 XkbConfigFieldPtr field,
455 XkbConfigRtrnPtr rtrn)
458 XkbCFScanResultRec val;
461 unsigned long * ctrls, ctrls_mask;
462 unsigned short * opts, opts_mask;
465 XkbConfigUnboundModPtr last;
468 tok= XkbCFScan(file,&val,rtrn);
472 switch (field->field_id) {
473 case _XkbCF_RulesFile: if (!str) str= &rtrn->rules_file;
474 case _XkbCF_Model: if (!str) str= &rtrn->model;
475 case _XkbCF_Layout: if (!str) str= &rtrn->layout;
476 case _XkbCF_Variant: if (!str) str= &rtrn->variant;
477 case _XkbCF_Options: if (!str) str= &rtrn->options;
478 case _XkbCF_Keymap: if (!str) str= &rtrn->keymap;
479 case _XkbCF_Keycodes: if (!str) str= &rtrn->keycodes;
480 case _XkbCF_Geometry: if (!str) str= &rtrn->geometry;
481 case _XkbCF_PhysSymbols:if (!str) str= &rtrn->phys_symbols;
482 case _XkbCF_Symbols: if (!str) str= &rtrn->symbols;
483 case _XkbCF_Types: if (!str) str= &rtrn->types;
484 case _XkbCF_CompatMap: if (!str) str= &rtrn->compat;
485 if (tok!=XkbCF_Equals) {
486 rtrn->error= XkbCF_MissingEquals;
489 tok= XkbCFScan(file,&val,rtrn);
490 if ((tok!=XkbCF_String)&&(tok!=XkbCF_Ident)) {
491 rtrn->error= XkbCF_ExpectedString;
494 tok= XkbCFScan(file,&val,rtrn);
495 if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
496 rtrn->error= XkbCF_ExpectedEOS;
501 *str= _XkbDupString(val.str);
503 case _XkbCF_InitialMods:
504 case _XkbCF_IgnoreLockMods:
505 case _XkbCF_InternalMods:
506 what= XkbCF_InitialMods;
507 if (field->field_id==_XkbCF_InitialMods)
508 rtrn->defined|= (what=XkbCF_InitialMods);
509 else if (field->field_id==_XkbCF_InternalMods)
510 rtrn->defined|= (what=XkbCF_InternalMods);
511 else if (field->field_id==_XkbCF_IgnoreLockMods)
512 rtrn->defined|= (what=XkbCF_IgnoreLockMods);
513 if (tok==XkbCF_Equals) merge= XkbCF_MergeSet;
514 else if (tok==XkbCF_MinusEquals) merge= XkbCF_MergeRemove;
515 else if (tok==XkbCF_PlusEquals) merge= XkbCF_MergeAdd;
517 rtrn->error= XkbCF_MissingEquals;
520 tok= XkbCFScan(file,&val,rtrn);
521 if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
522 rtrn->error= XkbCF_ExpectedModifier;
526 while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
527 if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
528 rtrn->error= XkbCF_ExpectedModifier;
531 last=XkbCFAddModByName(rtrn,what,val.str,merge,last);
534 if (merge==XkbCF_MergeSet)
535 merge= XkbCF_MergeAdd;
536 tok= XkbCFScan(file,&val,rtrn);
537 if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
538 if (tok!=XkbCF_Plus) {
539 rtrn->error= XkbCF_ExpectedOperator;
542 tok= XkbCFScan(file,&val,rtrn);
546 case _XkbCF_InitialCtrls:
547 rtrn->defined|= XkbCF_InitialCtrls;
549 if (tok==XkbCF_PlusEquals)
550 ctrls= &rtrn->initial_ctrls;
551 else if (tok==XkbCF_MinusEquals)
552 ctrls= &rtrn->initial_ctrls_clear;
553 else if (tok==XkbCF_Equals) {
554 ctrls= &rtrn->initial_ctrls;
555 rtrn->replace_initial_ctrls= True;
559 rtrn->error= XkbCF_MissingEquals;
562 tok= XkbCFScan(file,&val,rtrn);
563 if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
564 rtrn->error= XkbCF_ExpectedControl;
567 while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
568 if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
569 rtrn->error= XkbCF_ExpectedControl;
572 if (!AddCtrlByName(rtrn,val.str,&ctrls_mask)) {
575 *ctrls |= ctrls_mask;
576 tok= XkbCFScan(file,&val,rtrn);
577 if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
578 if (tok!=XkbCF_Plus) {
579 rtrn->error= XkbCF_ExpectedOperator;
582 tok= XkbCFScan(file,&val,rtrn);
586 case _XkbCF_AccessXTimeoutCtrlsOn:
587 case _XkbCF_AccessXTimeoutCtrlsOff:
589 if (tok==XkbCF_MinusEquals) {
590 ctrls= &rtrn->axt_ctrls_ignore;
591 opts= &rtrn->axt_opts_ignore;
593 else if ((tok==XkbCF_PlusEquals)||(tok==XkbCF_Equals)) {
594 if (field->field_id==_XkbCF_AccessXTimeoutCtrlsOff) {
595 ctrls= &rtrn->axt_ctrls_off;
596 opts= &rtrn->axt_opts_off;
597 if (tok==XkbCF_Equals)
598 rtrn->replace_axt_ctrls_off= True;
601 ctrls= &rtrn->axt_ctrls_on;
602 opts= &rtrn->axt_opts_on;
603 if (tok==XkbCF_Equals)
604 rtrn->replace_axt_ctrls_on= True;
609 rtrn->error= XkbCF_MissingEquals;
612 tok= XkbCFScan(file,&val,rtrn);
613 if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
614 rtrn->error= XkbCF_ExpectedControl;
617 while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
618 if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
619 rtrn->error= XkbCF_ExpectedControl;
622 if (!AddCtrlByName(rtrn,val.str,&ctrls_mask)) {
623 if (!AddAXTimeoutOptByName(rtrn,val.str,&opts_mask))
626 if (field->field_id==_XkbCF_AccessXTimeoutCtrlsOff) {
627 rtrn->defined|= XkbCF_AccessXTimeoutOptsOff;
628 if (rtrn->replace_axt_ctrls_off)
629 rtrn->replace_axt_opts_off= True;
632 rtrn->defined|= XkbCF_AccessXTimeoutOptsOn;
633 if (rtrn->replace_axt_ctrls_on)
634 rtrn->replace_axt_opts_on= True;
638 *ctrls |= ctrls_mask;
639 tok= XkbCFScan(file,&val,rtrn);
640 if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
641 if (tok!=XkbCF_Plus) {
642 rtrn->error= XkbCF_ExpectedOperator;
645 tok= XkbCFScan(file,&val,rtrn);
649 case _XkbCF_InitialFeedback:
650 rtrn->defined|= XkbCF_InitialOpts;
652 if (tok==XkbCF_PlusEquals)
653 opts= &rtrn->initial_opts;
654 else if (tok==XkbCF_MinusEquals)
655 opts= &rtrn->initial_opts_clear;
656 else if (tok==XkbCF_Equals) {
657 opts= &rtrn->initial_opts;
658 rtrn->replace_initial_opts= True;
662 rtrn->error= XkbCF_MissingEquals;
665 tok= XkbCFScan(file,&val,rtrn);
666 if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
667 rtrn->error= XkbCF_ExpectedAXOption;
670 while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
671 if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
672 rtrn->error= XkbCF_ExpectedAXOption;
675 if (!AddAXTimeoutOptByName(rtrn,val.str,&opts_mask)) {
679 tok= XkbCFScan(file,&val,rtrn);
680 if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
681 if (tok!=XkbCF_Plus) {
682 rtrn->error= XkbCF_ExpectedOperator;
685 tok= XkbCFScan(file,&val,rtrn);
689 case _XkbCF_AccessXTimeoutOptsOff:
690 case _XkbCF_AccessXTimeoutOptsOn:
692 if (tok==XkbCF_MinusEquals)
693 opts= &rtrn->axt_opts_ignore;
694 else if ((tok==XkbCF_PlusEquals)||(tok==XkbCF_Equals)) {
695 if (field->field_id==_XkbCF_AccessXTimeoutOptsOff) {
696 opts= &rtrn->axt_opts_off;
697 if (tok==XkbCF_Equals)
698 rtrn->replace_axt_opts_off= True;
701 opts= &rtrn->axt_opts_on;
702 if (tok==XkbCF_Equals)
703 rtrn->replace_axt_opts_on= True;
708 rtrn->error= XkbCF_MissingEquals;
711 tok= XkbCFScan(file,&val,rtrn);
712 if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
713 rtrn->error= XkbCF_ExpectedControl;
716 while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
717 if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
718 rtrn->error= XkbCF_ExpectedControl;
721 if (!AddAXTimeoutOptByName(rtrn,val.str,&opts_mask))
725 tok= XkbCFScan(file,&val,rtrn);
726 if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
727 if (tok!=XkbCF_Plus) {
728 rtrn->error= XkbCF_ExpectedOperator;
731 tok= XkbCFScan(file,&val,rtrn);
735 case _XkbCF_ClickVolume:
737 pival= &rtrn->click_volume;
740 case _XkbCF_BellVolume:
742 pival= &rtrn->bell_volume;
745 case _XkbCF_BellPitch:
747 pival= &rtrn->bell_pitch;
748 case _XkbCF_BellDuration:
750 pival= &rtrn->bell_duration;
751 case _XkbCF_RepeatDelay:
753 pival= &rtrn->repeat_delay;
754 case _XkbCF_RepeatInterval:
756 pival= &rtrn->repeat_interval;
757 case _XkbCF_SlowKeysDelay:
759 pival= &rtrn->slow_keys_delay;
760 case _XkbCF_DebounceDelay:
762 pival= &rtrn->debounce_delay;
763 case _XkbCF_MouseKeysDelay:
765 pival= &rtrn->mk_delay;
766 case _XkbCF_MouseKeysInterval:
768 pival= &rtrn->mk_interval;
769 case _XkbCF_MouseKeysTimeToMax:
771 pival= &rtrn->mk_time_to_max;
772 case _XkbCF_MouseKeysMaxSpeed:
774 pival= &rtrn->mk_max_speed;
775 case _XkbCF_MouseKeysCurve:
777 pival= &rtrn->mk_curve;
778 case _XkbCF_AccessXTimeout:
780 pival= &rtrn->ax_timeout;
781 if (tok!=XkbCF_Equals) {
782 rtrn->error= XkbCF_MissingEquals;
785 tok= XkbCFScan(file,&val,rtrn);
786 if (tok == XkbCF_Minus && field->field_id == _XkbCF_MouseKeysCurve) {
787 /* This can be a negative value */
788 tok = XkbCFScan(file,&val,rtrn);
793 if (tok!=XkbCF_Integer) {
795 if ((onoff)&&(tok==XkbCF_Ident)&&(val.str!=NULL)) {
796 if (_XkbStrCaseCmp(val.str,"on")) {
800 else if (_XkbStrCaseCmp(val.str,"off")) {
806 rtrn->error= XkbCF_ExpectedInteger;
810 *pival= val.ival * sign;
811 if (field->field_id == _XkbCF_AccessXTimeout)
812 rtrn->defined|=XkbCF_AccessXTimeout;
813 tok= XkbCFScan(file,&val,rtrn);
814 if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
815 rtrn->error= XkbCF_ExpectedEOS;
819 case _XkbCF_GroupsWrap:
820 if (tok!=XkbCF_Equals) {
821 rtrn->error= XkbCF_MissingEquals;
824 tok= XkbCFScan(file,&val,rtrn);
825 if (tok==XkbCF_Ident) {
826 if (_XkbStrCaseCmp(val.str,"wrap")==0) {
827 rtrn->groups_wrap= XkbSetGroupInfo(0,XkbWrapIntoRange,0);
829 else if (_XkbStrCaseCmp(val.str,"clamp")==0) {
830 rtrn->groups_wrap= XkbSetGroupInfo(0,XkbClampIntoRange,0);
833 rtrn->error= XkbCF_ExpectedOORGroupBehavior;
837 else if ((tok==XkbCF_Integer)&&(XkbIsLegalGroup(val.ival-1))) {
838 rtrn->groups_wrap= XkbSetGroupInfo(0,XkbRedirectIntoRange,
842 rtrn->error= XkbCF_ExpectedOORGroupBehavior;
845 rtrn->defined|= XkbCF_GroupsWrap;
846 tok= XkbCFScan(file,&val,rtrn);
847 if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
848 rtrn->error= XkbCF_ExpectedEOS;
853 rtrn->error= XkbCF_ExpectedInteger;
863 DefaultCleanUp(XkbConfigRtrnPtr rtrn)
865 if (rtrn->keymap) _XkbFree(rtrn->keymap);
866 if (rtrn->keycodes) _XkbFree(rtrn->keycodes);
867 if (rtrn->geometry) _XkbFree(rtrn->geometry);
868 if (rtrn->phys_symbols) _XkbFree(rtrn->phys_symbols);
869 if (rtrn->symbols) _XkbFree(rtrn->symbols);
870 if (rtrn->types) _XkbFree(rtrn->types);
871 if (rtrn->compat) _XkbFree(rtrn->compat);
872 rtrn->keycodes= rtrn->geometry= NULL;
873 rtrn->symbols= rtrn->phys_symbols= NULL;
874 rtrn->types= rtrn->compat= NULL;
875 if ((rtrn->unbound_mods!=NULL)&&(rtrn->num_unbound_mods>0)) {
877 for (i=0;i<rtrn->num_unbound_mods;i++) {
878 if (rtrn->unbound_mods[i].name!=NULL) {
879 _XkbFree(rtrn->unbound_mods[i].name);
880 rtrn->unbound_mods[i].name= NULL;
883 _XkbFree(rtrn->unbound_mods);
884 rtrn->sz_unbound_mods= 0;
885 rtrn->num_unbound_mods= 0;
886 rtrn->unbound_mods= NULL;
892 DefaultApplyNames(XkbConfigRtrnPtr rtrn,XkbDescPtr xkb)
896 if (XkbAllocNames(xkb,XkbComponentNamesMask,0,0)!=Success)
898 if ((str=rtrn->keycodes)!=NULL) {
899 xkb->names->keycodes= XkbInternAtom(xkb->dpy,str,False);
901 rtrn->keycodes= NULL;
903 if ((str=rtrn->geometry)!=NULL) {
904 xkb->names->geometry= XkbInternAtom(xkb->dpy,str,False);
906 rtrn->geometry= NULL;
908 if ((str=rtrn->symbols)!=NULL) {
909 xkb->names->symbols= XkbInternAtom(xkb->dpy,str,False);
913 if ((str=rtrn->phys_symbols)!=NULL) {
914 xkb->names->phys_symbols= XkbInternAtom(xkb->dpy,str,False);
916 rtrn->phys_symbols= NULL;
918 if ((str=rtrn->types)!=NULL) {
919 xkb->names->types= XkbInternAtom(xkb->dpy,str,False);
923 if ((str=rtrn->compat)!=NULL) {
924 xkb->names->compat= XkbInternAtom(xkb->dpy,str,False);
932 DefaultApplyControls(XkbConfigRtrnPtr rtrn,XkbDescPtr xkb)
935 XkbControlsPtr ctrls;
938 if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success)
941 if (rtrn->replace_initial_ctrls)
942 ctrls->enabled_ctrls= rtrn->initial_ctrls;
943 else ctrls->enabled_ctrls|= rtrn->initial_ctrls;
944 ctrls->enabled_ctrls&= ~rtrn->initial_ctrls_clear;
945 if (rtrn->internal_mods.replace) {
946 ctrls->internal.real_mods= rtrn->internal_mods.mods;
947 ctrls->internal.vmods= rtrn->internal_mods.vmods;
950 ctrls->internal.real_mods&= ~rtrn->internal_mods.mods_clear;
951 ctrls->internal.vmods&= ~rtrn->internal_mods.vmods_clear;
952 ctrls->internal.real_mods|= rtrn->internal_mods.mods;
953 ctrls->internal.vmods|= rtrn->internal_mods.vmods;
956 (void)XkbVirtualModsToReal(xkb,ctrls->internal.vmods,&mask);
957 ctrls->internal.mask= (ctrls->internal.real_mods|mask);
959 if (rtrn->ignore_lock_mods.replace) {
960 ctrls->ignore_lock.real_mods= rtrn->ignore_lock_mods.mods;
961 ctrls->ignore_lock.vmods= rtrn->ignore_lock_mods.vmods;
964 ctrls->ignore_lock.real_mods&= ~rtrn->ignore_lock_mods.mods_clear;
965 ctrls->ignore_lock.vmods&= ~rtrn->ignore_lock_mods.vmods_clear;
966 ctrls->ignore_lock.real_mods|= rtrn->ignore_lock_mods.mods;
967 ctrls->ignore_lock.vmods|= rtrn->ignore_lock_mods.vmods;
970 (void)XkbVirtualModsToReal(xkb,ctrls->ignore_lock.vmods,&mask);
971 ctrls->ignore_lock.mask= (ctrls->ignore_lock.real_mods|mask);
973 if (rtrn->repeat_delay>0)
974 ctrls->repeat_delay= rtrn->repeat_delay;
975 if (rtrn->repeat_interval>0)
976 ctrls->repeat_interval= rtrn->repeat_interval;
977 if (rtrn->slow_keys_delay>0)
978 ctrls->slow_keys_delay= rtrn->slow_keys_delay;
979 if (rtrn->debounce_delay>0)
980 ctrls->debounce_delay= rtrn->debounce_delay;
981 if (rtrn->mk_delay>0)
982 ctrls->mk_delay= rtrn->mk_delay;
983 if (rtrn->mk_interval>0)
984 ctrls->mk_interval= rtrn->mk_interval;
985 if (rtrn->mk_time_to_max>0)
986 ctrls->mk_time_to_max= rtrn->mk_time_to_max;
987 if (rtrn->mk_max_speed>0)
988 ctrls->mk_max_speed= rtrn->mk_max_speed;
989 if (rtrn->mk_curve>0)
990 ctrls->mk_curve= rtrn->mk_curve;
991 if (rtrn->defined&XkbCF_AccessXTimeout && rtrn->ax_timeout > 0)
992 ctrls->ax_timeout= rtrn->ax_timeout;
994 /* any value set to both off and on is reset to ignore */
995 if ((off=(rtrn->axt_ctrls_on&rtrn->axt_ctrls_off))!=0)
996 rtrn->axt_ctrls_ignore|= off;
998 /* ignore takes priority over on and off */
999 rtrn->axt_ctrls_on&= ~rtrn->axt_ctrls_ignore;
1000 rtrn->axt_ctrls_off&= ~rtrn->axt_ctrls_ignore;
1002 if (!rtrn->replace_axt_ctrls_off) {
1003 off= (ctrls->axt_ctrls_mask&(~ctrls->axt_ctrls_values));
1004 off&= ~rtrn->axt_ctrls_on;
1005 off|= rtrn->axt_ctrls_off;
1007 else off= rtrn->axt_ctrls_off;
1008 if (!rtrn->replace_axt_ctrls_on) {
1009 on= (ctrls->axt_ctrls_mask&ctrls->axt_ctrls_values);
1010 on&= ~rtrn->axt_ctrls_off;
1011 on|= rtrn->axt_ctrls_on;
1013 else on= rtrn->axt_ctrls_on;
1014 ctrls->axt_ctrls_mask= (on|off)&~rtrn->axt_ctrls_ignore;
1015 ctrls->axt_ctrls_values= on&~rtrn->axt_ctrls_ignore;
1017 /* any value set to both off and on is reset to ignore */
1018 if ((off=(rtrn->axt_opts_on&rtrn->axt_opts_off))!=0)
1019 rtrn->axt_opts_ignore|= off;
1021 /* ignore takes priority over on and off */
1022 rtrn->axt_opts_on&= ~rtrn->axt_opts_ignore;
1023 rtrn->axt_opts_off&= ~rtrn->axt_opts_ignore;
1025 if (rtrn->replace_axt_opts_off) {
1026 off= (ctrls->axt_opts_mask&(~ctrls->axt_opts_values));
1027 off&= ~rtrn->axt_opts_on;
1028 off|= rtrn->axt_opts_off;
1030 else off= rtrn->axt_opts_off;
1031 if (!rtrn->replace_axt_opts_on) {
1032 on= (ctrls->axt_opts_mask&ctrls->axt_opts_values);
1033 on&= ~rtrn->axt_opts_off;
1034 on|= rtrn->axt_opts_on;
1036 else on= rtrn->axt_opts_on;
1037 ctrls->axt_opts_mask= (unsigned short)((on|off)&~rtrn->axt_ctrls_ignore);
1038 ctrls->axt_opts_values= (unsigned short)(on&~rtrn->axt_ctrls_ignore);
1040 if (rtrn->defined&XkbCF_GroupsWrap) {
1042 n= XkbNumGroups(ctrls->groups_wrap);
1043 rtrn->groups_wrap= XkbSetNumGroups(rtrn->groups_wrap,n);
1044 ctrls->groups_wrap= rtrn->groups_wrap;
1051 DefaultFinish( XkbConfigFieldsPtr fields,
1053 XkbConfigRtrnPtr rtrn,
1056 if ((what==XkbCF_Destroy)||(what==XkbCF_CleanUp))
1057 return DefaultCleanUp(rtrn);
1058 if (what==XkbCF_Check) {
1059 if ((rtrn->symbols==NULL)&&(rtrn->phys_symbols!=NULL))
1060 rtrn->symbols= _XkbDupString(rtrn->phys_symbols);
1062 if ((what==XkbCF_Apply)||(what==XkbCF_Check)) {
1063 if (xkb && xkb->names && (rtrn->num_unbound_mods>0))
1064 XkbCFBindMods(rtrn,xkb);
1065 XkbCFApplyMods(rtrn,XkbCF_InitialMods,&rtrn->initial_mods);
1066 XkbCFApplyMods(rtrn,XkbCF_InternalMods,&rtrn->internal_mods);
1067 XkbCFApplyMods(rtrn,XkbCF_IgnoreLockMods,&rtrn->ignore_lock_mods);
1069 if (what==XkbCF_Apply) {
1071 DefaultApplyNames(rtrn,xkb);
1072 DefaultApplyControls(rtrn,xkb);
1073 XkbCFBindMods(rtrn,xkb);
1079 static XkbConfigFieldRec _XkbCFDfltFields[] = {
1080 { "rules", _XkbCF_RulesFile },
1081 { "model", _XkbCF_Model },
1082 { "layout", _XkbCF_Layout },
1083 { "variant", _XkbCF_Variant },
1084 { "options", _XkbCF_Options },
1085 { "keymap", _XkbCF_Keymap },
1086 { "keycodes", _XkbCF_Keycodes },
1087 { "geometry", _XkbCF_Geometry },
1088 { "realsymbols",_XkbCF_PhysSymbols },
1089 { "actualsymbols",_XkbCF_PhysSymbols },
1090 { "symbols", _XkbCF_Symbols },
1091 { "symbolstouse",_XkbCF_Symbols },
1092 { "types", _XkbCF_Types },
1093 { "compat", _XkbCF_CompatMap },
1094 { "modifiers", _XkbCF_InitialMods },
1095 { "controls", _XkbCF_InitialCtrls },
1096 { "click", _XkbCF_ClickVolume },
1097 { "clickvolume",_XkbCF_ClickVolume },
1098 { "bell", _XkbCF_BellVolume },
1099 { "bellvolume", _XkbCF_BellVolume },
1100 { "bellpitch", _XkbCF_BellPitch },
1101 { "bellduration",_XkbCF_BellDuration },
1102 { "repeatdelay",_XkbCF_RepeatDelay },
1103 { "repeatinterval",_XkbCF_RepeatInterval },
1104 { "slowkeysdelay",_XkbCF_SlowKeysDelay },
1105 { "debouncedelay",_XkbCF_DebounceDelay },
1106 { "mousekeysdelay",_XkbCF_MouseKeysDelay },
1107 { "mousekeysinterval",_XkbCF_MouseKeysInterval },
1108 { "mousekeystimetomax",_XkbCF_MouseKeysTimeToMax },
1109 { "mousekeysmaxspeed",_XkbCF_MouseKeysMaxSpeed },
1110 { "mousekeyscurve",_XkbCF_MouseKeysCurve },
1111 { "accessxtimeout",_XkbCF_AccessXTimeout },
1112 { "axtimeout",_XkbCF_AccessXTimeout },
1113 { "accessxtimeoutctrlson",_XkbCF_AccessXTimeoutCtrlsOn },
1114 { "axtctrlson", _XkbCF_AccessXTimeoutCtrlsOn },
1115 { "accessxtimeoutctrlsoff",_XkbCF_AccessXTimeoutCtrlsOff },
1116 { "axtctrlsoff",_XkbCF_AccessXTimeoutCtrlsOff },
1117 { "accessxtimeoutfeedbackon", _XkbCF_AccessXTimeoutOptsOn },
1118 { "axtfeedbackon", _XkbCF_AccessXTimeoutOptsOn },
1119 { "accessxtimeoutfeedbackoff", _XkbCF_AccessXTimeoutOptsOff },
1120 { "axtfeedbackoff", _XkbCF_AccessXTimeoutOptsOff },
1121 { "ignorelockmods",_XkbCF_IgnoreLockMods },
1122 { "ignorelockmodifiers",_XkbCF_IgnoreLockMods },
1123 { "ignoregrouplock",_XkbCF_IgnoreGroupLock },
1124 { "internalmods",_XkbCF_InternalMods },
1125 { "internalmodifiers",_XkbCF_InternalMods },
1126 { "outofrangegroups",_XkbCF_GroupsWrap },
1127 { "groups", _XkbCF_GroupsWrap },
1128 { "feedback", _XkbCF_InitialFeedback },
1130 #define _XkbCFNumDfltFields (sizeof(_XkbCFDfltFields)/sizeof(XkbConfigFieldRec))
1132 static XkbConfigFieldsRec _XkbCFDflts = {
1134 _XkbCFNumDfltFields, /* num_fields */
1135 _XkbCFDfltFields, /* fields */
1136 DefaultParser, /* parser */
1137 DefaultFinish, /* finish */
1142 XkbConfigFieldsPtr XkbCFDflts= &_XkbCFDflts;
1144 /***====================================================================***/
1147 XkbCFDup(XkbConfigFieldsPtr fields)
1149 XkbConfigFieldsPtr pNew;
1151 pNew= _XkbTypedAlloc(XkbConfigFieldsRec);
1153 memcpy(pNew,fields,sizeof(XkbConfigFieldsRec));
1154 if ((pNew->fields!=NULL)&&(pNew->num_fields>0)) {
1155 pNew->fields= _XkbTypedCalloc(pNew->num_fields,XkbConfigFieldRec);
1157 memcpy(fields->fields,pNew->fields,
1158 (pNew->num_fields*sizeof(XkbConfigFieldRec)));
1166 pNew->num_fields= 0;
1175 XkbCFFree(XkbConfigFieldsPtr fields,Bool all)
1177 XkbConfigFieldsPtr next;
1180 while (fields!=NULL) {
1182 if (fields!=XkbCFDflts) {
1183 if (fields->fields) {
1184 _XkbFree(fields->fields);
1185 fields->fields= NULL;
1186 fields->num_fields= 0;
1190 fields= (all?next:NULL);
1196 XkbCFApplyRtrnValues( XkbConfigRtrnPtr rtrn,
1197 XkbConfigFieldsPtr fields,
1202 if ((fields==NULL)||(rtrn==NULL)||(xkb==NULL))
1204 for (ok=True;fields!=NULL;fields=fields->next) {
1205 if (fields->finish!=NULL)
1206 ok= (*fields->finish)(fields,xkb,rtrn,XkbCF_Apply)&&ok;
1211 XkbConfigRtrnPrivPtr
1212 XkbCFAddPrivate( XkbConfigRtrnPtr rtrn,
1213 XkbConfigFieldsPtr fields,
1216 XkbConfigRtrnPrivPtr priv;
1218 if ((rtrn==NULL)||(fields==NULL))
1220 priv= _XkbTypedAlloc(XkbConfigRtrnPrivRec);
1222 priv->cfg_id= fields->cfg_id;
1224 priv->next= rtrn->priv;
1231 XkbCFFreeRtrn( XkbConfigRtrnPtr rtrn,
1232 XkbConfigFieldsPtr fields,
1235 XkbConfigRtrnPrivPtr tmp,next;
1237 if ((fields==NULL)||(rtrn==NULL))
1239 while (fields!=NULL) {
1240 if (fields->finish!=NULL)
1241 (*fields->finish)(fields,xkb,rtrn,XkbCF_Destroy);
1242 fields= fields->next;
1244 for (tmp=rtrn->priv;tmp!=NULL;tmp=next) {
1246 bzero((char *)tmp,sizeof(XkbConfigRtrnPrivRec));
1249 bzero((char *)rtrn,sizeof(XkbConfigRtrnRec));
1254 XkbCFParse( FILE * file,
1255 XkbConfigFieldsPtr fields,
1257 XkbConfigRtrnPtr rtrn)
1260 XkbCFScanResultRec val;
1261 XkbConfigFieldsPtr tmp;
1263 if ((file==NULL)||(fields==NULL)||(rtrn==NULL))
1265 for (tok=0,tmp=fields;tmp!=NULL;tmp=tmp->next,tok++) {
1266 fields->cfg_id= tok;
1268 bzero((char *)rtrn,sizeof(XkbConfigRtrnRec));
1270 rtrn->click_volume= -1;
1271 rtrn->bell_volume= -1;
1272 while ((tok=XkbCFScan(file,&val,rtrn))!=XkbCF_EOF) {
1273 if (tok==XkbCF_Ident) {
1275 for (tmp=fields,done=False;(tmp!=NULL)&&(!done);tmp=tmp->next) {
1277 XkbConfigFieldPtr f;
1279 for (i=0,f=tmp->fields;(i<tmp->num_fields)&&(!done);i++,f++) {
1280 if (_XkbStrCaseCmp(val.str,f->field)!=0)
1282 if ((*tmp->parser)(file,tmp,f,xkb,rtrn))
1288 else if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)) {
1289 rtrn->error= XkbCF_MissingIdent;
1293 for (tmp=fields;tmp!=NULL;tmp=tmp->next) {
1294 if ((tmp->finish)&&(!(*tmp->finish)(tmp,xkb,rtrn,XkbCF_Check)))
1299 for (tmp=fields;tmp!=NULL;tmp=tmp->next) {
1301 (*tmp->finish)(tmp,xkb,rtrn,XkbCF_CleanUp);
1308 XkbCFReportError(FILE *file,char *name,int error,int line)
1313 case XkbCF_BadAlloc:
1314 msg= "allocation failed\n"; break;
1315 case XkbCF_UnterminatedString:
1316 msg= "unterminated string on line %d"; break;
1317 case XkbCF_MissingIdent:
1318 msg= "expected identifier on line %d"; break;
1319 case XkbCF_MissingEquals:
1320 msg= "expected '=' on line %d"; break;
1321 case XkbCF_ExpectedEOS:
1322 msg= "expected ';' or newline on line %d"; break;
1323 case XkbCF_ExpectedBoolean:
1324 msg= "expected a boolean value on line %d"; break;
1325 case XkbCF_ExpectedInteger:
1326 msg= "expected a numeric value on line %d"; break;
1327 case XkbCF_ExpectedString:
1328 msg= "expected a string on line %d"; break;
1329 case XkbCF_ExpectedModifier:
1330 msg= "expected a modifier name on line %d"; break;
1331 case XkbCF_ExpectedControl:
1332 msg= "expected a control name on line %d"; break;
1333 case XkbCF_ExpectedAXOption:
1334 msg= "expected an AccessX option on line %d"; break;
1335 case XkbCF_ExpectedOperator:
1336 msg= "expected '+' or '-' on line %d"; break;
1337 case XkbCF_ExpectedOORGroupBehavior:
1338 msg= "expected wrap, clamp or group number on line %d"; break;
1340 msg= "unknown error on line %d"; break;
1342 #ifndef XKB_IN_SERVER
1343 fprintf(file,msg,line);
1344 if (name) fprintf(file," of %s\n",name);
1345 else fprintf(file,"\n");
1348 if (name) ErrorF(" of %s\n",name);