1356 lines
37 KiB
C
1356 lines
37 KiB
C
/* $Xorg: xkbconfig.c,v 1.4 2000/08/17 19:46:43 cpqbld Exp $ */
|
|
/************************************************************
|
|
Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
|
|
|
|
Permission to use, copy, modify, and distribute this
|
|
software and its documentation for any purpose and without
|
|
fee is hereby granted, provided that the above copyright
|
|
notice appear in all copies and that both that copyright
|
|
notice and this permission notice appear in supporting
|
|
documentation, and that the name of Silicon Graphics not be
|
|
used in advertising or publicity pertaining to distribution
|
|
of the software without specific prior written permission.
|
|
Silicon Graphics makes no representation about the suitability
|
|
of this software for any purpose. It is provided "as is"
|
|
without any express or implied warranty.
|
|
|
|
SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
|
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
|
|
GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
|
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
|
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
|
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
********************************************************/
|
|
/* $XFree86: xc/lib/xkbfile/xkbconfig.c,v 3.7 2001/11/30 12:11:51 eich Exp $ */
|
|
|
|
#ifdef HAVE_DIX_CONFIG_H
|
|
#include <dix-config.h>
|
|
#elif defined(HAVE_CONFIG_H)
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <X11/Xfuncs.h>
|
|
|
|
#include <X11/Xfuncs.h>
|
|
|
|
#ifndef XKB_IN_SERVER
|
|
|
|
#include <X11/Xos.h>
|
|
#include <X11/Xlib.h>
|
|
#include <X11/keysym.h>
|
|
#include <X11/XKBlib.h>
|
|
#include "XKBfileInt.h"
|
|
|
|
#else
|
|
|
|
#include <X11/X.h>
|
|
#define NEED_EVENTS
|
|
#include <X11/keysym.h>
|
|
#include <X11/Xproto.h>
|
|
#include "misc.h"
|
|
#include "inputstr.h"
|
|
#include "dix.h"
|
|
#define XKBSRV_NEED_FILE_FUNCS
|
|
#include <X11/extensions/XKBsrv.h>
|
|
#endif
|
|
|
|
#include <X11/extensions/XKBconfig.h>
|
|
|
|
/***====================================================================***/
|
|
|
|
#define XKBCF_MAX_STR_LEN 100
|
|
static char _XkbCF_rtrn[XKBCF_MAX_STR_LEN+1];
|
|
|
|
static int
|
|
ScanIdent(FILE *file,int ch,XkbCFScanResultPtr val_rtrn)
|
|
{
|
|
register int i;
|
|
char * str;
|
|
|
|
val_rtrn->str= str= _XkbCF_rtrn;
|
|
for (i=0;(isalpha(ch)||isdigit(ch)||(ch=='_'));ch=getc(file)) {
|
|
if (i<XKBCF_MAX_STR_LEN)
|
|
str[i++]= ch;
|
|
}
|
|
if ((ch!=EOF)&&(ch!=' ')&&(ch!='\t'))
|
|
ungetc(ch,file);
|
|
str[i]= '\0';
|
|
return XkbCF_Ident;
|
|
}
|
|
|
|
static int
|
|
ScanString(FILE *file,int quote,XkbCFScanResultPtr val_rtrn)
|
|
{
|
|
int ch,nInBuf;
|
|
|
|
nInBuf = 0;
|
|
while ( ((ch=getc(file))!=EOF) && (ch!='\n') && (ch!=quote) ) {
|
|
if ( ch == '\\' ) {
|
|
if ((ch = getc(file))!=EOF) {
|
|
if ( ch=='n' ) ch = '\n';
|
|
else if ( ch == 't' ) ch = '\t';
|
|
else if ( ch == 'v' ) ch = '\v';
|
|
else if ( ch == 'b' ) ch = '\b';
|
|
else if ( ch == 'r' ) ch = '\r';
|
|
else if ( ch == 'f' ) ch = '\f';
|
|
else if ( ch == 'e' ) ch = '\033';
|
|
else if ( ch == '0' ) {
|
|
int tmp,stop;
|
|
ch = stop = 0;
|
|
if (((tmp=getc(file))!=EOF) && (isdigit(tmp)) &&
|
|
(tmp!='8') && (tmp!='9')) {
|
|
ch= (ch*8)+(tmp-'0');
|
|
}
|
|
else {
|
|
stop= 1;
|
|
ungetc(tmp,file);
|
|
}
|
|
if ((!stop) && ((tmp=getc(file))!=EOF) && (isdigit(tmp)) &&
|
|
(tmp!='8') && (tmp!='9')) {
|
|
ch= (ch*8)+(tmp-'0');
|
|
}
|
|
else {
|
|
stop= 1;
|
|
ungetc(tmp,file);
|
|
}
|
|
if ((!stop) && ((tmp=getc(file))!=EOF) && (isdigit(tmp)) &&
|
|
(tmp!='8') && (tmp!='9')) {
|
|
ch= (ch*8)+(tmp-'0');
|
|
}
|
|
else {
|
|
stop= 1;
|
|
ungetc(tmp,file);
|
|
}
|
|
}
|
|
}
|
|
else return XkbCF_EOF;
|
|
}
|
|
|
|
if ( nInBuf < XKBCF_MAX_STR_LEN-1 )
|
|
_XkbCF_rtrn[nInBuf++] = ch;
|
|
}
|
|
if ( ch == quote ) {
|
|
_XkbCF_rtrn[nInBuf++] = '\0';
|
|
val_rtrn->str= _XkbCF_rtrn;
|
|
return XkbCF_String;
|
|
}
|
|
return XkbCF_UnterminatedString;
|
|
}
|
|
|
|
static int
|
|
ScanInteger(FILE *file,int ch,XkbCFScanResultPtr val_rtrn)
|
|
{
|
|
int i;
|
|
|
|
if (isdigit(ch))
|
|
ungetc(ch,file);
|
|
if (fscanf(file,"%i",&i)==1) {
|
|
val_rtrn->ival= i;
|
|
return XkbCF_Integer;
|
|
}
|
|
return XkbCF_Unknown;
|
|
}
|
|
|
|
int
|
|
XkbCFScan(FILE *file,XkbCFScanResultPtr val_rtrn,XkbConfigRtrnPtr rtrn)
|
|
{
|
|
int ch;
|
|
|
|
do {
|
|
ch= getc(file);
|
|
} while ((ch=='\t')||(ch==' '));
|
|
if (isalpha(ch))
|
|
return ScanIdent(file,ch,val_rtrn);
|
|
else if (isdigit(ch))
|
|
return ScanInteger(file,ch,val_rtrn);
|
|
else if (ch=='"')
|
|
return ScanString(file,ch,val_rtrn);
|
|
else if (ch=='\n') {
|
|
rtrn->line++;
|
|
return XkbCF_EOL;
|
|
}
|
|
else if (ch==';')
|
|
return XkbCF_Semi;
|
|
else if (ch=='=')
|
|
return XkbCF_Equals;
|
|
else if (ch=='+') {
|
|
ch= getc(file);
|
|
if (ch=='=')
|
|
return XkbCF_PlusEquals;
|
|
if ((ch!=EOF)&&(ch!=' ')&&(ch!='\t'))
|
|
ungetc(ch,file);
|
|
return XkbCF_Plus;
|
|
}
|
|
else if (ch=='-') {
|
|
ch= getc(file);
|
|
if (ch=='=')
|
|
return XkbCF_MinusEquals;
|
|
if ((ch!=EOF)&&(ch!=' ')&&(ch!='\t'))
|
|
ungetc(ch,file);
|
|
return XkbCF_Minus;
|
|
}
|
|
else if (ch==EOF)
|
|
return XkbCF_EOF;
|
|
else if ((ch=='#')||((ch=='/')&&(getc(file)=='/'))) {
|
|
while ((ch!='\n')&&(ch!=EOF))
|
|
ch= getc(file);
|
|
rtrn->line++;
|
|
return XkbCF_EOL;
|
|
}
|
|
return XkbCF_Unknown;
|
|
}
|
|
|
|
/***====================================================================***/
|
|
|
|
#define _XkbCF_Illegal 0
|
|
#define _XkbCF_Keymap 1
|
|
#define _XkbCF_Keycodes 2
|
|
#define _XkbCF_Geometry 3
|
|
#define _XkbCF_PhysSymbols 4
|
|
#define _XkbCF_Symbols 5
|
|
#define _XkbCF_Types 6
|
|
#define _XkbCF_CompatMap 7
|
|
|
|
#define _XkbCF_RulesFile 8
|
|
#define _XkbCF_Model 9
|
|
#define _XkbCF_Layout 10
|
|
#define _XkbCF_Variant 11
|
|
#define _XkbCF_Options 12
|
|
|
|
#define _XkbCF_InitialMods 13
|
|
#define _XkbCF_InitialCtrls 14
|
|
|
|
#define _XkbCF_ClickVolume 15
|
|
#define _XkbCF_BellVolume 16
|
|
#define _XkbCF_BellPitch 17
|
|
#define _XkbCF_BellDuration 18
|
|
#define _XkbCF_RepeatDelay 19
|
|
#define _XkbCF_RepeatInterval 20
|
|
#define _XkbCF_SlowKeysDelay 21
|
|
#define _XkbCF_DebounceDelay 22
|
|
#define _XkbCF_MouseKeysDelay 23
|
|
#define _XkbCF_MouseKeysInterval 24
|
|
#define _XkbCF_MouseKeysTimeToMax 25
|
|
#define _XkbCF_MouseKeysMaxSpeed 26
|
|
#define _XkbCF_MouseKeysCurve 27
|
|
#define _XkbCF_AccessXTimeout 28
|
|
#define _XkbCF_AccessXTimeoutCtrlsOn 29
|
|
#define _XkbCF_AccessXTimeoutCtrlsOff 30
|
|
#define _XkbCF_AccessXTimeoutOptsOn 31
|
|
#define _XkbCF_AccessXTimeoutOptsOff 32
|
|
|
|
#define _XkbCF_IgnoreLockMods 33
|
|
#define _XkbCF_IgnoreGroupLock 34
|
|
#define _XkbCF_InternalMods 35
|
|
|
|
#define _XkbCF_GroupsWrap 36
|
|
#define _XkbCF_InitialFeedback 37
|
|
|
|
static Bool
|
|
AddCtrlByName(XkbConfigRtrnPtr rtrn,char *name,unsigned long *ctrls_rtrn)
|
|
{
|
|
if ((_XkbStrCaseCmp(name,"repeat")==0)||
|
|
(_XkbStrCaseCmp(name,"repeatkeys")==0))
|
|
*ctrls_rtrn= XkbRepeatKeysMask;
|
|
else if (_XkbStrCaseCmp(name,"slowkeys")==0)
|
|
*ctrls_rtrn= XkbSlowKeysMask;
|
|
else if (_XkbStrCaseCmp(name,"bouncekeys")==0)
|
|
*ctrls_rtrn= XkbBounceKeysMask;
|
|
else if (_XkbStrCaseCmp(name,"stickykeys")==0)
|
|
*ctrls_rtrn= XkbStickyKeysMask;
|
|
else if (_XkbStrCaseCmp(name,"mousekeys")==0)
|
|
*ctrls_rtrn= XkbMouseKeysMask;
|
|
else if (_XkbStrCaseCmp(name,"mousekeysaccel")==0)
|
|
*ctrls_rtrn= XkbMouseKeysAccelMask;
|
|
else if (_XkbStrCaseCmp(name,"accessxkeys")==0)
|
|
*ctrls_rtrn= XkbAccessXKeysMask;
|
|
else if (_XkbStrCaseCmp(name,"accessxtimeout")==0)
|
|
*ctrls_rtrn= XkbAccessXTimeoutMask;
|
|
else if (_XkbStrCaseCmp(name,"accessxfeedback")==0)
|
|
*ctrls_rtrn= XkbAccessXFeedbackMask;
|
|
else if (_XkbStrCaseCmp(name,"audiblebell")==0)
|
|
*ctrls_rtrn= XkbAudibleBellMask;
|
|
else if (_XkbStrCaseCmp(name,"overlay1")==0)
|
|
*ctrls_rtrn= XkbOverlay1Mask;
|
|
else if (_XkbStrCaseCmp(name,"overlay2")==0)
|
|
*ctrls_rtrn= XkbOverlay2Mask;
|
|
else if (_XkbStrCaseCmp(name,"ignoregrouplock")==0)
|
|
*ctrls_rtrn= XkbIgnoreGroupLockMask;
|
|
else {
|
|
rtrn->error= XkbCF_ExpectedControl;
|
|
return False;
|
|
}
|
|
return True;
|
|
}
|
|
|
|
static Bool
|
|
AddAXTimeoutOptByName( XkbConfigRtrnPtr rtrn,
|
|
char * name,
|
|
unsigned short * opts_rtrn)
|
|
{
|
|
if (_XkbStrCaseCmp(name,"slowkeyspress")==0)
|
|
*opts_rtrn= XkbAX_SKPressFBMask;
|
|
else if (_XkbStrCaseCmp(name,"slowkeysaccept")==0)
|
|
*opts_rtrn= XkbAX_SKAcceptFBMask;
|
|
else if (_XkbStrCaseCmp(name,"feature")==0)
|
|
*opts_rtrn= XkbAX_FeatureFBMask;
|
|
else if (_XkbStrCaseCmp(name,"slowwarn")==0)
|
|
*opts_rtrn= XkbAX_SlowWarnFBMask;
|
|
else if (_XkbStrCaseCmp(name,"indicator")==0)
|
|
*opts_rtrn= XkbAX_IndicatorFBMask;
|
|
else if (_XkbStrCaseCmp(name,"stickykeys")==0)
|
|
*opts_rtrn= XkbAX_StickyKeysFBMask;
|
|
else if (_XkbStrCaseCmp(name,"twokeys")==0)
|
|
*opts_rtrn= XkbAX_TwoKeysMask;
|
|
else if (_XkbStrCaseCmp(name,"latchtolock")==0)
|
|
*opts_rtrn= XkbAX_LatchToLockMask;
|
|
else if (_XkbStrCaseCmp(name,"slowkeysrelease")==0)
|
|
*opts_rtrn= XkbAX_SKReleaseFBMask;
|
|
else if (_XkbStrCaseCmp(name,"slowkeysreject")==0)
|
|
*opts_rtrn= XkbAX_SKRejectFBMask;
|
|
else if (_XkbStrCaseCmp(name,"bouncekeysreject")==0)
|
|
*opts_rtrn= XkbAX_BKRejectFBMask;
|
|
else if (_XkbStrCaseCmp(name,"dumbbell")==0)
|
|
*opts_rtrn= XkbAX_DumbBellFBMask;
|
|
else {
|
|
rtrn->error= XkbCF_ExpectedControl;
|
|
return False;
|
|
}
|
|
return True;
|
|
}
|
|
|
|
XkbConfigUnboundModPtr
|
|
XkbCFAddModByName( XkbConfigRtrnPtr rtrn,
|
|
int what,
|
|
char * name,
|
|
Bool merge,
|
|
XkbConfigUnboundModPtr last)
|
|
{
|
|
if (rtrn->num_unbound_mods>=rtrn->sz_unbound_mods) {
|
|
rtrn->sz_unbound_mods+= 5;
|
|
rtrn->unbound_mods= _XkbTypedRealloc(rtrn->unbound_mods,
|
|
rtrn->sz_unbound_mods,
|
|
XkbConfigUnboundModRec);
|
|
if (rtrn->unbound_mods==NULL) {
|
|
rtrn->error= XkbCF_BadAlloc;
|
|
return False;
|
|
}
|
|
}
|
|
if (last==NULL) {
|
|
last= &rtrn->unbound_mods[rtrn->num_unbound_mods++];
|
|
last->what= what;
|
|
last->mods= 0;
|
|
last->vmods= 0;
|
|
last->merge= merge;
|
|
last->name= NULL;
|
|
}
|
|
if (_XkbStrCaseCmp(name,"shift")==0)
|
|
last->mods|= ShiftMask;
|
|
else if (_XkbStrCaseCmp(name,"lock")==0)
|
|
last->mods|= LockMask;
|
|
else if ((_XkbStrCaseCmp(name,"control")==0)||
|
|
(_XkbStrCaseCmp(name,"ctrl")==0))
|
|
last->mods|= ControlMask;
|
|
else if (_XkbStrCaseCmp(name,"mod1")==0)
|
|
last->mods|= Mod1Mask;
|
|
else if (_XkbStrCaseCmp(name,"mod2")==0)
|
|
last->mods|= Mod2Mask;
|
|
else if (_XkbStrCaseCmp(name,"mod3")==0)
|
|
last->mods|= Mod3Mask;
|
|
else if (_XkbStrCaseCmp(name,"mod4")==0)
|
|
last->mods|= Mod4Mask;
|
|
else if (_XkbStrCaseCmp(name,"mod5")==0)
|
|
last->mods|= Mod5Mask;
|
|
else {
|
|
if (last->name!=NULL) {
|
|
last= &rtrn->unbound_mods[rtrn->num_unbound_mods++];
|
|
last->what= what;
|
|
last->mods= 0;
|
|
last->vmods= 0;
|
|
last->merge= merge;
|
|
last->name= NULL;
|
|
}
|
|
last->name= _XkbDupString(name);
|
|
}
|
|
return last;
|
|
}
|
|
|
|
int
|
|
XkbCFBindMods(XkbConfigRtrnPtr rtrn,XkbDescPtr xkb)
|
|
{
|
|
register int n,v;
|
|
Atom name;
|
|
XkbConfigUnboundModPtr mod;
|
|
int missing;
|
|
|
|
if (rtrn->num_unbound_mods<1)
|
|
return 0;
|
|
if ((xkb==NULL) || (xkb->names==NULL))
|
|
return -1;
|
|
|
|
missing= 0;
|
|
for (n=0,mod=rtrn->unbound_mods;n<rtrn->num_unbound_mods;n++,mod++) {
|
|
if (mod->name!=NULL) {
|
|
name= XkbInternAtom(xkb->dpy,mod->name,True);
|
|
if (name==None)
|
|
continue;
|
|
for (v=0;v<XkbNumVirtualMods;v++) {
|
|
if (xkb->names->vmods[v]==name) {
|
|
mod->vmods= (1<<v);
|
|
_XkbFree(mod->name);
|
|
mod->name= NULL;
|
|
break;
|
|
}
|
|
}
|
|
if (mod->name!=NULL)
|
|
missing++;
|
|
}
|
|
}
|
|
return missing;
|
|
}
|
|
|
|
Bool
|
|
XkbCFApplyMods(XkbConfigRtrnPtr rtrn,int what,XkbConfigModInfoPtr info)
|
|
{
|
|
register int n;
|
|
XkbConfigUnboundModPtr mod;
|
|
|
|
if (rtrn->num_unbound_mods<1)
|
|
return True;
|
|
|
|
for (n=0,mod=rtrn->unbound_mods;n<rtrn->num_unbound_mods;n++,mod++) {
|
|
if (mod->what!=what)
|
|
continue;
|
|
if (mod->merge==XkbCF_MergeRemove) {
|
|
info->mods_clear|= mod->mods;
|
|
info->vmods_clear|= mod->vmods;
|
|
}
|
|
else {
|
|
if (mod->merge==XkbCF_MergeSet)
|
|
info->replace= True;
|
|
info->mods|= mod->mods;
|
|
info->vmods|= mod->vmods;
|
|
}
|
|
if (mod->name==NULL) {
|
|
mod->what= _XkbCF_Illegal;
|
|
}
|
|
else {
|
|
mod->mods= 0;
|
|
mod->vmods= 0;
|
|
}
|
|
}
|
|
return True;
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
static Bool
|
|
DefaultParser( FILE * file,
|
|
XkbConfigFieldsPtr fields,
|
|
XkbConfigFieldPtr field,
|
|
XkbDescPtr xkb,
|
|
XkbConfigRtrnPtr rtrn)
|
|
{
|
|
int tok;
|
|
XkbCFScanResultRec val;
|
|
char ** str;
|
|
int merge;
|
|
unsigned long * ctrls, ctrls_mask;
|
|
unsigned short * opts, opts_mask;
|
|
int * pival, sign;
|
|
int onoff;
|
|
XkbConfigUnboundModPtr last;
|
|
unsigned what;
|
|
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
str= NULL;
|
|
onoff= 0;
|
|
pival= NULL;
|
|
switch (field->field_id) {
|
|
case _XkbCF_RulesFile: if (!str) str= &rtrn->rules_file;
|
|
case _XkbCF_Model: if (!str) str= &rtrn->model;
|
|
case _XkbCF_Layout: if (!str) str= &rtrn->layout;
|
|
case _XkbCF_Variant: if (!str) str= &rtrn->variant;
|
|
case _XkbCF_Options: if (!str) str= &rtrn->options;
|
|
case _XkbCF_Keymap: if (!str) str= &rtrn->keymap;
|
|
case _XkbCF_Keycodes: if (!str) str= &rtrn->keycodes;
|
|
case _XkbCF_Geometry: if (!str) str= &rtrn->geometry;
|
|
case _XkbCF_PhysSymbols:if (!str) str= &rtrn->phys_symbols;
|
|
case _XkbCF_Symbols: if (!str) str= &rtrn->symbols;
|
|
case _XkbCF_Types: if (!str) str= &rtrn->types;
|
|
case _XkbCF_CompatMap: if (!str) str= &rtrn->compat;
|
|
if (tok!=XkbCF_Equals) {
|
|
rtrn->error= XkbCF_MissingEquals;
|
|
goto BAILOUT;
|
|
}
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
if ((tok!=XkbCF_String)&&(tok!=XkbCF_Ident)) {
|
|
rtrn->error= XkbCF_ExpectedString;
|
|
return False;
|
|
}
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
|
|
rtrn->error= XkbCF_ExpectedEOS;
|
|
return False;
|
|
}
|
|
if (*str!=NULL)
|
|
_XkbFree(*str);
|
|
*str= _XkbDupString(val.str);
|
|
break;
|
|
case _XkbCF_InitialMods:
|
|
case _XkbCF_IgnoreLockMods:
|
|
case _XkbCF_InternalMods:
|
|
what= XkbCF_InitialMods;
|
|
if (field->field_id==_XkbCF_InitialMods)
|
|
rtrn->defined|= (what=XkbCF_InitialMods);
|
|
else if (field->field_id==_XkbCF_InternalMods)
|
|
rtrn->defined|= (what=XkbCF_InternalMods);
|
|
else if (field->field_id==_XkbCF_IgnoreLockMods)
|
|
rtrn->defined|= (what=XkbCF_IgnoreLockMods);
|
|
if (tok==XkbCF_Equals) merge= XkbCF_MergeSet;
|
|
else if (tok==XkbCF_MinusEquals) merge= XkbCF_MergeRemove;
|
|
else if (tok==XkbCF_PlusEquals) merge= XkbCF_MergeAdd;
|
|
else {
|
|
rtrn->error= XkbCF_MissingEquals;
|
|
goto BAILOUT;
|
|
}
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
|
|
rtrn->error= XkbCF_ExpectedModifier;
|
|
return False;
|
|
}
|
|
last= NULL;
|
|
while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
|
|
if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
|
|
rtrn->error= XkbCF_ExpectedModifier;
|
|
return False;
|
|
}
|
|
last=XkbCFAddModByName(rtrn,what,val.str,merge,last);
|
|
if (last==NULL)
|
|
return False;
|
|
if (merge==XkbCF_MergeSet)
|
|
merge= XkbCF_MergeAdd;
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
|
|
if (tok!=XkbCF_Plus) {
|
|
rtrn->error= XkbCF_ExpectedOperator;
|
|
return False;
|
|
}
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
}
|
|
}
|
|
break;
|
|
case _XkbCF_InitialCtrls:
|
|
rtrn->defined|= XkbCF_InitialCtrls;
|
|
ctrls= NULL;
|
|
if (tok==XkbCF_PlusEquals)
|
|
ctrls= &rtrn->initial_ctrls;
|
|
else if (tok==XkbCF_MinusEquals)
|
|
ctrls= &rtrn->initial_ctrls_clear;
|
|
else if (tok==XkbCF_Equals) {
|
|
ctrls= &rtrn->initial_ctrls;
|
|
rtrn->replace_initial_ctrls= True;
|
|
*ctrls= 0;
|
|
}
|
|
else {
|
|
rtrn->error= XkbCF_MissingEquals;
|
|
goto BAILOUT;
|
|
}
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
|
|
rtrn->error= XkbCF_ExpectedControl;
|
|
return False;
|
|
}
|
|
while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
|
|
if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
|
|
rtrn->error= XkbCF_ExpectedControl;
|
|
return False;
|
|
}
|
|
if (!AddCtrlByName(rtrn,val.str,&ctrls_mask)) {
|
|
return False;
|
|
}
|
|
*ctrls |= ctrls_mask;
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
|
|
if (tok!=XkbCF_Plus) {
|
|
rtrn->error= XkbCF_ExpectedOperator;
|
|
return False;
|
|
}
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
}
|
|
}
|
|
break;
|
|
case _XkbCF_AccessXTimeoutCtrlsOn:
|
|
case _XkbCF_AccessXTimeoutCtrlsOff:
|
|
opts= NULL;
|
|
if (tok==XkbCF_MinusEquals) {
|
|
ctrls= &rtrn->axt_ctrls_ignore;
|
|
opts= &rtrn->axt_opts_ignore;
|
|
}
|
|
else if ((tok==XkbCF_PlusEquals)||(tok==XkbCF_Equals)) {
|
|
if (field->field_id==_XkbCF_AccessXTimeoutCtrlsOff) {
|
|
ctrls= &rtrn->axt_ctrls_off;
|
|
opts= &rtrn->axt_opts_off;
|
|
if (tok==XkbCF_Equals)
|
|
rtrn->replace_axt_ctrls_off= True;
|
|
}
|
|
else {
|
|
ctrls= &rtrn->axt_ctrls_on;
|
|
opts= &rtrn->axt_opts_on;
|
|
if (tok==XkbCF_Equals)
|
|
rtrn->replace_axt_ctrls_on= True;
|
|
}
|
|
*ctrls= 0;
|
|
}
|
|
else {
|
|
rtrn->error= XkbCF_MissingEquals;
|
|
goto BAILOUT;
|
|
}
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
|
|
rtrn->error= XkbCF_ExpectedControl;
|
|
return False;
|
|
}
|
|
while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
|
|
if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
|
|
rtrn->error= XkbCF_ExpectedControl;
|
|
return False;
|
|
}
|
|
if (!AddCtrlByName(rtrn,val.str,&ctrls_mask)) {
|
|
if (!AddAXTimeoutOptByName(rtrn,val.str,&opts_mask))
|
|
return False;
|
|
*opts |= opts_mask;
|
|
if (field->field_id==_XkbCF_AccessXTimeoutCtrlsOff) {
|
|
rtrn->defined|= XkbCF_AccessXTimeoutOptsOff;
|
|
if (rtrn->replace_axt_ctrls_off)
|
|
rtrn->replace_axt_opts_off= True;
|
|
}
|
|
else {
|
|
rtrn->defined|= XkbCF_AccessXTimeoutOptsOn;
|
|
if (rtrn->replace_axt_ctrls_on)
|
|
rtrn->replace_axt_opts_on= True;
|
|
}
|
|
}
|
|
else
|
|
*ctrls |= ctrls_mask;
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
|
|
if (tok!=XkbCF_Plus) {
|
|
rtrn->error= XkbCF_ExpectedOperator;
|
|
return False;
|
|
}
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
}
|
|
}
|
|
break;
|
|
case _XkbCF_InitialFeedback:
|
|
rtrn->defined|= XkbCF_InitialOpts;
|
|
opts= NULL;
|
|
if (tok==XkbCF_PlusEquals)
|
|
opts= &rtrn->initial_opts;
|
|
else if (tok==XkbCF_MinusEquals)
|
|
opts= &rtrn->initial_opts_clear;
|
|
else if (tok==XkbCF_Equals) {
|
|
opts= &rtrn->initial_opts;
|
|
rtrn->replace_initial_opts= True;
|
|
*opts= 0;
|
|
}
|
|
else {
|
|
rtrn->error= XkbCF_MissingEquals;
|
|
goto BAILOUT;
|
|
}
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
|
|
rtrn->error= XkbCF_ExpectedAXOption;
|
|
return False;
|
|
}
|
|
while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
|
|
if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
|
|
rtrn->error= XkbCF_ExpectedAXOption;
|
|
return False;
|
|
}
|
|
if (!AddAXTimeoutOptByName(rtrn,val.str,&opts_mask)) {
|
|
return False;
|
|
}
|
|
*opts |= opts_mask;
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
|
|
if (tok!=XkbCF_Plus) {
|
|
rtrn->error= XkbCF_ExpectedOperator;
|
|
return False;
|
|
}
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
}
|
|
}
|
|
break;
|
|
case _XkbCF_AccessXTimeoutOptsOff:
|
|
case _XkbCF_AccessXTimeoutOptsOn:
|
|
opts= NULL;
|
|
if (tok==XkbCF_MinusEquals)
|
|
opts= &rtrn->axt_opts_ignore;
|
|
else if ((tok==XkbCF_PlusEquals)||(tok==XkbCF_Equals)) {
|
|
if (field->field_id==_XkbCF_AccessXTimeoutOptsOff) {
|
|
opts= &rtrn->axt_opts_off;
|
|
if (tok==XkbCF_Equals)
|
|
rtrn->replace_axt_opts_off= True;
|
|
}
|
|
else {
|
|
opts= &rtrn->axt_opts_on;
|
|
if (tok==XkbCF_Equals)
|
|
rtrn->replace_axt_opts_on= True;
|
|
}
|
|
*opts = 0;
|
|
}
|
|
else {
|
|
rtrn->error= XkbCF_MissingEquals;
|
|
goto BAILOUT;
|
|
}
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
if ((tok==XkbCF_EOL)||(tok==XkbCF_Semi)||(tok==XkbCF_EOF)) {
|
|
rtrn->error= XkbCF_ExpectedControl;
|
|
return False;
|
|
}
|
|
while ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
|
|
if ((tok!=XkbCF_Ident)&&(tok!=XkbCF_String)) {
|
|
rtrn->error= XkbCF_ExpectedControl;
|
|
return False;
|
|
}
|
|
if (!AddAXTimeoutOptByName(rtrn,val.str,&opts_mask))
|
|
return False;
|
|
*opts |= opts_mask;
|
|
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_EOF)&&(tok!=XkbCF_Semi)) {
|
|
if (tok!=XkbCF_Plus) {
|
|
rtrn->error= XkbCF_ExpectedOperator;
|
|
return False;
|
|
}
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
}
|
|
}
|
|
break;
|
|
case _XkbCF_ClickVolume:
|
|
if (!pival) {
|
|
pival= &rtrn->click_volume;
|
|
onoff= 100;
|
|
}
|
|
case _XkbCF_BellVolume:
|
|
if (!pival) {
|
|
pival= &rtrn->bell_volume;
|
|
onoff= 100;
|
|
}
|
|
case _XkbCF_BellPitch:
|
|
if (!pival)
|
|
pival= &rtrn->bell_pitch;
|
|
case _XkbCF_BellDuration:
|
|
if (!pival)
|
|
pival= &rtrn->bell_duration;
|
|
case _XkbCF_RepeatDelay:
|
|
if (!pival)
|
|
pival= &rtrn->repeat_delay;
|
|
case _XkbCF_RepeatInterval:
|
|
if (!pival)
|
|
pival= &rtrn->repeat_interval;
|
|
case _XkbCF_SlowKeysDelay:
|
|
if (!pival)
|
|
pival= &rtrn->slow_keys_delay;
|
|
case _XkbCF_DebounceDelay:
|
|
if (!pival)
|
|
pival= &rtrn->debounce_delay;
|
|
case _XkbCF_MouseKeysDelay:
|
|
if (!pival)
|
|
pival= &rtrn->mk_delay;
|
|
case _XkbCF_MouseKeysInterval:
|
|
if (!pival)
|
|
pival= &rtrn->mk_interval;
|
|
case _XkbCF_MouseKeysTimeToMax:
|
|
if (!pival)
|
|
pival= &rtrn->mk_time_to_max;
|
|
case _XkbCF_MouseKeysMaxSpeed:
|
|
if (!pival)
|
|
pival= &rtrn->mk_max_speed;
|
|
case _XkbCF_MouseKeysCurve:
|
|
if (!pival)
|
|
pival= &rtrn->mk_curve;
|
|
case _XkbCF_AccessXTimeout:
|
|
if (!pival)
|
|
pival= &rtrn->ax_timeout;
|
|
if (tok!=XkbCF_Equals) {
|
|
rtrn->error= XkbCF_MissingEquals;
|
|
goto BAILOUT;
|
|
}
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
if (tok == XkbCF_Minus && field->field_id == _XkbCF_MouseKeysCurve) {
|
|
/* This can be a negative value */
|
|
tok = XkbCFScan(file,&val,rtrn);
|
|
sign = -1;
|
|
}
|
|
else
|
|
sign = 1;
|
|
if (tok!=XkbCF_Integer) {
|
|
Bool ok= False;
|
|
if ((onoff)&&(tok==XkbCF_Ident)&&(val.str!=NULL)) {
|
|
if (_XkbStrCaseCmp(val.str,"on")) {
|
|
val.ival= onoff;
|
|
ok= True;
|
|
}
|
|
else if (_XkbStrCaseCmp(val.str,"off")) {
|
|
val.ival= 0;
|
|
ok= True;
|
|
}
|
|
}
|
|
if (!ok) {
|
|
rtrn->error= XkbCF_ExpectedInteger;
|
|
goto BAILOUT;
|
|
}
|
|
}
|
|
*pival= val.ival * sign;
|
|
if (field->field_id == _XkbCF_AccessXTimeout)
|
|
rtrn->defined|=XkbCF_AccessXTimeout;
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
|
|
rtrn->error= XkbCF_ExpectedEOS;
|
|
return False;
|
|
}
|
|
break;
|
|
case _XkbCF_GroupsWrap:
|
|
if (tok!=XkbCF_Equals) {
|
|
rtrn->error= XkbCF_MissingEquals;
|
|
goto BAILOUT;
|
|
}
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
if (tok==XkbCF_Ident) {
|
|
if (_XkbStrCaseCmp(val.str,"wrap")==0) {
|
|
rtrn->groups_wrap= XkbSetGroupInfo(0,XkbWrapIntoRange,0);
|
|
}
|
|
else if (_XkbStrCaseCmp(val.str,"clamp")==0) {
|
|
rtrn->groups_wrap= XkbSetGroupInfo(0,XkbClampIntoRange,0);
|
|
}
|
|
else {
|
|
rtrn->error= XkbCF_ExpectedOORGroupBehavior;
|
|
return False;
|
|
}
|
|
}
|
|
else if ((tok==XkbCF_Integer)&&(XkbIsLegalGroup(val.ival-1))) {
|
|
rtrn->groups_wrap= XkbSetGroupInfo(0,XkbRedirectIntoRange,
|
|
val.ival-1);
|
|
}
|
|
else {
|
|
rtrn->error= XkbCF_ExpectedOORGroupBehavior;
|
|
return False;
|
|
}
|
|
rtrn->defined|= XkbCF_GroupsWrap;
|
|
tok= XkbCFScan(file,&val,rtrn);
|
|
if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)&&(tok!=XkbCF_EOF)) {
|
|
rtrn->error= XkbCF_ExpectedEOS;
|
|
return False;
|
|
}
|
|
break;
|
|
default:
|
|
rtrn->error= XkbCF_ExpectedInteger;
|
|
goto BAILOUT;
|
|
|
|
}
|
|
return True;
|
|
BAILOUT:
|
|
return False;
|
|
}
|
|
|
|
static Bool
|
|
DefaultCleanUp(XkbConfigRtrnPtr rtrn)
|
|
{
|
|
if (rtrn->keymap) _XkbFree(rtrn->keymap);
|
|
if (rtrn->keycodes) _XkbFree(rtrn->keycodes);
|
|
if (rtrn->geometry) _XkbFree(rtrn->geometry);
|
|
if (rtrn->phys_symbols) _XkbFree(rtrn->phys_symbols);
|
|
if (rtrn->symbols) _XkbFree(rtrn->symbols);
|
|
if (rtrn->types) _XkbFree(rtrn->types);
|
|
if (rtrn->compat) _XkbFree(rtrn->compat);
|
|
rtrn->keycodes= rtrn->geometry= NULL;
|
|
rtrn->symbols= rtrn->phys_symbols= NULL;
|
|
rtrn->types= rtrn->compat= NULL;
|
|
if ((rtrn->unbound_mods!=NULL)&&(rtrn->num_unbound_mods>0)) {
|
|
register int i;
|
|
for (i=0;i<rtrn->num_unbound_mods;i++) {
|
|
if (rtrn->unbound_mods[i].name!=NULL) {
|
|
_XkbFree(rtrn->unbound_mods[i].name);
|
|
rtrn->unbound_mods[i].name= NULL;
|
|
}
|
|
}
|
|
_XkbFree(rtrn->unbound_mods);
|
|
rtrn->sz_unbound_mods= 0;
|
|
rtrn->num_unbound_mods= 0;
|
|
rtrn->unbound_mods= NULL;
|
|
}
|
|
return True;
|
|
}
|
|
|
|
static Bool
|
|
DefaultApplyNames(XkbConfigRtrnPtr rtrn,XkbDescPtr xkb)
|
|
{
|
|
char *str;
|
|
|
|
if (XkbAllocNames(xkb,XkbComponentNamesMask,0,0)!=Success)
|
|
return False;
|
|
if ((str=rtrn->keycodes)!=NULL) {
|
|
xkb->names->keycodes= XkbInternAtom(xkb->dpy,str,False);
|
|
_XkbFree(str);
|
|
rtrn->keycodes= NULL;
|
|
}
|
|
if ((str=rtrn->geometry)!=NULL) {
|
|
xkb->names->geometry= XkbInternAtom(xkb->dpy,str,False);
|
|
_XkbFree(str);
|
|
rtrn->geometry= NULL;
|
|
}
|
|
if ((str=rtrn->symbols)!=NULL) {
|
|
xkb->names->symbols= XkbInternAtom(xkb->dpy,str,False);
|
|
_XkbFree(str);
|
|
rtrn->symbols= NULL;
|
|
}
|
|
if ((str=rtrn->phys_symbols)!=NULL) {
|
|
xkb->names->phys_symbols= XkbInternAtom(xkb->dpy,str,False);
|
|
_XkbFree(str);
|
|
rtrn->phys_symbols= NULL;
|
|
}
|
|
if ((str=rtrn->types)!=NULL) {
|
|
xkb->names->types= XkbInternAtom(xkb->dpy,str,False);
|
|
_XkbFree(str);
|
|
rtrn->types= NULL;
|
|
}
|
|
if ((str=rtrn->compat)!=NULL) {
|
|
xkb->names->compat= XkbInternAtom(xkb->dpy,str,False);
|
|
_XkbFree(str);
|
|
rtrn->compat= NULL;
|
|
}
|
|
return True;
|
|
}
|
|
|
|
static Bool
|
|
DefaultApplyControls(XkbConfigRtrnPtr rtrn,XkbDescPtr xkb)
|
|
{
|
|
unsigned on,off;
|
|
XkbControlsPtr ctrls;
|
|
unsigned int mask;
|
|
|
|
if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success)
|
|
return False;
|
|
ctrls= xkb->ctrls;
|
|
if (rtrn->replace_initial_ctrls)
|
|
ctrls->enabled_ctrls= rtrn->initial_ctrls;
|
|
else ctrls->enabled_ctrls|= rtrn->initial_ctrls;
|
|
ctrls->enabled_ctrls&= ~rtrn->initial_ctrls_clear;
|
|
if (rtrn->internal_mods.replace) {
|
|
ctrls->internal.real_mods= rtrn->internal_mods.mods;
|
|
ctrls->internal.vmods= rtrn->internal_mods.vmods;
|
|
}
|
|
else {
|
|
ctrls->internal.real_mods&= ~rtrn->internal_mods.mods_clear;
|
|
ctrls->internal.vmods&= ~rtrn->internal_mods.vmods_clear;
|
|
ctrls->internal.real_mods|= rtrn->internal_mods.mods;
|
|
ctrls->internal.vmods|= rtrn->internal_mods.vmods;
|
|
}
|
|
mask= 0;
|
|
(void)XkbVirtualModsToReal(xkb,ctrls->internal.vmods,&mask);
|
|
ctrls->internal.mask= (ctrls->internal.real_mods|mask);
|
|
|
|
if (rtrn->ignore_lock_mods.replace) {
|
|
ctrls->ignore_lock.real_mods= rtrn->ignore_lock_mods.mods;
|
|
ctrls->ignore_lock.vmods= rtrn->ignore_lock_mods.vmods;
|
|
}
|
|
else {
|
|
ctrls->ignore_lock.real_mods&= ~rtrn->ignore_lock_mods.mods_clear;
|
|
ctrls->ignore_lock.vmods&= ~rtrn->ignore_lock_mods.vmods_clear;
|
|
ctrls->ignore_lock.real_mods|= rtrn->ignore_lock_mods.mods;
|
|
ctrls->ignore_lock.vmods|= rtrn->ignore_lock_mods.vmods;
|
|
}
|
|
mask= 0;
|
|
(void)XkbVirtualModsToReal(xkb,ctrls->ignore_lock.vmods,&mask);
|
|
ctrls->ignore_lock.mask= (ctrls->ignore_lock.real_mods|mask);
|
|
|
|
if (rtrn->repeat_delay>0)
|
|
ctrls->repeat_delay= rtrn->repeat_delay;
|
|
if (rtrn->repeat_interval>0)
|
|
ctrls->repeat_interval= rtrn->repeat_interval;
|
|
if (rtrn->slow_keys_delay>0)
|
|
ctrls->slow_keys_delay= rtrn->slow_keys_delay;
|
|
if (rtrn->debounce_delay>0)
|
|
ctrls->debounce_delay= rtrn->debounce_delay;
|
|
if (rtrn->mk_delay>0)
|
|
ctrls->mk_delay= rtrn->mk_delay;
|
|
if (rtrn->mk_interval>0)
|
|
ctrls->mk_interval= rtrn->mk_interval;
|
|
if (rtrn->mk_time_to_max>0)
|
|
ctrls->mk_time_to_max= rtrn->mk_time_to_max;
|
|
if (rtrn->mk_max_speed>0)
|
|
ctrls->mk_max_speed= rtrn->mk_max_speed;
|
|
if (rtrn->mk_curve>0)
|
|
ctrls->mk_curve= rtrn->mk_curve;
|
|
if (rtrn->defined&XkbCF_AccessXTimeout && rtrn->ax_timeout > 0)
|
|
ctrls->ax_timeout= rtrn->ax_timeout;
|
|
|
|
/* any value set to both off and on is reset to ignore */
|
|
if ((off=(rtrn->axt_ctrls_on&rtrn->axt_ctrls_off))!=0)
|
|
rtrn->axt_ctrls_ignore|= off;
|
|
|
|
/* ignore takes priority over on and off */
|
|
rtrn->axt_ctrls_on&= ~rtrn->axt_ctrls_ignore;
|
|
rtrn->axt_ctrls_off&= ~rtrn->axt_ctrls_ignore;
|
|
|
|
if (!rtrn->replace_axt_ctrls_off) {
|
|
off= (ctrls->axt_ctrls_mask&(~ctrls->axt_ctrls_values));
|
|
off&= ~rtrn->axt_ctrls_on;
|
|
off|= rtrn->axt_ctrls_off;
|
|
}
|
|
else off= rtrn->axt_ctrls_off;
|
|
if (!rtrn->replace_axt_ctrls_on) {
|
|
on= (ctrls->axt_ctrls_mask&ctrls->axt_ctrls_values);
|
|
on&= ~rtrn->axt_ctrls_off;
|
|
on|= rtrn->axt_ctrls_on;
|
|
}
|
|
else on= rtrn->axt_ctrls_on;
|
|
ctrls->axt_ctrls_mask= (on|off)&~rtrn->axt_ctrls_ignore;
|
|
ctrls->axt_ctrls_values= on&~rtrn->axt_ctrls_ignore;
|
|
|
|
/* any value set to both off and on is reset to ignore */
|
|
if ((off=(rtrn->axt_opts_on&rtrn->axt_opts_off))!=0)
|
|
rtrn->axt_opts_ignore|= off;
|
|
|
|
/* ignore takes priority over on and off */
|
|
rtrn->axt_opts_on&= ~rtrn->axt_opts_ignore;
|
|
rtrn->axt_opts_off&= ~rtrn->axt_opts_ignore;
|
|
|
|
if (rtrn->replace_axt_opts_off) {
|
|
off= (ctrls->axt_opts_mask&(~ctrls->axt_opts_values));
|
|
off&= ~rtrn->axt_opts_on;
|
|
off|= rtrn->axt_opts_off;
|
|
}
|
|
else off= rtrn->axt_opts_off;
|
|
if (!rtrn->replace_axt_opts_on) {
|
|
on= (ctrls->axt_opts_mask&ctrls->axt_opts_values);
|
|
on&= ~rtrn->axt_opts_off;
|
|
on|= rtrn->axt_opts_on;
|
|
}
|
|
else on= rtrn->axt_opts_on;
|
|
ctrls->axt_opts_mask= (unsigned short)((on|off)&~rtrn->axt_ctrls_ignore);
|
|
ctrls->axt_opts_values= (unsigned short)(on&~rtrn->axt_ctrls_ignore);
|
|
|
|
if (rtrn->defined&XkbCF_GroupsWrap) {
|
|
int n;
|
|
n= XkbNumGroups(ctrls->groups_wrap);
|
|
rtrn->groups_wrap= XkbSetNumGroups(rtrn->groups_wrap,n);
|
|
ctrls->groups_wrap= rtrn->groups_wrap;
|
|
}
|
|
return True;
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
static Bool
|
|
DefaultFinish( XkbConfigFieldsPtr fields,
|
|
XkbDescPtr xkb,
|
|
XkbConfigRtrnPtr rtrn,
|
|
int what)
|
|
{
|
|
if ((what==XkbCF_Destroy)||(what==XkbCF_CleanUp))
|
|
return DefaultCleanUp(rtrn);
|
|
if (what==XkbCF_Check) {
|
|
if ((rtrn->symbols==NULL)&&(rtrn->phys_symbols!=NULL))
|
|
rtrn->symbols= _XkbDupString(rtrn->phys_symbols);
|
|
}
|
|
if ((what==XkbCF_Apply)||(what==XkbCF_Check)) {
|
|
if (xkb && xkb->names && (rtrn->num_unbound_mods>0))
|
|
XkbCFBindMods(rtrn,xkb);
|
|
XkbCFApplyMods(rtrn,XkbCF_InitialMods,&rtrn->initial_mods);
|
|
XkbCFApplyMods(rtrn,XkbCF_InternalMods,&rtrn->internal_mods);
|
|
XkbCFApplyMods(rtrn,XkbCF_IgnoreLockMods,&rtrn->ignore_lock_mods);
|
|
}
|
|
if (what==XkbCF_Apply) {
|
|
if (xkb!=NULL) {
|
|
DefaultApplyNames(rtrn,xkb);
|
|
DefaultApplyControls(rtrn,xkb);
|
|
XkbCFBindMods(rtrn,xkb);
|
|
}
|
|
}
|
|
return True;
|
|
}
|
|
|
|
static XkbConfigFieldRec _XkbCFDfltFields[] = {
|
|
{ "rules", _XkbCF_RulesFile },
|
|
{ "model", _XkbCF_Model },
|
|
{ "layout", _XkbCF_Layout },
|
|
{ "variant", _XkbCF_Variant },
|
|
{ "options", _XkbCF_Options },
|
|
{ "keymap", _XkbCF_Keymap },
|
|
{ "keycodes", _XkbCF_Keycodes },
|
|
{ "geometry", _XkbCF_Geometry },
|
|
{ "realsymbols",_XkbCF_PhysSymbols },
|
|
{ "actualsymbols",_XkbCF_PhysSymbols },
|
|
{ "symbols", _XkbCF_Symbols },
|
|
{ "symbolstouse",_XkbCF_Symbols },
|
|
{ "types", _XkbCF_Types },
|
|
{ "compat", _XkbCF_CompatMap },
|
|
{ "modifiers", _XkbCF_InitialMods },
|
|
{ "controls", _XkbCF_InitialCtrls },
|
|
{ "click", _XkbCF_ClickVolume },
|
|
{ "clickvolume",_XkbCF_ClickVolume },
|
|
{ "bell", _XkbCF_BellVolume },
|
|
{ "bellvolume", _XkbCF_BellVolume },
|
|
{ "bellpitch", _XkbCF_BellPitch },
|
|
{ "bellduration",_XkbCF_BellDuration },
|
|
{ "repeatdelay",_XkbCF_RepeatDelay },
|
|
{ "repeatinterval",_XkbCF_RepeatInterval },
|
|
{ "slowkeysdelay",_XkbCF_SlowKeysDelay },
|
|
{ "debouncedelay",_XkbCF_DebounceDelay },
|
|
{ "mousekeysdelay",_XkbCF_MouseKeysDelay },
|
|
{ "mousekeysinterval",_XkbCF_MouseKeysInterval },
|
|
{ "mousekeystimetomax",_XkbCF_MouseKeysTimeToMax },
|
|
{ "mousekeysmaxspeed",_XkbCF_MouseKeysMaxSpeed },
|
|
{ "mousekeyscurve",_XkbCF_MouseKeysCurve },
|
|
{ "accessxtimeout",_XkbCF_AccessXTimeout },
|
|
{ "axtimeout",_XkbCF_AccessXTimeout },
|
|
{ "accessxtimeoutctrlson",_XkbCF_AccessXTimeoutCtrlsOn },
|
|
{ "axtctrlson", _XkbCF_AccessXTimeoutCtrlsOn },
|
|
{ "accessxtimeoutctrlsoff",_XkbCF_AccessXTimeoutCtrlsOff },
|
|
{ "axtctrlsoff",_XkbCF_AccessXTimeoutCtrlsOff },
|
|
{ "accessxtimeoutfeedbackon", _XkbCF_AccessXTimeoutOptsOn },
|
|
{ "axtfeedbackon", _XkbCF_AccessXTimeoutOptsOn },
|
|
{ "accessxtimeoutfeedbackoff", _XkbCF_AccessXTimeoutOptsOff },
|
|
{ "axtfeedbackoff", _XkbCF_AccessXTimeoutOptsOff },
|
|
{ "ignorelockmods",_XkbCF_IgnoreLockMods },
|
|
{ "ignorelockmodifiers",_XkbCF_IgnoreLockMods },
|
|
{ "ignoregrouplock",_XkbCF_IgnoreGroupLock },
|
|
{ "internalmods",_XkbCF_InternalMods },
|
|
{ "internalmodifiers",_XkbCF_InternalMods },
|
|
{ "outofrangegroups",_XkbCF_GroupsWrap },
|
|
{ "groups", _XkbCF_GroupsWrap },
|
|
{ "feedback", _XkbCF_InitialFeedback },
|
|
};
|
|
#define _XkbCFNumDfltFields (sizeof(_XkbCFDfltFields)/sizeof(XkbConfigFieldRec))
|
|
|
|
static XkbConfigFieldsRec _XkbCFDflts = {
|
|
0, /* cfg_id */
|
|
_XkbCFNumDfltFields, /* num_fields */
|
|
_XkbCFDfltFields, /* fields */
|
|
DefaultParser, /* parser */
|
|
DefaultFinish, /* finish */
|
|
NULL, /* priv */
|
|
NULL /* next */
|
|
};
|
|
|
|
XkbConfigFieldsPtr XkbCFDflts= &_XkbCFDflts;
|
|
|
|
/***====================================================================***/
|
|
|
|
XkbConfigFieldsPtr
|
|
XkbCFDup(XkbConfigFieldsPtr fields)
|
|
{
|
|
XkbConfigFieldsPtr pNew;
|
|
|
|
pNew= _XkbTypedAlloc(XkbConfigFieldsRec);
|
|
if (pNew!=NULL) {
|
|
memcpy(pNew,fields,sizeof(XkbConfigFieldsRec));
|
|
if ((pNew->fields!=NULL)&&(pNew->num_fields>0)) {
|
|
pNew->fields= _XkbTypedCalloc(pNew->num_fields,XkbConfigFieldRec);
|
|
if (pNew->fields) {
|
|
memcpy(fields->fields,pNew->fields,
|
|
(pNew->num_fields*sizeof(XkbConfigFieldRec)));
|
|
}
|
|
else {
|
|
_XkbFree(pNew);
|
|
return NULL;
|
|
}
|
|
}
|
|
else {
|
|
pNew->num_fields= 0;
|
|
pNew->fields= NULL;
|
|
}
|
|
pNew->next= NULL;
|
|
}
|
|
return pNew;
|
|
}
|
|
|
|
XkbConfigFieldsPtr
|
|
XkbCFFree(XkbConfigFieldsPtr fields,Bool all)
|
|
{
|
|
XkbConfigFieldsPtr next;
|
|
|
|
next= NULL;
|
|
while (fields!=NULL) {
|
|
next= fields->next;
|
|
if (fields!=XkbCFDflts) {
|
|
if (fields->fields) {
|
|
_XkbFree(fields->fields);
|
|
fields->fields= NULL;
|
|
fields->num_fields= 0;
|
|
}
|
|
_XkbFree(fields);
|
|
}
|
|
fields= (all?next:NULL);
|
|
}
|
|
return next;
|
|
}
|
|
|
|
Bool
|
|
XkbCFApplyRtrnValues( XkbConfigRtrnPtr rtrn,
|
|
XkbConfigFieldsPtr fields,
|
|
XkbDescPtr xkb)
|
|
{
|
|
Bool ok;
|
|
|
|
if ((fields==NULL)||(rtrn==NULL)||(xkb==NULL))
|
|
return False;
|
|
for (ok=True;fields!=NULL;fields=fields->next) {
|
|
if (fields->finish!=NULL)
|
|
ok= (*fields->finish)(fields,xkb,rtrn,XkbCF_Apply)&&ok;
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
XkbConfigRtrnPrivPtr
|
|
XkbCFAddPrivate( XkbConfigRtrnPtr rtrn,
|
|
XkbConfigFieldsPtr fields,
|
|
XPointer ptr)
|
|
{
|
|
XkbConfigRtrnPrivPtr priv;
|
|
|
|
if ((rtrn==NULL)||(fields==NULL))
|
|
return NULL;
|
|
priv= _XkbTypedAlloc(XkbConfigRtrnPrivRec);
|
|
if (priv!=NULL) {
|
|
priv->cfg_id= fields->cfg_id;
|
|
priv->priv= ptr;
|
|
priv->next= rtrn->priv;
|
|
rtrn->priv= priv;
|
|
}
|
|
return priv;
|
|
}
|
|
|
|
void
|
|
XkbCFFreeRtrn( XkbConfigRtrnPtr rtrn,
|
|
XkbConfigFieldsPtr fields,
|
|
XkbDescPtr xkb)
|
|
{
|
|
XkbConfigRtrnPrivPtr tmp,next;
|
|
|
|
if ((fields==NULL)||(rtrn==NULL))
|
|
return;
|
|
while (fields!=NULL) {
|
|
if (fields->finish!=NULL)
|
|
(*fields->finish)(fields,xkb,rtrn,XkbCF_Destroy);
|
|
fields= fields->next;
|
|
}
|
|
for (tmp=rtrn->priv;tmp!=NULL;tmp=next) {
|
|
next= tmp->next;
|
|
bzero((char *)tmp,sizeof(XkbConfigRtrnPrivRec));
|
|
_XkbFree(tmp);
|
|
}
|
|
bzero((char *)rtrn,sizeof(XkbConfigRtrnRec));
|
|
return;
|
|
}
|
|
|
|
Bool
|
|
XkbCFParse( FILE * file,
|
|
XkbConfigFieldsPtr fields,
|
|
XkbDescPtr xkb,
|
|
XkbConfigRtrnPtr rtrn)
|
|
{
|
|
int tok;
|
|
XkbCFScanResultRec val;
|
|
XkbConfigFieldsPtr tmp;
|
|
|
|
if ((file==NULL)||(fields==NULL)||(rtrn==NULL))
|
|
return False;
|
|
for (tok=0,tmp=fields;tmp!=NULL;tmp=tmp->next,tok++) {
|
|
fields->cfg_id= tok;
|
|
}
|
|
bzero((char *)rtrn,sizeof(XkbConfigRtrnRec));
|
|
rtrn->line= 1;
|
|
rtrn->click_volume= -1;
|
|
rtrn->bell_volume= -1;
|
|
while ((tok=XkbCFScan(file,&val,rtrn))!=XkbCF_EOF) {
|
|
if (tok==XkbCF_Ident) {
|
|
Bool done;
|
|
for (tmp=fields,done=False;(tmp!=NULL)&&(!done);tmp=tmp->next) {
|
|
register int i;
|
|
XkbConfigFieldPtr f;
|
|
|
|
for (i=0,f=tmp->fields;(i<tmp->num_fields)&&(!done);i++,f++) {
|
|
if (_XkbStrCaseCmp(val.str,f->field)!=0)
|
|
continue;
|
|
if ((*tmp->parser)(file,tmp,f,xkb,rtrn))
|
|
done= True;
|
|
else goto BAILOUT;
|
|
}
|
|
}
|
|
}
|
|
else if ((tok!=XkbCF_EOL)&&(tok!=XkbCF_Semi)) {
|
|
rtrn->error= XkbCF_MissingIdent;
|
|
goto BAILOUT;
|
|
}
|
|
}
|
|
for (tmp=fields;tmp!=NULL;tmp=tmp->next) {
|
|
if ((tmp->finish)&&(!(*tmp->finish)(tmp,xkb,rtrn,XkbCF_Check)))
|
|
goto BAILOUT;
|
|
}
|
|
return True;
|
|
BAILOUT:
|
|
for (tmp=fields;tmp!=NULL;tmp=tmp->next) {
|
|
if (tmp->finish)
|
|
(*tmp->finish)(tmp,xkb,rtrn,XkbCF_CleanUp);
|
|
}
|
|
return False;
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
void
|
|
XkbCFReportError(FILE *file,char *name,int error,int line)
|
|
{
|
|
char * msg;
|
|
|
|
switch(error) {
|
|
case XkbCF_BadAlloc:
|
|
msg= "allocation failed\n"; break;
|
|
case XkbCF_UnterminatedString:
|
|
msg= "unterminated string on line %d"; break;
|
|
case XkbCF_MissingIdent:
|
|
msg= "expected identifier on line %d"; break;
|
|
case XkbCF_MissingEquals:
|
|
msg= "expected '=' on line %d"; break;
|
|
case XkbCF_ExpectedEOS:
|
|
msg= "expected ';' or newline on line %d"; break;
|
|
case XkbCF_ExpectedBoolean:
|
|
msg= "expected a boolean value on line %d"; break;
|
|
case XkbCF_ExpectedInteger:
|
|
msg= "expected a numeric value on line %d"; break;
|
|
case XkbCF_ExpectedString:
|
|
msg= "expected a string on line %d"; break;
|
|
case XkbCF_ExpectedModifier:
|
|
msg= "expected a modifier name on line %d"; break;
|
|
case XkbCF_ExpectedControl:
|
|
msg= "expected a control name on line %d"; break;
|
|
case XkbCF_ExpectedAXOption:
|
|
msg= "expected an AccessX option on line %d"; break;
|
|
case XkbCF_ExpectedOperator:
|
|
msg= "expected '+' or '-' on line %d"; break;
|
|
case XkbCF_ExpectedOORGroupBehavior:
|
|
msg= "expected wrap, clamp or group number on line %d"; break;
|
|
default:
|
|
msg= "unknown error on line %d"; break;
|
|
}
|
|
#ifndef XKB_IN_SERVER
|
|
fprintf(file,msg,line);
|
|
if (name) fprintf(file," of %s\n",name);
|
|
else fprintf(file,"\n");
|
|
#else
|
|
ErrorF(msg,line);
|
|
if (name) ErrorF(" of %s\n",name);
|
|
else ErrorF("\n");
|
|
#endif
|
|
return;
|
|
}
|