1706f2543Smrg/************************************************************ 2706f2543SmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 3706f2543Smrg 4706f2543SmrgPermission to use, copy, modify, and distribute this 5706f2543Smrgsoftware and its documentation for any purpose and without 6706f2543Smrgfee is hereby granted, provided that the above copyright 7706f2543Smrgnotice appear in all copies and that both that copyright 8706f2543Smrgnotice and this permission notice appear in supporting 9706f2543Smrgdocumentation, and that the name of Silicon Graphics not be 10706f2543Smrgused in advertising or publicity pertaining to distribution 11706f2543Smrgof the software without specific prior written permission. 12706f2543SmrgSilicon Graphics makes no representation about the suitability 13706f2543Smrgof this software for any purpose. It is provided "as is" 14706f2543Smrgwithout any express or implied warranty. 15706f2543Smrg 16706f2543SmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17706f2543SmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18706f2543SmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19706f2543SmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20706f2543SmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21706f2543SmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22706f2543SmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23706f2543SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 24706f2543Smrg 25706f2543Smrg********************************************************/ 26706f2543Smrg 27706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 28706f2543Smrg#include <dix-config.h> 29706f2543Smrg#endif 30706f2543Smrg 31706f2543Smrg#include <xkb-config.h> 32706f2543Smrg 33706f2543Smrg#include <stdio.h> 34706f2543Smrg#include <stdlib.h> 35706f2543Smrg#include <ctype.h> 36706f2543Smrg#include <unistd.h> 37706f2543Smrg#include <math.h> 38706f2543Smrg#include <X11/X.h> 39706f2543Smrg#include <X11/Xproto.h> 40706f2543Smrg#include <X11/keysym.h> 41706f2543Smrg#include <X11/Xatom.h> 42706f2543Smrg#include "misc.h" 43706f2543Smrg#include "inputstr.h" 44706f2543Smrg#include "opaque.h" 45706f2543Smrg#include "property.h" 46706f2543Smrg#include "scrnintstr.h" 47706f2543Smrg#define XKBSRV_NEED_FILE_FUNCS 48706f2543Smrg#include <xkbsrv.h> 49706f2543Smrg#include "xkbgeom.h" 50706f2543Smrg#include <X11/extensions/XKMformat.h> 51706f2543Smrg#include "xkbfile.h" 52706f2543Smrg#include "xkb.h" 53706f2543Smrg 54706f2543Smrg#define CREATE_ATOM(s) MakeAtom(s,sizeof(s)-1,1) 55706f2543Smrg 56706f2543Smrg#if defined(__alpha) || defined(__alpha__) 57706f2543Smrg#define LED_COMPOSE 2 58706f2543Smrg#define LED_CAPS 3 59706f2543Smrg#define LED_SCROLL 4 60706f2543Smrg#define LED_NUM 5 61706f2543Smrg#define PHYS_LEDS 0x1f 62706f2543Smrg#else 63706f2543Smrg#ifdef sun 64706f2543Smrg#define LED_NUM 1 65706f2543Smrg#define LED_SCROLL 2 66706f2543Smrg#define LED_COMPOSE 3 67706f2543Smrg#define LED_CAPS 4 68706f2543Smrg#define PHYS_LEDS 0x0f 69706f2543Smrg#else 70706f2543Smrg#define LED_CAPS 1 71706f2543Smrg#define LED_NUM 2 72706f2543Smrg#define LED_SCROLL 3 73706f2543Smrg#define PHYS_LEDS 0x07 74706f2543Smrg#endif 75706f2543Smrg#endif 76706f2543Smrg 77706f2543Smrg#define MAX_TOC 16 78706f2543Smrgtypedef struct _SrvXkmInfo { 79706f2543Smrg DeviceIntPtr dev; 80706f2543Smrg FILE * file; 81706f2543Smrg XkbDescPtr xkb; 82706f2543Smrg} SrvXkmInfo; 83706f2543Smrg 84706f2543Smrg 85706f2543Smrg/***====================================================================***/ 86706f2543Smrg 87706f2543Smrg#ifndef XKB_DFLT_RULES_PROP 88706f2543Smrg#define XKB_DFLT_RULES_PROP TRUE 89706f2543Smrg#endif 90706f2543Smrg 91706f2543Smrgchar * XkbBaseDirectory= XKB_BASE_DIRECTORY; 92706f2543Smrgchar * XkbBinDirectory= XKB_BIN_DIRECTORY; 93706f2543Smrgstatic int XkbWantAccessX= 0; 94706f2543Smrg 95706f2543Smrgstatic char * XkbRulesDflt= NULL; 96706f2543Smrgstatic char * XkbModelDflt= NULL; 97706f2543Smrgstatic char * XkbLayoutDflt= NULL; 98706f2543Smrgstatic char * XkbVariantDflt= NULL; 99706f2543Smrgstatic char * XkbOptionsDflt= NULL; 100706f2543Smrg 101706f2543Smrgstatic char * XkbRulesUsed= NULL; 102706f2543Smrgstatic char * XkbModelUsed= NULL; 103706f2543Smrgstatic char * XkbLayoutUsed= NULL; 104706f2543Smrgstatic char * XkbVariantUsed= NULL; 105706f2543Smrgstatic char * XkbOptionsUsed= NULL; 106706f2543Smrg 107706f2543Smrgstatic XkbDescPtr xkb_cached_map = NULL; 108706f2543Smrg 109706f2543Smrgstatic Bool XkbWantRulesProp= XKB_DFLT_RULES_PROP; 110706f2543Smrg 111706f2543Smrg/***====================================================================***/ 112706f2543Smrg 113706f2543Smrg/** 114706f2543Smrg * Get the current default XKB rules. 115706f2543Smrg * Caller must free the data in rmlvo. 116706f2543Smrg */ 117706f2543Smrgvoid 118706f2543SmrgXkbGetRulesDflts(XkbRMLVOSet *rmlvo) 119706f2543Smrg{ 120706f2543Smrg if (XkbRulesDflt) rmlvo->rules = XkbRulesDflt; 121706f2543Smrg else rmlvo->rules = XKB_DFLT_RULES; 122706f2543Smrg if (XkbModelDflt) rmlvo->model= XkbModelDflt; 123706f2543Smrg else rmlvo->model= XKB_DFLT_MODEL; 124706f2543Smrg if (XkbLayoutDflt) rmlvo->layout= XkbLayoutDflt; 125706f2543Smrg else rmlvo->layout= XKB_DFLT_LAYOUT; 126706f2543Smrg if (XkbVariantDflt) rmlvo->variant= XkbVariantDflt; 127706f2543Smrg else rmlvo->variant= XKB_DFLT_VARIANT; 128706f2543Smrg if (XkbOptionsDflt) rmlvo->options= XkbOptionsDflt; 129706f2543Smrg else rmlvo->options= XKB_DFLT_OPTIONS; 130706f2543Smrg 131706f2543Smrg rmlvo->rules = strdup(rmlvo->rules); 132706f2543Smrg rmlvo->model = strdup(rmlvo->model); 133706f2543Smrg rmlvo->layout = strdup(rmlvo->layout); 134706f2543Smrg rmlvo->variant = strdup(rmlvo->variant); 135706f2543Smrg rmlvo->options = strdup(rmlvo->options); 136706f2543Smrg} 137706f2543Smrg 138706f2543Smrgvoid 139706f2543SmrgXkbFreeRMLVOSet(XkbRMLVOSet *rmlvo, Bool freeRMLVO) 140706f2543Smrg{ 141706f2543Smrg if (!rmlvo) 142706f2543Smrg return; 143706f2543Smrg 144706f2543Smrg free(rmlvo->rules); 145706f2543Smrg free(rmlvo->model); 146706f2543Smrg free(rmlvo->layout); 147706f2543Smrg free(rmlvo->variant); 148706f2543Smrg free(rmlvo->options); 149706f2543Smrg 150706f2543Smrg if (freeRMLVO) 151706f2543Smrg free(rmlvo); 152706f2543Smrg else 153706f2543Smrg memset(rmlvo, 0, sizeof(XkbRMLVOSet)); 154706f2543Smrg} 155706f2543Smrg 156706f2543Smrgstatic Bool 157706f2543SmrgXkbWriteRulesProp(ClientPtr client, pointer closure) 158706f2543Smrg{ 159706f2543Smrgint len,out; 160706f2543SmrgAtom name; 161706f2543Smrgchar * pval; 162706f2543Smrg 163706f2543Smrg len= (XkbRulesUsed?strlen(XkbRulesUsed):0); 164706f2543Smrg len+= (XkbModelUsed?strlen(XkbModelUsed):0); 165706f2543Smrg len+= (XkbLayoutUsed?strlen(XkbLayoutUsed):0); 166706f2543Smrg len+= (XkbVariantUsed?strlen(XkbVariantUsed):0); 167706f2543Smrg len+= (XkbOptionsUsed?strlen(XkbOptionsUsed):0); 168706f2543Smrg if (len<1) 169706f2543Smrg return TRUE; 170706f2543Smrg 171706f2543Smrg len+= 5; /* trailing NULs */ 172706f2543Smrg 173706f2543Smrg name= MakeAtom(_XKB_RF_NAMES_PROP_ATOM,strlen(_XKB_RF_NAMES_PROP_ATOM),1); 174706f2543Smrg if (name==None) { 175706f2543Smrg ErrorF("[xkb] Atom error: %s not created\n",_XKB_RF_NAMES_PROP_ATOM); 176706f2543Smrg return TRUE; 177706f2543Smrg } 178706f2543Smrg pval= (char*) malloc(len); 179706f2543Smrg if (!pval) { 180706f2543Smrg ErrorF("[xkb] Allocation error: %s proprerty not created\n", 181706f2543Smrg _XKB_RF_NAMES_PROP_ATOM); 182706f2543Smrg return TRUE; 183706f2543Smrg } 184706f2543Smrg out= 0; 185706f2543Smrg if (XkbRulesUsed) { 186706f2543Smrg strcpy(&pval[out],XkbRulesUsed); 187706f2543Smrg out+= strlen(XkbRulesUsed); 188706f2543Smrg } 189706f2543Smrg pval[out++]= '\0'; 190706f2543Smrg if (XkbModelUsed) { 191706f2543Smrg strcpy(&pval[out],XkbModelUsed); 192706f2543Smrg out+= strlen(XkbModelUsed); 193706f2543Smrg } 194706f2543Smrg pval[out++]= '\0'; 195706f2543Smrg if (XkbLayoutUsed) { 196706f2543Smrg strcpy(&pval[out],XkbLayoutUsed); 197706f2543Smrg out+= strlen(XkbLayoutUsed); 198706f2543Smrg } 199706f2543Smrg pval[out++]= '\0'; 200706f2543Smrg if (XkbVariantUsed) { 201706f2543Smrg strcpy(&pval[out],XkbVariantUsed); 202706f2543Smrg out+= strlen(XkbVariantUsed); 203706f2543Smrg } 204706f2543Smrg pval[out++]= '\0'; 205706f2543Smrg if (XkbOptionsUsed) { 206706f2543Smrg strcpy(&pval[out],XkbOptionsUsed); 207706f2543Smrg out+= strlen(XkbOptionsUsed); 208706f2543Smrg } 209706f2543Smrg pval[out++]= '\0'; 210706f2543Smrg if (out!=len) { 211706f2543Smrg ErrorF("[xkb] Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n", 212706f2543Smrg out,len); 213706f2543Smrg } 214706f2543Smrg dixChangeWindowProperty(serverClient, screenInfo.screens[0]->root, name, XA_STRING, 8, 215706f2543Smrg PropModeReplace, len, pval, TRUE); 216706f2543Smrg free(pval); 217706f2543Smrg return TRUE; 218706f2543Smrg} 219706f2543Smrg 220706f2543Smrgstatic void 221706f2543SmrgXkbSetRulesUsed(XkbRMLVOSet *rmlvo) 222706f2543Smrg{ 223706f2543Smrg free(XkbRulesUsed); 224706f2543Smrg XkbRulesUsed= (rmlvo->rules?_XkbDupString(rmlvo->rules):NULL); 225706f2543Smrg free(XkbModelUsed); 226706f2543Smrg XkbModelUsed= (rmlvo->model?_XkbDupString(rmlvo->model):NULL); 227706f2543Smrg free(XkbLayoutUsed); 228706f2543Smrg XkbLayoutUsed= (rmlvo->layout?_XkbDupString(rmlvo->layout):NULL); 229706f2543Smrg free(XkbVariantUsed); 230706f2543Smrg XkbVariantUsed= (rmlvo->variant?_XkbDupString(rmlvo->variant):NULL); 231706f2543Smrg free(XkbOptionsUsed); 232706f2543Smrg XkbOptionsUsed= (rmlvo->options?_XkbDupString(rmlvo->options):NULL); 233706f2543Smrg if (XkbWantRulesProp) 234706f2543Smrg QueueWorkProc(XkbWriteRulesProp,NULL,NULL); 235706f2543Smrg return; 236706f2543Smrg} 237706f2543Smrg 238706f2543Smrgvoid 239706f2543SmrgXkbSetRulesDflts(XkbRMLVOSet *rmlvo) 240706f2543Smrg{ 241706f2543Smrg if (rmlvo->rules) { 242706f2543Smrg free(XkbRulesDflt); 243706f2543Smrg XkbRulesDflt= _XkbDupString(rmlvo->rules); 244706f2543Smrg } 245706f2543Smrg if (rmlvo->model) { 246706f2543Smrg free(XkbModelDflt); 247706f2543Smrg XkbModelDflt= _XkbDupString(rmlvo->model); 248706f2543Smrg } 249706f2543Smrg if (rmlvo->layout) { 250706f2543Smrg free(XkbLayoutDflt); 251706f2543Smrg XkbLayoutDflt= _XkbDupString(rmlvo->layout); 252706f2543Smrg } 253706f2543Smrg if (rmlvo->variant) { 254706f2543Smrg free(XkbVariantDflt); 255706f2543Smrg XkbVariantDflt= _XkbDupString(rmlvo->variant); 256706f2543Smrg } 257706f2543Smrg if (rmlvo->options) { 258706f2543Smrg free(XkbOptionsDflt); 259706f2543Smrg XkbOptionsDflt= _XkbDupString(rmlvo->options); 260706f2543Smrg } 261706f2543Smrg return; 262706f2543Smrg} 263706f2543Smrg 264706f2543Smrgvoid 265706f2543SmrgXkbDeleteRulesDflts(void) 266706f2543Smrg{ 267706f2543Smrg free(XkbRulesDflt); 268706f2543Smrg XkbRulesDflt = NULL; 269706f2543Smrg free(XkbModelDflt); 270706f2543Smrg XkbModelDflt = NULL; 271706f2543Smrg free(XkbLayoutDflt); 272706f2543Smrg XkbLayoutDflt = NULL; 273706f2543Smrg free(XkbVariantDflt); 274706f2543Smrg XkbVariantDflt = NULL; 275706f2543Smrg free(XkbOptionsDflt); 276706f2543Smrg XkbOptionsDflt = NULL; 277706f2543Smrg 278706f2543Smrg XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE); 279706f2543Smrg xkb_cached_map = NULL; 280706f2543Smrg} 281706f2543Smrg 282706f2543Smrg#define DIFFERS(a, b) (strcmp((a) ? (a) : "", (b) ? (b) : "") != 0) 283706f2543Smrg 284706f2543Smrgstatic Bool 285706f2543SmrgXkbCompareUsedRMLVO(XkbRMLVOSet *rmlvo) 286706f2543Smrg{ 287706f2543Smrg if (DIFFERS(rmlvo->rules, XkbRulesUsed) || 288706f2543Smrg DIFFERS(rmlvo->model, XkbModelUsed) || 289706f2543Smrg DIFFERS(rmlvo->layout, XkbLayoutUsed) || 290706f2543Smrg DIFFERS(rmlvo->variant, XkbVariantUsed) || 291706f2543Smrg DIFFERS(rmlvo->options, XkbOptionsUsed)) 292706f2543Smrg return FALSE; 293706f2543Smrg return TRUE; 294706f2543Smrg} 295706f2543Smrg 296706f2543Smrg#undef DIFFERS 297706f2543Smrg 298706f2543Smrg/***====================================================================***/ 299706f2543Smrg 300706f2543Smrg#include "xkbDflts.h" 301706f2543Smrg 302706f2543Smrgstatic Bool 303706f2543SmrgXkbInitKeyTypes(XkbDescPtr xkb) 304706f2543Smrg{ 305706f2543Smrg if (xkb->defined & XkmTypesMask) 306706f2543Smrg return TRUE; 307706f2543Smrg 308706f2543Smrg initTypeNames(NULL); 309706f2543Smrg if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_dflt_types)!=Success) 310706f2543Smrg return FALSE; 311706f2543Smrg if (XkbCopyKeyTypes(dflt_types,xkb->map->types,num_dflt_types)!= 312706f2543Smrg Success) { 313706f2543Smrg return FALSE; 314706f2543Smrg } 315706f2543Smrg xkb->map->size_types= xkb->map->num_types= num_dflt_types; 316706f2543Smrg return TRUE; 317706f2543Smrg} 318706f2543Smrg 319706f2543Smrgstatic void 320706f2543SmrgXkbInitRadioGroups(XkbSrvInfoPtr xkbi) 321706f2543Smrg{ 322706f2543Smrg xkbi->nRadioGroups = 0; 323706f2543Smrg xkbi->radioGroups = NULL; 324706f2543Smrg return; 325706f2543Smrg} 326706f2543Smrg 327706f2543Smrg 328706f2543Smrgstatic Status 329706f2543SmrgXkbInitCompatStructs(XkbDescPtr xkb) 330706f2543Smrg{ 331706f2543Smrgregister int i; 332706f2543SmrgXkbCompatMapPtr compat; 333706f2543Smrg 334706f2543Smrg if (xkb->defined & XkmCompatMapMask) 335706f2543Smrg return TRUE; 336706f2543Smrg 337706f2543Smrg if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_dfltSI)!=Success) 338706f2543Smrg return BadAlloc; 339706f2543Smrg compat = xkb->compat; 340706f2543Smrg if (compat->sym_interpret) { 341706f2543Smrg compat->num_si = num_dfltSI; 342706f2543Smrg memcpy((char *)compat->sym_interpret,(char *)dfltSI,sizeof(dfltSI)); 343706f2543Smrg } 344706f2543Smrg for (i=0;i<XkbNumKbdGroups;i++) { 345706f2543Smrg compat->groups[i]= compatMap.groups[i]; 346706f2543Smrg if (compat->groups[i].vmods!=0) { 347706f2543Smrg unsigned mask; 348706f2543Smrg mask= XkbMaskForVMask(xkb,compat->groups[i].vmods); 349706f2543Smrg compat->groups[i].mask= compat->groups[i].real_mods|mask; 350706f2543Smrg } 351706f2543Smrg else compat->groups[i].mask= compat->groups[i].real_mods; 352706f2543Smrg } 353706f2543Smrg return Success; 354706f2543Smrg} 355706f2543Smrg 356706f2543Smrgstatic void 357706f2543SmrgXkbInitSemantics(XkbDescPtr xkb) 358706f2543Smrg{ 359706f2543Smrg XkbInitKeyTypes(xkb); 360706f2543Smrg XkbInitCompatStructs(xkb); 361706f2543Smrg return; 362706f2543Smrg} 363706f2543Smrg 364706f2543Smrg/***====================================================================***/ 365706f2543Smrg 366706f2543Smrgstatic Status 367706f2543SmrgXkbInitNames(XkbSrvInfoPtr xkbi) 368706f2543Smrg{ 369706f2543SmrgXkbDescPtr xkb; 370706f2543SmrgXkbNamesPtr names; 371706f2543SmrgStatus rtrn; 372706f2543SmrgAtom unknown; 373706f2543Smrg 374706f2543Smrg xkb= xkbi->desc; 375706f2543Smrg if ((rtrn=XkbAllocNames(xkb,XkbAllNamesMask,0,0))!=Success) 376706f2543Smrg return rtrn; 377706f2543Smrg unknown= CREATE_ATOM("unknown"); 378706f2543Smrg names = xkb->names; 379706f2543Smrg if (names->keycodes==None) names->keycodes= unknown; 380706f2543Smrg if (names->geometry==None) names->geometry= unknown; 381706f2543Smrg if (names->phys_symbols==None) names->phys_symbols= unknown; 382706f2543Smrg if (names->symbols==None) names->symbols= unknown; 383706f2543Smrg if (names->types==None) names->types= unknown; 384706f2543Smrg if (names->compat==None) names->compat= unknown; 385706f2543Smrg if (!(xkb->defined & XkmVirtualModsMask)) { 386706f2543Smrg if (names->vmods[vmod_NumLock]==None) 387706f2543Smrg names->vmods[vmod_NumLock]= CREATE_ATOM("NumLock"); 388706f2543Smrg if (names->vmods[vmod_Alt]==None) 389706f2543Smrg names->vmods[vmod_Alt]= CREATE_ATOM("Alt"); 390706f2543Smrg if (names->vmods[vmod_AltGr]==None) 391706f2543Smrg names->vmods[vmod_AltGr]= CREATE_ATOM("ModeSwitch"); 392706f2543Smrg } 393706f2543Smrg 394706f2543Smrg if (!(xkb->defined & XkmIndicatorsMask) || 395706f2543Smrg !(xkb->defined & XkmGeometryMask)) { 396706f2543Smrg initIndicatorNames(NULL,xkb); 397706f2543Smrg if (names->indicators[LED_CAPS-1]==None) 398706f2543Smrg names->indicators[LED_CAPS-1] = CREATE_ATOM("Caps Lock"); 399706f2543Smrg if (names->indicators[LED_NUM-1]==None) 400706f2543Smrg names->indicators[LED_NUM-1] = CREATE_ATOM("Num Lock"); 401706f2543Smrg if (names->indicators[LED_SCROLL-1]==None) 402706f2543Smrg names->indicators[LED_SCROLL-1] = CREATE_ATOM("Scroll Lock"); 403706f2543Smrg#ifdef LED_COMPOSE 404706f2543Smrg if (names->indicators[LED_COMPOSE-1]==None) 405706f2543Smrg names->indicators[LED_COMPOSE-1] = CREATE_ATOM("Compose"); 406706f2543Smrg#endif 407706f2543Smrg } 408706f2543Smrg 409706f2543Smrg if (xkb->geom!=NULL) 410706f2543Smrg names->geometry= xkb->geom->name; 411706f2543Smrg else names->geometry= unknown; 412706f2543Smrg 413706f2543Smrg return Success; 414706f2543Smrg} 415706f2543Smrg 416706f2543Smrgstatic Status 417706f2543SmrgXkbInitIndicatorMap(XkbSrvInfoPtr xkbi) 418706f2543Smrg{ 419706f2543SmrgXkbDescPtr xkb; 420706f2543SmrgXkbIndicatorPtr map; 421706f2543SmrgXkbSrvLedInfoPtr sli; 422706f2543Smrg 423706f2543Smrg xkb= xkbi->desc; 424706f2543Smrg if (XkbAllocIndicatorMaps(xkb)!=Success) 425706f2543Smrg return BadAlloc; 426706f2543Smrg 427706f2543Smrg if (!(xkb->defined & XkmIndicatorsMask)) { 428706f2543Smrg map= xkb->indicators; 429706f2543Smrg map->phys_indicators = PHYS_LEDS; 430706f2543Smrg map->maps[LED_CAPS-1].flags= XkbIM_NoExplicit; 431706f2543Smrg map->maps[LED_CAPS-1].which_mods= XkbIM_UseLocked; 432706f2543Smrg map->maps[LED_CAPS-1].mods.mask= LockMask; 433706f2543Smrg map->maps[LED_CAPS-1].mods.real_mods= LockMask; 434706f2543Smrg 435706f2543Smrg map->maps[LED_NUM-1].flags= XkbIM_NoExplicit; 436706f2543Smrg map->maps[LED_NUM-1].which_mods= XkbIM_UseLocked; 437706f2543Smrg map->maps[LED_NUM-1].mods.mask= 0; 438706f2543Smrg map->maps[LED_NUM-1].mods.real_mods= 0; 439706f2543Smrg map->maps[LED_NUM-1].mods.vmods= vmod_NumLockMask; 440706f2543Smrg 441706f2543Smrg map->maps[LED_SCROLL-1].flags= XkbIM_NoExplicit; 442706f2543Smrg map->maps[LED_SCROLL-1].which_mods= XkbIM_UseLocked; 443706f2543Smrg map->maps[LED_SCROLL-1].mods.mask= Mod3Mask; 444706f2543Smrg map->maps[LED_SCROLL-1].mods.real_mods= Mod3Mask; 445706f2543Smrg } 446706f2543Smrg 447706f2543Smrg sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0); 448706f2543Smrg if (sli) 449706f2543Smrg XkbCheckIndicatorMaps(xkbi->device,sli,XkbAllIndicatorsMask); 450706f2543Smrg 451706f2543Smrg return Success; 452706f2543Smrg} 453706f2543Smrg 454706f2543Smrgstatic Status 455706f2543SmrgXkbInitControls(DeviceIntPtr pXDev,XkbSrvInfoPtr xkbi) 456706f2543Smrg{ 457706f2543SmrgXkbDescPtr xkb; 458706f2543SmrgXkbControlsPtr ctrls; 459706f2543Smrg 460706f2543Smrg xkb= xkbi->desc; 461706f2543Smrg /* 12/31/94 (ef) -- XXX! Should check if controls loaded from file */ 462706f2543Smrg if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success) 463706f2543Smrg FatalError("Couldn't allocate keyboard controls\n"); 464706f2543Smrg ctrls= xkb->ctrls; 465706f2543Smrg if (!(xkb->defined & XkmSymbolsMask)) 466706f2543Smrg ctrls->num_groups = 1; 467706f2543Smrg ctrls->groups_wrap = XkbSetGroupInfo(1,XkbWrapIntoRange,0); 468706f2543Smrg ctrls->internal.mask = 0; 469706f2543Smrg ctrls->internal.real_mods = 0; 470706f2543Smrg ctrls->internal.vmods = 0; 471706f2543Smrg ctrls->ignore_lock.mask = 0; 472706f2543Smrg ctrls->ignore_lock.real_mods = 0; 473706f2543Smrg ctrls->ignore_lock.vmods = 0; 474706f2543Smrg ctrls->enabled_ctrls = XkbAccessXTimeoutMask|XkbRepeatKeysMask| 475706f2543Smrg XkbMouseKeysAccelMask|XkbAudibleBellMask| 476706f2543Smrg XkbIgnoreGroupLockMask; 477706f2543Smrg if (XkbWantAccessX) 478706f2543Smrg ctrls->enabled_ctrls|= XkbAccessXKeysMask; 479706f2543Smrg AccessXInit(pXDev); 480706f2543Smrg return Success; 481706f2543Smrg} 482706f2543Smrg 483706f2543Smrg_X_EXPORT Bool 484706f2543SmrgInitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet *rmlvo, 485706f2543Smrg BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func) 486706f2543Smrg{ 487706f2543Smrg int i; 488706f2543Smrg unsigned int check; 489706f2543Smrg XkbSrvInfoPtr xkbi; 490706f2543Smrg XkbDescPtr xkb; 491706f2543Smrg XkbSrvLedInfoPtr sli; 492706f2543Smrg XkbChangesRec changes; 493706f2543Smrg XkbEventCauseRec cause; 494706f2543Smrg XkbRMLVOSet rmlvo_dflts = { NULL }; 495706f2543Smrg 496706f2543Smrg if (dev->key || dev->kbdfeed) 497706f2543Smrg return FALSE; 498706f2543Smrg 499706f2543Smrg if (!rmlvo) 500706f2543Smrg { 501706f2543Smrg rmlvo = &rmlvo_dflts; 502706f2543Smrg XkbGetRulesDflts(rmlvo); 503706f2543Smrg } 504706f2543Smrg 505706f2543Smrg 506706f2543Smrg memset(&changes, 0, sizeof(changes)); 507706f2543Smrg XkbSetCauseUnknown(&cause); 508706f2543Smrg 509706f2543Smrg dev->key = calloc(1, sizeof(*dev->key)); 510706f2543Smrg if (!dev->key) { 511706f2543Smrg ErrorF("XKB: Failed to allocate key class\n"); 512706f2543Smrg return FALSE; 513706f2543Smrg } 514706f2543Smrg dev->key->sourceid = dev->id; 515706f2543Smrg 516706f2543Smrg dev->kbdfeed = calloc(1, sizeof(*dev->kbdfeed)); 517706f2543Smrg if (!dev->kbdfeed) { 518706f2543Smrg ErrorF("XKB: Failed to allocate key feedback class\n"); 519706f2543Smrg goto unwind_key; 520706f2543Smrg } 521706f2543Smrg 522706f2543Smrg xkbi = calloc(1, sizeof(*xkbi)); 523706f2543Smrg if (!xkbi) { 524706f2543Smrg ErrorF("XKB: Failed to allocate XKB info\n"); 525706f2543Smrg goto unwind_kbdfeed; 526706f2543Smrg } 527706f2543Smrg dev->key->xkbInfo = xkbi; 528706f2543Smrg 529706f2543Smrg if (xkb_cached_map && !XkbCompareUsedRMLVO(rmlvo)) { 530706f2543Smrg XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE); 531706f2543Smrg xkb_cached_map = NULL; 532706f2543Smrg } 533706f2543Smrg 534706f2543Smrg if (xkb_cached_map) 535706f2543Smrg LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n"); 536706f2543Smrg else { 537706f2543Smrg xkb_cached_map = XkbCompileKeymap(dev, rmlvo); 538706f2543Smrg if (!xkb_cached_map) { 539706f2543Smrg ErrorF("XKB: Failed to compile keymap\n"); 540706f2543Smrg goto unwind_info; 541706f2543Smrg } 542706f2543Smrg } 543706f2543Smrg 544706f2543Smrg xkb = XkbAllocKeyboard(); 545706f2543Smrg if (!xkb) { 546706f2543Smrg ErrorF("XKB: Failed to allocate keyboard description\n"); 547706f2543Smrg goto unwind_info; 548706f2543Smrg } 549706f2543Smrg 550706f2543Smrg if (!XkbCopyKeymap(xkb, xkb_cached_map)) { 551706f2543Smrg ErrorF("XKB: Failed to copy keymap\n"); 552706f2543Smrg goto unwind_desc; 553706f2543Smrg } 554706f2543Smrg xkb->defined = xkb_cached_map->defined; 555706f2543Smrg xkb->flags = xkb_cached_map->flags; 556706f2543Smrg xkb->device_spec = xkb_cached_map->device_spec; 557706f2543Smrg xkbi->desc = xkb; 558706f2543Smrg 559706f2543Smrg if (xkb->min_key_code == 0) 560706f2543Smrg xkb->min_key_code = 8; 561706f2543Smrg if (xkb->max_key_code == 0) 562706f2543Smrg xkb->max_key_code = 255; 563706f2543Smrg 564706f2543Smrg i = XkbNumKeys(xkb) / 3 + 1; 565706f2543Smrg if (XkbAllocClientMap(xkb, XkbAllClientInfoMask, 0) != Success) 566706f2543Smrg goto unwind_desc; 567706f2543Smrg if (XkbAllocServerMap(xkb, XkbAllServerInfoMask, i) != Success) 568706f2543Smrg goto unwind_desc; 569706f2543Smrg 570706f2543Smrg xkbi->dfltPtrDelta = 1; 571706f2543Smrg xkbi->device = dev; 572706f2543Smrg 573706f2543Smrg XkbInitSemantics(xkb); 574706f2543Smrg XkbInitNames(xkbi); 575706f2543Smrg XkbInitRadioGroups(xkbi); 576706f2543Smrg 577706f2543Smrg XkbInitControls(dev, xkbi); 578706f2543Smrg 579706f2543Smrg XkbInitIndicatorMap(xkbi); 580706f2543Smrg 581706f2543Smrg XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &changes, 582706f2543Smrg &check, &cause); 583706f2543Smrg 584706f2543Smrg InitFocusClassDeviceStruct(dev); 585706f2543Smrg 586706f2543Smrg xkbi->kbdProc = ctrl_func; 587706f2543Smrg dev->kbdfeed->BellProc = bell_func; 588706f2543Smrg dev->kbdfeed->CtrlProc = XkbDDXKeybdCtrlProc; 589706f2543Smrg 590706f2543Smrg dev->kbdfeed->ctrl = defaultKeyboardControl; 591706f2543Smrg if (dev->kbdfeed->ctrl.autoRepeat) 592706f2543Smrg xkb->ctrls->enabled_ctrls |= XkbRepeatKeysMask; 593706f2543Smrg 594706f2543Smrg memcpy(dev->kbdfeed->ctrl.autoRepeats, xkb->ctrls->per_key_repeat, 595706f2543Smrg XkbPerKeyBitArraySize); 596706f2543Smrg 597706f2543Smrg sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0); 598706f2543Smrg if (sli) 599706f2543Smrg XkbCheckIndicatorMaps(dev, sli, XkbAllIndicatorsMask); 600706f2543Smrg else 601706f2543Smrg DebugF("XKB: No indicator feedback in XkbFinishInit!\n"); 602706f2543Smrg 603706f2543Smrg dev->kbdfeed->CtrlProc(dev,&dev->kbdfeed->ctrl); 604706f2543Smrg 605706f2543Smrg XkbSetRulesDflts(rmlvo); 606706f2543Smrg XkbSetRulesUsed(rmlvo); 607706f2543Smrg XkbFreeRMLVOSet(&rmlvo_dflts, FALSE); 608706f2543Smrg 609706f2543Smrg return TRUE; 610706f2543Smrg 611706f2543Smrgunwind_desc: 612706f2543Smrg XkbFreeKeyboard(xkb, 0, TRUE); 613706f2543Smrgunwind_info: 614706f2543Smrg free(xkbi); 615706f2543Smrg dev->key->xkbInfo = NULL; 616706f2543Smrgunwind_kbdfeed: 617706f2543Smrg free(dev->kbdfeed); 618706f2543Smrg dev->kbdfeed = NULL; 619706f2543Smrgunwind_key: 620706f2543Smrg free(dev->key); 621706f2543Smrg dev->key = NULL; 622706f2543Smrg return FALSE; 623706f2543Smrg} 624706f2543Smrg 625706f2543Smrg 626706f2543Smrg/***====================================================================***/ 627706f2543Smrg 628706f2543Smrg /* 629706f2543Smrg * Be very careful about what does and doesn't get freed by this 630706f2543Smrg * function. To reduce fragmentation, XkbInitDevice allocates a 631706f2543Smrg * single huge block per device and divides it up into most of the 632706f2543Smrg * fixed-size structures for the device. Don't free anything that 633706f2543Smrg * is part of this larger block. 634706f2543Smrg */ 635706f2543Smrgvoid 636706f2543SmrgXkbFreeInfo(XkbSrvInfoPtr xkbi) 637706f2543Smrg{ 638706f2543Smrg free(xkbi->radioGroups); 639706f2543Smrg xkbi->radioGroups = NULL; 640706f2543Smrg if (xkbi->mouseKeyTimer) { 641706f2543Smrg TimerFree(xkbi->mouseKeyTimer); 642706f2543Smrg xkbi->mouseKeyTimer= NULL; 643706f2543Smrg } 644706f2543Smrg if (xkbi->slowKeysTimer) { 645706f2543Smrg TimerFree(xkbi->slowKeysTimer); 646706f2543Smrg xkbi->slowKeysTimer= NULL; 647706f2543Smrg } 648706f2543Smrg if (xkbi->bounceKeysTimer) { 649706f2543Smrg TimerFree(xkbi->bounceKeysTimer); 650706f2543Smrg xkbi->bounceKeysTimer= NULL; 651706f2543Smrg } 652706f2543Smrg if (xkbi->repeatKeyTimer) { 653706f2543Smrg TimerFree(xkbi->repeatKeyTimer); 654706f2543Smrg xkbi->repeatKeyTimer= NULL; 655706f2543Smrg } 656706f2543Smrg if (xkbi->krgTimer) { 657706f2543Smrg TimerFree(xkbi->krgTimer); 658706f2543Smrg xkbi->krgTimer= NULL; 659706f2543Smrg } 660706f2543Smrg xkbi->beepType= _BEEP_NONE; 661706f2543Smrg if (xkbi->beepTimer) { 662706f2543Smrg TimerFree(xkbi->beepTimer); 663706f2543Smrg xkbi->beepTimer= NULL; 664706f2543Smrg } 665706f2543Smrg if (xkbi->desc) { 666706f2543Smrg XkbFreeKeyboard(xkbi->desc,XkbAllComponentsMask,TRUE); 667706f2543Smrg xkbi->desc= NULL; 668706f2543Smrg } 669706f2543Smrg free(xkbi); 670706f2543Smrg return; 671706f2543Smrg} 672706f2543Smrg 673706f2543Smrg/***====================================================================***/ 674706f2543Smrg 675706f2543Smrgextern int XkbDfltRepeatDelay; 676706f2543Smrgextern int XkbDfltRepeatInterval; 677706f2543Smrg 678706f2543Smrgextern unsigned short XkbDfltAccessXTimeout; 679706f2543Smrgextern unsigned int XkbDfltAccessXTimeoutMask; 680706f2543Smrgextern unsigned int XkbDfltAccessXFeedback; 681706f2543Smrgextern unsigned char XkbDfltAccessXOptions; 682706f2543Smrg 683706f2543Smrgint 684706f2543SmrgXkbProcessArguments(int argc,char *argv[],int i) 685706f2543Smrg{ 686706f2543Smrg if (strncmp(argv[i], "-xkbdir", 7) == 0) { 687706f2543Smrg if(++i < argc) { 688706f2543Smrg#if !defined(WIN32) && !defined(__CYGWIN__) 689706f2543Smrg if (getuid() != geteuid()) { 690706f2543Smrg LogMessage(X_WARNING, "-xkbdir is not available for setuid X servers\n"); 691706f2543Smrg return -1; 692706f2543Smrg } else 693706f2543Smrg#endif 694706f2543Smrg { 695706f2543Smrg if (strlen(argv[i]) < PATH_MAX) { 696706f2543Smrg XkbBaseDirectory= argv[i]; 697706f2543Smrg return 2; 698706f2543Smrg } else { 699706f2543Smrg LogMessage(X_ERROR, "-xkbdir pathname too long\n"); 700706f2543Smrg return -1; 701706f2543Smrg } 702706f2543Smrg } 703706f2543Smrg } 704706f2543Smrg else { 705706f2543Smrg return -1; 706706f2543Smrg } 707706f2543Smrg } 708706f2543Smrg else if ((strncmp(argv[i],"-accessx",8)==0)|| 709706f2543Smrg (strncmp(argv[i],"+accessx",8)==0)) { 710706f2543Smrg int j=1; 711706f2543Smrg if (argv[i][0]=='-') 712706f2543Smrg XkbWantAccessX= 0; 713706f2543Smrg else { 714706f2543Smrg XkbWantAccessX= 1; 715706f2543Smrg 716706f2543Smrg if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) { 717706f2543Smrg XkbDfltAccessXTimeout = atoi(argv[++i]); 718706f2543Smrg j++; 719706f2543Smrg 720706f2543Smrg if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) { 721706f2543Smrg /* 722706f2543Smrg * presumption that the reasonably useful range of 723706f2543Smrg * values fits in 0..MAXINT since SunOS 4 doesn't 724706f2543Smrg * have strtoul. 725706f2543Smrg */ 726706f2543Smrg XkbDfltAccessXTimeoutMask=(unsigned int) 727706f2543Smrg strtol(argv[++i],NULL,16); 728706f2543Smrg j++; 729706f2543Smrg } 730706f2543Smrg if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) { 731706f2543Smrg if (argv[++i][0] == '1' ) 732706f2543Smrg XkbDfltAccessXFeedback=XkbAccessXFeedbackMask; 733706f2543Smrg else 734706f2543Smrg XkbDfltAccessXFeedback=0; 735706f2543Smrg j++; 736706f2543Smrg } 737706f2543Smrg if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) { 738706f2543Smrg XkbDfltAccessXOptions=(unsigned char) 739706f2543Smrg strtol(argv[++i],NULL,16); 740706f2543Smrg j++; 741706f2543Smrg } 742706f2543Smrg } 743706f2543Smrg } 744706f2543Smrg return j; 745706f2543Smrg } 746706f2543Smrg if ((strcmp(argv[i], "-ardelay") == 0) || 747706f2543Smrg (strcmp (argv[i], "-ar1") == 0)) { /* -ardelay int */ 748706f2543Smrg if (++i >= argc) UseMsg (); 749706f2543Smrg XkbDfltRepeatDelay = (long)atoi(argv[i]); 750706f2543Smrg return 2; 751706f2543Smrg } 752706f2543Smrg if ((strcmp(argv[i], "-arinterval") == 0) || 753706f2543Smrg (strcmp (argv[i], "-ar2") == 0)) { /* -arinterval int */ 754706f2543Smrg if (++i >= argc) UseMsg (); 755706f2543Smrg XkbDfltRepeatInterval = (long)atoi(argv[i]); 756706f2543Smrg return 2; 757706f2543Smrg } 758706f2543Smrg return 0; 759706f2543Smrg} 760706f2543Smrg 761706f2543Smrgvoid 762706f2543SmrgXkbUseMsg(void) 763706f2543Smrg{ 764706f2543Smrg ErrorF("[+-]accessx [ timeout [ timeout_mask [ feedback [ options_mask] ] ] ]\n"); 765706f2543Smrg ErrorF(" enable/disable accessx key sequences\n"); 766706f2543Smrg ErrorF("-ardelay set XKB autorepeat delay\n"); 767706f2543Smrg ErrorF("-arinterval set XKB autorepeat interval\n"); 768706f2543Smrg} 769