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