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