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