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_CONFIG_H 28#include <config.h> 29#endif 30 31 32#include <stdio.h> 33#include "Xlibint.h" 34#include <X11/extensions/XKBproto.h> 35#include <X11/keysym.h> 36#include "XKBlibint.h" 37 38 39/***====================================================================***/ 40 41#define mapSize(m) (sizeof(m)/sizeof(XkbKTMapEntryRec)) 42static XkbKTMapEntryRec map2Level[] = { 43 { True, ShiftMask, {1, ShiftMask, 0} } 44}; 45 46static XkbKTMapEntryRec mapAlpha[] = { 47 { True, ShiftMask, {1, ShiftMask, 0} }, 48 { True, LockMask, {0, LockMask, 0} } 49}; 50 51static XkbModsRec preAlpha[] = { 52 { 0, 0, 0 }, 53 { LockMask, LockMask, 0 } 54}; 55 56#define NL_VMOD_MASK 0 57static XkbKTMapEntryRec mapKeypad[] = { 58 { True, ShiftMask, { 1, ShiftMask, 0 } }, 59 { False, 0, { 1, 0, NL_VMOD_MASK } } 60}; 61 62static XkbKeyTypeRec canonicalTypes[XkbNumRequiredTypes] = { 63 { { 0, 0, 0 }, 64 1, /* num_levels */ 65 0, /* map_count */ 66 NULL, NULL, 67 None, NULL 68 }, 69 { { ShiftMask, ShiftMask, 0 }, 70 2, /* num_levels */ 71 mapSize(map2Level), /* map_count */ 72 map2Level, NULL, 73 None, NULL 74 }, 75 { { ShiftMask|LockMask, ShiftMask|LockMask, 0 }, 76 2, /* num_levels */ 77 mapSize(mapAlpha), /* map_count */ 78 mapAlpha, preAlpha, 79 None, NULL 80 }, 81 { { ShiftMask, ShiftMask, NL_VMOD_MASK }, 82 2, /* num_levels */ 83 mapSize(mapKeypad), /* map_count */ 84 mapKeypad, NULL, 85 None, NULL 86 } 87}; 88 89Status 90XkbInitCanonicalKeyTypes(XkbDescPtr xkb, unsigned which, int keypadVMod) 91{ 92 XkbClientMapPtr map; 93 XkbKeyTypePtr from, to; 94 Status rtrn; 95 96 if (!xkb) 97 return BadMatch; 98 rtrn = XkbAllocClientMap(xkb, XkbKeyTypesMask, XkbNumRequiredTypes); 99 if (rtrn != Success) 100 return rtrn; 101 map = xkb->map; 102 if ((which & XkbAllRequiredTypes) == 0) 103 return Success; 104 rtrn = Success; 105 from = canonicalTypes; 106 to = map->types; 107 if (which & XkbOneLevelMask) 108 rtrn = XkbCopyKeyType(&from[XkbOneLevelIndex], &to[XkbOneLevelIndex]); 109 if ((which & XkbTwoLevelMask) && (rtrn == Success)) 110 rtrn = XkbCopyKeyType(&from[XkbTwoLevelIndex], &to[XkbTwoLevelIndex]); 111 if ((which & XkbAlphabeticMask) && (rtrn == Success)) 112 rtrn = 113 XkbCopyKeyType(&from[XkbAlphabeticIndex], &to[XkbAlphabeticIndex]); 114 if ((which & XkbKeypadMask) && (rtrn == Success)) { 115 XkbKeyTypePtr type; 116 117 rtrn = XkbCopyKeyType(&from[XkbKeypadIndex], &to[XkbKeypadIndex]); 118 type = &to[XkbKeypadIndex]; 119 if ((keypadVMod >= 0) && (keypadVMod < XkbNumVirtualMods) && 120 (rtrn == Success)) { 121 type->mods.vmods = (1 << keypadVMod); 122 type->map[0].active = True; 123 type->map[0].mods.mask = ShiftMask; 124 type->map[0].mods.real_mods = ShiftMask; 125 type->map[0].mods.vmods = 0; 126 type->map[0].level = 1; 127 type->map[1].active = False; 128 type->map[1].mods.mask = 0; 129 type->map[1].mods.real_mods = 0; 130 type->map[1].mods.vmods = (1 << keypadVMod); 131 type->map[1].level = 1; 132 } 133 } 134 return Success; 135} 136 137/***====================================================================***/ 138 139#define CORE_SYM(i) (i<map_width?core_syms[i]:NoSymbol) 140#define XKB_OFFSET(g,l) (((g)*groupsWidth)+(l)) 141 142int 143XkbKeyTypesForCoreSymbols(XkbDescPtr xkb, 144 int map_width, 145 KeySym *core_syms, 146 unsigned int protected, 147 int *types_inout, 148 KeySym *xkb_syms_rtrn) 149{ 150 register int i; 151 unsigned int empty; 152 int nSyms[XkbNumKbdGroups]; 153 int nGroups, tmp, groupsWidth; 154 155 /* Section 12.2 of the protocol describes this process in more detail */ 156 /* Step 1: find the # of symbols in the core mapping per group */ 157 groupsWidth = 2; 158 for (i = 0; i < XkbNumKbdGroups; i++) { 159 if ((protected & (1 << i)) && (types_inout[i] < xkb->map->num_types)) { 160 nSyms[i] = xkb->map->types[types_inout[i]].num_levels; 161 if (nSyms[i] > groupsWidth) 162 groupsWidth = nSyms[i]; 163 } 164 else { 165 types_inout[i] = XkbTwoLevelIndex; /* don't really know, yet */ 166 nSyms[i] = 2; 167 } 168 } 169 if (nSyms[XkbGroup1Index] < 2) 170 nSyms[XkbGroup1Index] = 2; 171 if (nSyms[XkbGroup2Index] < 2) 172 nSyms[XkbGroup2Index] = 2; 173 /* Step 2: Copy the symbols from the core ordering to XKB ordering */ 174 /* symbols in the core are in the order: */ 175 /* G1L1 G1L2 G2L1 G2L2 [G1L[3-n]] [G2L[3-n]] [G3L*] [G3L*] */ 176 xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index, 0)] = CORE_SYM(0); 177 xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index, 1)] = CORE_SYM(1); 178 for (i = 2; i < nSyms[XkbGroup1Index]; i++) { 179 xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index, i)] = CORE_SYM(2 + i); 180 } 181 xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index, 0)] = CORE_SYM(2); 182 xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index, 1)] = CORE_SYM(3); 183 tmp = 2 + (nSyms[XkbGroup1Index] - 2); /* offset to extra group2 syms */ 184 for (i = 2; i < nSyms[XkbGroup2Index]; i++) { 185 xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index, i)] = CORE_SYM(tmp + i); 186 } 187 tmp = nSyms[XkbGroup1Index] + nSyms[XkbGroup2Index]; 188 if ((tmp >= map_width) && 189 ((protected & (XkbExplicitKeyType3Mask | XkbExplicitKeyType4Mask)) == 190 0)) { 191 nSyms[XkbGroup3Index] = 0; 192 nSyms[XkbGroup4Index] = 0; 193 nGroups = 2; 194 } 195 else { 196 nGroups = 3; 197 for (i = 0; i < nSyms[XkbGroup3Index]; i++, tmp++) { 198 xkb_syms_rtrn[XKB_OFFSET(XkbGroup3Index, i)] = CORE_SYM(tmp); 199 } 200 if ((tmp < map_width) || (protected & XkbExplicitKeyType4Mask)) { 201 nGroups = 4; 202 for (i = 0; i < nSyms[XkbGroup4Index]; i++, tmp++) { 203 xkb_syms_rtrn[XKB_OFFSET(XkbGroup4Index, i)] = CORE_SYM(tmp); 204 } 205 } 206 else { 207 nSyms[XkbGroup4Index] = 0; 208 } 209 } 210 /* steps 3&4: alphanumeric expansion, assign canonical types */ 211 empty = 0; 212 for (i = 0; i < nGroups; i++) { 213 KeySym *syms; 214 215 syms = &xkb_syms_rtrn[XKB_OFFSET(i, 0)]; 216 if ((nSyms[i] > 1) && (syms[1] == NoSymbol) && (syms[0] != NoSymbol)) { 217 KeySym upper, lower; 218 219 XConvertCase(syms[0], &lower, &upper); 220 if (upper != lower) { 221 xkb_syms_rtrn[XKB_OFFSET(i, 0)] = lower; 222 xkb_syms_rtrn[XKB_OFFSET(i, 1)] = upper; 223 if ((protected & (1 << i)) == 0) 224 types_inout[i] = XkbAlphabeticIndex; 225 } 226 else if ((protected & (1 << i)) == 0) { 227 types_inout[i] = XkbOneLevelIndex; 228 /* nSyms[i]= 1; */ 229 } 230 } 231 if (((protected & (1 << i)) == 0) && 232 (types_inout[i] == XkbTwoLevelIndex)) { 233 if (IsKeypadKey(syms[0]) || IsKeypadKey(syms[1])) 234 types_inout[i] = XkbKeypadIndex; 235 else { 236 KeySym upper, lower; 237 238 XConvertCase(syms[0], &lower, &upper); 239 if ((syms[0] == lower) && (syms[1] == upper)) 240 types_inout[i] = XkbAlphabeticIndex; 241 } 242 } 243 if (syms[0] == NoSymbol) { 244 register int n; 245 Bool found; 246 247 for (n = 1, found = False; (!found) && (n < nSyms[i]); n++) { 248 found = (syms[n] != NoSymbol); 249 } 250 if (!found) 251 empty |= (1 << i); 252 } 253 } 254 /* step 5: squoosh out empty groups */ 255 if (empty) { 256 for (i = nGroups - 1; i >= 0; i--) { 257 if (((empty & (1 << i)) == 0) || (protected & (1 << i))) 258 break; 259 nGroups--; 260 } 261 } 262 if (nGroups < 1) 263 return 0; 264 265 /* step 6: replicate group 1 into group two, if necessary */ 266 if ((nGroups > 1) && 267 ((empty & (XkbGroup1Mask | XkbGroup2Mask)) == XkbGroup2Mask)) { 268 if ((protected & (XkbExplicitKeyType1Mask | XkbExplicitKeyType2Mask)) == 269 0) { 270 nSyms[XkbGroup2Index] = nSyms[XkbGroup1Index]; 271 types_inout[XkbGroup2Index] = types_inout[XkbGroup1Index]; 272 memcpy((char *) &xkb_syms_rtrn[2], (char *) xkb_syms_rtrn, 273 2 * sizeof(KeySym)); 274 } 275 else if (types_inout[XkbGroup1Index] == types_inout[XkbGroup2Index]) { 276 memcpy((char *) &xkb_syms_rtrn[nSyms[XkbGroup1Index]], 277 (char *) xkb_syms_rtrn, 278 nSyms[XkbGroup1Index] * sizeof(KeySym)); 279 } 280 } 281 282 /* step 7: check for all groups identical or all width 1 */ 283 if (nGroups > 1) { 284 Bool sameType, allOneLevel; 285 286 allOneLevel = (xkb->map->types[types_inout[0]].num_levels == 1); 287 for (i = 1, sameType = True; (allOneLevel || sameType) && (i < nGroups); 288 i++) { 289 sameType = (sameType && 290 (types_inout[i] == types_inout[XkbGroup1Index])); 291 if (allOneLevel) 292 allOneLevel = (xkb->map->types[types_inout[i]].num_levels == 1); 293 } 294 if ((sameType) && 295 (!(protected & 296 (XkbExplicitKeyTypesMask & ~XkbExplicitKeyType1Mask)))) { 297 register int s; 298 Bool identical; 299 300 for (i = 1, identical = True; identical && (i < nGroups); i++) { 301 KeySym *syms; 302 303 syms = &xkb_syms_rtrn[XKB_OFFSET(i, 0)]; 304 for (s = 0; identical && (s < nSyms[i]); s++) { 305 if (syms[s] != xkb_syms_rtrn[s]) 306 identical = False; 307 } 308 } 309 if (identical) 310 nGroups = 1; 311 } 312 if (allOneLevel && (nGroups > 1)) { 313 KeySym *syms; 314 315 syms = &xkb_syms_rtrn[nSyms[XkbGroup1Index]]; 316 nSyms[XkbGroup1Index] = 1; 317 for (i = 1; i < nGroups; i++) { 318 xkb_syms_rtrn[i] = syms[0]; 319 syms += nSyms[i]; 320 nSyms[i] = 1; 321 } 322 } 323 } 324 return nGroups; 325} 326 327static XkbSymInterpretPtr 328_XkbFindMatchingInterp(XkbDescPtr xkb, 329 KeySym sym, 330 unsigned int real_mods, 331 unsigned int level) 332{ 333 register unsigned i; 334 XkbSymInterpretPtr interp, rtrn; 335 CARD8 mods; 336 337 rtrn = NULL; 338 interp = xkb->compat->sym_interpret; 339 for (i = 0; i < xkb->compat->num_si; i++, interp++) { 340 if ((interp->sym == NoSymbol) || (sym == interp->sym)) { 341 int match; 342 343 if ((level == 0) || ((interp->match & XkbSI_LevelOneOnly) == 0)) 344 mods = real_mods; 345 else 346 mods = 0; 347 switch (interp->match & XkbSI_OpMask) { 348 case XkbSI_NoneOf: 349 match = ((interp->mods & mods) == 0); 350 break; 351 case XkbSI_AnyOfOrNone: 352 match = ((mods == 0) || ((interp->mods & mods) != 0)); 353 break; 354 case XkbSI_AnyOf: 355 match = ((interp->mods & mods) != 0); 356 break; 357 case XkbSI_AllOf: 358 match = ((interp->mods & mods) == interp->mods); 359 break; 360 case XkbSI_Exactly: 361 match = (interp->mods == mods); 362 break; 363 default: 364 match = 0; 365 break; 366 } 367 if (match) { 368 if (interp->sym != NoSymbol) { 369 return interp; 370 } 371 else if (rtrn == NULL) { 372 rtrn = interp; 373 } 374 } 375 } 376 } 377 return rtrn; 378} 379 380static void 381_XkbAddKeyChange(KeyCode *pFirst, unsigned char *pNum, KeyCode newKey) 382{ 383 KeyCode last; 384 385 last = (*pFirst) + (*pNum); 386 if (newKey < *pFirst) { 387 *pFirst = newKey; 388 *pNum = (last - newKey) + 1; 389 } 390 else if (newKey > last) { 391 *pNum = (last - *pFirst) + 1; 392 } 393 return; 394} 395 396static void 397_XkbSetActionKeyMods(XkbDescPtr xkb, XkbAction *act, unsigned mods) 398{ 399 unsigned tmp; 400 401 switch (act->type) { 402 case XkbSA_SetMods: 403 case XkbSA_LatchMods: 404 case XkbSA_LockMods: 405 if (act->mods.flags & XkbSA_UseModMapMods) 406 act->mods.real_mods = act->mods.mask = mods; 407 if ((tmp = XkbModActionVMods(&act->mods)) != 0) { 408 XkbVirtualModsToReal(xkb, tmp, &tmp); 409 act->mods.mask |= tmp; 410 } 411 break; 412 case XkbSA_ISOLock: 413 if (act->iso.flags & XkbSA_UseModMapMods) 414 act->iso.real_mods = act->iso.mask = mods; 415 if ((tmp = XkbModActionVMods(&act->iso)) != 0) { 416 XkbVirtualModsToReal(xkb, tmp, &tmp); 417 act->iso.mask |= tmp; 418 } 419 break; 420 } 421 return; 422} 423 424#define IBUF_SIZE 8 425 426Bool 427XkbApplyCompatMapToKey(XkbDescPtr xkb, KeyCode key, XkbChangesPtr changes) 428{ 429 KeySym *syms; 430 unsigned char explicit, mods; 431 XkbSymInterpretPtr *interps, ibuf[IBUF_SIZE]; 432 int n, nSyms, found; 433 unsigned changed, tmp; 434 435 if ((!xkb) || (!xkb->map) || (!xkb->map->key_sym_map) || 436 (!xkb->compat) || (!xkb->compat->sym_interpret) || 437 (key < xkb->min_key_code) || (key > xkb->max_key_code)) { 438 return False; 439 } 440 if (((!xkb->server) || (!xkb->server->key_acts)) && 441 (XkbAllocServerMap(xkb, XkbAllServerInfoMask, 0) != Success)) { 442 return False; 443 } 444 changed = 0; /* keeps track of what has changed in _this_ call */ 445 explicit = xkb->server->explicit[key]; 446 if (explicit & XkbExplicitInterpretMask) /* nothing to do */ 447 return True; 448 mods = (xkb->map->modmap ? xkb->map->modmap[key] : 0); 449 nSyms = XkbKeyNumSyms(xkb, key); 450 syms = XkbKeySymsPtr(xkb, key); 451 if (nSyms > IBUF_SIZE) { 452 interps = _XkbTypedCalloc(nSyms, XkbSymInterpretPtr); 453 if (interps == NULL) { 454 interps = ibuf; 455 nSyms = IBUF_SIZE; 456 } 457 } 458 else { 459 interps = ibuf; 460 } 461 found = 0; 462 for (n = 0; n < nSyms; n++) { 463 unsigned level = (n % XkbKeyGroupsWidth(xkb, key)); 464 465 interps[n] = NULL; 466 if (syms[n] != NoSymbol) { 467 interps[n] = _XkbFindMatchingInterp(xkb, syms[n], mods, level); 468 if (interps[n] && interps[n]->act.type != XkbSA_NoAction) 469 found++; 470 else 471 interps[n] = NULL; 472 } 473 } 474 /* 1/28/96 (ef) -- XXX! WORKING HERE */ 475 if (!found) { 476 if (xkb->server->key_acts[key] != 0) { 477 xkb->server->key_acts[key] = 0; 478 changed |= XkbKeyActionsMask; 479 } 480 } 481 else { 482 XkbAction *pActs; 483 unsigned int new_vmodmask; 484 485 changed |= XkbKeyActionsMask; 486 pActs = XkbResizeKeyActions(xkb, key, nSyms); 487 if (!pActs) { 488 if (nSyms > IBUF_SIZE) 489 Xfree(interps); 490 return False; 491 } 492 new_vmodmask = 0; 493 for (n = 0; n < nSyms; n++) { 494 if (interps[n]) { 495 unsigned effMods; 496 497 pActs[n] = *((XkbAction *) &interps[n]->act); 498 if ((n == 0) || ((interps[n]->match & XkbSI_LevelOneOnly) == 0)) { 499 effMods = mods; 500 if (interps[n]->virtual_mod != XkbNoModifier) 501 new_vmodmask |= (1 << interps[n]->virtual_mod); 502 } 503 else 504 effMods = 0; 505 _XkbSetActionKeyMods(xkb, &pActs[n], effMods); 506 } 507 else 508 pActs[n].type = XkbSA_NoAction; 509 } 510 if (((explicit & XkbExplicitVModMapMask) == 0) && 511 (xkb->server->vmodmap[key] != new_vmodmask)) { 512 changed |= XkbVirtualModMapMask; 513 xkb->server->vmodmap[key] = new_vmodmask; 514 } 515 if (interps[0]) { 516 if ((interps[0]->flags & XkbSI_LockingKey) && 517 ((explicit & XkbExplicitBehaviorMask) == 0)) { 518 xkb->server->behaviors[key].type = XkbKB_Lock; 519 changed |= XkbKeyBehaviorsMask; 520 } 521 if (((explicit & XkbExplicitAutoRepeatMask) == 0) && (xkb->ctrls)) { 522 CARD8 old; 523 524 old = xkb->ctrls->per_key_repeat[key / 8]; 525 if (interps[0]->flags & XkbSI_AutoRepeat) 526 xkb->ctrls->per_key_repeat[key / 8] |= (1 << (key % 8)); 527 else 528 xkb->ctrls->per_key_repeat[key / 8] &= ~(1 << (key % 8)); 529 if (changes && (old != xkb->ctrls->per_key_repeat[key / 8])) 530 changes->ctrls.changed_ctrls |= XkbPerKeyRepeatMask; 531 } 532 } 533 } 534 if ((!found) || (interps[0] == NULL)) { 535 if (((explicit & XkbExplicitAutoRepeatMask) == 0) && (xkb->ctrls)) { 536 CARD8 old; 537 538 old = xkb->ctrls->per_key_repeat[key / 8]; 539#ifdef RETURN_SHOULD_REPEAT 540 if (*XkbKeySymsPtr(xkb, key) != XK_Return) 541#endif 542 xkb->ctrls->per_key_repeat[key / 8] |= (1 << (key % 8)); 543 if (changes && (old != xkb->ctrls->per_key_repeat[key / 8])) 544 changes->ctrls.changed_ctrls |= XkbPerKeyRepeatMask; 545 } 546 if (((explicit & XkbExplicitBehaviorMask) == 0) && 547 (xkb->server->behaviors[key].type == XkbKB_Lock)) { 548 xkb->server->behaviors[key].type = XkbKB_Default; 549 changed |= XkbKeyBehaviorsMask; 550 } 551 } 552 if (changes) { 553 XkbMapChangesPtr mc; 554 555 mc = &changes->map; 556 tmp = (changed & mc->changed); 557 if (tmp & XkbKeyActionsMask) 558 _XkbAddKeyChange(&mc->first_key_act, &mc->num_key_acts, key); 559 else if (changed & XkbKeyActionsMask) { 560 mc->changed |= XkbKeyActionsMask; 561 mc->first_key_act = key; 562 mc->num_key_acts = 1; 563 } 564 if (tmp & XkbKeyBehaviorsMask) { 565 _XkbAddKeyChange(&mc->first_key_behavior, &mc->num_key_behaviors, 566 key); 567 } 568 else if (changed & XkbKeyBehaviorsMask) { 569 mc->changed |= XkbKeyBehaviorsMask; 570 mc->first_key_behavior = key; 571 mc->num_key_behaviors = 1; 572 } 573 if (tmp & XkbVirtualModMapMask) 574 _XkbAddKeyChange(&mc->first_vmodmap_key, &mc->num_vmodmap_keys, 575 key); 576 else if (changed & XkbVirtualModMapMask) { 577 mc->changed |= XkbVirtualModMapMask; 578 mc->first_vmodmap_key = key; 579 mc->num_vmodmap_keys = 1; 580 } 581 mc->changed |= changed; 582 } 583 if (interps != ibuf) 584 _XkbFree(interps); 585 return True; 586} 587 588Bool 589XkbUpdateMapFromCore(XkbDescPtr xkb, 590 KeyCode first_key, 591 int num_keys, 592 int map_width, 593 KeySym *core_keysyms, 594 XkbChangesPtr changes) 595{ 596 register int key, last_key; 597 KeySym *syms; 598 599 syms = &core_keysyms[(first_key - xkb->min_key_code) * map_width]; 600 if (changes) { 601 if (changes->map.changed & XkbKeySymsMask) { 602 _XkbAddKeyChange(&changes->map.first_key_sym, 603 &changes->map.num_key_syms, first_key); 604 if (num_keys > 1) { 605 _XkbAddKeyChange(&changes->map.first_key_sym, 606 &changes->map.num_key_syms, 607 first_key + num_keys - 1); 608 } 609 } 610 else { 611 changes->map.changed |= XkbKeySymsMask; 612 changes->map.first_key_sym = first_key; 613 changes->map.num_key_syms = num_keys; 614 } 615 } 616 last_key = first_key + num_keys - 1; 617 for (key = first_key; key <= last_key; key++, syms += map_width) { 618 XkbMapChangesPtr mc; 619 unsigned explicit; 620 KeySym tsyms[XkbMaxSymsPerKey]; 621 int types[XkbNumKbdGroups]; 622 int nG; 623 624 explicit = xkb->server->explicit[key] & XkbExplicitKeyTypesMask; 625 types[XkbGroup1Index] = XkbKeyKeyTypeIndex(xkb, key, XkbGroup1Index); 626 types[XkbGroup2Index] = XkbKeyKeyTypeIndex(xkb, key, XkbGroup2Index); 627 types[XkbGroup3Index] = XkbKeyKeyTypeIndex(xkb, key, XkbGroup3Index); 628 types[XkbGroup4Index] = XkbKeyKeyTypeIndex(xkb, key, XkbGroup4Index); 629 nG = XkbKeyTypesForCoreSymbols(xkb, map_width, syms, explicit, types, 630 tsyms); 631 if (changes) 632 mc = &changes->map; 633 else 634 mc = NULL; 635 XkbChangeTypesOfKey(xkb, key, nG, XkbAllGroupsMask, types, mc); 636 memcpy((char *) XkbKeySymsPtr(xkb, key), (char *) tsyms, 637 XkbKeyNumSyms(xkb, key) * sizeof(KeySym)); 638 XkbApplyCompatMapToKey(xkb, key, changes); 639 } 640 641 if ((xkb->map->modmap != NULL) && (changes) && 642 (changes->map.changed & (XkbVirtualModMapMask | XkbModifierMapMask))) { 643 unsigned char newVMods[XkbNumVirtualMods]; 644 register unsigned bit, i; 645 unsigned present; 646 647 bzero(newVMods, XkbNumVirtualMods); 648 present = 0; 649 for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) { 650 if (xkb->server->vmodmap[key] == 0) 651 continue; 652 for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 653 if (bit & xkb->server->vmodmap[key]) { 654 present |= bit; 655 newVMods[i] |= xkb->map->modmap[key]; 656 } 657 } 658 } 659 for (i = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 660 if ((bit & present) && (newVMods[i] != xkb->server->vmods[i])) { 661 changes->map.changed |= XkbVirtualModsMask; 662 changes->map.vmods |= bit; 663 xkb->server->vmods[i] = newVMods[i]; 664 } 665 } 666 } 667 if (changes && (changes->map.changed & XkbVirtualModsMask)) 668 XkbApplyVirtualModChanges(xkb, changes->map.vmods, changes); 669 return True; 670} 671 672Status 673XkbChangeTypesOfKey(XkbDescPtr xkb, 674 int key, 675 int nGroups, 676 unsigned groups, 677 int *newTypesIn, 678 XkbMapChangesPtr changes) 679{ 680 XkbKeyTypePtr pOldType, pNewType; 681 register int i; 682 int width, nOldGroups, oldWidth, newTypes[XkbNumKbdGroups]; 683 684 if ((!xkb) || (!XkbKeycodeInRange(xkb, key)) || (!xkb->map) || 685 (!xkb->map->types) || (!newTypesIn) || 686 ((groups & XkbAllGroupsMask) == 0) || (nGroups > XkbNumKbdGroups)) { 687 return BadMatch; 688 } 689 if (nGroups == 0) { 690 for (i = 0; i < XkbNumKbdGroups; i++) { 691 xkb->map->key_sym_map[key].kt_index[i] = XkbOneLevelIndex; 692 } 693 i = xkb->map->key_sym_map[key].group_info; 694 i = XkbSetNumGroups(i, 0); 695 xkb->map->key_sym_map[key].group_info = i; 696 XkbResizeKeySyms(xkb, key, 0); 697 XkbResizeKeyActions(xkb, key, 0); 698 return Success; 699 } 700 701 nOldGroups = XkbKeyNumGroups(xkb, key); 702 oldWidth = XkbKeyGroupsWidth(xkb, key); 703 for (width = i = 0; i < nGroups; i++) { 704 if (groups & (1 << i)) 705 newTypes[i] = newTypesIn[i]; 706 else if (i < nOldGroups) 707 newTypes[i] = XkbKeyKeyTypeIndex(xkb, key, i); 708 else if (nOldGroups > 0) 709 newTypes[i] = XkbKeyKeyTypeIndex(xkb, key, XkbGroup1Index); 710 else 711 newTypes[i] = XkbTwoLevelIndex; 712 if (newTypes[i] > xkb->map->num_types) 713 return BadMatch; 714 pNewType = &xkb->map->types[newTypes[i]]; 715 if (pNewType->num_levels > width) 716 width = pNewType->num_levels; 717 } 718 if ((xkb->ctrls) && (nGroups > xkb->ctrls->num_groups)) 719 xkb->ctrls->num_groups = nGroups; 720 if ((width != oldWidth) || (nGroups != nOldGroups)) { 721 KeySym oldSyms[XkbMaxSymsPerKey], *pSyms; 722 int nCopy; 723 724 if (nOldGroups == 0) { 725 pSyms = XkbResizeKeySyms(xkb, key, width * nGroups); 726 if (pSyms != NULL) { 727 i = xkb->map->key_sym_map[key].group_info; 728 i = XkbSetNumGroups(i, nGroups); 729 xkb->map->key_sym_map[key].group_info = i; 730 xkb->map->key_sym_map[key].width = width; 731 for (i = 0; i < nGroups; i++) { 732 xkb->map->key_sym_map[key].kt_index[i] = newTypes[i]; 733 } 734 return Success; 735 } 736 return BadAlloc; 737 } 738 pSyms = XkbKeySymsPtr(xkb, key); 739 memcpy(oldSyms, pSyms, (size_t) XkbKeyNumSyms(xkb, key) * sizeof(KeySym)); 740 pSyms = XkbResizeKeySyms(xkb, key, width * nGroups); 741 if (pSyms == NULL) 742 return BadAlloc; 743 bzero(pSyms, width * nGroups * sizeof(KeySym)); 744 for (i = 0; (i < nGroups) && (i < nOldGroups); i++) { 745 pOldType = XkbKeyKeyType(xkb, key, i); 746 pNewType = &xkb->map->types[newTypes[i]]; 747 if (pNewType->num_levels > pOldType->num_levels) 748 nCopy = pOldType->num_levels; 749 else 750 nCopy = pNewType->num_levels; 751 memcpy(&pSyms[i * width], &oldSyms[i * oldWidth], 752 nCopy * sizeof(KeySym)); 753 } 754 if (XkbKeyHasActions(xkb, key)) { 755 XkbAction oldActs[XkbMaxSymsPerKey], *pActs; 756 757 pActs = XkbKeyActionsPtr(xkb, key); 758 memcpy(oldActs, pActs, (size_t) XkbKeyNumSyms(xkb, key) * sizeof(XkbAction)); 759 pActs = XkbResizeKeyActions(xkb, key, width * nGroups); 760 if (pActs == NULL) 761 return BadAlloc; 762 bzero(pActs, width * nGroups * sizeof(XkbAction)); 763 for (i = 0; (i < nGroups) && (i < nOldGroups); i++) { 764 pOldType = XkbKeyKeyType(xkb, key, i); 765 pNewType = &xkb->map->types[newTypes[i]]; 766 if (pNewType->num_levels > pOldType->num_levels) 767 nCopy = pOldType->num_levels; 768 else 769 nCopy = pNewType->num_levels; 770 memcpy(&pActs[i * width], &oldActs[i * oldWidth], 771 nCopy * sizeof(XkbAction)); 772 } 773 } 774 i = xkb->map->key_sym_map[key].group_info; 775 i = XkbSetNumGroups(i, nGroups); 776 xkb->map->key_sym_map[key].group_info = i; 777 xkb->map->key_sym_map[key].width = width; 778 } 779 width = 0; 780 for (i = 0; i < nGroups; i++) { 781 xkb->map->key_sym_map[key].kt_index[i] = newTypes[i]; 782 if (xkb->map->types[newTypes[i]].num_levels > width) 783 width = xkb->map->types[newTypes[i]].num_levels; 784 } 785 xkb->map->key_sym_map[key].width = width; 786 if (changes != NULL) { 787 if (changes->changed & XkbKeySymsMask) { 788 _XkbAddKeyChange(&changes->first_key_sym, &changes->num_key_syms, 789 key); 790 } 791 else { 792 changes->changed |= XkbKeySymsMask; 793 changes->first_key_sym = key; 794 changes->num_key_syms = 1; 795 } 796 } 797 return Success; 798} 799 800/***====================================================================***/ 801 802Bool 803XkbVirtualModsToReal(XkbDescPtr xkb, unsigned virtual_mask, unsigned *mask_rtrn) 804{ 805 register int i, bit; 806 register unsigned mask; 807 808 if ((xkb == NULL) || (xkb->server == NULL)) { 809 *mask_rtrn = 0; 810 return False; 811 } 812 if (virtual_mask == 0) { 813 *mask_rtrn = 0; 814 return True; 815 } 816 for (i = mask = 0, bit = 1; i < XkbNumVirtualMods; i++, bit <<= 1) { 817 if (virtual_mask & bit) 818 mask |= xkb->server->vmods[i]; 819 } 820 *mask_rtrn = mask; 821 return True; 822} 823 824/***====================================================================***/ 825 826Bool 827XkbUpdateActionVirtualMods(XkbDescPtr xkb, XkbAction *act, unsigned changed) 828{ 829 unsigned int tmp; 830 831 switch (act->type) { 832 case XkbSA_SetMods: 833 case XkbSA_LatchMods: 834 case XkbSA_LockMods: 835 if (((tmp = XkbModActionVMods(&act->mods)) & changed) != 0) { 836 XkbVirtualModsToReal(xkb, tmp, &tmp); 837 act->mods.mask = act->mods.real_mods; 838 act->mods.mask |= tmp; 839 return True; 840 } 841 break; 842 case XkbSA_ISOLock: 843 if ((((tmp = XkbModActionVMods(&act->iso)) != 0) & changed) != 0) { 844 XkbVirtualModsToReal(xkb, tmp, &tmp); 845 act->iso.mask = act->iso.real_mods; 846 act->iso.mask |= tmp; 847 return True; 848 } 849 break; 850 } 851 return False; 852} 853 854void 855XkbUpdateKeyTypeVirtualMods(XkbDescPtr xkb, 856 XkbKeyTypePtr type, 857 unsigned int changed, 858 XkbChangesPtr changes) 859{ 860 register unsigned int i; 861 unsigned int mask = 0; 862 863 XkbVirtualModsToReal(xkb, type->mods.vmods, &mask); 864 type->mods.mask = type->mods.real_mods | mask; 865 if ((type->map_count > 0) && (type->mods.vmods != 0)) { 866 XkbKTMapEntryPtr entry; 867 868 for (i = 0, entry = type->map; i < type->map_count; i++, entry++) { 869 if (entry->mods.vmods != 0) { 870 XkbVirtualModsToReal(xkb, entry->mods.vmods, &mask); 871 entry->mods.mask = entry->mods.real_mods | mask; 872 /* entry is active if vmods are bound */ 873 entry->active = (mask != 0); 874 } 875 else 876 entry->active = 1; 877 } 878 } 879 if (changes) { 880 int type_ndx; 881 882 type_ndx = type - xkb->map->types; 883 if ((type_ndx < 0) || (type_ndx > xkb->map->num_types)) 884 return; 885 if (changes->map.changed & XkbKeyTypesMask) { 886 int last; 887 888 last = changes->map.first_type + changes->map.num_types - 1; 889 if (type_ndx < changes->map.first_type) { 890 changes->map.first_type = type_ndx; 891 changes->map.num_types = (last - type_ndx) + 1; 892 } 893 else if (type_ndx > last) { 894 changes->map.num_types = 895 (type_ndx - changes->map.first_type) + 1; 896 } 897 } 898 else { 899 changes->map.changed |= XkbKeyTypesMask; 900 changes->map.first_type = type_ndx; 901 changes->map.num_types = 1; 902 } 903 } 904 return; 905} 906 907Bool 908XkbApplyVirtualModChanges(XkbDescPtr xkb, 909 unsigned changed, 910 XkbChangesPtr changes) 911{ 912 register int i; 913 unsigned int checkState = 0; 914 915 if ((!xkb) || (!xkb->map) || (changed == 0)) 916 return False; 917 for (i = 0; i < xkb->map->num_types; i++) { 918 if (xkb->map->types[i].mods.vmods & changed) 919 XkbUpdateKeyTypeVirtualMods(xkb, &xkb->map->types[i], changed, 920 changes); 921 } 922 if (changed & xkb->ctrls->internal.vmods) { 923 unsigned int newMask; 924 925 XkbVirtualModsToReal(xkb, xkb->ctrls->internal.vmods, &newMask); 926 newMask |= xkb->ctrls->internal.real_mods; 927 if (xkb->ctrls->internal.mask != newMask) { 928 xkb->ctrls->internal.mask = newMask; 929 if (changes) { 930 changes->ctrls.changed_ctrls |= XkbInternalModsMask; 931 checkState = True; 932 } 933 } 934 } 935 if (changed & xkb->ctrls->ignore_lock.vmods) { 936 unsigned int newMask; 937 938 XkbVirtualModsToReal(xkb, xkb->ctrls->ignore_lock.vmods, &newMask); 939 newMask |= xkb->ctrls->ignore_lock.real_mods; 940 if (xkb->ctrls->ignore_lock.mask != newMask) { 941 xkb->ctrls->ignore_lock.mask = newMask; 942 if (changes) { 943 changes->ctrls.changed_ctrls |= XkbIgnoreLockModsMask; 944 checkState = True; 945 } 946 } 947 } 948 if (xkb->indicators != NULL) { 949 XkbIndicatorMapPtr map; 950 951 map = &xkb->indicators->maps[0]; 952 for (i = 0; i < XkbNumIndicators; i++, map++) { 953 if (map->mods.vmods & changed) { 954 unsigned int newMask; 955 956 XkbVirtualModsToReal(xkb, map->mods.vmods, &newMask); 957 newMask |= map->mods.real_mods; 958 if (newMask != map->mods.mask) { 959 map->mods.mask = newMask; 960 if (changes) { 961 changes->indicators.map_changes |= (1 << i); 962 checkState = True; 963 } 964 } 965 } 966 } 967 } 968 if (xkb->compat != NULL) { 969 XkbCompatMapPtr compat; 970 971 compat = xkb->compat; 972 for (i = 0; i < XkbNumKbdGroups; i++) { 973 unsigned int newMask; 974 975 XkbVirtualModsToReal(xkb, compat->groups[i].vmods, &newMask); 976 newMask |= compat->groups[i].real_mods; 977 if (compat->groups[i].mask != newMask) { 978 compat->groups[i].mask = newMask; 979 if (changes) { 980 changes->compat.changed_groups |= (1 << i); 981 checkState = True; 982 } 983 } 984 } 985 } 986 if (xkb->map && xkb->server) { 987 int highChange = 0, lowChange = -1; 988 989 for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) { 990 if (XkbKeyHasActions(xkb, i)) { 991 register XkbAction *pAct; 992 register int n; 993 994 pAct = XkbKeyActionsPtr(xkb, i); 995 for (n = XkbKeyNumActions(xkb, i); n > 0; n--, pAct++) { 996 if ((pAct->type != XkbSA_NoAction) && 997 XkbUpdateActionVirtualMods(xkb, pAct, changed)) { 998 if (lowChange < 0) 999 lowChange = i; 1000 highChange = i; 1001 } 1002 } 1003 } 1004 } 1005 if (changes && (lowChange > 0)) { /* something changed */ 1006 if (changes->map.changed & XkbKeyActionsMask) { 1007 int last; 1008 1009 if (changes->map.first_key_act < lowChange) 1010 lowChange = changes->map.first_key_act; 1011 last = 1012 changes->map.first_key_act + changes->map.num_key_acts - 1; 1013 if (last > highChange) 1014 highChange = last; 1015 } 1016 changes->map.changed |= XkbKeyActionsMask; 1017 changes->map.first_key_act = lowChange; 1018 changes->map.num_key_acts = (highChange - lowChange) + 1; 1019 } 1020 } 1021 return checkState; 1022} 1023