xkbInit.c revision 4642e01f
105b261ecSmrg/************************************************************ 205b261ecSmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 305b261ecSmrg 405b261ecSmrgPermission to use, copy, modify, and distribute this 505b261ecSmrgsoftware and its documentation for any purpose and without 605b261ecSmrgfee is hereby granted, provided that the above copyright 705b261ecSmrgnotice appear in all copies and that both that copyright 805b261ecSmrgnotice and this permission notice appear in supporting 905b261ecSmrgdocumentation, and that the name of Silicon Graphics not be 1005b261ecSmrgused in advertising or publicity pertaining to distribution 1105b261ecSmrgof the software without specific prior written permission. 1205b261ecSmrgSilicon Graphics makes no representation about the suitability 1305b261ecSmrgof this software for any purpose. It is provided "as is" 1405b261ecSmrgwithout any express or implied warranty. 1505b261ecSmrg 1605b261ecSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 1705b261ecSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 1805b261ecSmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 1905b261ecSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 2005b261ecSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2105b261ecSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 2205b261ecSmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 2305b261ecSmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 2405b261ecSmrg 2505b261ecSmrg********************************************************/ 2605b261ecSmrg 2705b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2805b261ecSmrg#include <dix-config.h> 2905b261ecSmrg#endif 3005b261ecSmrg 3105b261ecSmrg#ifdef HAVE_XKB_CONFIG_H 3205b261ecSmrg#include <xkb-config.h> 3305b261ecSmrg#endif 3405b261ecSmrg 3505b261ecSmrg#include <stdio.h> 3605b261ecSmrg#include <stdlib.h> 3705b261ecSmrg#include <ctype.h> 3805b261ecSmrg#include <unistd.h> 3905b261ecSmrg#include <math.h> 4005b261ecSmrg#define NEED_EVENTS 1 4105b261ecSmrg#include <X11/X.h> 4205b261ecSmrg#include <X11/Xproto.h> 4305b261ecSmrg#include <X11/keysym.h> 4405b261ecSmrg#include <X11/Xatom.h> 4505b261ecSmrg#include "misc.h" 4605b261ecSmrg#include "inputstr.h" 4705b261ecSmrg#include "opaque.h" 4805b261ecSmrg#include "property.h" 4905b261ecSmrg#define XKBSRV_NEED_FILE_FUNCS 5005b261ecSmrg#include <xkbsrv.h> 514642e01fSmrg#include "xkbgeom.h" 5205b261ecSmrg#include <X11/extensions/XKMformat.h> 534642e01fSmrg#include "xkbfile.h" 5405b261ecSmrg#include "xkb.h" 5505b261ecSmrg 5605b261ecSmrg#define CREATE_ATOM(s) MakeAtom(s,sizeof(s)-1,1) 5705b261ecSmrg 584642e01fSmrg#if defined(__alpha) || defined(__alpha__) 5905b261ecSmrg#define LED_COMPOSE 2 6005b261ecSmrg#define LED_CAPS 3 6105b261ecSmrg#define LED_SCROLL 4 6205b261ecSmrg#define LED_NUM 5 6305b261ecSmrg#define PHYS_LEDS 0x1f 6405b261ecSmrg#else 6505b261ecSmrg#ifdef sun 6605b261ecSmrg#define LED_NUM 1 6705b261ecSmrg#define LED_SCROLL 2 6805b261ecSmrg#define LED_COMPOSE 3 6905b261ecSmrg#define LED_CAPS 4 7005b261ecSmrg#define PHYS_LEDS 0x0f 7105b261ecSmrg#else 7205b261ecSmrg#define LED_CAPS 1 7305b261ecSmrg#define LED_NUM 2 7405b261ecSmrg#define LED_SCROLL 3 7505b261ecSmrg#define PHYS_LEDS 0x07 7605b261ecSmrg#endif 7705b261ecSmrg#endif 7805b261ecSmrg 7905b261ecSmrg#define MAX_TOC 16 8005b261ecSmrgtypedef struct _SrvXkmInfo { 8105b261ecSmrg DeviceIntPtr dev; 8205b261ecSmrg FILE * file; 834642e01fSmrg XkbDescPtr xkb; 8405b261ecSmrg} SrvXkmInfo; 8505b261ecSmrg 8605b261ecSmrg 8705b261ecSmrg/***====================================================================***/ 8805b261ecSmrg 8905b261ecSmrg#ifndef XKB_BASE_DIRECTORY 9005b261ecSmrg#define XKB_BASE_DIRECTORY "/usr/lib/X11/xkb" 9105b261ecSmrg#endif 9205b261ecSmrg#ifndef XKB_BIN_DIRECTORY 9305b261ecSmrg#define XKB_BIN_DIRECTORY XKB_BASE_DIRECTORY 9405b261ecSmrg#endif 9505b261ecSmrg#ifndef XKB_DFLT_RULES_FILE 964642e01fSmrg#define XKB_DFLT_RULES_FILE "base" 9705b261ecSmrg#endif 9805b261ecSmrg#ifndef XKB_DFLT_KB_LAYOUT 9905b261ecSmrg#define XKB_DFLT_KB_LAYOUT "us" 10005b261ecSmrg#endif 10105b261ecSmrg#ifndef XKB_DFLT_KB_MODEL 10205b261ecSmrg#define XKB_DFLT_KB_MODEL "dflt" 10305b261ecSmrg#endif 10405b261ecSmrg#ifndef XKB_DFLT_KB_VARIANT 10505b261ecSmrg#define XKB_DFLT_KB_VARIANT NULL 10605b261ecSmrg#endif 10705b261ecSmrg#ifndef XKB_DFLT_KB_OPTIONS 10805b261ecSmrg#define XKB_DFLT_KB_OPTIONS NULL 10905b261ecSmrg#endif 11005b261ecSmrg#ifndef XKB_DFLT_DISABLED 11105b261ecSmrg#define XKB_DFLT_DISABLED True 11205b261ecSmrg#endif 11305b261ecSmrg#ifndef XKB_DFLT_RULES_PROP 11405b261ecSmrg#define XKB_DFLT_RULES_PROP True 11505b261ecSmrg#endif 11605b261ecSmrg 11705b261ecSmrgchar * XkbBaseDirectory= XKB_BASE_DIRECTORY; 11805b261ecSmrgchar * XkbBinDirectory= XKB_BIN_DIRECTORY; 11905b261ecSmrgstatic int XkbWantAccessX= 0; 12005b261ecSmrg 12105b261ecSmrgstatic Bool rulesDefined= False; 12205b261ecSmrgstatic char * XkbRulesFile= NULL; 12305b261ecSmrgstatic char * XkbModelDflt= NULL; 12405b261ecSmrgstatic char * XkbLayoutDflt= NULL; 12505b261ecSmrgstatic char * XkbVariantDflt= NULL; 12605b261ecSmrgstatic char * XkbOptionsDflt= NULL; 12705b261ecSmrg 12805b261ecSmrgstatic char * XkbModelUsed= NULL; 12905b261ecSmrgstatic char * XkbLayoutUsed= NULL; 13005b261ecSmrgstatic char * XkbVariantUsed= NULL; 13105b261ecSmrgstatic char * XkbOptionsUsed= NULL; 13205b261ecSmrg 1334642e01fSmrgstatic XkbDescPtr xkb_cached_map = NULL; 1344642e01fSmrg 13505b261ecSmrg_X_EXPORT Bool noXkbExtension= XKB_DFLT_DISABLED; 13605b261ecSmrgstatic Bool XkbWantRulesProp= XKB_DFLT_RULES_PROP; 13705b261ecSmrg 13805b261ecSmrg/***====================================================================***/ 13905b261ecSmrg 14005b261ecSmrgstatic char * 14105b261ecSmrgXkbGetRulesDflts(XkbRF_VarDefsPtr defs) 14205b261ecSmrg{ 14305b261ecSmrg if (XkbModelDflt) defs->model= XkbModelDflt; 14405b261ecSmrg else defs->model= XKB_DFLT_KB_MODEL; 14505b261ecSmrg if (XkbLayoutDflt) defs->layout= XkbLayoutDflt; 14605b261ecSmrg else defs->layout= XKB_DFLT_KB_LAYOUT; 14705b261ecSmrg if (XkbVariantDflt) defs->variant= XkbVariantDflt; 14805b261ecSmrg else defs->variant= XKB_DFLT_KB_VARIANT; 14905b261ecSmrg if (XkbOptionsDflt) defs->options= XkbOptionsDflt; 15005b261ecSmrg else defs->options= XKB_DFLT_KB_OPTIONS; 15105b261ecSmrg return (rulesDefined?XkbRulesFile:XKB_DFLT_RULES_FILE); 15205b261ecSmrg} 15305b261ecSmrg 15405b261ecSmrgstatic Bool 15505b261ecSmrgXkbWriteRulesProp(ClientPtr client, pointer closure) 15605b261ecSmrg{ 15705b261ecSmrgint len,out; 15805b261ecSmrgAtom name; 15905b261ecSmrgchar * pval; 16005b261ecSmrg 16105b261ecSmrg if (rulesDefined && (!XkbRulesFile)) 16205b261ecSmrg return False; 16305b261ecSmrg len= (XkbRulesFile?strlen(XkbRulesFile):strlen(XKB_DFLT_RULES_FILE)); 16405b261ecSmrg len+= (XkbModelUsed?strlen(XkbModelUsed):0); 16505b261ecSmrg len+= (XkbLayoutUsed?strlen(XkbLayoutUsed):0); 16605b261ecSmrg len+= (XkbVariantUsed?strlen(XkbVariantUsed):0); 16705b261ecSmrg len+= (XkbOptionsUsed?strlen(XkbOptionsUsed):0); 16805b261ecSmrg if (len<1) 16905b261ecSmrg return True; 17005b261ecSmrg 17105b261ecSmrg len+= 5; /* trailing NULs */ 17205b261ecSmrg 17305b261ecSmrg name= MakeAtom(_XKB_RF_NAMES_PROP_ATOM,strlen(_XKB_RF_NAMES_PROP_ATOM),1); 17405b261ecSmrg if (name==None) { 1754642e01fSmrg ErrorF("[xkb] Atom error: %s not created\n",_XKB_RF_NAMES_PROP_ATOM); 17605b261ecSmrg return True; 17705b261ecSmrg } 1784642e01fSmrg pval= (char*) xalloc(len); 17905b261ecSmrg if (!pval) { 1804642e01fSmrg ErrorF("[xkb] Allocation error: %s proprerty not created\n", 18105b261ecSmrg _XKB_RF_NAMES_PROP_ATOM); 18205b261ecSmrg return True; 18305b261ecSmrg } 18405b261ecSmrg out= 0; 18505b261ecSmrg if (XkbRulesFile) { 18605b261ecSmrg strcpy(&pval[out],XkbRulesFile); 18705b261ecSmrg out+= strlen(XkbRulesFile); 18805b261ecSmrg } else { 18905b261ecSmrg strcpy(&pval[out],XKB_DFLT_RULES_FILE); 19005b261ecSmrg out+= strlen(XKB_DFLT_RULES_FILE); 19105b261ecSmrg } 19205b261ecSmrg pval[out++]= '\0'; 19305b261ecSmrg if (XkbModelUsed) { 19405b261ecSmrg strcpy(&pval[out],XkbModelUsed); 19505b261ecSmrg out+= strlen(XkbModelUsed); 19605b261ecSmrg } 19705b261ecSmrg pval[out++]= '\0'; 19805b261ecSmrg if (XkbLayoutUsed) { 19905b261ecSmrg strcpy(&pval[out],XkbLayoutUsed); 20005b261ecSmrg out+= strlen(XkbLayoutUsed); 20105b261ecSmrg } 20205b261ecSmrg pval[out++]= '\0'; 20305b261ecSmrg if (XkbVariantUsed) { 20405b261ecSmrg strcpy(&pval[out],XkbVariantUsed); 20505b261ecSmrg out+= strlen(XkbVariantUsed); 20605b261ecSmrg } 20705b261ecSmrg pval[out++]= '\0'; 20805b261ecSmrg if (XkbOptionsUsed) { 20905b261ecSmrg strcpy(&pval[out],XkbOptionsUsed); 21005b261ecSmrg out+= strlen(XkbOptionsUsed); 21105b261ecSmrg } 21205b261ecSmrg pval[out++]= '\0'; 21305b261ecSmrg if (out!=len) { 2144642e01fSmrg ErrorF("[xkb] Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n", 21505b261ecSmrg out,len); 21605b261ecSmrg } 2174642e01fSmrg dixChangeWindowProperty(serverClient, WindowTable[0], name, XA_STRING, 8, 2184642e01fSmrg PropModeReplace, len, pval, True); 2194642e01fSmrg xfree(pval); 22005b261ecSmrg return True; 22105b261ecSmrg} 22205b261ecSmrg 22305b261ecSmrgstatic void 22405b261ecSmrgXkbSetRulesUsed(XkbRF_VarDefsPtr defs) 22505b261ecSmrg{ 22605b261ecSmrg if (XkbModelUsed) 22705b261ecSmrg _XkbFree(XkbModelUsed); 22805b261ecSmrg XkbModelUsed= (defs->model?_XkbDupString(defs->model):NULL); 22905b261ecSmrg if (XkbLayoutUsed) 23005b261ecSmrg _XkbFree(XkbLayoutUsed); 23105b261ecSmrg XkbLayoutUsed= (defs->layout?_XkbDupString(defs->layout):NULL); 23205b261ecSmrg if (XkbVariantUsed) 23305b261ecSmrg _XkbFree(XkbVariantUsed); 23405b261ecSmrg XkbVariantUsed= (defs->variant?_XkbDupString(defs->variant):NULL); 23505b261ecSmrg if (XkbOptionsUsed) 23605b261ecSmrg _XkbFree(XkbOptionsUsed); 23705b261ecSmrg XkbOptionsUsed= (defs->options?_XkbDupString(defs->options):NULL); 23805b261ecSmrg if (XkbWantRulesProp) 23905b261ecSmrg QueueWorkProc(XkbWriteRulesProp,NULL,NULL); 24005b261ecSmrg return; 24105b261ecSmrg} 24205b261ecSmrg 2434642e01fSmrg/** 2444642e01fSmrg * Set the default RMLVO for the next device to be initialised. 2454642e01fSmrg * If a parameter is NULL, the previous setting will be used. Use empty 2464642e01fSmrg * strings if you want to delete a previous setting. 2474642e01fSmrg * 2484642e01fSmrg * If @rulesFile is NULL and no previous @rulesFile has been set, the 2494642e01fSmrg * built-in default is chosen as default. 2504642e01fSmrg */ 25105b261ecSmrg_X_EXPORT void 25205b261ecSmrgXkbSetRulesDflts(char *rulesFile,char *model,char *layout, 25305b261ecSmrg char *variant,char *options) 25405b261ecSmrg{ 2554642e01fSmrg if (!rulesFile && !XkbRulesFile) 2564642e01fSmrg { 2574642e01fSmrg LogMessage(X_WARNING, "[xkb] No rule given, and no previous rule " 2584642e01fSmrg "defined. Defaulting to '%s'.\n", 2594642e01fSmrg XKB_DFLT_RULES_FILE); 2604642e01fSmrg rulesFile = XKB_DFLT_RULES_FILE; 2614642e01fSmrg } 2624642e01fSmrg 2634642e01fSmrg if (rulesFile) { 2644642e01fSmrg if (XkbRulesFile) 2654642e01fSmrg _XkbFree(XkbRulesFile); 2664642e01fSmrg XkbRulesFile= _XkbDupString(rulesFile); 2674642e01fSmrg rulesDefined= True; 2684642e01fSmrg } 2694642e01fSmrg 27005b261ecSmrg if (model) { 27105b261ecSmrg if (XkbModelDflt) 27205b261ecSmrg _XkbFree(XkbModelDflt); 27305b261ecSmrg XkbModelDflt= _XkbDupString(model); 27405b261ecSmrg } 27505b261ecSmrg if (layout) { 27605b261ecSmrg if (XkbLayoutDflt) 27705b261ecSmrg _XkbFree(XkbLayoutDflt); 27805b261ecSmrg XkbLayoutDflt= _XkbDupString(layout); 27905b261ecSmrg } 28005b261ecSmrg if (variant) { 28105b261ecSmrg if (XkbVariantDflt) 28205b261ecSmrg _XkbFree(XkbVariantDflt); 28305b261ecSmrg XkbVariantDflt= _XkbDupString(variant); 28405b261ecSmrg } 28505b261ecSmrg if (options) { 28605b261ecSmrg if (XkbOptionsDflt) 28705b261ecSmrg _XkbFree(XkbOptionsDflt); 28805b261ecSmrg XkbOptionsDflt= _XkbDupString(options); 28905b261ecSmrg } 29005b261ecSmrg return; 29105b261ecSmrg} 29205b261ecSmrg 2934642e01fSmrgvoid 2944642e01fSmrgXkbDeleteRulesDflts() 2954642e01fSmrg{ 2964642e01fSmrg _XkbFree(XkbRulesFile); 2974642e01fSmrg XkbRulesFile = NULL; 2984642e01fSmrg _XkbFree(XkbModelDflt); 2994642e01fSmrg XkbModelDflt = NULL; 3004642e01fSmrg _XkbFree(XkbLayoutDflt); 3014642e01fSmrg XkbLayoutDflt = NULL; 3024642e01fSmrg _XkbFree(XkbVariantDflt); 3034642e01fSmrg XkbVariantDflt = NULL; 3044642e01fSmrg _XkbFree(XkbOptionsDflt); 3054642e01fSmrg XkbOptionsDflt = NULL; 3064642e01fSmrg 3074642e01fSmrg XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, True); 3084642e01fSmrg xkb_cached_map = NULL; 3094642e01fSmrg} 31005b261ecSmrg 3114642e01fSmrg/***====================================================================***/ 31205b261ecSmrg 31305b261ecSmrg#include "xkbDflts.h" 31405b261ecSmrg 31505b261ecSmrgstatic Bool 3164642e01fSmrgXkbInitKeyTypes(XkbDescPtr xkb) 31705b261ecSmrg{ 3184642e01fSmrg if (xkb->defined & XkmTypesMask) 3194642e01fSmrg return True; 3204642e01fSmrg 32105b261ecSmrg initTypeNames(NULL); 32205b261ecSmrg if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_dflt_types)!=Success) 32305b261ecSmrg return False; 32405b261ecSmrg if (XkbCopyKeyTypes(dflt_types,xkb->map->types,num_dflt_types)!= 32505b261ecSmrg Success) { 32605b261ecSmrg return False; 32705b261ecSmrg } 32805b261ecSmrg xkb->map->size_types= xkb->map->num_types= num_dflt_types; 32905b261ecSmrg return True; 33005b261ecSmrg} 33105b261ecSmrg 33205b261ecSmrgstatic void 3334642e01fSmrgXkbInitRadioGroups(XkbSrvInfoPtr xkbi) 33405b261ecSmrg{ 33505b261ecSmrg xkbi->nRadioGroups = 0; 33605b261ecSmrg xkbi->radioGroups = NULL; 33705b261ecSmrg return; 33805b261ecSmrg} 33905b261ecSmrg 34005b261ecSmrg 34105b261ecSmrgstatic Status 3424642e01fSmrgXkbInitCompatStructs(XkbDescPtr xkb) 34305b261ecSmrg{ 34405b261ecSmrgregister int i; 34505b261ecSmrgXkbCompatMapPtr compat; 34605b261ecSmrg 3474642e01fSmrg if (xkb->defined & XkmCompatMapMask) 3484642e01fSmrg return True; 3494642e01fSmrg 35005b261ecSmrg if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_dfltSI)!=Success) 35105b261ecSmrg return BadAlloc; 35205b261ecSmrg compat = xkb->compat; 35305b261ecSmrg if (compat->sym_interpret) { 35405b261ecSmrg compat->num_si = num_dfltSI; 35505b261ecSmrg memcpy((char *)compat->sym_interpret,(char *)dfltSI,sizeof(dfltSI)); 35605b261ecSmrg } 35705b261ecSmrg for (i=0;i<XkbNumKbdGroups;i++) { 35805b261ecSmrg compat->groups[i]= compatMap.groups[i]; 35905b261ecSmrg if (compat->groups[i].vmods!=0) { 36005b261ecSmrg unsigned mask; 36105b261ecSmrg mask= XkbMaskForVMask(xkb,compat->groups[i].vmods); 36205b261ecSmrg compat->groups[i].mask= compat->groups[i].real_mods|mask; 36305b261ecSmrg } 36405b261ecSmrg else compat->groups[i].mask= compat->groups[i].real_mods; 36505b261ecSmrg } 36605b261ecSmrg return Success; 36705b261ecSmrg} 36805b261ecSmrg 36905b261ecSmrgstatic void 3704642e01fSmrgXkbInitSemantics(XkbDescPtr xkb) 37105b261ecSmrg{ 3724642e01fSmrg XkbInitKeyTypes(xkb); 3734642e01fSmrg XkbInitCompatStructs(xkb); 37405b261ecSmrg return; 37505b261ecSmrg} 37605b261ecSmrg 37705b261ecSmrg/***====================================================================***/ 37805b261ecSmrg 37905b261ecSmrgstatic Status 3804642e01fSmrgXkbInitNames(XkbSrvInfoPtr xkbi) 38105b261ecSmrg{ 38205b261ecSmrgXkbDescPtr xkb; 38305b261ecSmrgXkbNamesPtr names; 38405b261ecSmrgStatus rtrn; 38505b261ecSmrgAtom unknown; 38605b261ecSmrg 38705b261ecSmrg xkb= xkbi->desc; 38805b261ecSmrg if ((rtrn=XkbAllocNames(xkb,XkbAllNamesMask,0,0))!=Success) 38905b261ecSmrg return rtrn; 39005b261ecSmrg unknown= CREATE_ATOM("unknown"); 39105b261ecSmrg names = xkb->names; 39205b261ecSmrg if (names->keycodes==None) names->keycodes= unknown; 39305b261ecSmrg if (names->geometry==None) names->geometry= unknown; 39405b261ecSmrg if (names->phys_symbols==None) names->phys_symbols= unknown; 39505b261ecSmrg if (names->symbols==None) names->symbols= unknown; 39605b261ecSmrg if (names->types==None) names->types= unknown; 39705b261ecSmrg if (names->compat==None) names->compat= unknown; 3984642e01fSmrg if (!(xkb->defined & XkmVirtualModsMask)) { 3994642e01fSmrg if (names->vmods[vmod_NumLock]==None) 4004642e01fSmrg names->vmods[vmod_NumLock]= CREATE_ATOM("NumLock"); 4014642e01fSmrg if (names->vmods[vmod_Alt]==None) 4024642e01fSmrg names->vmods[vmod_Alt]= CREATE_ATOM("Alt"); 4034642e01fSmrg if (names->vmods[vmod_AltGr]==None) 4044642e01fSmrg names->vmods[vmod_AltGr]= CREATE_ATOM("ModeSwitch"); 40505b261ecSmrg } 40605b261ecSmrg 4074642e01fSmrg if (!(xkb->defined & XkmIndicatorsMask) || 4084642e01fSmrg !(xkb->defined & XkmGeometryMask)) { 4094642e01fSmrg initIndicatorNames(NULL,xkb); 4104642e01fSmrg if (names->indicators[LED_CAPS-1]==None) 4114642e01fSmrg names->indicators[LED_CAPS-1] = CREATE_ATOM("Caps Lock"); 4124642e01fSmrg if (names->indicators[LED_NUM-1]==None) 4134642e01fSmrg names->indicators[LED_NUM-1] = CREATE_ATOM("Num Lock"); 4144642e01fSmrg if (names->indicators[LED_SCROLL-1]==None) 4154642e01fSmrg names->indicators[LED_SCROLL-1] = CREATE_ATOM("Scroll Lock"); 41605b261ecSmrg#ifdef LED_COMPOSE 4174642e01fSmrg if (names->indicators[LED_COMPOSE-1]==None) 4184642e01fSmrg names->indicators[LED_COMPOSE-1] = CREATE_ATOM("Compose"); 41905b261ecSmrg#endif 42005b261ecSmrg } 4214642e01fSmrg 42205b261ecSmrg if (xkb->geom!=NULL) 42305b261ecSmrg names->geometry= xkb->geom->name; 42405b261ecSmrg else names->geometry= unknown; 4254642e01fSmrg 42605b261ecSmrg return Success; 42705b261ecSmrg} 42805b261ecSmrg 42905b261ecSmrgstatic Status 4304642e01fSmrgXkbInitIndicatorMap(XkbSrvInfoPtr xkbi) 43105b261ecSmrg{ 43205b261ecSmrgXkbDescPtr xkb; 43305b261ecSmrgXkbIndicatorPtr map; 43405b261ecSmrgXkbSrvLedInfoPtr sli; 43505b261ecSmrg 43605b261ecSmrg xkb= xkbi->desc; 43705b261ecSmrg if (XkbAllocIndicatorMaps(xkb)!=Success) 43805b261ecSmrg return BadAlloc; 4394642e01fSmrg 4404642e01fSmrg if (!(xkb->defined & XkmIndicatorsMask)) { 4414642e01fSmrg map= xkb->indicators; 4424642e01fSmrg map->phys_indicators = PHYS_LEDS; 4434642e01fSmrg map->maps[LED_CAPS-1].flags= XkbIM_NoExplicit; 4444642e01fSmrg map->maps[LED_CAPS-1].which_mods= XkbIM_UseLocked; 4454642e01fSmrg map->maps[LED_CAPS-1].mods.mask= LockMask; 4464642e01fSmrg map->maps[LED_CAPS-1].mods.real_mods= LockMask; 4474642e01fSmrg 4484642e01fSmrg map->maps[LED_NUM-1].flags= XkbIM_NoExplicit; 4494642e01fSmrg map->maps[LED_NUM-1].which_mods= XkbIM_UseLocked; 4504642e01fSmrg map->maps[LED_NUM-1].mods.mask= 0; 4514642e01fSmrg map->maps[LED_NUM-1].mods.real_mods= 0; 4524642e01fSmrg map->maps[LED_NUM-1].mods.vmods= vmod_NumLockMask; 4534642e01fSmrg 4544642e01fSmrg map->maps[LED_SCROLL-1].flags= XkbIM_NoExplicit; 4554642e01fSmrg map->maps[LED_SCROLL-1].which_mods= XkbIM_UseLocked; 4564642e01fSmrg map->maps[LED_SCROLL-1].mods.mask= Mod3Mask; 4574642e01fSmrg map->maps[LED_SCROLL-1].mods.real_mods= Mod3Mask; 45805b261ecSmrg } 4594642e01fSmrg 46005b261ecSmrg sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0); 46105b261ecSmrg if (sli) 46205b261ecSmrg XkbCheckIndicatorMaps(xkbi->device,sli,XkbAllIndicatorsMask); 4634642e01fSmrg 46405b261ecSmrg return Success; 46505b261ecSmrg} 46605b261ecSmrg 46705b261ecSmrgstatic Status 4684642e01fSmrgXkbInitControls(DeviceIntPtr pXDev,XkbSrvInfoPtr xkbi) 46905b261ecSmrg{ 47005b261ecSmrgXkbDescPtr xkb; 47105b261ecSmrgXkbControlsPtr ctrls; 47205b261ecSmrg 47305b261ecSmrg xkb= xkbi->desc; 47405b261ecSmrg /* 12/31/94 (ef) -- XXX! Should check if controls loaded from file */ 47505b261ecSmrg if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success) 47605b261ecSmrg FatalError("Couldn't allocate keyboard controls\n"); 47705b261ecSmrg ctrls= xkb->ctrls; 4784642e01fSmrg if (!(xkb->defined & XkmSymbolsMask)) 4794642e01fSmrg ctrls->num_groups = 1; 48005b261ecSmrg ctrls->groups_wrap = XkbSetGroupInfo(1,XkbWrapIntoRange,0); 48105b261ecSmrg ctrls->internal.mask = 0; 48205b261ecSmrg ctrls->internal.real_mods = 0; 48305b261ecSmrg ctrls->internal.vmods = 0; 48405b261ecSmrg ctrls->ignore_lock.mask = 0; 48505b261ecSmrg ctrls->ignore_lock.real_mods = 0; 48605b261ecSmrg ctrls->ignore_lock.vmods = 0; 48705b261ecSmrg ctrls->enabled_ctrls = XkbAccessXTimeoutMask|XkbRepeatKeysMask| 48805b261ecSmrg XkbMouseKeysAccelMask|XkbAudibleBellMask| 48905b261ecSmrg XkbIgnoreGroupLockMask; 49005b261ecSmrg if (XkbWantAccessX) 49105b261ecSmrg ctrls->enabled_ctrls|= XkbAccessXKeysMask; 49205b261ecSmrg AccessXInit(pXDev); 49305b261ecSmrg return Success; 49405b261ecSmrg} 49505b261ecSmrg 49605b261ecSmrgvoid 49705b261ecSmrgXkbInitDevice(DeviceIntPtr pXDev) 49805b261ecSmrg{ 49905b261ecSmrgint i; 50005b261ecSmrgXkbSrvInfoPtr xkbi; 50105b261ecSmrgXkbChangesRec changes; 50205b261ecSmrgunsigned check; 50305b261ecSmrgXkbEventCauseRec cause; 50405b261ecSmrg 50505b261ecSmrg bzero(&changes,sizeof(XkbChangesRec)); 50605b261ecSmrg pXDev->key->xkbInfo= xkbi= _XkbTypedCalloc(1,XkbSrvInfoRec); 50705b261ecSmrg if ( xkbi ) { 50805b261ecSmrg XkbDescPtr xkb; 5094642e01fSmrg 5104642e01fSmrg if (xkb_cached_map) { 5114642e01fSmrg xkbi->desc = xkb_cached_map; 5124642e01fSmrg xkb_cached_map = NULL; 5134642e01fSmrg } 5144642e01fSmrg else { 5154642e01fSmrg xkbi->desc= XkbAllocKeyboard(); 5164642e01fSmrg if (!xkbi->desc) 5174642e01fSmrg FatalError("Couldn't allocate keyboard description\n"); 5184642e01fSmrg xkbi->desc->min_key_code = pXDev->key->curKeySyms.minKeyCode; 5194642e01fSmrg xkbi->desc->max_key_code = pXDev->key->curKeySyms.maxKeyCode; 5204642e01fSmrg } 52105b261ecSmrg xkb= xkbi->desc; 52205b261ecSmrg if (xkb->min_key_code == 0) 52305b261ecSmrg xkb->min_key_code = pXDev->key->curKeySyms.minKeyCode; 52405b261ecSmrg if (xkb->max_key_code == 0) 52505b261ecSmrg xkb->max_key_code = pXDev->key->curKeySyms.maxKeyCode; 52605b261ecSmrg if ((pXDev->key->curKeySyms.minKeyCode!=xkbi->desc->min_key_code)|| 52705b261ecSmrg (pXDev->key->curKeySyms.maxKeyCode!=xkbi->desc->max_key_code)) { 52805b261ecSmrg /* 12/9/95 (ef) -- XXX! Maybe we should try to fix up one or */ 52905b261ecSmrg /* the other here, but for now just complain */ 53005b261ecSmrg /* can't just update the core range without */ 53105b261ecSmrg /* reallocating the KeySymsRec (pain) */ 5324642e01fSmrg ErrorF("[xkb] Internal Error!! XKB and core keymap have different range\n"); 53305b261ecSmrg } 53405b261ecSmrg if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success) 53505b261ecSmrg FatalError("Couldn't allocate client map in XkbInitDevice\n"); 53605b261ecSmrg i= XkbNumKeys(xkb)/3+1; 53705b261ecSmrg if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,i)!=Success) 53805b261ecSmrg FatalError("Couldn't allocate server map in XkbInitDevice\n"); 53905b261ecSmrg 54005b261ecSmrg xkbi->dfltPtrDelta=1; 54105b261ecSmrg xkbi->device = pXDev; 54205b261ecSmrg 5434642e01fSmrg XkbInitSemantics(xkb); 5444642e01fSmrg XkbInitNames(xkbi); 5454642e01fSmrg XkbInitRadioGroups(xkbi); 54605b261ecSmrg 54705b261ecSmrg /* 12/31/94 (ef) -- XXX! Should check if state loaded from file */ 54805b261ecSmrg bzero(&xkbi->state,sizeof(XkbStateRec)); 54905b261ecSmrg 5504642e01fSmrg XkbInitControls(pXDev,xkbi); 55105b261ecSmrg 5524642e01fSmrg if (xkb->defined & XkmSymbolsMask) 5534642e01fSmrg memcpy(pXDev->key->modifierMap, xkb->map->modmap, 5544642e01fSmrg xkb->max_key_code + 1); 5554642e01fSmrg else 5564642e01fSmrg memcpy(xkb->map->modmap, pXDev->key->modifierMap, 5574642e01fSmrg xkb->max_key_code + 1); 55805b261ecSmrg 5594642e01fSmrg XkbInitIndicatorMap(xkbi); 56005b261ecSmrg 56105b261ecSmrg XkbDDXInitDevice(pXDev); 56205b261ecSmrg 5634642e01fSmrg if (xkb->defined & XkmSymbolsMask) 5644642e01fSmrg XkbUpdateCoreDescription(pXDev, True); 5654642e01fSmrg else 5664642e01fSmrg XkbUpdateKeyTypesFromCore(pXDev, xkb->min_key_code, 5674642e01fSmrg XkbNumKeys(xkb), &changes); 5684642e01fSmrg 56905b261ecSmrg XkbSetCauseUnknown(&cause); 57005b261ecSmrg XkbUpdateActions(pXDev,xkb->min_key_code, XkbNumKeys(xkb),&changes, 57105b261ecSmrg &check,&cause); 57205b261ecSmrg /* For sanity. The first time the connection 57305b261ecSmrg * is opened, the client side min and max are set 57405b261ecSmrg * using QueryMinMaxKeyCodes() which grabs them 57505b261ecSmrg * from pXDev. 57605b261ecSmrg */ 57705b261ecSmrg pXDev->key->curKeySyms.minKeyCode = xkb->min_key_code; 57805b261ecSmrg pXDev->key->curKeySyms.maxKeyCode = xkb->max_key_code; 57905b261ecSmrg } 58005b261ecSmrg return; 58105b261ecSmrg} 58205b261ecSmrg 58305b261ecSmrg#if MAP_LENGTH > XkbMaxKeyCount 58405b261ecSmrg#undef XkbMaxKeyCount 58505b261ecSmrg#define XkbMaxKeyCount MAP_LENGTH 58605b261ecSmrg#endif 58705b261ecSmrg 58805b261ecSmrg_X_EXPORT Bool 58905b261ecSmrgXkbInitKeyboardDeviceStruct( 59005b261ecSmrg DeviceIntPtr dev, 59105b261ecSmrg XkbComponentNamesPtr names, 59205b261ecSmrg KeySymsPtr pSymsIn, 59305b261ecSmrg CARD8 pModsIn[], 59405b261ecSmrg void (*bellProc)( 59505b261ecSmrg int /*percent*/, 59605b261ecSmrg DeviceIntPtr /*device*/, 59705b261ecSmrg pointer /*ctrl*/, 59805b261ecSmrg int), 59905b261ecSmrg void (*ctrlProc)( 60005b261ecSmrg DeviceIntPtr /*device*/, 60105b261ecSmrg KeybdCtrl * /*ctrl*/)) 60205b261ecSmrg{ 60305b261ecSmrgKeySymsRec tmpSyms,*pSyms; 60405b261ecSmrgCARD8 tmpMods[XkbMaxLegalKeyCode+1],*pMods; 60505b261ecSmrgchar name[PATH_MAX],*rules; 60605b261ecSmrgBool ok=False; 60705b261ecSmrgXkbRF_VarDefsRec defs; 6084642e01fSmrgXkbDescPtr xkb; 60905b261ecSmrg 61005b261ecSmrg if ((dev->key!=NULL)||(dev->kbdfeed!=NULL)) 61105b261ecSmrg return False; 61205b261ecSmrg pSyms= pSymsIn; 61305b261ecSmrg pMods= pModsIn; 61405b261ecSmrg bzero(&defs,sizeof(XkbRF_VarDefsRec)); 61505b261ecSmrg rules= XkbGetRulesDflts(&defs); 61605b261ecSmrg 61705b261ecSmrg /* 61805b261ecSmrg * The strings are duplicated because it is not guaranteed that 61905b261ecSmrg * they are allocated, or that they are allocated for every server 62005b261ecSmrg * generation. Eventually they will be freed at the end of this 62105b261ecSmrg * function. 62205b261ecSmrg */ 6234642e01fSmrg names->keymap = NULL; 62405b261ecSmrg if (names->keycodes) names->keycodes = _XkbDupString(names->keycodes); 62505b261ecSmrg if (names->types) names->types = _XkbDupString(names->types); 62605b261ecSmrg if (names->compat) names->compat = _XkbDupString(names->compat); 62705b261ecSmrg if (names->geometry) names->geometry = _XkbDupString(names->geometry); 62805b261ecSmrg if (names->symbols) names->symbols = _XkbDupString(names->symbols); 62905b261ecSmrg 63005b261ecSmrg if (defs.model && defs.layout && rules) { 63105b261ecSmrg XkbComponentNamesRec rNames; 63205b261ecSmrg bzero(&rNames,sizeof(XkbComponentNamesRec)); 63305b261ecSmrg if (XkbDDXNamesFromRules(dev,rules,&defs,&rNames)) { 63405b261ecSmrg if (rNames.keycodes) { 63505b261ecSmrg if (!names->keycodes) 63605b261ecSmrg names->keycodes = rNames.keycodes; 63705b261ecSmrg else 63805b261ecSmrg _XkbFree(rNames.keycodes); 63905b261ecSmrg } 64005b261ecSmrg if (rNames.types) { 64105b261ecSmrg if (!names->types) 64205b261ecSmrg names->types = rNames.types; 64305b261ecSmrg else _XkbFree(rNames.types); 64405b261ecSmrg } 64505b261ecSmrg if (rNames.compat) { 64605b261ecSmrg if (!names->compat) 64705b261ecSmrg names->compat = rNames.compat; 64805b261ecSmrg else _XkbFree(rNames.compat); 64905b261ecSmrg } 65005b261ecSmrg if (rNames.symbols) { 65105b261ecSmrg if (!names->symbols) 65205b261ecSmrg names->symbols = rNames.symbols; 65305b261ecSmrg else _XkbFree(rNames.symbols); 65405b261ecSmrg } 65505b261ecSmrg if (rNames.geometry) { 65605b261ecSmrg if (!names->geometry) 65705b261ecSmrg names->geometry = rNames.geometry; 65805b261ecSmrg else _XkbFree(rNames.geometry); 65905b261ecSmrg } 66005b261ecSmrg XkbSetRulesUsed(&defs); 66105b261ecSmrg } 66205b261ecSmrg } 66305b261ecSmrg 6644642e01fSmrg ok = (Bool) XkbDDXLoadKeymapByNames(dev,names,XkmAllIndicesMask,0, 6654642e01fSmrg &xkb,name,PATH_MAX); 66605b261ecSmrg 6674642e01fSmrg if (ok && (xkb!=NULL)) { 66805b261ecSmrg KeyCode minKC,maxKC; 66905b261ecSmrg 67005b261ecSmrg minKC= xkb->min_key_code; 67105b261ecSmrg maxKC= xkb->max_key_code; 67205b261ecSmrg if (XkbIsLegalKeycode(minKC)&&XkbIsLegalKeycode(maxKC)&&(minKC<=maxKC)&& 67305b261ecSmrg ((minKC!=pSyms->minKeyCode)||(maxKC!=pSyms->maxKeyCode))) { 67405b261ecSmrg if (xkb->map!=NULL) { 67505b261ecSmrg KeySym *inSym,*outSym; 67605b261ecSmrg int width= pSymsIn->mapWidth; 67705b261ecSmrg 67805b261ecSmrg tmpSyms.minKeyCode= minKC; 67905b261ecSmrg tmpSyms.maxKeyCode= maxKC; 68005b261ecSmrg 68105b261ecSmrg if (minKC<pSymsIn->minKeyCode) 68205b261ecSmrg minKC= pSymsIn->minKeyCode; 68305b261ecSmrg if (maxKC>pSymsIn->maxKeyCode) 68405b261ecSmrg maxKC= pSymsIn->maxKeyCode; 68505b261ecSmrg 68605b261ecSmrg tmpSyms.mapWidth= width; 68705b261ecSmrg tmpSyms.map= _XkbTypedCalloc(width*XkbNumKeys(xkb),KeySym); 68805b261ecSmrg inSym= &pSymsIn->map[(minKC-pSymsIn->minKeyCode)*width]; 68905b261ecSmrg outSym= &tmpSyms.map[(minKC-tmpSyms.minKeyCode)*width]; 69005b261ecSmrg memcpy(outSym,inSym,((maxKC-minKC+1)*width)*sizeof(KeySym)); 69105b261ecSmrg pSyms= &tmpSyms; 69205b261ecSmrg } 69305b261ecSmrg if ((xkb->map!=NULL)&&(xkb->map->modmap!=NULL)) { 69405b261ecSmrg bzero(tmpMods,XkbMaxKeyCount); 69505b261ecSmrg memcpy(tmpMods,xkb->map->modmap,maxKC+1); 69605b261ecSmrg pMods= tmpMods; 69705b261ecSmrg } 69805b261ecSmrg } 6994642e01fSmrg /* Store the map here so we can pick it back up in XkbInitDevice. 7004642e01fSmrg * Sigh. */ 7014642e01fSmrg xkb_cached_map = xkb; 70205b261ecSmrg } 70305b261ecSmrg else { 70405b261ecSmrg LogMessage(X_WARNING, "Couldn't load XKB keymap, falling back to pre-XKB keymap\n"); 70505b261ecSmrg } 70605b261ecSmrg ok= InitKeyboardDeviceStruct((DevicePtr)dev,pSyms,pMods,bellProc,ctrlProc); 7074642e01fSmrg xkb_cached_map = NULL; 70805b261ecSmrg if ((pSyms==&tmpSyms)&&(pSyms->map!=NULL)) { 70905b261ecSmrg _XkbFree(pSyms->map); 71005b261ecSmrg pSyms->map= NULL; 71105b261ecSmrg } 71205b261ecSmrg 71305b261ecSmrg if (names->keycodes) _XkbFree(names->keycodes); 71405b261ecSmrg names->keycodes = NULL; 71505b261ecSmrg if (names->types) _XkbFree(names->types); 71605b261ecSmrg names->types = NULL; 71705b261ecSmrg if (names->compat) _XkbFree(names->compat); 71805b261ecSmrg names->compat = NULL; 71905b261ecSmrg if (names->geometry) _XkbFree(names->geometry); 72005b261ecSmrg names->geometry = NULL; 72105b261ecSmrg if (names->symbols) _XkbFree(names->symbols); 72205b261ecSmrg names->symbols = NULL; 72305b261ecSmrg 72405b261ecSmrg return ok; 72505b261ecSmrg} 72605b261ecSmrg 72705b261ecSmrg/***====================================================================***/ 72805b261ecSmrg 72905b261ecSmrg /* 73005b261ecSmrg * InitKeyClassDeviceStruct initializes the key class before it 73105b261ecSmrg * initializes the keyboard feedback class for a device. 73205b261ecSmrg * UpdateActions can't set up the correct autorepeat for keyboard 73305b261ecSmrg * initialization because the keyboard feedback isn't created yet. 73405b261ecSmrg * Instead, UpdateActions notes the "correct" autorepeat in the 73505b261ecSmrg * SrvInfo structure and InitKbdFeedbackClass calls UpdateAutoRepeat 73605b261ecSmrg * to apply the computed autorepeat once the feedback class exists. 73705b261ecSmrg * 73805b261ecSmrg * DIX will apply the changed autorepeat, so there's no need to 73905b261ecSmrg * do so here. This function returns True if both RepeatKeys and 74005b261ecSmrg * the core protocol autorepeat ctrls are set (i.e. should use 74105b261ecSmrg * software autorepeat), false otherwise. 74205b261ecSmrg * 74305b261ecSmrg * This function also computes the autorepeat accelerators for the 74405b261ecSmrg * default indicator feedback. 74505b261ecSmrg */ 74605b261ecSmrgint 74705b261ecSmrgXkbFinishDeviceInit(DeviceIntPtr pXDev) 74805b261ecSmrg{ 74905b261ecSmrgXkbSrvInfoPtr xkbi; 75005b261ecSmrgXkbDescPtr xkb; 75105b261ecSmrgint softRepeat; 75205b261ecSmrgXkbSrvLedInfoPtr sli; 75305b261ecSmrg 75405b261ecSmrg xkbi = NULL; 75505b261ecSmrg if (pXDev && pXDev->key && pXDev->key->xkbInfo && pXDev->kbdfeed) { 75605b261ecSmrg xkbi= pXDev->key->xkbInfo; 75705b261ecSmrg xkb= xkbi->desc; 7584642e01fSmrg /* If we come from DeepCopyDeviceClasses, the CtrlProc was already set 7594642e01fSmrg * to XkbDDXKeybdCtrlProc, overwriting it leads to happy recursion. 7604642e01fSmrg */ 7614642e01fSmrg if (pXDev->kbdfeed && pXDev->kbdfeed->CtrlProc != XkbDDXKeybdCtrlProc) { 76205b261ecSmrg xkbi->kbdProc= pXDev->kbdfeed->CtrlProc; 76305b261ecSmrg pXDev->kbdfeed->CtrlProc= XkbDDXKeybdCtrlProc; 76405b261ecSmrg } 76505b261ecSmrg if (pXDev->kbdfeed->ctrl.autoRepeat) 76605b261ecSmrg xkb->ctrls->enabled_ctrls|= XkbRepeatKeysMask; 76705b261ecSmrg softRepeat= (xkb->ctrls->enabled_ctrls&XkbRepeatKeysMask)!=0; 76805b261ecSmrg if (pXDev->kbdfeed) { 76905b261ecSmrg memcpy(pXDev->kbdfeed->ctrl.autoRepeats, 77005b261ecSmrg xkb->ctrls->per_key_repeat,XkbPerKeyBitArraySize); 77105b261ecSmrg softRepeat= softRepeat&&pXDev->kbdfeed->ctrl.autoRepeat; 77205b261ecSmrg } 77305b261ecSmrg } 77405b261ecSmrg else softRepeat= 0; 77505b261ecSmrg sli= XkbFindSrvLedInfo(pXDev,XkbDfltXIClass,XkbDfltXIId,0); 77605b261ecSmrg if (sli && xkbi) 77705b261ecSmrg XkbCheckIndicatorMaps(xkbi->device,sli,XkbAllIndicatorsMask); 7784642e01fSmrg else DebugF("[xkb] No indicator feedback in XkbFinishInit (shouldn't happen)!\n"); 77905b261ecSmrg return softRepeat; 78005b261ecSmrg} 78105b261ecSmrg 78205b261ecSmrg /* 78305b261ecSmrg * Be very careful about what does and doesn't get freed by this 78405b261ecSmrg * function. To reduce fragmentation, XkbInitDevice allocates a 78505b261ecSmrg * single huge block per device and divides it up into most of the 78605b261ecSmrg * fixed-size structures for the device. Don't free anything that 78705b261ecSmrg * is part of this larger block. 78805b261ecSmrg */ 78905b261ecSmrgvoid 79005b261ecSmrgXkbFreeInfo(XkbSrvInfoPtr xkbi) 79105b261ecSmrg{ 79205b261ecSmrg if (xkbi->radioGroups) { 79305b261ecSmrg _XkbFree(xkbi->radioGroups); 79405b261ecSmrg xkbi->radioGroups= NULL; 79505b261ecSmrg } 79605b261ecSmrg if (xkbi->mouseKeyTimer) { 79705b261ecSmrg TimerFree(xkbi->mouseKeyTimer); 79805b261ecSmrg xkbi->mouseKeyTimer= NULL; 79905b261ecSmrg } 80005b261ecSmrg if (xkbi->slowKeysTimer) { 80105b261ecSmrg TimerFree(xkbi->slowKeysTimer); 80205b261ecSmrg xkbi->slowKeysTimer= NULL; 80305b261ecSmrg } 80405b261ecSmrg if (xkbi->bounceKeysTimer) { 80505b261ecSmrg TimerFree(xkbi->bounceKeysTimer); 80605b261ecSmrg xkbi->bounceKeysTimer= NULL; 80705b261ecSmrg } 80805b261ecSmrg if (xkbi->repeatKeyTimer) { 80905b261ecSmrg TimerFree(xkbi->repeatKeyTimer); 81005b261ecSmrg xkbi->repeatKeyTimer= NULL; 81105b261ecSmrg } 81205b261ecSmrg if (xkbi->krgTimer) { 81305b261ecSmrg TimerFree(xkbi->krgTimer); 81405b261ecSmrg xkbi->krgTimer= NULL; 81505b261ecSmrg } 81605b261ecSmrg xkbi->beepType= _BEEP_NONE; 81705b261ecSmrg if (xkbi->beepTimer) { 81805b261ecSmrg TimerFree(xkbi->beepTimer); 81905b261ecSmrg xkbi->beepTimer= NULL; 82005b261ecSmrg } 82105b261ecSmrg if (xkbi->desc) { 82205b261ecSmrg XkbFreeKeyboard(xkbi->desc,XkbAllComponentsMask,True); 82305b261ecSmrg xkbi->desc= NULL; 82405b261ecSmrg } 82505b261ecSmrg _XkbFree(xkbi); 82605b261ecSmrg return; 82705b261ecSmrg} 82805b261ecSmrg 82905b261ecSmrg/***====================================================================***/ 83005b261ecSmrg 83105b261ecSmrgextern int XkbDfltRepeatDelay; 83205b261ecSmrgextern int XkbDfltRepeatInterval; 83305b261ecSmrg 83405b261ecSmrgextern unsigned short XkbDfltAccessXTimeout; 83505b261ecSmrgextern unsigned int XkbDfltAccessXTimeoutMask; 83605b261ecSmrgextern unsigned int XkbDfltAccessXFeedback; 83705b261ecSmrgextern unsigned char XkbDfltAccessXOptions; 83805b261ecSmrg 83905b261ecSmrgint 84005b261ecSmrgXkbProcessArguments(int argc,char *argv[],int i) 84105b261ecSmrg{ 84205b261ecSmrg if (strcmp(argv[i],"-kb")==0) { 84305b261ecSmrg noXkbExtension= True; 84405b261ecSmrg return 1; 84505b261ecSmrg } 84605b261ecSmrg else if (strcmp(argv[i],"+kb")==0) { 84705b261ecSmrg noXkbExtension= False; 84805b261ecSmrg return 1; 84905b261ecSmrg } 85005b261ecSmrg else if (strncmp(argv[i], "-xkbdir", 7) == 0) { 85105b261ecSmrg if(++i < argc) { 85205b261ecSmrg#if !defined(WIN32) && !defined(__CYGWIN__) 85305b261ecSmrg if (getuid() != geteuid()) { 85405b261ecSmrg LogMessage(X_WARNING, "-xkbdir is not available for setuid X servers\n"); 85505b261ecSmrg return -1; 85605b261ecSmrg } else 85705b261ecSmrg#endif 85805b261ecSmrg { 85905b261ecSmrg if (strlen(argv[i]) < PATH_MAX) { 86005b261ecSmrg XkbBaseDirectory= argv[i]; 86105b261ecSmrg return 2; 86205b261ecSmrg } else { 86305b261ecSmrg LogMessage(X_ERROR, "-xkbdir pathname too long\n"); 86405b261ecSmrg return -1; 86505b261ecSmrg } 86605b261ecSmrg } 86705b261ecSmrg } 86805b261ecSmrg else { 86905b261ecSmrg return -1; 87005b261ecSmrg } 87105b261ecSmrg } 87205b261ecSmrg else if ((strncmp(argv[i],"-accessx",8)==0)|| 87305b261ecSmrg (strncmp(argv[i],"+accessx",8)==0)) { 87405b261ecSmrg int j=1; 87505b261ecSmrg if (argv[i][0]=='-') 87605b261ecSmrg XkbWantAccessX= 0; 87705b261ecSmrg else { 87805b261ecSmrg XkbWantAccessX= 1; 87905b261ecSmrg 88005b261ecSmrg if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) { 88105b261ecSmrg XkbDfltAccessXTimeout = atoi(argv[++i]); 88205b261ecSmrg j++; 88305b261ecSmrg 88405b261ecSmrg if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) { 88505b261ecSmrg /* 88605b261ecSmrg * presumption that the reasonably useful range of 88705b261ecSmrg * values fits in 0..MAXINT since SunOS 4 doesn't 88805b261ecSmrg * have strtoul. 88905b261ecSmrg */ 89005b261ecSmrg XkbDfltAccessXTimeoutMask=(unsigned int) 89105b261ecSmrg strtol(argv[++i],NULL,16); 89205b261ecSmrg j++; 89305b261ecSmrg } 89405b261ecSmrg if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) { 89505b261ecSmrg if (argv[++i][0] == '1' ) 89605b261ecSmrg XkbDfltAccessXFeedback=XkbAccessXFeedbackMask; 89705b261ecSmrg else 89805b261ecSmrg XkbDfltAccessXFeedback=0; 89905b261ecSmrg j++; 90005b261ecSmrg } 90105b261ecSmrg if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) { 90205b261ecSmrg XkbDfltAccessXOptions=(unsigned char) 90305b261ecSmrg strtol(argv[++i],NULL,16); 90405b261ecSmrg j++; 90505b261ecSmrg } 90605b261ecSmrg } 90705b261ecSmrg } 90805b261ecSmrg return j; 90905b261ecSmrg } 91005b261ecSmrg if ((strcmp(argv[i], "-ardelay") == 0) || 91105b261ecSmrg (strcmp (argv[i], "-ar1") == 0)) { /* -ardelay int */ 91205b261ecSmrg if (++i >= argc) UseMsg (); 91305b261ecSmrg XkbDfltRepeatDelay = (long)atoi(argv[i]); 91405b261ecSmrg return 2; 91505b261ecSmrg } 91605b261ecSmrg if ((strcmp(argv[i], "-arinterval") == 0) || 91705b261ecSmrg (strcmp (argv[i], "-ar2") == 0)) { /* -arinterval int */ 91805b261ecSmrg if (++i >= argc) UseMsg (); 91905b261ecSmrg XkbDfltRepeatInterval = (long)atoi(argv[i]); 92005b261ecSmrg return 2; 92105b261ecSmrg } 92205b261ecSmrg return 0; 92305b261ecSmrg} 92405b261ecSmrg 92505b261ecSmrgvoid 92605b261ecSmrgXkbUseMsg(void) 92705b261ecSmrg{ 92805b261ecSmrg ErrorF("-kb disable the X Keyboard Extension\n"); 92905b261ecSmrg ErrorF("+kb enable the X Keyboard Extension\n"); 93005b261ecSmrg ErrorF("[+-]accessx [ timeout [ timeout_mask [ feedback [ options_mask] ] ] ]\n"); 93105b261ecSmrg ErrorF(" enable/disable accessx key sequences\n"); 93205b261ecSmrg ErrorF("-ardelay set XKB autorepeat delay\n"); 93305b261ecSmrg ErrorF("-arinterval set XKB autorepeat interval\n"); 93405b261ecSmrg} 935