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