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