18c9fbc29Smrg/************************************************************ 28c9fbc29Smrg Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc. 38c9fbc29Smrg 48c9fbc29Smrg Permission to use, copy, modify, and distribute this 58c9fbc29Smrg software and its documentation for any purpose and without 68c9fbc29Smrg fee is hereby granted, provided that the above copyright 78c9fbc29Smrg notice appear in all copies and that both that copyright 88c9fbc29Smrg notice and this permission notice appear in supporting 94cd6a3aeSmrg documentation, and that the name of Silicon Graphics not be 104cd6a3aeSmrg used in advertising or publicity pertaining to distribution 118c9fbc29Smrg of the software without specific prior written permission. 124cd6a3aeSmrg Silicon Graphics makes no representation about the suitability 138c9fbc29Smrg of this software for any purpose. It is provided "as is" 148c9fbc29Smrg without any express or implied warranty. 154cd6a3aeSmrg 164cd6a3aeSmrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 174cd6a3aeSmrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 188c9fbc29Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 194cd6a3aeSmrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 204cd6a3aeSmrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 214cd6a3aeSmrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 228c9fbc29Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 238c9fbc29Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE. 248c9fbc29Smrg 258c9fbc29Smrg ********************************************************/ 268c9fbc29Smrg 278c9fbc29Smrg#ifdef HAVE_DIX_CONFIG_H 288c9fbc29Smrg#include <dix-config.h> 298c9fbc29Smrg#elif defined(HAVE_CONFIG_H) 308c9fbc29Smrg#include <config.h> 318c9fbc29Smrg#endif 328c9fbc29Smrg 338c9fbc29Smrg#include <stdio.h> 348c9fbc29Smrg#include <ctype.h> 358c9fbc29Smrg#include <stdlib.h> 368c9fbc29Smrg 378c9fbc29Smrg#include <X11/Xfuncs.h> 388c9fbc29Smrg 398c9fbc29Smrg#include <X11/Xfuncs.h> 408c9fbc29Smrg 418c9fbc29Smrg 428c9fbc29Smrg#include <X11/Xos.h> 438c9fbc29Smrg#include <X11/Xlib.h> 448c9fbc29Smrg#include <X11/keysym.h> 458c9fbc29Smrg#include <X11/XKBlib.h> 468c9fbc29Smrg#include "XKBfileInt.h" 478c9fbc29Smrg 488c9fbc29Smrg 498c9fbc29Smrg#include <X11/extensions/XKBconfig.h> 508c9fbc29Smrg 518c9fbc29Smrg/***====================================================================***/ 528c9fbc29Smrg 538c9fbc29Smrg#define XKBCF_MAX_STR_LEN 100 5470728a38Smrgstatic char _XkbCF_rtrn[XKBCF_MAX_STR_LEN + 1]; 558c9fbc29Smrg 568c9fbc29Smrgstatic int 5770728a38SmrgScanIdent(FILE *file, int ch, XkbCFScanResultPtr val_rtrn) 588c9fbc29Smrg{ 5970728a38Smrg register int i; 6070728a38Smrg char *str; 618c9fbc29Smrg 6270728a38Smrg val_rtrn->str = str = _XkbCF_rtrn; 6370728a38Smrg for (i = 0; (isalpha(ch) || isdigit(ch) || (ch == '_')); ch = getc(file)) { 6470728a38Smrg if (i < XKBCF_MAX_STR_LEN) 6570728a38Smrg str[i++] = ch; 668c9fbc29Smrg } 6770728a38Smrg if ((ch != EOF) && (ch != ' ') && (ch != '\t')) 6870728a38Smrg ungetc(ch, file); 6970728a38Smrg str[i] = '\0'; 708c9fbc29Smrg return XkbCF_Ident; 718c9fbc29Smrg} 728c9fbc29Smrg 738c9fbc29Smrgstatic int 7470728a38SmrgScanString(FILE *file, int quote, XkbCFScanResultPtr val_rtrn) 758c9fbc29Smrg{ 7670728a38Smrg int ch, nInBuf; 778c9fbc29Smrg 788c9fbc29Smrg nInBuf = 0; 7970728a38Smrg while (((ch = getc(file)) != EOF) && (ch != '\n') && (ch != quote)) { 8070728a38Smrg if (ch == '\\') { 8170728a38Smrg if ((ch = getc(file)) != EOF) { 8270728a38Smrg if (ch == 'n') 8370728a38Smrg ch = '\n'; 8470728a38Smrg else if (ch == 't') 8570728a38Smrg ch = '\t'; 8670728a38Smrg else if (ch == 'v') 8770728a38Smrg ch = '\v'; 8870728a38Smrg else if (ch == 'b') 8970728a38Smrg ch = '\b'; 9070728a38Smrg else if (ch == 'r') 9170728a38Smrg ch = '\r'; 9270728a38Smrg else if (ch == 'f') 9370728a38Smrg ch = '\f'; 9470728a38Smrg else if (ch == 'e') 9570728a38Smrg ch = '\033'; 9670728a38Smrg else if (ch == '0') { 9770728a38Smrg int tmp, stop; 9870728a38Smrg 9970728a38Smrg ch = stop = 0; 10070728a38Smrg if (((tmp = getc(file)) != EOF) && (isdigit(tmp)) && 10170728a38Smrg (tmp != '8') && (tmp != '9')) { 10270728a38Smrg ch = (ch * 8) + (tmp - '0'); 10370728a38Smrg } 10470728a38Smrg else { 10570728a38Smrg stop = 1; 10670728a38Smrg ungetc(tmp, file); 10770728a38Smrg } 10870728a38Smrg if ((!stop) && ((tmp = getc(file)) != EOF) && (isdigit(tmp)) 10970728a38Smrg && (tmp != '8') && (tmp != '9')) { 11070728a38Smrg ch = (ch * 8) + (tmp - '0'); 11170728a38Smrg } 11270728a38Smrg else { 11370728a38Smrg stop = 1; 11470728a38Smrg ungetc(tmp, file); 11570728a38Smrg } 11670728a38Smrg if ((!stop) && ((tmp = getc(file)) != EOF) && (isdigit(tmp)) 11770728a38Smrg && (tmp != '8') && (tmp != '9')) { 11870728a38Smrg ch = (ch * 8) + (tmp - '0'); 11970728a38Smrg } 12070728a38Smrg else { 12170728a38Smrg stop = 1; 12270728a38Smrg ungetc(tmp, file); 12370728a38Smrg } 12470728a38Smrg } 12570728a38Smrg } 12670728a38Smrg else 12770728a38Smrg return XkbCF_EOF; 12870728a38Smrg } 12970728a38Smrg 13070728a38Smrg if (nInBuf < XKBCF_MAX_STR_LEN - 1) 13170728a38Smrg _XkbCF_rtrn[nInBuf++] = ch; 1328c9fbc29Smrg } 13370728a38Smrg if (ch == quote) { 13470728a38Smrg _XkbCF_rtrn[nInBuf++] = '\0'; 13570728a38Smrg val_rtrn->str = _XkbCF_rtrn; 13670728a38Smrg return XkbCF_String; 1378c9fbc29Smrg } 1388c9fbc29Smrg return XkbCF_UnterminatedString; 1398c9fbc29Smrg} 1408c9fbc29Smrg 1418c9fbc29Smrgstatic int 14270728a38SmrgScanInteger(FILE *file, int ch, XkbCFScanResultPtr val_rtrn) 1438c9fbc29Smrg{ 14470728a38Smrg int i; 1458c9fbc29Smrg 1468c9fbc29Smrg if (isdigit(ch)) 14770728a38Smrg ungetc(ch, file); 14870728a38Smrg if (fscanf(file, "%i", &i) == 1) { 14970728a38Smrg val_rtrn->ival = i; 15070728a38Smrg return XkbCF_Integer; 1518c9fbc29Smrg } 1528c9fbc29Smrg return XkbCF_Unknown; 1538c9fbc29Smrg} 1548c9fbc29Smrg 1554cd6a3aeSmrgint 15670728a38SmrgXkbCFScan(FILE *file, XkbCFScanResultPtr val_rtrn, XkbConfigRtrnPtr rtrn) 1578c9fbc29Smrg{ 15870728a38Smrg int ch; 1598c9fbc29Smrg 1608c9fbc29Smrg do { 16170728a38Smrg ch = getc(file); 16270728a38Smrg } while ((ch == '\t') || (ch == ' ')); 1638c9fbc29Smrg if (isalpha(ch)) 16470728a38Smrg return ScanIdent(file, ch, val_rtrn); 1658c9fbc29Smrg else if (isdigit(ch)) 16670728a38Smrg return ScanInteger(file, ch, val_rtrn); 16770728a38Smrg else if (ch == '"') 16870728a38Smrg return ScanString(file, ch, val_rtrn); 16970728a38Smrg else if (ch == '\n') { 17070728a38Smrg rtrn->line++; 17170728a38Smrg return XkbCF_EOL; 1728c9fbc29Smrg } 17370728a38Smrg else if (ch == ';') 17470728a38Smrg return XkbCF_Semi; 17570728a38Smrg else if (ch == '=') 17670728a38Smrg return XkbCF_Equals; 17770728a38Smrg else if (ch == '+') { 17870728a38Smrg ch = getc(file); 17970728a38Smrg if (ch == '=') 18070728a38Smrg return XkbCF_PlusEquals; 18170728a38Smrg if ((ch != EOF) && (ch != ' ') && (ch != '\t')) 18270728a38Smrg ungetc(ch, file); 18370728a38Smrg return XkbCF_Plus; 1848c9fbc29Smrg } 18570728a38Smrg else if (ch == '-') { 18670728a38Smrg ch = getc(file); 18770728a38Smrg if (ch == '=') 18870728a38Smrg return XkbCF_MinusEquals; 18970728a38Smrg if ((ch != EOF) && (ch != ' ') && (ch != '\t')) 19070728a38Smrg ungetc(ch, file); 19170728a38Smrg return XkbCF_Minus; 1928c9fbc29Smrg } 19370728a38Smrg else if (ch == EOF) 19470728a38Smrg return XkbCF_EOF; 19570728a38Smrg else if ((ch == '#') || ((ch == '/') && (getc(file) == '/'))) { 19670728a38Smrg while ((ch != '\n') && (ch != EOF)) 19770728a38Smrg ch = getc(file); 19870728a38Smrg rtrn->line++; 19970728a38Smrg return XkbCF_EOL; 2008c9fbc29Smrg } 2018c9fbc29Smrg return XkbCF_Unknown; 2028c9fbc29Smrg} 2038c9fbc29Smrg 2048c9fbc29Smrg/***====================================================================***/ 2058c9fbc29Smrg 2068c9fbc29Smrg#define _XkbCF_Illegal 0 2078c9fbc29Smrg#define _XkbCF_Keymap 1 2088c9fbc29Smrg#define _XkbCF_Keycodes 2 2098c9fbc29Smrg#define _XkbCF_Geometry 3 2108c9fbc29Smrg#define _XkbCF_PhysSymbols 4 2118c9fbc29Smrg#define _XkbCF_Symbols 5 2128c9fbc29Smrg#define _XkbCF_Types 6 2138c9fbc29Smrg#define _XkbCF_CompatMap 7 2148c9fbc29Smrg 2158c9fbc29Smrg#define _XkbCF_RulesFile 8 2168c9fbc29Smrg#define _XkbCF_Model 9 2178c9fbc29Smrg#define _XkbCF_Layout 10 2188c9fbc29Smrg#define _XkbCF_Variant 11 2198c9fbc29Smrg#define _XkbCF_Options 12 2204cd6a3aeSmrg 2218c9fbc29Smrg#define _XkbCF_InitialMods 13 2228c9fbc29Smrg#define _XkbCF_InitialCtrls 14 2238c9fbc29Smrg 2248c9fbc29Smrg#define _XkbCF_ClickVolume 15 2258c9fbc29Smrg#define _XkbCF_BellVolume 16 2268c9fbc29Smrg#define _XkbCF_BellPitch 17 2278c9fbc29Smrg#define _XkbCF_BellDuration 18 2288c9fbc29Smrg#define _XkbCF_RepeatDelay 19 2298c9fbc29Smrg#define _XkbCF_RepeatInterval 20 2308c9fbc29Smrg#define _XkbCF_SlowKeysDelay 21 2318c9fbc29Smrg#define _XkbCF_DebounceDelay 22 2328c9fbc29Smrg#define _XkbCF_MouseKeysDelay 23 2338c9fbc29Smrg#define _XkbCF_MouseKeysInterval 24 2348c9fbc29Smrg#define _XkbCF_MouseKeysTimeToMax 25 2358c9fbc29Smrg#define _XkbCF_MouseKeysMaxSpeed 26 2368c9fbc29Smrg#define _XkbCF_MouseKeysCurve 27 2378c9fbc29Smrg#define _XkbCF_AccessXTimeout 28 2388c9fbc29Smrg#define _XkbCF_AccessXTimeoutCtrlsOn 29 2398c9fbc29Smrg#define _XkbCF_AccessXTimeoutCtrlsOff 30 2408c9fbc29Smrg#define _XkbCF_AccessXTimeoutOptsOn 31 2418c9fbc29Smrg#define _XkbCF_AccessXTimeoutOptsOff 32 2428c9fbc29Smrg 2438c9fbc29Smrg#define _XkbCF_IgnoreLockMods 33 2448c9fbc29Smrg#define _XkbCF_IgnoreGroupLock 34 2458c9fbc29Smrg#define _XkbCF_InternalMods 35 2468c9fbc29Smrg 2478c9fbc29Smrg#define _XkbCF_GroupsWrap 36 2488c9fbc29Smrg#define _XkbCF_InitialFeedback 37 2498c9fbc29Smrg 2508c9fbc29Smrgstatic Bool 25170728a38SmrgAddCtrlByName(XkbConfigRtrnPtr rtrn, char *name, unsigned long *ctrls_rtrn) 2528c9fbc29Smrg{ 25370728a38Smrg if ((_XkbStrCaseCmp(name, "repeat") == 0) || 25470728a38Smrg (_XkbStrCaseCmp(name, "repeatkeys") == 0)) 25570728a38Smrg *ctrls_rtrn = XkbRepeatKeysMask; 25670728a38Smrg else if (_XkbStrCaseCmp(name, "slowkeys") == 0) 25770728a38Smrg *ctrls_rtrn = XkbSlowKeysMask; 25870728a38Smrg else if (_XkbStrCaseCmp(name, "bouncekeys") == 0) 25970728a38Smrg *ctrls_rtrn = XkbBounceKeysMask; 26070728a38Smrg else if (_XkbStrCaseCmp(name, "stickykeys") == 0) 26170728a38Smrg *ctrls_rtrn = XkbStickyKeysMask; 26270728a38Smrg else if (_XkbStrCaseCmp(name, "mousekeys") == 0) 26370728a38Smrg *ctrls_rtrn = XkbMouseKeysMask; 26470728a38Smrg else if (_XkbStrCaseCmp(name, "mousekeysaccel") == 0) 26570728a38Smrg *ctrls_rtrn = XkbMouseKeysAccelMask; 26670728a38Smrg else if (_XkbStrCaseCmp(name, "accessxkeys") == 0) 26770728a38Smrg *ctrls_rtrn = XkbAccessXKeysMask; 26870728a38Smrg else if (_XkbStrCaseCmp(name, "accessxtimeout") == 0) 26970728a38Smrg *ctrls_rtrn = XkbAccessXTimeoutMask; 27070728a38Smrg else if (_XkbStrCaseCmp(name, "accessxfeedback") == 0) 27170728a38Smrg *ctrls_rtrn = XkbAccessXFeedbackMask; 27270728a38Smrg else if (_XkbStrCaseCmp(name, "audiblebell") == 0) 27370728a38Smrg *ctrls_rtrn = XkbAudibleBellMask; 27470728a38Smrg else if (_XkbStrCaseCmp(name, "overlay1") == 0) 27570728a38Smrg *ctrls_rtrn = XkbOverlay1Mask; 27670728a38Smrg else if (_XkbStrCaseCmp(name, "overlay2") == 0) 27770728a38Smrg *ctrls_rtrn = XkbOverlay2Mask; 27870728a38Smrg else if (_XkbStrCaseCmp(name, "ignoregrouplock") == 0) 27970728a38Smrg *ctrls_rtrn = XkbIgnoreGroupLockMask; 2808c9fbc29Smrg else { 28170728a38Smrg rtrn->error = XkbCF_ExpectedControl; 28270728a38Smrg return False; 2838c9fbc29Smrg } 2848c9fbc29Smrg return True; 2858c9fbc29Smrg} 2868c9fbc29Smrg 2878c9fbc29Smrgstatic Bool 28870728a38SmrgAddAXTimeoutOptByName(XkbConfigRtrnPtr rtrn, 28970728a38Smrg char *name, 29070728a38Smrg unsigned short *opts_rtrn) 2918c9fbc29Smrg{ 29270728a38Smrg if (_XkbStrCaseCmp(name, "slowkeyspress") == 0) 29370728a38Smrg *opts_rtrn = XkbAX_SKPressFBMask; 29470728a38Smrg else if (_XkbStrCaseCmp(name, "slowkeysaccept") == 0) 29570728a38Smrg *opts_rtrn = XkbAX_SKAcceptFBMask; 29670728a38Smrg else if (_XkbStrCaseCmp(name, "feature") == 0) 29770728a38Smrg *opts_rtrn = XkbAX_FeatureFBMask; 29870728a38Smrg else if (_XkbStrCaseCmp(name, "slowwarn") == 0) 29970728a38Smrg *opts_rtrn = XkbAX_SlowWarnFBMask; 30070728a38Smrg else if (_XkbStrCaseCmp(name, "indicator") == 0) 30170728a38Smrg *opts_rtrn = XkbAX_IndicatorFBMask; 30270728a38Smrg else if (_XkbStrCaseCmp(name, "stickykeys") == 0) 30370728a38Smrg *opts_rtrn = XkbAX_StickyKeysFBMask; 30470728a38Smrg else if (_XkbStrCaseCmp(name, "twokeys") == 0) 30570728a38Smrg *opts_rtrn = XkbAX_TwoKeysMask; 30670728a38Smrg else if (_XkbStrCaseCmp(name, "latchtolock") == 0) 30770728a38Smrg *opts_rtrn = XkbAX_LatchToLockMask; 30870728a38Smrg else if (_XkbStrCaseCmp(name, "slowkeysrelease") == 0) 30970728a38Smrg *opts_rtrn = XkbAX_SKReleaseFBMask; 31070728a38Smrg else if (_XkbStrCaseCmp(name, "slowkeysreject") == 0) 31170728a38Smrg *opts_rtrn = XkbAX_SKRejectFBMask; 31270728a38Smrg else if (_XkbStrCaseCmp(name, "bouncekeysreject") == 0) 31370728a38Smrg *opts_rtrn = XkbAX_BKRejectFBMask; 31470728a38Smrg else if (_XkbStrCaseCmp(name, "dumbbell") == 0) 31570728a38Smrg *opts_rtrn = XkbAX_DumbBellFBMask; 3168c9fbc29Smrg else { 31770728a38Smrg rtrn->error = XkbCF_ExpectedControl; 31870728a38Smrg return False; 3198c9fbc29Smrg } 3208c9fbc29Smrg return True; 3218c9fbc29Smrg} 3228c9fbc29Smrg 3238c9fbc29SmrgXkbConfigUnboundModPtr 32470728a38SmrgXkbCFAddModByName(XkbConfigRtrnPtr rtrn, int what, char *name, Bool merge, 32570728a38Smrg XkbConfigUnboundModPtr last) 3268c9fbc29Smrg{ 32770728a38Smrg if (rtrn->num_unbound_mods >= rtrn->sz_unbound_mods) { 32870728a38Smrg rtrn->sz_unbound_mods += 5; 32970728a38Smrg rtrn->unbound_mods = _XkbTypedRealloc(rtrn->unbound_mods, 33070728a38Smrg rtrn->sz_unbound_mods, 33170728a38Smrg XkbConfigUnboundModRec); 33270728a38Smrg if (rtrn->unbound_mods == NULL) { 33370728a38Smrg rtrn->error = XkbCF_BadAlloc; 33470728a38Smrg return NULL; 33570728a38Smrg } 3368c9fbc29Smrg } 33770728a38Smrg if (last == NULL) { 33870728a38Smrg last = &rtrn->unbound_mods[rtrn->num_unbound_mods++]; 33970728a38Smrg last->what = what; 34070728a38Smrg last->mods = 0; 34170728a38Smrg last->vmods = 0; 34270728a38Smrg last->merge = merge; 34370728a38Smrg last->name = NULL; 3448c9fbc29Smrg } 34570728a38Smrg if (_XkbStrCaseCmp(name, "shift") == 0) 34670728a38Smrg last->mods |= ShiftMask; 34770728a38Smrg else if (_XkbStrCaseCmp(name, "lock") == 0) 34870728a38Smrg last->mods |= LockMask; 34970728a38Smrg else if ((_XkbStrCaseCmp(name, "control") == 0) || 35070728a38Smrg (_XkbStrCaseCmp(name, "ctrl") == 0)) 35170728a38Smrg last->mods |= ControlMask; 35270728a38Smrg else if (_XkbStrCaseCmp(name, "mod1") == 0) 35370728a38Smrg last->mods |= Mod1Mask; 35470728a38Smrg else if (_XkbStrCaseCmp(name, "mod2") == 0) 35570728a38Smrg last->mods |= Mod2Mask; 35670728a38Smrg else if (_XkbStrCaseCmp(name, "mod3") == 0) 35770728a38Smrg last->mods |= Mod3Mask; 35870728a38Smrg else if (_XkbStrCaseCmp(name, "mod4") == 0) 35970728a38Smrg last->mods |= Mod4Mask; 36070728a38Smrg else if (_XkbStrCaseCmp(name, "mod5") == 0) 36170728a38Smrg last->mods |= Mod5Mask; 3628c9fbc29Smrg else { 36370728a38Smrg if (last->name != NULL) { 36470728a38Smrg last = &rtrn->unbound_mods[rtrn->num_unbound_mods++]; 36570728a38Smrg last->what = what; 36670728a38Smrg last->mods = 0; 36770728a38Smrg last->vmods = 0; 36870728a38Smrg last->merge = merge; 36970728a38Smrg last->name = NULL; 37070728a38Smrg } 37170728a38Smrg last->name = _XkbDupString(name); 3728c9fbc29Smrg } 3738c9fbc29Smrg return last; 3748c9fbc29Smrg} 3758c9fbc29Smrg 3768c9fbc29Smrgint 37770728a38SmrgXkbCFBindMods(XkbConfigRtrnPtr rtrn, XkbDescPtr xkb) 3788c9fbc29Smrg{ 37970728a38Smrg register int n, v; 38070728a38Smrg Atom name; 38170728a38Smrg XkbConfigUnboundModPtr mod; 38270728a38Smrg int missing; 38370728a38Smrg 38470728a38Smrg if (rtrn->num_unbound_mods < 1) 38570728a38Smrg return 0; 38670728a38Smrg if ((xkb == NULL) || (xkb->names == NULL)) 38770728a38Smrg return -1; 38870728a38Smrg 38970728a38Smrg missing = 0; 39070728a38Smrg for (n = 0, mod = rtrn->unbound_mods; n < rtrn->num_unbound_mods; 39170728a38Smrg n++, mod++) { 39270728a38Smrg if (mod->name != NULL) { 39370728a38Smrg name = XkbInternAtom(xkb->dpy, mod->name, True); 39470728a38Smrg if (name == None) 39570728a38Smrg continue; 39670728a38Smrg for (v = 0; v < XkbNumVirtualMods; v++) { 39770728a38Smrg if (xkb->names->vmods[v] == name) { 39870728a38Smrg mod->vmods = (1 << v); 39970728a38Smrg _XkbFree(mod->name); 40070728a38Smrg mod->name = NULL; 40170728a38Smrg break; 40270728a38Smrg } 40370728a38Smrg } 40470728a38Smrg if (mod->name != NULL) 40570728a38Smrg missing++; 40670728a38Smrg } 4078c9fbc29Smrg } 4088c9fbc29Smrg return missing; 4098c9fbc29Smrg} 4108c9fbc29Smrg 4118c9fbc29SmrgBool 41270728a38SmrgXkbCFApplyMods(XkbConfigRtrnPtr rtrn, int what, XkbConfigModInfoPtr info) 4138c9fbc29Smrg{ 41470728a38Smrg register int n; 41570728a38Smrg XkbConfigUnboundModPtr mod; 41670728a38Smrg 41770728a38Smrg if (rtrn->num_unbound_mods < 1) 41870728a38Smrg return True; 41970728a38Smrg 42070728a38Smrg for (n = 0, mod = rtrn->unbound_mods; n < rtrn->num_unbound_mods; 42170728a38Smrg n++, mod++) { 42270728a38Smrg if (mod->what != what) 42370728a38Smrg continue; 42470728a38Smrg if (mod->merge == XkbCF_MergeRemove) { 42570728a38Smrg info->mods_clear |= mod->mods; 42670728a38Smrg info->vmods_clear |= mod->vmods; 42770728a38Smrg } 42870728a38Smrg else { 42970728a38Smrg if (mod->merge == XkbCF_MergeSet) 43070728a38Smrg info->replace = True; 43170728a38Smrg info->mods |= mod->mods; 43270728a38Smrg info->vmods |= mod->vmods; 43370728a38Smrg } 43470728a38Smrg if (mod->name == NULL) { 43570728a38Smrg mod->what = _XkbCF_Illegal; 43670728a38Smrg } 43770728a38Smrg else { 43870728a38Smrg mod->mods = 0; 43970728a38Smrg mod->vmods = 0; 44070728a38Smrg } 4418c9fbc29Smrg } 4428c9fbc29Smrg return True; 4438c9fbc29Smrg} 4448c9fbc29Smrg 4458c9fbc29Smrg/*ARGSUSED*/ 4468c9fbc29Smrgstatic Bool 44770728a38SmrgDefaultParser(FILE * file, 44870728a38Smrg XkbConfigFieldsPtr fields, 44970728a38Smrg XkbConfigFieldPtr field, 45070728a38Smrg XkbDescPtr xkb, 45170728a38Smrg XkbConfigRtrnPtr rtrn) 4528c9fbc29Smrg{ 45370728a38Smrg int tok; 45470728a38Smrg XkbCFScanResultRec val; 45570728a38Smrg char **str; 45670728a38Smrg int merge; 45770728a38Smrg unsigned long *ctrls, ctrls_mask; 45870728a38Smrg unsigned short *opts, opts_mask; 45970728a38Smrg int *pival, sign; 46070728a38Smrg int onoff; 46170728a38Smrg XkbConfigUnboundModPtr last; 46270728a38Smrg unsigned what; 46370728a38Smrg 46470728a38Smrg tok = XkbCFScan(file, &val, rtrn); 46570728a38Smrg str = NULL; 46670728a38Smrg onoff = 0; 46770728a38Smrg pival = NULL; 4688c9fbc29Smrg switch (field->field_id) { 46970728a38Smrg case _XkbCF_RulesFile: if (!str) str = &rtrn->rules_file; 47070728a38Smrg case _XkbCF_Model: if (!str) str = &rtrn->model; 47170728a38Smrg case _XkbCF_Layout: if (!str) str = &rtrn->layout; 47270728a38Smrg case _XkbCF_Variant: if (!str) str = &rtrn->variant; 47370728a38Smrg case _XkbCF_Options: if (!str) str = &rtrn->options; 47470728a38Smrg case _XkbCF_Keymap: if (!str) str = &rtrn->keymap; 47570728a38Smrg case _XkbCF_Keycodes: if (!str) str = &rtrn->keycodes; 47670728a38Smrg case _XkbCF_Geometry: if (!str) str = &rtrn->geometry; 47770728a38Smrg case _XkbCF_PhysSymbols: if (!str) str = &rtrn->phys_symbols; 47870728a38Smrg case _XkbCF_Symbols: if (!str) str = &rtrn->symbols; 47970728a38Smrg case _XkbCF_Types: if (!str) str = &rtrn->types; 48070728a38Smrg case _XkbCF_CompatMap: if (!str) str = &rtrn->compat; 48170728a38Smrg if (tok != XkbCF_Equals) { 48270728a38Smrg rtrn->error = XkbCF_MissingEquals; 48370728a38Smrg goto BAILOUT; 48470728a38Smrg } 48570728a38Smrg tok = XkbCFScan(file, &val, rtrn); 48670728a38Smrg if ((tok != XkbCF_String) && (tok != XkbCF_Ident)) { 48770728a38Smrg rtrn->error = XkbCF_ExpectedString; 48870728a38Smrg return False; 48970728a38Smrg } 49070728a38Smrg tok = XkbCFScan(file, &val, rtrn); 49170728a38Smrg if ((tok != XkbCF_EOL) && (tok != XkbCF_Semi) && (tok != XkbCF_EOF)) { 49270728a38Smrg rtrn->error = XkbCF_ExpectedEOS; 49370728a38Smrg return False; 49470728a38Smrg } 49570728a38Smrg if (*str != NULL) 49670728a38Smrg _XkbFree(*str); 49770728a38Smrg *str = _XkbDupString(val.str); 49870728a38Smrg break; 49970728a38Smrg case _XkbCF_InitialMods: 50070728a38Smrg case _XkbCF_IgnoreLockMods: 50170728a38Smrg case _XkbCF_InternalMods: 50270728a38Smrg what = XkbCF_InitialMods; 50370728a38Smrg if (field->field_id == _XkbCF_InitialMods) 50470728a38Smrg rtrn->defined |= (what = XkbCF_InitialMods); 50570728a38Smrg else if (field->field_id == _XkbCF_InternalMods) 50670728a38Smrg rtrn->defined |= (what = XkbCF_InternalMods); 50770728a38Smrg else if (field->field_id == _XkbCF_IgnoreLockMods) 50870728a38Smrg rtrn->defined |= (what = XkbCF_IgnoreLockMods); 50970728a38Smrg if (tok == XkbCF_Equals) 51070728a38Smrg merge = XkbCF_MergeSet; 51170728a38Smrg else if (tok == XkbCF_MinusEquals) 51270728a38Smrg merge = XkbCF_MergeRemove; 51370728a38Smrg else if (tok == XkbCF_PlusEquals) 51470728a38Smrg merge = XkbCF_MergeAdd; 51570728a38Smrg else { 51670728a38Smrg rtrn->error = XkbCF_MissingEquals; 51770728a38Smrg goto BAILOUT; 51870728a38Smrg } 51970728a38Smrg tok = XkbCFScan(file, &val, rtrn); 52070728a38Smrg if ((tok == XkbCF_EOL) || (tok == XkbCF_Semi) || (tok == XkbCF_EOF)) { 52170728a38Smrg rtrn->error = XkbCF_ExpectedModifier; 52270728a38Smrg return False; 52370728a38Smrg } 52470728a38Smrg last = NULL; 52570728a38Smrg while ((tok != XkbCF_EOL) && (tok != XkbCF_Semi) && (tok != XkbCF_EOF)) { 52670728a38Smrg if ((tok != XkbCF_Ident) && (tok != XkbCF_String)) { 52770728a38Smrg rtrn->error = XkbCF_ExpectedModifier; 52870728a38Smrg return False; 52970728a38Smrg } 53070728a38Smrg last = XkbCFAddModByName(rtrn, what, val.str, merge, last); 53170728a38Smrg if (last == NULL) 53270728a38Smrg return False; 53370728a38Smrg if (merge == XkbCF_MergeSet) 53470728a38Smrg merge = XkbCF_MergeAdd; 53570728a38Smrg tok = XkbCFScan(file, &val, rtrn); 53670728a38Smrg if ((tok != XkbCF_EOL) && (tok != XkbCF_EOF) && (tok != XkbCF_Semi)) { 53770728a38Smrg if (tok != XkbCF_Plus) { 53870728a38Smrg rtrn->error = XkbCF_ExpectedOperator; 53970728a38Smrg return False; 54070728a38Smrg } 54170728a38Smrg tok = XkbCFScan(file, &val, rtrn); 54270728a38Smrg } 54370728a38Smrg } 54470728a38Smrg break; 54570728a38Smrg case _XkbCF_InitialCtrls: 54670728a38Smrg rtrn->defined |= XkbCF_InitialCtrls; 54770728a38Smrg ctrls = NULL; 54870728a38Smrg if (tok == XkbCF_PlusEquals) 54970728a38Smrg ctrls = &rtrn->initial_ctrls; 55070728a38Smrg else if (tok == XkbCF_MinusEquals) 55170728a38Smrg ctrls = &rtrn->initial_ctrls_clear; 55270728a38Smrg else if (tok == XkbCF_Equals) { 55370728a38Smrg ctrls = &rtrn->initial_ctrls; 55470728a38Smrg rtrn->replace_initial_ctrls = True; 55570728a38Smrg *ctrls = 0; 55670728a38Smrg } 55770728a38Smrg else { 55870728a38Smrg rtrn->error = XkbCF_MissingEquals; 55970728a38Smrg goto BAILOUT; 56070728a38Smrg } 56170728a38Smrg tok = XkbCFScan(file, &val, rtrn); 56270728a38Smrg if ((tok == XkbCF_EOL) || (tok == XkbCF_Semi) || (tok == XkbCF_EOF)) { 56370728a38Smrg rtrn->error = XkbCF_ExpectedControl; 56470728a38Smrg return False; 56570728a38Smrg } 56670728a38Smrg while ((tok != XkbCF_EOL) && (tok != XkbCF_Semi) && (tok != XkbCF_EOF)) { 56770728a38Smrg if ((tok != XkbCF_Ident) && (tok != XkbCF_String)) { 56870728a38Smrg rtrn->error = XkbCF_ExpectedControl; 56970728a38Smrg return False; 57070728a38Smrg } 57170728a38Smrg if (!AddCtrlByName(rtrn, val.str, &ctrls_mask)) { 57270728a38Smrg return False; 57370728a38Smrg } 57470728a38Smrg *ctrls |= ctrls_mask; 57570728a38Smrg tok = XkbCFScan(file, &val, rtrn); 57670728a38Smrg if ((tok != XkbCF_EOL) && (tok != XkbCF_EOF) && (tok != XkbCF_Semi)) { 57770728a38Smrg if (tok != XkbCF_Plus) { 57870728a38Smrg rtrn->error = XkbCF_ExpectedOperator; 57970728a38Smrg return False; 58070728a38Smrg } 58170728a38Smrg tok = XkbCFScan(file, &val, rtrn); 58270728a38Smrg } 58370728a38Smrg } 58470728a38Smrg break; 58570728a38Smrg case _XkbCF_AccessXTimeoutCtrlsOn: 58670728a38Smrg case _XkbCF_AccessXTimeoutCtrlsOff: 58770728a38Smrg opts = NULL; 58870728a38Smrg if (tok == XkbCF_MinusEquals) { 58970728a38Smrg ctrls = &rtrn->axt_ctrls_ignore; 59070728a38Smrg opts = &rtrn->axt_opts_ignore; 59170728a38Smrg } 59270728a38Smrg else if ((tok == XkbCF_PlusEquals) || (tok == XkbCF_Equals)) { 59370728a38Smrg if (field->field_id == _XkbCF_AccessXTimeoutCtrlsOff) { 59470728a38Smrg ctrls = &rtrn->axt_ctrls_off; 59570728a38Smrg opts = &rtrn->axt_opts_off; 59670728a38Smrg if (tok == XkbCF_Equals) 59770728a38Smrg rtrn->replace_axt_ctrls_off = True; 59870728a38Smrg } 59970728a38Smrg else { 60070728a38Smrg ctrls = &rtrn->axt_ctrls_on; 60170728a38Smrg opts = &rtrn->axt_opts_on; 60270728a38Smrg if (tok == XkbCF_Equals) 60370728a38Smrg rtrn->replace_axt_ctrls_on = True; 60470728a38Smrg } 60570728a38Smrg *ctrls = 0; 60670728a38Smrg } 60770728a38Smrg else { 60870728a38Smrg rtrn->error = XkbCF_MissingEquals; 60970728a38Smrg goto BAILOUT; 61070728a38Smrg } 61170728a38Smrg tok = XkbCFScan(file, &val, rtrn); 61270728a38Smrg if ((tok == XkbCF_EOL) || (tok == XkbCF_Semi) || (tok == XkbCF_EOF)) { 61370728a38Smrg rtrn->error = XkbCF_ExpectedControl; 61470728a38Smrg return False; 61570728a38Smrg } 61670728a38Smrg while ((tok != XkbCF_EOL) && (tok != XkbCF_Semi) && (tok != XkbCF_EOF)) { 61770728a38Smrg if ((tok != XkbCF_Ident) && (tok != XkbCF_String)) { 61870728a38Smrg rtrn->error = XkbCF_ExpectedControl; 61970728a38Smrg return False; 62070728a38Smrg } 62170728a38Smrg if (!AddCtrlByName(rtrn, val.str, &ctrls_mask)) { 62270728a38Smrg if (!AddAXTimeoutOptByName(rtrn, val.str, &opts_mask)) 62370728a38Smrg return False; 62470728a38Smrg *opts |= opts_mask; 62570728a38Smrg if (field->field_id == _XkbCF_AccessXTimeoutCtrlsOff) { 62670728a38Smrg rtrn->defined |= XkbCF_AccessXTimeoutOptsOff; 62770728a38Smrg if (rtrn->replace_axt_ctrls_off) 62870728a38Smrg rtrn->replace_axt_opts_off = True; 62970728a38Smrg } 63070728a38Smrg else { 63170728a38Smrg rtrn->defined |= XkbCF_AccessXTimeoutOptsOn; 63270728a38Smrg if (rtrn->replace_axt_ctrls_on) 63370728a38Smrg rtrn->replace_axt_opts_on = True; 63470728a38Smrg } 63570728a38Smrg } 63670728a38Smrg else 63770728a38Smrg *ctrls |= ctrls_mask; 63870728a38Smrg tok = XkbCFScan(file, &val, rtrn); 63970728a38Smrg if ((tok != XkbCF_EOL) && (tok != XkbCF_EOF) && (tok != XkbCF_Semi)) { 64070728a38Smrg if (tok != XkbCF_Plus) { 64170728a38Smrg rtrn->error = XkbCF_ExpectedOperator; 64270728a38Smrg return False; 64370728a38Smrg } 64470728a38Smrg tok = XkbCFScan(file, &val, rtrn); 64570728a38Smrg } 64670728a38Smrg } 64770728a38Smrg break; 64870728a38Smrg case _XkbCF_InitialFeedback: 64970728a38Smrg rtrn->defined |= XkbCF_InitialOpts; 65070728a38Smrg opts = NULL; 65170728a38Smrg if (tok == XkbCF_PlusEquals) 65270728a38Smrg opts = &rtrn->initial_opts; 65370728a38Smrg else if (tok == XkbCF_MinusEquals) 65470728a38Smrg opts = &rtrn->initial_opts_clear; 65570728a38Smrg else if (tok == XkbCF_Equals) { 65670728a38Smrg opts = &rtrn->initial_opts; 65770728a38Smrg rtrn->replace_initial_opts = True; 65870728a38Smrg *opts = 0; 65970728a38Smrg } 66070728a38Smrg else { 66170728a38Smrg rtrn->error = XkbCF_MissingEquals; 66270728a38Smrg goto BAILOUT; 66370728a38Smrg } 66470728a38Smrg tok = XkbCFScan(file, &val, rtrn); 66570728a38Smrg if ((tok == XkbCF_EOL) || (tok == XkbCF_Semi) || (tok == XkbCF_EOF)) { 66670728a38Smrg rtrn->error = XkbCF_ExpectedAXOption; 66770728a38Smrg return False; 66870728a38Smrg } 66970728a38Smrg while ((tok != XkbCF_EOL) && (tok != XkbCF_Semi) && (tok != XkbCF_EOF)) { 67070728a38Smrg if ((tok != XkbCF_Ident) && (tok != XkbCF_String)) { 67170728a38Smrg rtrn->error = XkbCF_ExpectedAXOption; 67270728a38Smrg return False; 67370728a38Smrg } 67470728a38Smrg if (!AddAXTimeoutOptByName(rtrn, val.str, &opts_mask)) { 67570728a38Smrg return False; 67670728a38Smrg } 67770728a38Smrg *opts |= opts_mask; 67870728a38Smrg tok = XkbCFScan(file, &val, rtrn); 67970728a38Smrg if ((tok != XkbCF_EOL) && (tok != XkbCF_EOF) && (tok != XkbCF_Semi)) { 68070728a38Smrg if (tok != XkbCF_Plus) { 68170728a38Smrg rtrn->error = XkbCF_ExpectedOperator; 68270728a38Smrg return False; 68370728a38Smrg } 68470728a38Smrg tok = XkbCFScan(file, &val, rtrn); 68570728a38Smrg } 68670728a38Smrg } 68770728a38Smrg break; 68870728a38Smrg case _XkbCF_AccessXTimeoutOptsOff: 68970728a38Smrg case _XkbCF_AccessXTimeoutOptsOn: 69070728a38Smrg opts = NULL; 69170728a38Smrg if (tok == XkbCF_MinusEquals) 69270728a38Smrg opts = &rtrn->axt_opts_ignore; 69370728a38Smrg else if ((tok == XkbCF_PlusEquals) || (tok == XkbCF_Equals)) { 69470728a38Smrg if (field->field_id == _XkbCF_AccessXTimeoutOptsOff) { 69570728a38Smrg opts = &rtrn->axt_opts_off; 69670728a38Smrg if (tok == XkbCF_Equals) 69770728a38Smrg rtrn->replace_axt_opts_off = True; 69870728a38Smrg } 69970728a38Smrg else { 70070728a38Smrg opts = &rtrn->axt_opts_on; 70170728a38Smrg if (tok == XkbCF_Equals) 70270728a38Smrg rtrn->replace_axt_opts_on = True; 70370728a38Smrg } 70470728a38Smrg *opts = 0; 70570728a38Smrg } 70670728a38Smrg else { 70770728a38Smrg rtrn->error = XkbCF_MissingEquals; 70870728a38Smrg goto BAILOUT; 70970728a38Smrg } 71070728a38Smrg tok = XkbCFScan(file, &val, rtrn); 71170728a38Smrg if ((tok == XkbCF_EOL) || (tok == XkbCF_Semi) || (tok == XkbCF_EOF)) { 71270728a38Smrg rtrn->error = XkbCF_ExpectedControl; 71370728a38Smrg return False; 71470728a38Smrg } 71570728a38Smrg while ((tok != XkbCF_EOL) && (tok != XkbCF_Semi) && (tok != XkbCF_EOF)) { 71670728a38Smrg if ((tok != XkbCF_Ident) && (tok != XkbCF_String)) { 71770728a38Smrg rtrn->error = XkbCF_ExpectedControl; 71870728a38Smrg return False; 71970728a38Smrg } 72070728a38Smrg if (!AddAXTimeoutOptByName(rtrn, val.str, &opts_mask)) 72170728a38Smrg return False; 72270728a38Smrg *opts |= opts_mask; 72370728a38Smrg 72470728a38Smrg tok = XkbCFScan(file, &val, rtrn); 72570728a38Smrg if ((tok != XkbCF_EOL) && (tok != XkbCF_EOF) && (tok != XkbCF_Semi)) { 72670728a38Smrg if (tok != XkbCF_Plus) { 72770728a38Smrg rtrn->error = XkbCF_ExpectedOperator; 72870728a38Smrg return False; 72970728a38Smrg } 73070728a38Smrg tok = XkbCFScan(file, &val, rtrn); 73170728a38Smrg } 73270728a38Smrg } 73370728a38Smrg break; 73470728a38Smrg case _XkbCF_ClickVolume: 73570728a38Smrg if (!pival) { 73670728a38Smrg pival = &rtrn->click_volume; 73770728a38Smrg onoff = 100; 73870728a38Smrg } 73970728a38Smrg case _XkbCF_BellVolume: 74070728a38Smrg if (!pival) { 74170728a38Smrg pival = &rtrn->bell_volume; 74270728a38Smrg onoff = 100; 74370728a38Smrg } 74470728a38Smrg case _XkbCF_BellPitch: if (!pival) pival = &rtrn->bell_pitch; 74570728a38Smrg case _XkbCF_BellDuration: if (!pival) pival = &rtrn->bell_duration; 74670728a38Smrg case _XkbCF_RepeatDelay: if (!pival) pival = &rtrn->repeat_delay; 74770728a38Smrg case _XkbCF_RepeatInterval: if (!pival) pival = &rtrn->repeat_interval; 74870728a38Smrg case _XkbCF_SlowKeysDelay: if (!pival) pival = &rtrn->slow_keys_delay; 74970728a38Smrg case _XkbCF_DebounceDelay: if (!pival) pival = &rtrn->debounce_delay; 75070728a38Smrg case _XkbCF_MouseKeysDelay: if (!pival) pival = &rtrn->mk_delay; 75170728a38Smrg case _XkbCF_MouseKeysInterval: if (!pival) pival = &rtrn->mk_interval; 75270728a38Smrg case _XkbCF_MouseKeysTimeToMax: if (!pival) pival = &rtrn->mk_time_to_max; 75370728a38Smrg case _XkbCF_MouseKeysMaxSpeed: if (!pival) pival = &rtrn->mk_max_speed; 75470728a38Smrg case _XkbCF_MouseKeysCurve: if (!pival) pival = &rtrn->mk_curve; 75570728a38Smrg case _XkbCF_AccessXTimeout: if (!pival) pival = &rtrn->ax_timeout; 75670728a38Smrg if (tok != XkbCF_Equals) { 75770728a38Smrg rtrn->error = XkbCF_MissingEquals; 75870728a38Smrg goto BAILOUT; 75970728a38Smrg } 76070728a38Smrg tok = XkbCFScan(file, &val, rtrn); 76170728a38Smrg if (tok == XkbCF_Minus && field->field_id == _XkbCF_MouseKeysCurve) { 76270728a38Smrg /* This can be a negative value */ 76370728a38Smrg tok = XkbCFScan(file, &val, rtrn); 76470728a38Smrg sign = -1; 76570728a38Smrg } 76670728a38Smrg else 76770728a38Smrg sign = 1; 76870728a38Smrg if (tok != XkbCF_Integer) { 76970728a38Smrg Bool ok = False; 77070728a38Smrg 77170728a38Smrg if ((onoff) && (tok == XkbCF_Ident) && (val.str != NULL)) { 77270728a38Smrg if (_XkbStrCaseCmp(val.str, "on")) { 77370728a38Smrg val.ival = onoff; 77470728a38Smrg ok = True; 77570728a38Smrg } 77670728a38Smrg else if (_XkbStrCaseCmp(val.str, "off")) { 77770728a38Smrg val.ival = 0; 77870728a38Smrg ok = True; 77970728a38Smrg } 78070728a38Smrg } 78170728a38Smrg if (!ok) { 78270728a38Smrg rtrn->error = XkbCF_ExpectedInteger; 78370728a38Smrg goto BAILOUT; 78470728a38Smrg } 78570728a38Smrg } 78670728a38Smrg *pival = val.ival * sign; 78770728a38Smrg if (field->field_id == _XkbCF_AccessXTimeout) 78870728a38Smrg rtrn->defined |= XkbCF_AccessXTimeout; 78970728a38Smrg tok = XkbCFScan(file, &val, rtrn); 79070728a38Smrg if ((tok != XkbCF_EOL) && (tok != XkbCF_Semi) && (tok != XkbCF_EOF)) { 79170728a38Smrg rtrn->error = XkbCF_ExpectedEOS; 79270728a38Smrg return False; 79370728a38Smrg } 79470728a38Smrg break; 79570728a38Smrg case _XkbCF_GroupsWrap: 79670728a38Smrg if (tok != XkbCF_Equals) { 79770728a38Smrg rtrn->error = XkbCF_MissingEquals; 79870728a38Smrg goto BAILOUT; 79970728a38Smrg } 80070728a38Smrg tok = XkbCFScan(file, &val, rtrn); 80170728a38Smrg if (tok == XkbCF_Ident) { 80270728a38Smrg if (_XkbStrCaseCmp(val.str, "wrap") == 0) { 80370728a38Smrg rtrn->groups_wrap = XkbSetGroupInfo(0, XkbWrapIntoRange, 0); 80470728a38Smrg } 80570728a38Smrg else if (_XkbStrCaseCmp(val.str, "clamp") == 0) { 80670728a38Smrg rtrn->groups_wrap = XkbSetGroupInfo(0, XkbClampIntoRange, 0); 80770728a38Smrg } 80870728a38Smrg else { 80970728a38Smrg rtrn->error = XkbCF_ExpectedOORGroupBehavior; 81070728a38Smrg return False; 81170728a38Smrg } 81270728a38Smrg } 81370728a38Smrg else if ((tok == XkbCF_Integer) && (XkbIsLegalGroup(val.ival - 1))) { 81470728a38Smrg rtrn->groups_wrap = XkbSetGroupInfo(0, XkbRedirectIntoRange, 81570728a38Smrg val.ival - 1); 81670728a38Smrg } 81770728a38Smrg else { 81870728a38Smrg rtrn->error = XkbCF_ExpectedOORGroupBehavior; 81970728a38Smrg return False; 82070728a38Smrg } 82170728a38Smrg rtrn->defined |= XkbCF_GroupsWrap; 82270728a38Smrg tok = XkbCFScan(file, &val, rtrn); 82370728a38Smrg if ((tok != XkbCF_EOL) && (tok != XkbCF_Semi) && (tok != XkbCF_EOF)) { 82470728a38Smrg rtrn->error = XkbCF_ExpectedEOS; 82570728a38Smrg return False; 82670728a38Smrg } 82770728a38Smrg break; 82870728a38Smrg default: 82970728a38Smrg rtrn->error = XkbCF_ExpectedInteger; 83070728a38Smrg goto BAILOUT; 8314cd6a3aeSmrg 8328c9fbc29Smrg } 8338c9fbc29Smrg return True; 83470728a38Smrg BAILOUT: 8358c9fbc29Smrg return False; 8368c9fbc29Smrg} 8378c9fbc29Smrg 8388c9fbc29Smrgstatic Bool 8398c9fbc29SmrgDefaultCleanUp(XkbConfigRtrnPtr rtrn) 8408c9fbc29Smrg{ 84170728a38Smrg if (rtrn->keymap) 84270728a38Smrg _XkbFree(rtrn->keymap); 84370728a38Smrg if (rtrn->keycodes) 84470728a38Smrg _XkbFree(rtrn->keycodes); 84570728a38Smrg if (rtrn->geometry) 84670728a38Smrg _XkbFree(rtrn->geometry); 84770728a38Smrg if (rtrn->phys_symbols) 84870728a38Smrg _XkbFree(rtrn->phys_symbols); 84970728a38Smrg if (rtrn->symbols) 85070728a38Smrg _XkbFree(rtrn->symbols); 85170728a38Smrg if (rtrn->types) 85270728a38Smrg _XkbFree(rtrn->types); 85370728a38Smrg if (rtrn->compat) 85470728a38Smrg _XkbFree(rtrn->compat); 85570728a38Smrg rtrn->keycodes = rtrn->geometry = NULL; 85670728a38Smrg rtrn->symbols = rtrn->phys_symbols = NULL; 85770728a38Smrg rtrn->types = rtrn->compat = NULL; 85870728a38Smrg if ((rtrn->unbound_mods != NULL) && (rtrn->num_unbound_mods > 0)) { 85970728a38Smrg register int i; 86070728a38Smrg 86170728a38Smrg for (i = 0; i < rtrn->num_unbound_mods; i++) { 86270728a38Smrg if (rtrn->unbound_mods[i].name != NULL) { 86370728a38Smrg _XkbFree(rtrn->unbound_mods[i].name); 86470728a38Smrg rtrn->unbound_mods[i].name = NULL; 86570728a38Smrg } 86670728a38Smrg } 86770728a38Smrg _XkbFree(rtrn->unbound_mods); 86870728a38Smrg rtrn->sz_unbound_mods = 0; 86970728a38Smrg rtrn->num_unbound_mods = 0; 87070728a38Smrg rtrn->unbound_mods = NULL; 8718c9fbc29Smrg } 8728c9fbc29Smrg return True; 8738c9fbc29Smrg} 8748c9fbc29Smrg 8758c9fbc29Smrgstatic Bool 87670728a38SmrgDefaultApplyNames(XkbConfigRtrnPtr rtrn, XkbDescPtr xkb) 8778c9fbc29Smrg{ 87870728a38Smrg char *str; 87970728a38Smrg 88070728a38Smrg if (XkbAllocNames(xkb, XkbComponentNamesMask, 0, 0) != Success) 88170728a38Smrg return False; 88270728a38Smrg if ((str = rtrn->keycodes) != NULL) { 88370728a38Smrg xkb->names->keycodes = XkbInternAtom(xkb->dpy, str, False); 88470728a38Smrg _XkbFree(str); 88570728a38Smrg rtrn->keycodes = NULL; 8868c9fbc29Smrg } 88770728a38Smrg if ((str = rtrn->geometry) != NULL) { 88870728a38Smrg xkb->names->geometry = XkbInternAtom(xkb->dpy, str, False); 88970728a38Smrg _XkbFree(str); 89070728a38Smrg rtrn->geometry = NULL; 8918c9fbc29Smrg } 89270728a38Smrg if ((str = rtrn->symbols) != NULL) { 89370728a38Smrg xkb->names->symbols = XkbInternAtom(xkb->dpy, str, False); 89470728a38Smrg _XkbFree(str); 89570728a38Smrg rtrn->symbols = NULL; 8968c9fbc29Smrg } 89770728a38Smrg if ((str = rtrn->phys_symbols) != NULL) { 89870728a38Smrg xkb->names->phys_symbols = XkbInternAtom(xkb->dpy, str, False); 89970728a38Smrg _XkbFree(str); 90070728a38Smrg rtrn->phys_symbols = NULL; 9018c9fbc29Smrg } 90270728a38Smrg if ((str = rtrn->types) != NULL) { 90370728a38Smrg xkb->names->types = XkbInternAtom(xkb->dpy, str, False); 90470728a38Smrg _XkbFree(str); 90570728a38Smrg rtrn->types = NULL; 9068c9fbc29Smrg } 90770728a38Smrg if ((str = rtrn->compat) != NULL) { 90870728a38Smrg xkb->names->compat = XkbInternAtom(xkb->dpy, str, False); 90970728a38Smrg _XkbFree(str); 91070728a38Smrg rtrn->compat = NULL; 9118c9fbc29Smrg } 9128c9fbc29Smrg return True; 9138c9fbc29Smrg} 9148c9fbc29Smrg 9158c9fbc29Smrgstatic Bool 91670728a38SmrgDefaultApplyControls(XkbConfigRtrnPtr rtrn, XkbDescPtr xkb) 9178c9fbc29Smrg{ 91870728a38Smrg unsigned on, off; 91970728a38Smrg XkbControlsPtr ctrls; 92070728a38Smrg unsigned int mask; 9218c9fbc29Smrg 92270728a38Smrg if (XkbAllocControls(xkb, XkbAllControlsMask) != Success) 92370728a38Smrg return False; 92470728a38Smrg ctrls = xkb->ctrls; 9258c9fbc29Smrg if (rtrn->replace_initial_ctrls) 92670728a38Smrg ctrls->enabled_ctrls = rtrn->initial_ctrls; 92770728a38Smrg else 92870728a38Smrg ctrls->enabled_ctrls |= rtrn->initial_ctrls; 92970728a38Smrg ctrls->enabled_ctrls &= ~rtrn->initial_ctrls_clear; 9308c9fbc29Smrg if (rtrn->internal_mods.replace) { 93170728a38Smrg ctrls->internal.real_mods = rtrn->internal_mods.mods; 93270728a38Smrg ctrls->internal.vmods = rtrn->internal_mods.vmods; 9338c9fbc29Smrg } 9348c9fbc29Smrg else { 93570728a38Smrg ctrls->internal.real_mods &= ~rtrn->internal_mods.mods_clear; 93670728a38Smrg ctrls->internal.vmods &= ~rtrn->internal_mods.vmods_clear; 93770728a38Smrg ctrls->internal.real_mods |= rtrn->internal_mods.mods; 93870728a38Smrg ctrls->internal.vmods |= rtrn->internal_mods.vmods; 9398c9fbc29Smrg } 94070728a38Smrg mask = 0; 94170728a38Smrg (void) XkbVirtualModsToReal(xkb, ctrls->internal.vmods, &mask); 94270728a38Smrg ctrls->internal.mask = (ctrls->internal.real_mods | mask); 9438c9fbc29Smrg 9448c9fbc29Smrg if (rtrn->ignore_lock_mods.replace) { 94570728a38Smrg ctrls->ignore_lock.real_mods = rtrn->ignore_lock_mods.mods; 94670728a38Smrg ctrls->ignore_lock.vmods = rtrn->ignore_lock_mods.vmods; 9478c9fbc29Smrg } 9488c9fbc29Smrg else { 94970728a38Smrg ctrls->ignore_lock.real_mods &= ~rtrn->ignore_lock_mods.mods_clear; 95070728a38Smrg ctrls->ignore_lock.vmods &= ~rtrn->ignore_lock_mods.vmods_clear; 95170728a38Smrg ctrls->ignore_lock.real_mods |= rtrn->ignore_lock_mods.mods; 95270728a38Smrg ctrls->ignore_lock.vmods |= rtrn->ignore_lock_mods.vmods; 9538c9fbc29Smrg } 95470728a38Smrg mask = 0; 95570728a38Smrg (void) XkbVirtualModsToReal(xkb, ctrls->ignore_lock.vmods, &mask); 95670728a38Smrg ctrls->ignore_lock.mask = (ctrls->ignore_lock.real_mods | mask); 95770728a38Smrg 95870728a38Smrg if (rtrn->repeat_delay > 0) 95970728a38Smrg ctrls->repeat_delay = rtrn->repeat_delay; 96070728a38Smrg if (rtrn->repeat_interval > 0) 96170728a38Smrg ctrls->repeat_interval = rtrn->repeat_interval; 96270728a38Smrg if (rtrn->slow_keys_delay > 0) 96370728a38Smrg ctrls->slow_keys_delay = rtrn->slow_keys_delay; 96470728a38Smrg if (rtrn->debounce_delay > 0) 96570728a38Smrg ctrls->debounce_delay = rtrn->debounce_delay; 96670728a38Smrg if (rtrn->mk_delay > 0) 96770728a38Smrg ctrls->mk_delay = rtrn->mk_delay; 96870728a38Smrg if (rtrn->mk_interval > 0) 96970728a38Smrg ctrls->mk_interval = rtrn->mk_interval; 97070728a38Smrg if (rtrn->mk_time_to_max > 0) 97170728a38Smrg ctrls->mk_time_to_max = rtrn->mk_time_to_max; 97270728a38Smrg if (rtrn->mk_max_speed > 0) 97370728a38Smrg ctrls->mk_max_speed = rtrn->mk_max_speed; 97470728a38Smrg if (rtrn->mk_curve > 0) 97570728a38Smrg ctrls->mk_curve = rtrn->mk_curve; 97670728a38Smrg if (rtrn->defined & XkbCF_AccessXTimeout && rtrn->ax_timeout > 0) 97770728a38Smrg ctrls->ax_timeout = rtrn->ax_timeout; 9788c9fbc29Smrg 9798c9fbc29Smrg /* any value set to both off and on is reset to ignore */ 98070728a38Smrg if ((off = (rtrn->axt_ctrls_on & rtrn->axt_ctrls_off)) != 0) 98170728a38Smrg rtrn->axt_ctrls_ignore |= off; 9828c9fbc29Smrg 9838c9fbc29Smrg /* ignore takes priority over on and off */ 98470728a38Smrg rtrn->axt_ctrls_on &= ~rtrn->axt_ctrls_ignore; 98570728a38Smrg rtrn->axt_ctrls_off &= ~rtrn->axt_ctrls_ignore; 9868c9fbc29Smrg 9878c9fbc29Smrg if (!rtrn->replace_axt_ctrls_off) { 98870728a38Smrg off = (ctrls->axt_ctrls_mask & (~ctrls->axt_ctrls_values)); 98970728a38Smrg off &= ~rtrn->axt_ctrls_on; 99070728a38Smrg off |= rtrn->axt_ctrls_off; 9918c9fbc29Smrg } 99270728a38Smrg else 99370728a38Smrg off = rtrn->axt_ctrls_off; 9948c9fbc29Smrg if (!rtrn->replace_axt_ctrls_on) { 99570728a38Smrg on = (ctrls->axt_ctrls_mask & ctrls->axt_ctrls_values); 99670728a38Smrg on &= ~rtrn->axt_ctrls_off; 99770728a38Smrg on |= rtrn->axt_ctrls_on; 9988c9fbc29Smrg } 99970728a38Smrg else 100070728a38Smrg on = rtrn->axt_ctrls_on; 100170728a38Smrg ctrls->axt_ctrls_mask = (on | off) & ~rtrn->axt_ctrls_ignore; 100270728a38Smrg ctrls->axt_ctrls_values = on & ~rtrn->axt_ctrls_ignore; 10038c9fbc29Smrg 10048c9fbc29Smrg /* any value set to both off and on is reset to ignore */ 100570728a38Smrg if ((off = (rtrn->axt_opts_on & rtrn->axt_opts_off)) != 0) 100670728a38Smrg rtrn->axt_opts_ignore |= off; 10078c9fbc29Smrg 10088c9fbc29Smrg /* ignore takes priority over on and off */ 100970728a38Smrg rtrn->axt_opts_on &= ~rtrn->axt_opts_ignore; 101070728a38Smrg rtrn->axt_opts_off &= ~rtrn->axt_opts_ignore; 10118c9fbc29Smrg 10128c9fbc29Smrg if (rtrn->replace_axt_opts_off) { 101370728a38Smrg off = (ctrls->axt_opts_mask & (~ctrls->axt_opts_values)); 101470728a38Smrg off &= ~rtrn->axt_opts_on; 101570728a38Smrg off |= rtrn->axt_opts_off; 10168c9fbc29Smrg } 101770728a38Smrg else 101870728a38Smrg off = rtrn->axt_opts_off; 10198c9fbc29Smrg if (!rtrn->replace_axt_opts_on) { 102070728a38Smrg on = (ctrls->axt_opts_mask & ctrls->axt_opts_values); 102170728a38Smrg on &= ~rtrn->axt_opts_off; 102270728a38Smrg on |= rtrn->axt_opts_on; 10238c9fbc29Smrg } 102470728a38Smrg else 102570728a38Smrg on = rtrn->axt_opts_on; 102670728a38Smrg ctrls->axt_opts_mask = 102770728a38Smrg (unsigned short) ((on | off) & ~rtrn->axt_ctrls_ignore); 102870728a38Smrg ctrls->axt_opts_values = (unsigned short) (on & ~rtrn->axt_ctrls_ignore); 102970728a38Smrg 103070728a38Smrg if (rtrn->defined & XkbCF_GroupsWrap) { 103170728a38Smrg int n; 103270728a38Smrg 103370728a38Smrg n = XkbNumGroups(ctrls->groups_wrap); 103470728a38Smrg rtrn->groups_wrap = XkbSetNumGroups(rtrn->groups_wrap, n); 103570728a38Smrg ctrls->groups_wrap = rtrn->groups_wrap; 10368c9fbc29Smrg } 10378c9fbc29Smrg return True; 10388c9fbc29Smrg} 10398c9fbc29Smrg 10408c9fbc29Smrg/*ARGSUSED*/ 10418c9fbc29Smrgstatic Bool 104270728a38SmrgDefaultFinish(XkbConfigFieldsPtr fields, XkbDescPtr xkb, 104370728a38Smrg XkbConfigRtrnPtr rtrn, int what) 10448c9fbc29Smrg{ 104570728a38Smrg if ((what == XkbCF_Destroy) || (what == XkbCF_CleanUp)) 104670728a38Smrg return DefaultCleanUp(rtrn); 104770728a38Smrg if (what == XkbCF_Check) { 104870728a38Smrg if ((rtrn->symbols == NULL) && (rtrn->phys_symbols != NULL)) 104970728a38Smrg rtrn->symbols = _XkbDupString(rtrn->phys_symbols); 10508c9fbc29Smrg } 105170728a38Smrg if ((what == XkbCF_Apply) || (what == XkbCF_Check)) { 105270728a38Smrg if (xkb && xkb->names && (rtrn->num_unbound_mods > 0)) 105370728a38Smrg XkbCFBindMods(rtrn, xkb); 105470728a38Smrg XkbCFApplyMods(rtrn, XkbCF_InitialMods, &rtrn->initial_mods); 105570728a38Smrg XkbCFApplyMods(rtrn, XkbCF_InternalMods, &rtrn->internal_mods); 105670728a38Smrg XkbCFApplyMods(rtrn, XkbCF_IgnoreLockMods, &rtrn->ignore_lock_mods); 10578c9fbc29Smrg } 105870728a38Smrg if (what == XkbCF_Apply) { 105970728a38Smrg if (xkb != NULL) { 106070728a38Smrg DefaultApplyNames(rtrn, xkb); 106170728a38Smrg DefaultApplyControls(rtrn, xkb); 106270728a38Smrg XkbCFBindMods(rtrn, xkb); 106370728a38Smrg } 10648c9fbc29Smrg } 10658c9fbc29Smrg return True; 10668c9fbc29Smrg} 10678c9fbc29Smrg 10688c9fbc29Smrgstatic XkbConfigFieldRec _XkbCFDfltFields[] = { 106970728a38Smrg {"rules", _XkbCF_RulesFile}, 107070728a38Smrg {"model", _XkbCF_Model}, 107170728a38Smrg {"layout", _XkbCF_Layout}, 107270728a38Smrg {"variant", _XkbCF_Variant}, 107370728a38Smrg {"options", _XkbCF_Options}, 107470728a38Smrg {"keymap", _XkbCF_Keymap}, 107570728a38Smrg {"keycodes", _XkbCF_Keycodes}, 107670728a38Smrg {"geometry", _XkbCF_Geometry}, 107770728a38Smrg {"realsymbols", _XkbCF_PhysSymbols}, 107870728a38Smrg {"actualsymbols", _XkbCF_PhysSymbols}, 107970728a38Smrg {"symbols", _XkbCF_Symbols}, 108070728a38Smrg {"symbolstouse", _XkbCF_Symbols}, 108170728a38Smrg {"types", _XkbCF_Types}, 108270728a38Smrg {"compat", _XkbCF_CompatMap}, 108370728a38Smrg {"modifiers", _XkbCF_InitialMods}, 108470728a38Smrg {"controls", _XkbCF_InitialCtrls}, 108570728a38Smrg {"click", _XkbCF_ClickVolume}, 108670728a38Smrg {"clickvolume", _XkbCF_ClickVolume}, 108770728a38Smrg {"bell", _XkbCF_BellVolume}, 108870728a38Smrg {"bellvolume", _XkbCF_BellVolume}, 108970728a38Smrg {"bellpitch", _XkbCF_BellPitch}, 109070728a38Smrg {"bellduration", _XkbCF_BellDuration}, 109170728a38Smrg {"repeatdelay", _XkbCF_RepeatDelay}, 109270728a38Smrg {"repeatinterval", _XkbCF_RepeatInterval}, 109370728a38Smrg {"slowkeysdelay", _XkbCF_SlowKeysDelay}, 109470728a38Smrg {"debouncedelay", _XkbCF_DebounceDelay}, 109570728a38Smrg {"mousekeysdelay", _XkbCF_MouseKeysDelay}, 109670728a38Smrg {"mousekeysinterval", _XkbCF_MouseKeysInterval}, 109770728a38Smrg {"mousekeystimetomax", _XkbCF_MouseKeysTimeToMax}, 109870728a38Smrg {"mousekeysmaxspeed", _XkbCF_MouseKeysMaxSpeed}, 109970728a38Smrg {"mousekeyscurve", _XkbCF_MouseKeysCurve}, 110070728a38Smrg {"accessxtimeout", _XkbCF_AccessXTimeout}, 110170728a38Smrg {"axtimeout", _XkbCF_AccessXTimeout}, 110270728a38Smrg {"accessxtimeoutctrlson", _XkbCF_AccessXTimeoutCtrlsOn}, 110370728a38Smrg {"axtctrlson", _XkbCF_AccessXTimeoutCtrlsOn}, 110470728a38Smrg {"accessxtimeoutctrlsoff", _XkbCF_AccessXTimeoutCtrlsOff}, 110570728a38Smrg {"axtctrlsoff", _XkbCF_AccessXTimeoutCtrlsOff}, 110670728a38Smrg {"accessxtimeoutfeedbackon",_XkbCF_AccessXTimeoutOptsOn}, 110770728a38Smrg {"axtfeedbackon", _XkbCF_AccessXTimeoutOptsOn}, 110870728a38Smrg {"accessxtimeoutfeedbackoff",_XkbCF_AccessXTimeoutOptsOff}, 110970728a38Smrg {"axtfeedbackoff", _XkbCF_AccessXTimeoutOptsOff}, 111070728a38Smrg {"ignorelockmods", _XkbCF_IgnoreLockMods}, 111170728a38Smrg {"ignorelockmodifiers", _XkbCF_IgnoreLockMods}, 111270728a38Smrg {"ignoregrouplock", _XkbCF_IgnoreGroupLock}, 111370728a38Smrg {"internalmods", _XkbCF_InternalMods}, 111470728a38Smrg {"internalmodifiers", _XkbCF_InternalMods}, 111570728a38Smrg {"outofrangegroups", _XkbCF_GroupsWrap}, 111670728a38Smrg {"groups", _XkbCF_GroupsWrap}, 111770728a38Smrg {"feedback", _XkbCF_InitialFeedback}, 11188c9fbc29Smrg}; 11198c9fbc29Smrg#define _XkbCFNumDfltFields (sizeof(_XkbCFDfltFields)/sizeof(XkbConfigFieldRec)) 11208c9fbc29Smrg 11218c9fbc29Smrgstatic XkbConfigFieldsRec _XkbCFDflts = { 112270728a38Smrg 0, /* cfg_id */ 112370728a38Smrg _XkbCFNumDfltFields, /* num_fields */ 112470728a38Smrg _XkbCFDfltFields, /* fields */ 112570728a38Smrg DefaultParser, /* parser */ 112670728a38Smrg DefaultFinish, /* finish */ 112770728a38Smrg NULL, /* priv */ 112870728a38Smrg NULL /* next */ 11298c9fbc29Smrg}; 11308c9fbc29Smrg 113170728a38SmrgXkbConfigFieldsPtr XkbCFDflts = &_XkbCFDflts; 11328c9fbc29Smrg 11338c9fbc29Smrg/***====================================================================***/ 11348c9fbc29Smrg 11358c9fbc29SmrgXkbConfigFieldsPtr 11368c9fbc29SmrgXkbCFDup(XkbConfigFieldsPtr fields) 11378c9fbc29Smrg{ 113870728a38Smrg XkbConfigFieldsPtr pNew; 113970728a38Smrg 114070728a38Smrg pNew = _XkbTypedAlloc(XkbConfigFieldsRec); 114170728a38Smrg if (pNew != NULL) { 114270728a38Smrg memcpy(pNew, fields, sizeof(XkbConfigFieldsRec)); 114370728a38Smrg if ((pNew->fields != NULL) && (pNew->num_fields > 0)) { 114470728a38Smrg pNew->fields = _XkbTypedCalloc(pNew->num_fields, XkbConfigFieldRec); 114570728a38Smrg if (pNew->fields) { 114670728a38Smrg memcpy(fields->fields, pNew->fields, 114770728a38Smrg (pNew->num_fields * sizeof(XkbConfigFieldRec))); 114870728a38Smrg } 114970728a38Smrg else { 115070728a38Smrg _XkbFree(pNew); 115170728a38Smrg return NULL; 115270728a38Smrg } 115370728a38Smrg } 115470728a38Smrg else { 115570728a38Smrg pNew->num_fields = 0; 115670728a38Smrg pNew->fields = NULL; 115770728a38Smrg } 115870728a38Smrg pNew->next = NULL; 11598c9fbc29Smrg } 11608c9fbc29Smrg return pNew; 11618c9fbc29Smrg} 11628c9fbc29Smrg 11634cd6a3aeSmrgXkbConfigFieldsPtr 116470728a38SmrgXkbCFFree(XkbConfigFieldsPtr fields, Bool all) 11658c9fbc29Smrg{ 116670728a38Smrg XkbConfigFieldsPtr next; 116770728a38Smrg 116870728a38Smrg next = NULL; 116970728a38Smrg while (fields != NULL) { 117070728a38Smrg next = fields->next; 117170728a38Smrg if (fields != XkbCFDflts) { 117270728a38Smrg if (fields->fields) { 117370728a38Smrg _XkbFree(fields->fields); 117470728a38Smrg fields->fields = NULL; 117570728a38Smrg fields->num_fields = 0; 117670728a38Smrg } 117770728a38Smrg _XkbFree(fields); 117870728a38Smrg } 117970728a38Smrg fields = (all ? next : NULL); 11808c9fbc29Smrg } 11818c9fbc29Smrg return next; 11828c9fbc29Smrg} 11838c9fbc29Smrg 11848c9fbc29SmrgBool 118570728a38SmrgXkbCFApplyRtrnValues(XkbConfigRtrnPtr rtrn, 118670728a38Smrg XkbConfigFieldsPtr fields, 118770728a38Smrg XkbDescPtr xkb) 11888c9fbc29Smrg{ 118970728a38Smrg Bool ok; 11908c9fbc29Smrg 119170728a38Smrg if ((fields == NULL) || (rtrn == NULL) || (xkb == NULL)) 119270728a38Smrg return False; 119370728a38Smrg for (ok = True; fields != NULL; fields = fields->next) { 119470728a38Smrg if (fields->finish != NULL) 119570728a38Smrg ok = (*fields->finish) (fields, xkb, rtrn, XkbCF_Apply) && ok; 11968c9fbc29Smrg } 11978c9fbc29Smrg return ok; 11988c9fbc29Smrg} 11998c9fbc29Smrg 12008c9fbc29SmrgXkbConfigRtrnPrivPtr 120170728a38SmrgXkbCFAddPrivate(XkbConfigRtrnPtr rtrn, XkbConfigFieldsPtr fields, XPointer ptr) 12028c9fbc29Smrg{ 120370728a38Smrg XkbConfigRtrnPrivPtr priv; 120470728a38Smrg 120570728a38Smrg if ((rtrn == NULL) || (fields == NULL)) 120670728a38Smrg return NULL; 120770728a38Smrg priv = _XkbTypedAlloc(XkbConfigRtrnPrivRec); 120870728a38Smrg if (priv != NULL) { 120970728a38Smrg priv->cfg_id = fields->cfg_id; 121070728a38Smrg priv->priv = ptr; 121170728a38Smrg priv->next = rtrn->priv; 121270728a38Smrg rtrn->priv = priv; 12138c9fbc29Smrg } 12148c9fbc29Smrg return priv; 12158c9fbc29Smrg} 12168c9fbc29Smrg 12178c9fbc29Smrgvoid 121870728a38SmrgXkbCFFreeRtrn(XkbConfigRtrnPtr rtrn, XkbConfigFieldsPtr fields, XkbDescPtr xkb) 12198c9fbc29Smrg{ 122070728a38Smrg XkbConfigRtrnPrivPtr tmp, next; 122170728a38Smrg 122270728a38Smrg if ((fields == NULL) || (rtrn == NULL)) 122370728a38Smrg return; 122470728a38Smrg while (fields != NULL) { 122570728a38Smrg if (fields->finish != NULL) 122670728a38Smrg (*fields->finish) (fields, xkb, rtrn, XkbCF_Destroy); 122770728a38Smrg fields = fields->next; 12288c9fbc29Smrg } 122970728a38Smrg for (tmp = rtrn->priv; tmp != NULL; tmp = next) { 123070728a38Smrg next = tmp->next; 123170728a38Smrg bzero((char *) tmp, sizeof(XkbConfigRtrnPrivRec)); 123270728a38Smrg _XkbFree(tmp); 12338c9fbc29Smrg } 123470728a38Smrg bzero((char *) rtrn, sizeof(XkbConfigRtrnRec)); 12358c9fbc29Smrg return; 12368c9fbc29Smrg} 12378c9fbc29Smrg 12388c9fbc29SmrgBool 123970728a38SmrgXkbCFParse(FILE *file, XkbConfigFieldsPtr fields, 124070728a38Smrg XkbDescPtr xkb, XkbConfigRtrnPtr rtrn) 12418c9fbc29Smrg{ 124270728a38Smrg int tok; 124370728a38Smrg XkbCFScanResultRec val; 124470728a38Smrg XkbConfigFieldsPtr tmp; 124570728a38Smrg 124670728a38Smrg if ((file == NULL) || (fields == NULL) || (rtrn == NULL)) 124770728a38Smrg return False; 124870728a38Smrg for (tok = 0, tmp = fields; tmp != NULL; tmp = tmp->next, tok++) { 124970728a38Smrg fields->cfg_id = tok; 12508c9fbc29Smrg } 125170728a38Smrg bzero((char *) rtrn, sizeof(XkbConfigRtrnRec)); 125270728a38Smrg rtrn->line = 1; 125370728a38Smrg rtrn->click_volume = -1; 125470728a38Smrg rtrn->bell_volume = -1; 125570728a38Smrg while ((tok = XkbCFScan(file, &val, rtrn)) != XkbCF_EOF) { 125670728a38Smrg if (tok == XkbCF_Ident) { 125770728a38Smrg Bool done; 125870728a38Smrg 125970728a38Smrg for (tmp = fields, done = False; (tmp != NULL) && (!done); 126070728a38Smrg tmp = tmp->next) { 126170728a38Smrg register int i; 126270728a38Smrg 126370728a38Smrg XkbConfigFieldPtr f; 126470728a38Smrg 126570728a38Smrg for (i = 0, f = tmp->fields; (i < tmp->num_fields) && (!done); 126670728a38Smrg i++, f++) { 126770728a38Smrg if (_XkbStrCaseCmp(val.str, f->field) != 0) 126870728a38Smrg continue; 126970728a38Smrg if ((*tmp->parser) (file, tmp, f, xkb, rtrn)) 127070728a38Smrg done = True; 127170728a38Smrg else 127270728a38Smrg goto BAILOUT; 127370728a38Smrg } 127470728a38Smrg } 127570728a38Smrg } 127670728a38Smrg else if ((tok != XkbCF_EOL) && (tok != XkbCF_Semi)) { 127770728a38Smrg rtrn->error = XkbCF_MissingIdent; 127870728a38Smrg goto BAILOUT; 127970728a38Smrg } 12808c9fbc29Smrg } 128170728a38Smrg for (tmp = fields; tmp != NULL; tmp = tmp->next) { 128270728a38Smrg if ((tmp->finish) && (!(*tmp->finish) (tmp, xkb, rtrn, XkbCF_Check))) 128370728a38Smrg goto BAILOUT; 12848c9fbc29Smrg } 12858c9fbc29Smrg return True; 128670728a38Smrg BAILOUT: 128770728a38Smrg for (tmp = fields; tmp != NULL; tmp = tmp->next) { 128870728a38Smrg if (tmp->finish) 128970728a38Smrg (*tmp->finish) (tmp, xkb, rtrn, XkbCF_CleanUp); 12908c9fbc29Smrg } 12918c9fbc29Smrg return False; 12928c9fbc29Smrg} 12938c9fbc29Smrg 12948c9fbc29Smrg/*ARGSUSED*/ 12958c9fbc29Smrgvoid 129670728a38SmrgXkbCFReportError(FILE *file, char *name, int error, int line) 12978c9fbc29Smrg{ 129870728a38Smrg const char *msg; 129970728a38Smrg 130070728a38Smrg switch (error) { 130170728a38Smrg case XkbCF_BadAlloc: 130270728a38Smrg msg = "allocation failed\n"; 130370728a38Smrg break; 130470728a38Smrg case XkbCF_UnterminatedString: 130570728a38Smrg msg = "unterminated string on line %d"; 130670728a38Smrg break; 130770728a38Smrg case XkbCF_MissingIdent: 130870728a38Smrg msg = "expected identifier on line %d"; 130970728a38Smrg break; 131070728a38Smrg case XkbCF_MissingEquals: 131170728a38Smrg msg = "expected '=' on line %d"; 131270728a38Smrg break; 131370728a38Smrg case XkbCF_ExpectedEOS: 131470728a38Smrg msg = "expected ';' or newline on line %d"; 131570728a38Smrg break; 131670728a38Smrg case XkbCF_ExpectedBoolean: 131770728a38Smrg msg = "expected a boolean value on line %d"; 131870728a38Smrg break; 131970728a38Smrg case XkbCF_ExpectedInteger: 132070728a38Smrg msg = "expected a numeric value on line %d"; 132170728a38Smrg break; 132270728a38Smrg case XkbCF_ExpectedString: 132370728a38Smrg msg = "expected a string on line %d"; 132470728a38Smrg break; 132570728a38Smrg case XkbCF_ExpectedModifier: 132670728a38Smrg msg = "expected a modifier name on line %d"; 132770728a38Smrg break; 132870728a38Smrg case XkbCF_ExpectedControl: 132970728a38Smrg msg = "expected a control name on line %d"; 133070728a38Smrg break; 133170728a38Smrg case XkbCF_ExpectedAXOption: 133270728a38Smrg msg = "expected an AccessX option on line %d"; 133370728a38Smrg break; 133470728a38Smrg case XkbCF_ExpectedOperator: 133570728a38Smrg msg = "expected '+' or '-' on line %d"; 133670728a38Smrg break; 133770728a38Smrg case XkbCF_ExpectedOORGroupBehavior: 133870728a38Smrg msg = "expected wrap, clamp or group number on line %d"; 133970728a38Smrg break; 134070728a38Smrg default: 134170728a38Smrg msg = "unknown error on line %d"; 134270728a38Smrg break; 13438c9fbc29Smrg } 134470728a38Smrg fprintf(file, msg, line); 134570728a38Smrg if (name) 134670728a38Smrg fprintf(file, " of %s\n", name); 134770728a38Smrg else 134870728a38Smrg fprintf(file, "\n"); 13498c9fbc29Smrg return; 13508c9fbc29Smrg} 1351