1/************************************************************ 2Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 3 4Permission to use, copy, modify, and distribute this 5software and its documentation for any purpose and without 6fee is hereby granted, provided that the above copyright 7notice appear in all copies and that both that copyright 8notice and this permission notice appear in supporting 9documentation, and that the name of Silicon Graphics not be 10used in advertising or publicity pertaining to distribution 11of the software without specific prior written permission. 12Silicon Graphics makes no representation about the suitability 13of this software for any purpose. It is provided "as is" 14without any express or implied warranty. 15 16SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 17SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 19GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 20DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 22OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 23THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 25********************************************************/ 26 27#ifdef HAVE_DIX_CONFIG_H 28#include <dix-config.h> 29#endif 30 31#include <xkb-config.h> 32 33#include <stdio.h> 34#include <stdlib.h> 35#include <ctype.h> 36#include <unistd.h> 37#include <math.h> 38#include <X11/X.h> 39#include <X11/Xproto.h> 40#include <X11/keysym.h> 41#include <X11/Xatom.h> 42#include "misc.h" 43#include "inputstr.h" 44#include "opaque.h" 45#include "property.h" 46#include "scrnintstr.h" 47#define XKBSRV_NEED_FILE_FUNCS 48#include <xkbsrv.h> 49#include "xkbgeom.h" 50#include <X11/extensions/XKMformat.h> 51#include "xkbfile.h" 52#include "xkb.h" 53 54#define CREATE_ATOM(s) MakeAtom(s,sizeof(s)-1,1) 55 56#if defined(__alpha) || defined(__alpha__) 57#define LED_COMPOSE 2 58#define LED_CAPS 3 59#define LED_SCROLL 4 60#define LED_NUM 5 61#define PHYS_LEDS 0x1f 62#else 63#ifdef sun 64#define LED_NUM 1 65#define LED_SCROLL 2 66#define LED_COMPOSE 3 67#define LED_CAPS 4 68#define PHYS_LEDS 0x0f 69#else 70#define LED_CAPS 1 71#define LED_NUM 2 72#define LED_SCROLL 3 73#define PHYS_LEDS 0x07 74#endif 75#endif 76 77#define MAX_TOC 16 78typedef struct _SrvXkmInfo { 79 DeviceIntPtr dev; 80 FILE * file; 81 XkbDescPtr xkb; 82} SrvXkmInfo; 83 84 85/***====================================================================***/ 86 87#ifndef XKB_DFLT_RULES_PROP 88#define XKB_DFLT_RULES_PROP TRUE 89#endif 90 91char * XkbBaseDirectory= XKB_BASE_DIRECTORY; 92char * XkbBinDirectory= XKB_BIN_DIRECTORY; 93static int XkbWantAccessX= 0; 94 95static char * XkbRulesDflt= NULL; 96static char * XkbModelDflt= NULL; 97static char * XkbLayoutDflt= NULL; 98static char * XkbVariantDflt= NULL; 99static char * XkbOptionsDflt= NULL; 100 101static char * XkbRulesUsed= NULL; 102static char * XkbModelUsed= NULL; 103static char * XkbLayoutUsed= NULL; 104static char * XkbVariantUsed= NULL; 105static char * XkbOptionsUsed= NULL; 106 107static XkbDescPtr xkb_cached_map = NULL; 108 109static Bool XkbWantRulesProp= XKB_DFLT_RULES_PROP; 110 111/***====================================================================***/ 112 113/** 114 * Get the current default XKB rules. 115 * Caller must free the data in rmlvo. 116 */ 117void 118XkbGetRulesDflts(XkbRMLVOSet *rmlvo) 119{ 120 if (XkbRulesDflt) rmlvo->rules = XkbRulesDflt; 121 else rmlvo->rules = XKB_DFLT_RULES; 122 if (XkbModelDflt) rmlvo->model= XkbModelDflt; 123 else rmlvo->model= XKB_DFLT_MODEL; 124 if (XkbLayoutDflt) rmlvo->layout= XkbLayoutDflt; 125 else rmlvo->layout= XKB_DFLT_LAYOUT; 126 if (XkbVariantDflt) rmlvo->variant= XkbVariantDflt; 127 else rmlvo->variant= XKB_DFLT_VARIANT; 128 if (XkbOptionsDflt) rmlvo->options= XkbOptionsDflt; 129 else rmlvo->options= XKB_DFLT_OPTIONS; 130 131 rmlvo->rules = strdup(rmlvo->rules); 132 rmlvo->model = strdup(rmlvo->model); 133 rmlvo->layout = strdup(rmlvo->layout); 134 rmlvo->variant = strdup(rmlvo->variant); 135 rmlvo->options = strdup(rmlvo->options); 136} 137 138void 139XkbFreeRMLVOSet(XkbRMLVOSet *rmlvo, Bool freeRMLVO) 140{ 141 if (!rmlvo) 142 return; 143 144 free(rmlvo->rules); 145 free(rmlvo->model); 146 free(rmlvo->layout); 147 free(rmlvo->variant); 148 free(rmlvo->options); 149 150 if (freeRMLVO) 151 free(rmlvo); 152 else 153 memset(rmlvo, 0, sizeof(XkbRMLVOSet)); 154} 155 156static Bool 157XkbWriteRulesProp(ClientPtr client, pointer closure) 158{ 159int len,out; 160Atom name; 161char * pval; 162 163 len= (XkbRulesUsed?strlen(XkbRulesUsed):0); 164 len+= (XkbModelUsed?strlen(XkbModelUsed):0); 165 len+= (XkbLayoutUsed?strlen(XkbLayoutUsed):0); 166 len+= (XkbVariantUsed?strlen(XkbVariantUsed):0); 167 len+= (XkbOptionsUsed?strlen(XkbOptionsUsed):0); 168 if (len<1) 169 return TRUE; 170 171 len+= 5; /* trailing NULs */ 172 173 name= MakeAtom(_XKB_RF_NAMES_PROP_ATOM,strlen(_XKB_RF_NAMES_PROP_ATOM),1); 174 if (name==None) { 175 ErrorF("[xkb] Atom error: %s not created\n",_XKB_RF_NAMES_PROP_ATOM); 176 return TRUE; 177 } 178 pval= (char*) malloc(len); 179 if (!pval) { 180 ErrorF("[xkb] Allocation error: %s proprerty not created\n", 181 _XKB_RF_NAMES_PROP_ATOM); 182 return TRUE; 183 } 184 out= 0; 185 if (XkbRulesUsed) { 186 strcpy(&pval[out],XkbRulesUsed); 187 out+= strlen(XkbRulesUsed); 188 } 189 pval[out++]= '\0'; 190 if (XkbModelUsed) { 191 strcpy(&pval[out],XkbModelUsed); 192 out+= strlen(XkbModelUsed); 193 } 194 pval[out++]= '\0'; 195 if (XkbLayoutUsed) { 196 strcpy(&pval[out],XkbLayoutUsed); 197 out+= strlen(XkbLayoutUsed); 198 } 199 pval[out++]= '\0'; 200 if (XkbVariantUsed) { 201 strcpy(&pval[out],XkbVariantUsed); 202 out+= strlen(XkbVariantUsed); 203 } 204 pval[out++]= '\0'; 205 if (XkbOptionsUsed) { 206 strcpy(&pval[out],XkbOptionsUsed); 207 out+= strlen(XkbOptionsUsed); 208 } 209 pval[out++]= '\0'; 210 if (out!=len) { 211 ErrorF("[xkb] Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n", 212 out,len); 213 } 214 dixChangeWindowProperty(serverClient, screenInfo.screens[0]->root, name, XA_STRING, 8, 215 PropModeReplace, len, pval, TRUE); 216 free(pval); 217 return TRUE; 218} 219 220static void 221XkbSetRulesUsed(XkbRMLVOSet *rmlvo) 222{ 223 free(XkbRulesUsed); 224 XkbRulesUsed= (rmlvo->rules?_XkbDupString(rmlvo->rules):NULL); 225 free(XkbModelUsed); 226 XkbModelUsed= (rmlvo->model?_XkbDupString(rmlvo->model):NULL); 227 free(XkbLayoutUsed); 228 XkbLayoutUsed= (rmlvo->layout?_XkbDupString(rmlvo->layout):NULL); 229 free(XkbVariantUsed); 230 XkbVariantUsed= (rmlvo->variant?_XkbDupString(rmlvo->variant):NULL); 231 free(XkbOptionsUsed); 232 XkbOptionsUsed= (rmlvo->options?_XkbDupString(rmlvo->options):NULL); 233 if (XkbWantRulesProp) 234 QueueWorkProc(XkbWriteRulesProp,NULL,NULL); 235 return; 236} 237 238void 239XkbSetRulesDflts(XkbRMLVOSet *rmlvo) 240{ 241 if (rmlvo->rules) { 242 free(XkbRulesDflt); 243 XkbRulesDflt= _XkbDupString(rmlvo->rules); 244 } 245 if (rmlvo->model) { 246 free(XkbModelDflt); 247 XkbModelDflt= _XkbDupString(rmlvo->model); 248 } 249 if (rmlvo->layout) { 250 free(XkbLayoutDflt); 251 XkbLayoutDflt= _XkbDupString(rmlvo->layout); 252 } 253 if (rmlvo->variant) { 254 free(XkbVariantDflt); 255 XkbVariantDflt= _XkbDupString(rmlvo->variant); 256 } 257 if (rmlvo->options) { 258 free(XkbOptionsDflt); 259 XkbOptionsDflt= _XkbDupString(rmlvo->options); 260 } 261 return; 262} 263 264void 265XkbDeleteRulesDflts(void) 266{ 267 free(XkbRulesDflt); 268 XkbRulesDflt = NULL; 269 free(XkbModelDflt); 270 XkbModelDflt = NULL; 271 free(XkbLayoutDflt); 272 XkbLayoutDflt = NULL; 273 free(XkbVariantDflt); 274 XkbVariantDflt = NULL; 275 free(XkbOptionsDflt); 276 XkbOptionsDflt = NULL; 277 278 XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE); 279 xkb_cached_map = NULL; 280} 281 282#define DIFFERS(a, b) (strcmp((a) ? (a) : "", (b) ? (b) : "") != 0) 283 284static Bool 285XkbCompareUsedRMLVO(XkbRMLVOSet *rmlvo) 286{ 287 if (DIFFERS(rmlvo->rules, XkbRulesUsed) || 288 DIFFERS(rmlvo->model, XkbModelUsed) || 289 DIFFERS(rmlvo->layout, XkbLayoutUsed) || 290 DIFFERS(rmlvo->variant, XkbVariantUsed) || 291 DIFFERS(rmlvo->options, XkbOptionsUsed)) 292 return FALSE; 293 return TRUE; 294} 295 296#undef DIFFERS 297 298/***====================================================================***/ 299 300#include "xkbDflts.h" 301 302static Bool 303XkbInitKeyTypes(XkbDescPtr xkb) 304{ 305 if (xkb->defined & XkmTypesMask) 306 return TRUE; 307 308 initTypeNames(NULL); 309 if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_dflt_types)!=Success) 310 return FALSE; 311 if (XkbCopyKeyTypes(dflt_types,xkb->map->types,num_dflt_types)!= 312 Success) { 313 return FALSE; 314 } 315 xkb->map->size_types= xkb->map->num_types= num_dflt_types; 316 return TRUE; 317} 318 319static void 320XkbInitRadioGroups(XkbSrvInfoPtr xkbi) 321{ 322 xkbi->nRadioGroups = 0; 323 xkbi->radioGroups = NULL; 324 return; 325} 326 327 328static Status 329XkbInitCompatStructs(XkbDescPtr xkb) 330{ 331register int i; 332XkbCompatMapPtr compat; 333 334 if (xkb->defined & XkmCompatMapMask) 335 return TRUE; 336 337 if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_dfltSI)!=Success) 338 return BadAlloc; 339 compat = xkb->compat; 340 if (compat->sym_interpret) { 341 compat->num_si = num_dfltSI; 342 memcpy((char *)compat->sym_interpret,(char *)dfltSI,sizeof(dfltSI)); 343 } 344 for (i=0;i<XkbNumKbdGroups;i++) { 345 compat->groups[i]= compatMap.groups[i]; 346 if (compat->groups[i].vmods!=0) { 347 unsigned mask; 348 mask= XkbMaskForVMask(xkb,compat->groups[i].vmods); 349 compat->groups[i].mask= compat->groups[i].real_mods|mask; 350 } 351 else compat->groups[i].mask= compat->groups[i].real_mods; 352 } 353 return Success; 354} 355 356static void 357XkbInitSemantics(XkbDescPtr xkb) 358{ 359 XkbInitKeyTypes(xkb); 360 XkbInitCompatStructs(xkb); 361 return; 362} 363 364/***====================================================================***/ 365 366static Status 367XkbInitNames(XkbSrvInfoPtr xkbi) 368{ 369XkbDescPtr xkb; 370XkbNamesPtr names; 371Status rtrn; 372Atom unknown; 373 374 xkb= xkbi->desc; 375 if ((rtrn=XkbAllocNames(xkb,XkbAllNamesMask,0,0))!=Success) 376 return rtrn; 377 unknown= CREATE_ATOM("unknown"); 378 names = xkb->names; 379 if (names->keycodes==None) names->keycodes= unknown; 380 if (names->geometry==None) names->geometry= unknown; 381 if (names->phys_symbols==None) names->phys_symbols= unknown; 382 if (names->symbols==None) names->symbols= unknown; 383 if (names->types==None) names->types= unknown; 384 if (names->compat==None) names->compat= unknown; 385 if (!(xkb->defined & XkmVirtualModsMask)) { 386 if (names->vmods[vmod_NumLock]==None) 387 names->vmods[vmod_NumLock]= CREATE_ATOM("NumLock"); 388 if (names->vmods[vmod_Alt]==None) 389 names->vmods[vmod_Alt]= CREATE_ATOM("Alt"); 390 if (names->vmods[vmod_AltGr]==None) 391 names->vmods[vmod_AltGr]= CREATE_ATOM("ModeSwitch"); 392 } 393 394 if (!(xkb->defined & XkmIndicatorsMask) || 395 !(xkb->defined & XkmGeometryMask)) { 396 initIndicatorNames(NULL,xkb); 397 if (names->indicators[LED_CAPS-1]==None) 398 names->indicators[LED_CAPS-1] = CREATE_ATOM("Caps Lock"); 399 if (names->indicators[LED_NUM-1]==None) 400 names->indicators[LED_NUM-1] = CREATE_ATOM("Num Lock"); 401 if (names->indicators[LED_SCROLL-1]==None) 402 names->indicators[LED_SCROLL-1] = CREATE_ATOM("Scroll Lock"); 403#ifdef LED_COMPOSE 404 if (names->indicators[LED_COMPOSE-1]==None) 405 names->indicators[LED_COMPOSE-1] = CREATE_ATOM("Compose"); 406#endif 407 } 408 409 if (xkb->geom!=NULL) 410 names->geometry= xkb->geom->name; 411 else names->geometry= unknown; 412 413 return Success; 414} 415 416static Status 417XkbInitIndicatorMap(XkbSrvInfoPtr xkbi) 418{ 419XkbDescPtr xkb; 420XkbIndicatorPtr map; 421XkbSrvLedInfoPtr sli; 422 423 xkb= xkbi->desc; 424 if (XkbAllocIndicatorMaps(xkb)!=Success) 425 return BadAlloc; 426 427 if (!(xkb->defined & XkmIndicatorsMask)) { 428 map= xkb->indicators; 429 map->phys_indicators = PHYS_LEDS; 430 map->maps[LED_CAPS-1].flags= XkbIM_NoExplicit; 431 map->maps[LED_CAPS-1].which_mods= XkbIM_UseLocked; 432 map->maps[LED_CAPS-1].mods.mask= LockMask; 433 map->maps[LED_CAPS-1].mods.real_mods= LockMask; 434 435 map->maps[LED_NUM-1].flags= XkbIM_NoExplicit; 436 map->maps[LED_NUM-1].which_mods= XkbIM_UseLocked; 437 map->maps[LED_NUM-1].mods.mask= 0; 438 map->maps[LED_NUM-1].mods.real_mods= 0; 439 map->maps[LED_NUM-1].mods.vmods= vmod_NumLockMask; 440 441 map->maps[LED_SCROLL-1].flags= XkbIM_NoExplicit; 442 map->maps[LED_SCROLL-1].which_mods= XkbIM_UseLocked; 443 map->maps[LED_SCROLL-1].mods.mask= Mod3Mask; 444 map->maps[LED_SCROLL-1].mods.real_mods= Mod3Mask; 445 } 446 447 sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0); 448 if (sli) 449 XkbCheckIndicatorMaps(xkbi->device,sli,XkbAllIndicatorsMask); 450 451 return Success; 452} 453 454static Status 455XkbInitControls(DeviceIntPtr pXDev,XkbSrvInfoPtr xkbi) 456{ 457XkbDescPtr xkb; 458XkbControlsPtr ctrls; 459 460 xkb= xkbi->desc; 461 /* 12/31/94 (ef) -- XXX! Should check if controls loaded from file */ 462 if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success) 463 FatalError("Couldn't allocate keyboard controls\n"); 464 ctrls= xkb->ctrls; 465 if (!(xkb->defined & XkmSymbolsMask)) 466 ctrls->num_groups = 1; 467 ctrls->groups_wrap = XkbSetGroupInfo(1,XkbWrapIntoRange,0); 468 ctrls->internal.mask = 0; 469 ctrls->internal.real_mods = 0; 470 ctrls->internal.vmods = 0; 471 ctrls->ignore_lock.mask = 0; 472 ctrls->ignore_lock.real_mods = 0; 473 ctrls->ignore_lock.vmods = 0; 474 ctrls->enabled_ctrls = XkbAccessXTimeoutMask|XkbRepeatKeysMask| 475 XkbMouseKeysAccelMask|XkbAudibleBellMask| 476 XkbIgnoreGroupLockMask; 477 if (XkbWantAccessX) 478 ctrls->enabled_ctrls|= XkbAccessXKeysMask; 479 AccessXInit(pXDev); 480 return Success; 481} 482 483_X_EXPORT Bool 484InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet *rmlvo, 485 BellProcPtr bell_func, KbdCtrlProcPtr ctrl_func) 486{ 487 int i; 488 unsigned int check; 489 XkbSrvInfoPtr xkbi; 490 XkbDescPtr xkb; 491 XkbSrvLedInfoPtr sli; 492 XkbChangesRec changes; 493 XkbEventCauseRec cause; 494 XkbRMLVOSet rmlvo_dflts = { NULL }; 495 496 if (dev->key || dev->kbdfeed) 497 return FALSE; 498 499 if (!rmlvo) 500 { 501 rmlvo = &rmlvo_dflts; 502 XkbGetRulesDflts(rmlvo); 503 } 504 505 506 memset(&changes, 0, sizeof(changes)); 507 XkbSetCauseUnknown(&cause); 508 509 dev->key = calloc(1, sizeof(*dev->key)); 510 if (!dev->key) { 511 ErrorF("XKB: Failed to allocate key class\n"); 512 return FALSE; 513 } 514 dev->key->sourceid = dev->id; 515 516 dev->kbdfeed = calloc(1, sizeof(*dev->kbdfeed)); 517 if (!dev->kbdfeed) { 518 ErrorF("XKB: Failed to allocate key feedback class\n"); 519 goto unwind_key; 520 } 521 522 xkbi = calloc(1, sizeof(*xkbi)); 523 if (!xkbi) { 524 ErrorF("XKB: Failed to allocate XKB info\n"); 525 goto unwind_kbdfeed; 526 } 527 dev->key->xkbInfo = xkbi; 528 529 if (xkb_cached_map && !XkbCompareUsedRMLVO(rmlvo)) { 530 XkbFreeKeyboard(xkb_cached_map, XkbAllComponentsMask, TRUE); 531 xkb_cached_map = NULL; 532 } 533 534 if (xkb_cached_map) 535 LogMessageVerb(X_INFO, 4, "XKB: Reusing cached keymap\n"); 536 else { 537 xkb_cached_map = XkbCompileKeymap(dev, rmlvo); 538 if (!xkb_cached_map) { 539 ErrorF("XKB: Failed to compile keymap\n"); 540 goto unwind_info; 541 } 542 } 543 544 xkb = XkbAllocKeyboard(); 545 if (!xkb) { 546 ErrorF("XKB: Failed to allocate keyboard description\n"); 547 goto unwind_info; 548 } 549 550 if (!XkbCopyKeymap(xkb, xkb_cached_map)) { 551 ErrorF("XKB: Failed to copy keymap\n"); 552 goto unwind_desc; 553 } 554 xkb->defined = xkb_cached_map->defined; 555 xkb->flags = xkb_cached_map->flags; 556 xkb->device_spec = xkb_cached_map->device_spec; 557 xkbi->desc = xkb; 558 559 if (xkb->min_key_code == 0) 560 xkb->min_key_code = 8; 561 if (xkb->max_key_code == 0) 562 xkb->max_key_code = 255; 563 564 i = XkbNumKeys(xkb) / 3 + 1; 565 if (XkbAllocClientMap(xkb, XkbAllClientInfoMask, 0) != Success) 566 goto unwind_desc; 567 if (XkbAllocServerMap(xkb, XkbAllServerInfoMask, i) != Success) 568 goto unwind_desc; 569 570 xkbi->dfltPtrDelta = 1; 571 xkbi->device = dev; 572 573 XkbInitSemantics(xkb); 574 XkbInitNames(xkbi); 575 XkbInitRadioGroups(xkbi); 576 577 XkbInitControls(dev, xkbi); 578 579 XkbInitIndicatorMap(xkbi); 580 581 XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &changes, 582 &check, &cause); 583 584 InitFocusClassDeviceStruct(dev); 585 586 xkbi->kbdProc = ctrl_func; 587 dev->kbdfeed->BellProc = bell_func; 588 dev->kbdfeed->CtrlProc = XkbDDXKeybdCtrlProc; 589 590 dev->kbdfeed->ctrl = defaultKeyboardControl; 591 if (dev->kbdfeed->ctrl.autoRepeat) 592 xkb->ctrls->enabled_ctrls |= XkbRepeatKeysMask; 593 594 memcpy(dev->kbdfeed->ctrl.autoRepeats, xkb->ctrls->per_key_repeat, 595 XkbPerKeyBitArraySize); 596 597 sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0); 598 if (sli) 599 XkbCheckIndicatorMaps(dev, sli, XkbAllIndicatorsMask); 600 else 601 DebugF("XKB: No indicator feedback in XkbFinishInit!\n"); 602 603 dev->kbdfeed->CtrlProc(dev,&dev->kbdfeed->ctrl); 604 605 XkbSetRulesDflts(rmlvo); 606 XkbSetRulesUsed(rmlvo); 607 XkbFreeRMLVOSet(&rmlvo_dflts, FALSE); 608 609 return TRUE; 610 611unwind_desc: 612 XkbFreeKeyboard(xkb, 0, TRUE); 613unwind_info: 614 free(xkbi); 615 dev->key->xkbInfo = NULL; 616unwind_kbdfeed: 617 free(dev->kbdfeed); 618 dev->kbdfeed = NULL; 619unwind_key: 620 free(dev->key); 621 dev->key = NULL; 622 return FALSE; 623} 624 625 626/***====================================================================***/ 627 628 /* 629 * Be very careful about what does and doesn't get freed by this 630 * function. To reduce fragmentation, XkbInitDevice allocates a 631 * single huge block per device and divides it up into most of the 632 * fixed-size structures for the device. Don't free anything that 633 * is part of this larger block. 634 */ 635void 636XkbFreeInfo(XkbSrvInfoPtr xkbi) 637{ 638 free(xkbi->radioGroups); 639 xkbi->radioGroups = NULL; 640 if (xkbi->mouseKeyTimer) { 641 TimerFree(xkbi->mouseKeyTimer); 642 xkbi->mouseKeyTimer= NULL; 643 } 644 if (xkbi->slowKeysTimer) { 645 TimerFree(xkbi->slowKeysTimer); 646 xkbi->slowKeysTimer= NULL; 647 } 648 if (xkbi->bounceKeysTimer) { 649 TimerFree(xkbi->bounceKeysTimer); 650 xkbi->bounceKeysTimer= NULL; 651 } 652 if (xkbi->repeatKeyTimer) { 653 TimerFree(xkbi->repeatKeyTimer); 654 xkbi->repeatKeyTimer= NULL; 655 } 656 if (xkbi->krgTimer) { 657 TimerFree(xkbi->krgTimer); 658 xkbi->krgTimer= NULL; 659 } 660 xkbi->beepType= _BEEP_NONE; 661 if (xkbi->beepTimer) { 662 TimerFree(xkbi->beepTimer); 663 xkbi->beepTimer= NULL; 664 } 665 if (xkbi->desc) { 666 XkbFreeKeyboard(xkbi->desc,XkbAllComponentsMask,TRUE); 667 xkbi->desc= NULL; 668 } 669 free(xkbi); 670 return; 671} 672 673/***====================================================================***/ 674 675extern int XkbDfltRepeatDelay; 676extern int XkbDfltRepeatInterval; 677 678extern unsigned short XkbDfltAccessXTimeout; 679extern unsigned int XkbDfltAccessXTimeoutMask; 680extern unsigned int XkbDfltAccessXFeedback; 681extern unsigned char XkbDfltAccessXOptions; 682 683int 684XkbProcessArguments(int argc,char *argv[],int i) 685{ 686 if (strncmp(argv[i], "-xkbdir", 7) == 0) { 687 if(++i < argc) { 688#if !defined(WIN32) && !defined(__CYGWIN__) 689 if (getuid() != geteuid()) { 690 LogMessage(X_WARNING, "-xkbdir is not available for setuid X servers\n"); 691 return -1; 692 } else 693#endif 694 { 695 if (strlen(argv[i]) < PATH_MAX) { 696 XkbBaseDirectory= argv[i]; 697 return 2; 698 } else { 699 LogMessage(X_ERROR, "-xkbdir pathname too long\n"); 700 return -1; 701 } 702 } 703 } 704 else { 705 return -1; 706 } 707 } 708 else if ((strncmp(argv[i],"-accessx",8)==0)|| 709 (strncmp(argv[i],"+accessx",8)==0)) { 710 int j=1; 711 if (argv[i][0]=='-') 712 XkbWantAccessX= 0; 713 else { 714 XkbWantAccessX= 1; 715 716 if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) { 717 XkbDfltAccessXTimeout = atoi(argv[++i]); 718 j++; 719 720 if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) { 721 /* 722 * presumption that the reasonably useful range of 723 * values fits in 0..MAXINT since SunOS 4 doesn't 724 * have strtoul. 725 */ 726 XkbDfltAccessXTimeoutMask=(unsigned int) 727 strtol(argv[++i],NULL,16); 728 j++; 729 } 730 if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) { 731 if (argv[++i][0] == '1' ) 732 XkbDfltAccessXFeedback=XkbAccessXFeedbackMask; 733 else 734 XkbDfltAccessXFeedback=0; 735 j++; 736 } 737 if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) { 738 XkbDfltAccessXOptions=(unsigned char) 739 strtol(argv[++i],NULL,16); 740 j++; 741 } 742 } 743 } 744 return j; 745 } 746 if ((strcmp(argv[i], "-ardelay") == 0) || 747 (strcmp (argv[i], "-ar1") == 0)) { /* -ardelay int */ 748 if (++i >= argc) UseMsg (); 749 XkbDfltRepeatDelay = (long)atoi(argv[i]); 750 return 2; 751 } 752 if ((strcmp(argv[i], "-arinterval") == 0) || 753 (strcmp (argv[i], "-ar2") == 0)) { /* -arinterval int */ 754 if (++i >= argc) UseMsg (); 755 XkbDfltRepeatInterval = (long)atoi(argv[i]); 756 return 2; 757 } 758 return 0; 759} 760 761void 762XkbUseMsg(void) 763{ 764 ErrorF("[+-]accessx [ timeout [ timeout_mask [ feedback [ options_mask] ] ] ]\n"); 765 ErrorF(" enable/disable accessx key sequences\n"); 766 ErrorF("-ardelay set XKB autorepeat delay\n"); 767 ErrorF("-arinterval set XKB autorepeat interval\n"); 768} 769