XKBMisc.c revision 61b2299d
11ab64890Smrg/* $Xorg: XKBMisc.c,v 1.4 2000/08/17 19:45:02 cpqbld Exp $ */ 21ab64890Smrg/************************************************************ 31ab64890SmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 41ab64890Smrg 51ab64890SmrgPermission to use, copy, modify, and distribute this 61ab64890Smrgsoftware and its documentation for any purpose and without 71ab64890Smrgfee is hereby granted, provided that the above copyright 81ab64890Smrgnotice appear in all copies and that both that copyright 91ab64890Smrgnotice and this permission notice appear in supporting 1061b2299dSmrgdocumentation, and that the name of Silicon Graphics not be 1161b2299dSmrgused in advertising or publicity pertaining to distribution 121ab64890Smrgof the software without specific prior written permission. 1361b2299dSmrgSilicon Graphics makes no representation about the suitability 141ab64890Smrgof this software for any purpose. It is provided "as is" 151ab64890Smrgwithout any express or implied warranty. 161ab64890Smrg 1761b2299dSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 1861b2299dSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 191ab64890SmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 2061b2299dSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 2161b2299dSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2261b2299dSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 231ab64890SmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 241ab64890SmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 251ab64890Smrg 261ab64890Smrg********************************************************/ 271ab64890Smrg/* $XFree86: xc/lib/X11/XKBMisc.c,v 3.5 2001/10/28 03:32:33 tsi Exp $ */ 281ab64890Smrg 291ab64890Smrg#ifdef HAVE_DIX_CONFIG_H 301ab64890Smrg#include <dix-config.h> 311ab64890Smrg#elif defined(HAVE_CONFIG_H) 321ab64890Smrg#include <config.h> 331ab64890Smrg#endif 341ab64890Smrg 351ab64890Smrg#ifndef XKB_IN_SERVER 361ab64890Smrg 371ab64890Smrg#include <stdio.h> 381ab64890Smrg#define NEED_REPLIES 391ab64890Smrg#define NEED_EVENTS 401ab64890Smrg#include "Xlibint.h" 411ab64890Smrg#include <X11/extensions/XKBproto.h> 421ab64890Smrg#include <X11/keysym.h> 431ab64890Smrg#include "XKBlibint.h" 441ab64890Smrg 4561b2299dSmrg#else 461ab64890Smrg 471ab64890Smrg#include <stdio.h> 481ab64890Smrg#include <X11/X.h> 491ab64890Smrg#define NEED_EVENTS 501ab64890Smrg#define NEED_REPLIES 511ab64890Smrg#include <X11/Xproto.h> 521ab64890Smrg#include "misc.h" 531ab64890Smrg#include "inputstr.h" 541ab64890Smrg#include <X11/keysym.h> 551ab64890Smrg#define XKBSRV_NEED_FILE_FUNCS 561ab64890Smrg#include <X11/extensions/XKBsrv.h> 571ab64890Smrg 581ab64890Smrg#endif /* XKB_IN_SERVER */ 591ab64890Smrg 601ab64890Smrg/***====================================================================***/ 611ab64890Smrg 621ab64890Smrg#define mapSize(m) (sizeof(m)/sizeof(XkbKTMapEntryRec)) 6361b2299dSmrgstatic XkbKTMapEntryRec map2Level[]= { 641ab64890Smrg { True, ShiftMask, {1, ShiftMask, 0} } 651ab64890Smrg}; 661ab64890Smrg 6761b2299dSmrgstatic XkbKTMapEntryRec mapAlpha[]= { 681ab64890Smrg { True, ShiftMask, { 1, ShiftMask, 0 } }, 691ab64890Smrg { True, LockMask, { 0, LockMask, 0 } } 701ab64890Smrg}; 711ab64890Smrg 721ab64890Smrgstatic XkbModsRec preAlpha[]= { 731ab64890Smrg { 0, 0, 0 }, 741ab64890Smrg { LockMask, LockMask, 0 } 751ab64890Smrg}; 761ab64890Smrg 771ab64890Smrg#define NL_VMOD_MASK 0 7861b2299dSmrgstatic XkbKTMapEntryRec mapKeypad[]= { 791ab64890Smrg { True, ShiftMask, { 1, ShiftMask, 0 } }, 801ab64890Smrg { False, 0, { 1, 0, NL_VMOD_MASK } } 811ab64890Smrg}; 821ab64890Smrg 831ab64890Smrgstatic XkbKeyTypeRec canonicalTypes[XkbNumRequiredTypes] = { 8461b2299dSmrg { { 0, 0, 0 }, 851ab64890Smrg 1, /* num_levels */ 861ab64890Smrg 0, /* map_count */ 871ab64890Smrg NULL, NULL, 881ab64890Smrg None, NULL 891ab64890Smrg }, 9061b2299dSmrg { { ShiftMask, ShiftMask, 0 }, 911ab64890Smrg 2, /* num_levels */ 921ab64890Smrg mapSize(map2Level), /* map_count */ 931ab64890Smrg map2Level, NULL, 941ab64890Smrg None, NULL 951ab64890Smrg }, 9661b2299dSmrg { { ShiftMask|LockMask, ShiftMask|LockMask, 0 }, 971ab64890Smrg 2, /* num_levels */ 981ab64890Smrg mapSize(mapAlpha), /* map_count */ 991ab64890Smrg mapAlpha, preAlpha, 1001ab64890Smrg None, NULL 1011ab64890Smrg }, 1021ab64890Smrg { { ShiftMask, ShiftMask, NL_VMOD_MASK }, 1031ab64890Smrg 2, /* num_levels */ 1041ab64890Smrg mapSize(mapKeypad), /* map_count */ 1051ab64890Smrg mapKeypad, NULL, 1061ab64890Smrg None, NULL 1071ab64890Smrg } 1081ab64890Smrg}; 1091ab64890Smrg 1101ab64890SmrgStatus 1111ab64890SmrgXkbInitCanonicalKeyTypes(XkbDescPtr xkb,unsigned which,int keypadVMod) 1121ab64890Smrg{ 1131ab64890SmrgXkbClientMapPtr map; 1141ab64890SmrgXkbKeyTypePtr from,to; 1151ab64890SmrgStatus rtrn; 1161ab64890Smrg 1171ab64890Smrg if (!xkb) 1181ab64890Smrg return BadMatch; 1191ab64890Smrg rtrn= XkbAllocClientMap(xkb,XkbKeyTypesMask,XkbNumRequiredTypes); 1201ab64890Smrg if (rtrn!=Success) 1211ab64890Smrg return rtrn; 1221ab64890Smrg map= xkb->map; 1231ab64890Smrg if ((which&XkbAllRequiredTypes)==0) 1241ab64890Smrg return Success; 1251ab64890Smrg rtrn= Success; 1261ab64890Smrg from= canonicalTypes; 1271ab64890Smrg to= map->types; 1281ab64890Smrg if (which&XkbOneLevelMask) 1291ab64890Smrg rtrn= XkbCopyKeyType(&from[XkbOneLevelIndex],&to[XkbOneLevelIndex]); 1301ab64890Smrg if ((which&XkbTwoLevelMask)&&(rtrn==Success)) 1311ab64890Smrg rtrn= XkbCopyKeyType(&from[XkbTwoLevelIndex],&to[XkbTwoLevelIndex]); 1321ab64890Smrg if ((which&XkbAlphabeticMask)&&(rtrn==Success)) 1331ab64890Smrg rtrn= XkbCopyKeyType(&from[XkbAlphabeticIndex],&to[XkbAlphabeticIndex]); 1341ab64890Smrg if ((which&XkbKeypadMask)&&(rtrn==Success)) { 1351ab64890Smrg XkbKeyTypePtr type; 1361ab64890Smrg rtrn= XkbCopyKeyType(&from[XkbKeypadIndex],&to[XkbKeypadIndex]); 1371ab64890Smrg type= &to[XkbKeypadIndex]; 1381ab64890Smrg if ((keypadVMod>=0)&&(keypadVMod<XkbNumVirtualMods)&&(rtrn==Success)) { 1391ab64890Smrg type->mods.vmods= (1<<keypadVMod); 1401ab64890Smrg type->map[0].active= True; 1411ab64890Smrg type->map[0].mods.mask= ShiftMask; 1421ab64890Smrg type->map[0].mods.real_mods= ShiftMask; 1431ab64890Smrg type->map[0].mods.vmods= 0; 1441ab64890Smrg type->map[0].level= 1; 1451ab64890Smrg type->map[1].active= False; 1461ab64890Smrg type->map[1].mods.mask= 0; 1471ab64890Smrg type->map[1].mods.real_mods= 0; 1481ab64890Smrg type->map[1].mods.vmods= (1<<keypadVMod); 1491ab64890Smrg type->map[1].level= 1; 1501ab64890Smrg } 1511ab64890Smrg } 1521ab64890Smrg return Success; 1531ab64890Smrg} 1541ab64890Smrg 1551ab64890Smrg/***====================================================================***/ 1561ab64890Smrg 1571ab64890Smrg#define CORE_SYM(i) (i<map_width?core_syms[i]:NoSymbol) 1581ab64890Smrg#define XKB_OFFSET(g,l) (((g)*groupsWidth)+(l)) 1591ab64890Smrg 1601ab64890Smrgint 1611ab64890SmrgXkbKeyTypesForCoreSymbols( XkbDescPtr xkb, 1621ab64890Smrg int map_width, 1631ab64890Smrg KeySym * core_syms, 1641ab64890Smrg unsigned int protected, 1651ab64890Smrg int * types_inout, 1661ab64890Smrg KeySym * xkb_syms_rtrn) 1671ab64890Smrg{ 1681ab64890Smrgregister int i; 1691ab64890Smrgunsigned int empty; 1701ab64890Smrgint nSyms[XkbNumKbdGroups]; 1711ab64890Smrgint nGroups,tmp,groupsWidth; 1721ab64890Smrg 1731ab64890Smrg /* Section 12.2 of the protocol describes this process in more detail */ 1741ab64890Smrg /* Step 1: find the # of symbols in the core mapping per group */ 1751ab64890Smrg groupsWidth= 2; 1761ab64890Smrg for (i=0;i<XkbNumKbdGroups;i++) { 1771ab64890Smrg if ((protected&(1<<i))&&(types_inout[i]<xkb->map->num_types)) { 1781ab64890Smrg nSyms[i]= xkb->map->types[types_inout[i]].num_levels; 1791ab64890Smrg if (nSyms[i]>groupsWidth) 1801ab64890Smrg groupsWidth= nSyms[i]; 1811ab64890Smrg } 1821ab64890Smrg else { 1831ab64890Smrg types_inout[i]= XkbTwoLevelIndex; /* don't really know, yet */ 1841ab64890Smrg nSyms[i]= 2; 1851ab64890Smrg } 1861ab64890Smrg } 1871ab64890Smrg if (nSyms[XkbGroup1Index]<2) 1881ab64890Smrg nSyms[XkbGroup1Index]= 2; 1891ab64890Smrg if (nSyms[XkbGroup2Index]<2) 1901ab64890Smrg nSyms[XkbGroup2Index]= 2; 1911ab64890Smrg /* Step 2: Copy the symbols from the core ordering to XKB ordering */ 1921ab64890Smrg /* symbols in the core are in the order: */ 1931ab64890Smrg /* G1L1 G1L2 G2L1 G2L2 [G1L[3-n]] [G2L[3-n]] [G3L*] [G3L*] */ 1941ab64890Smrg xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,0)]= CORE_SYM(0); 1951ab64890Smrg xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,1)]= CORE_SYM(1); 1961ab64890Smrg for (i=2;i<nSyms[XkbGroup1Index];i++) { 1971ab64890Smrg xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,i)]= CORE_SYM(2+i); 1981ab64890Smrg } 1991ab64890Smrg xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,0)]= CORE_SYM(2); 2001ab64890Smrg xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,1)]= CORE_SYM(3); 2011ab64890Smrg tmp= 2+(nSyms[XkbGroup1Index]-2); /* offset to extra group2 syms */ 2021ab64890Smrg for (i=2;i<nSyms[XkbGroup2Index];i++) { 2031ab64890Smrg xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,i)]= CORE_SYM(tmp+i); 2041ab64890Smrg } 2051ab64890Smrg tmp= nSyms[XkbGroup1Index]+nSyms[XkbGroup2Index]; 2061ab64890Smrg if ((tmp>=map_width)&& 2071ab64890Smrg ((protected&(XkbExplicitKeyType3Mask|XkbExplicitKeyType4Mask))==0)) { 2081ab64890Smrg nSyms[XkbGroup3Index]= 0; 2091ab64890Smrg nSyms[XkbGroup4Index]= 0; 2101ab64890Smrg nGroups= 2; 2111ab64890Smrg } 2121ab64890Smrg else { 2131ab64890Smrg nGroups= 3; 2141ab64890Smrg for (i=0;i<nSyms[XkbGroup3Index];i++,tmp++) { 2151ab64890Smrg xkb_syms_rtrn[XKB_OFFSET(XkbGroup3Index,i)]= CORE_SYM(tmp); 2161ab64890Smrg } 2171ab64890Smrg if ((tmp<map_width)||(protected&XkbExplicitKeyType4Mask)) { 2181ab64890Smrg nGroups= 4; 2191ab64890Smrg for (i=0;i<nSyms[XkbGroup4Index];i++,tmp++) { 2201ab64890Smrg xkb_syms_rtrn[XKB_OFFSET(XkbGroup4Index,i)]= CORE_SYM(tmp); 2211ab64890Smrg } 2221ab64890Smrg } 2231ab64890Smrg else { 2241ab64890Smrg nSyms[XkbGroup4Index]= 0; 2251ab64890Smrg } 2261ab64890Smrg } 2271ab64890Smrg /* steps 3&4: alphanumeric expansion, assign canonical types */ 2281ab64890Smrg empty= 0; 2291ab64890Smrg for (i=0;i<nGroups;i++) { 2301ab64890Smrg KeySym *syms; 2311ab64890Smrg syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)]; 2321ab64890Smrg if ((nSyms[i]>1)&&(syms[1]==NoSymbol)&&(syms[0]!=NoSymbol)) { 2331ab64890Smrg KeySym upper,lower; 2341ab64890Smrg XConvertCase(syms[0],&lower,&upper); 2351ab64890Smrg if (upper!=lower) { 2361ab64890Smrg xkb_syms_rtrn[XKB_OFFSET(i,0)]= lower; 2371ab64890Smrg xkb_syms_rtrn[XKB_OFFSET(i,1)]= upper; 2381ab64890Smrg if ((protected&(1<<i))==0) 2391ab64890Smrg types_inout[i]= XkbAlphabeticIndex; 2401ab64890Smrg } 2411ab64890Smrg else if ((protected&(1<<i))==0) { 2421ab64890Smrg types_inout[i]= XkbOneLevelIndex; 2431ab64890Smrg /* nSyms[i]= 1;*/ 2441ab64890Smrg } 2451ab64890Smrg } 2461ab64890Smrg if (((protected&(1<<i))==0)&&(types_inout[i]==XkbTwoLevelIndex)) { 2471ab64890Smrg if (IsKeypadKey(syms[0])||IsKeypadKey(syms[1])) 2481ab64890Smrg types_inout[i]= XkbKeypadIndex; 2491ab64890Smrg else { 2501ab64890Smrg KeySym upper,lower; 2511ab64890Smrg XConvertCase(syms[0],&lower,&upper); 2521ab64890Smrg if ((syms[0]==lower)&&(syms[1]==upper)) 2531ab64890Smrg types_inout[i]= XkbAlphabeticIndex; 2541ab64890Smrg } 2551ab64890Smrg } 2561ab64890Smrg if (syms[0]==NoSymbol) { 2571ab64890Smrg register int n; 2581ab64890Smrg Bool found; 2591ab64890Smrg for (n=1,found=False;(!found)&&(n<nSyms[i]);n++) { 2601ab64890Smrg found= (syms[n]!=NoSymbol); 2611ab64890Smrg } 2621ab64890Smrg if (!found) 2631ab64890Smrg empty|= (1<<i); 2641ab64890Smrg } 2651ab64890Smrg } 2661ab64890Smrg /* step 5: squoosh out empty groups */ 2671ab64890Smrg if (empty) { 2681ab64890Smrg for (i=nGroups-1;i>=0;i--) { 2691ab64890Smrg if (((empty&(1<<i))==0)||(protected&(1<<i))) 2701ab64890Smrg break; 2711ab64890Smrg nGroups--; 2721ab64890Smrg } 2731ab64890Smrg } 2741ab64890Smrg if (nGroups<1) 2751ab64890Smrg return 0; 2761ab64890Smrg 2771ab64890Smrg /* step 6: replicate group 1 into group two, if necessary */ 2781ab64890Smrg if ((nGroups>1)&&((empty&(XkbGroup1Mask|XkbGroup2Mask))==XkbGroup2Mask)) { 2791ab64890Smrg if ((protected&(XkbExplicitKeyType1Mask|XkbExplicitKeyType2Mask))==0) { 2801ab64890Smrg nSyms[XkbGroup2Index]= nSyms[XkbGroup1Index]; 2811ab64890Smrg types_inout[XkbGroup2Index]= types_inout[XkbGroup1Index]; 2821ab64890Smrg memcpy((char *)&xkb_syms_rtrn[2],(char *)xkb_syms_rtrn, 2831ab64890Smrg 2*sizeof(KeySym)); 2841ab64890Smrg } 2851ab64890Smrg else if (types_inout[XkbGroup1Index]==types_inout[XkbGroup2Index]) { 2861ab64890Smrg memcpy((char *)&xkb_syms_rtrn[nSyms[XkbGroup1Index]], 2871ab64890Smrg (char *)xkb_syms_rtrn, 2881ab64890Smrg nSyms[XkbGroup1Index]*sizeof(KeySym)); 2891ab64890Smrg } 2901ab64890Smrg } 2911ab64890Smrg 2921ab64890Smrg /* step 7: check for all groups identical or all width 1 */ 2931ab64890Smrg if (nGroups>1) { 2941ab64890Smrg Bool sameType,allOneLevel; 2951ab64890Smrg allOneLevel= (xkb->map->types[types_inout[0]].num_levels==1); 2961ab64890Smrg for (i=1,sameType=True;(allOneLevel||sameType)&&(i<nGroups);i++) { 2971ab64890Smrg sameType=(sameType&&(types_inout[i]==types_inout[XkbGroup1Index])); 2981ab64890Smrg if (allOneLevel) 2991ab64890Smrg allOneLevel= (xkb->map->types[types_inout[i]].num_levels==1); 3001ab64890Smrg } 3011ab64890Smrg if ((sameType)&& 3021ab64890Smrg (!(protected&(XkbExplicitKeyTypesMask&~XkbExplicitKeyType1Mask)))){ 3031ab64890Smrg register int s; 3041ab64890Smrg Bool identical; 3051ab64890Smrg for (i=1,identical=True;identical&&(i<nGroups);i++) { 3061ab64890Smrg KeySym *syms; 3071ab64890Smrg syms= &xkb_syms_rtrn[XKB_OFFSET(i,0)]; 3081ab64890Smrg for (s=0;identical&&(s<nSyms[i]);s++) { 3091ab64890Smrg if (syms[s]!=xkb_syms_rtrn[s]) 3101ab64890Smrg identical= False; 3111ab64890Smrg } 3121ab64890Smrg } 3131ab64890Smrg if (identical) 3141ab64890Smrg nGroups= 1; 3151ab64890Smrg } 3161ab64890Smrg if (allOneLevel && (nGroups>1)) { 3171ab64890Smrg KeySym *syms; 3181ab64890Smrg syms= &xkb_syms_rtrn[nSyms[XkbGroup1Index]]; 3191ab64890Smrg nSyms[XkbGroup1Index]= 1; 3201ab64890Smrg for (i=1;i<nGroups;i++) { 3211ab64890Smrg xkb_syms_rtrn[i]= syms[0]; 3221ab64890Smrg syms+= nSyms[i]; 3231ab64890Smrg nSyms[i]= 1; 3241ab64890Smrg } 3251ab64890Smrg } 3261ab64890Smrg } 3271ab64890Smrg return nGroups; 3281ab64890Smrg} 3291ab64890Smrg 3301ab64890Smrgstatic XkbSymInterpretPtr 3311ab64890Smrg_XkbFindMatchingInterp( XkbDescPtr xkb, 3321ab64890Smrg KeySym sym, 3331ab64890Smrg unsigned int real_mods, 3341ab64890Smrg unsigned int level) 3351ab64890Smrg{ 3361ab64890Smrgregister unsigned i; 3371ab64890SmrgXkbSymInterpretPtr interp,rtrn; 3381ab64890SmrgCARD8 mods; 3391ab64890Smrg 3401ab64890Smrg rtrn= NULL; 3411ab64890Smrg interp= xkb->compat->sym_interpret; 3421ab64890Smrg for (i=0;i<xkb->compat->num_si;i++,interp++) { 3431ab64890Smrg if ((interp->sym==NoSymbol)||(sym==interp->sym)) { 3441ab64890Smrg int match; 3451ab64890Smrg if ((level==0)||((interp->match&XkbSI_LevelOneOnly)==0)) 3461ab64890Smrg mods= real_mods; 3471ab64890Smrg else mods= 0; 3481ab64890Smrg switch (interp->match&XkbSI_OpMask) { 3491ab64890Smrg case XkbSI_NoneOf: 3501ab64890Smrg match= ((interp->mods&mods)==0); 3511ab64890Smrg break; 3521ab64890Smrg case XkbSI_AnyOfOrNone: 3531ab64890Smrg match= ((mods==0)||((interp->mods&mods)!=0)); 3541ab64890Smrg break; 3551ab64890Smrg case XkbSI_AnyOf: 3561ab64890Smrg match= ((interp->mods&mods)!=0); 3571ab64890Smrg break; 3581ab64890Smrg case XkbSI_AllOf: 3591ab64890Smrg match= ((interp->mods&mods)==interp->mods); 3601ab64890Smrg break; 3611ab64890Smrg case XkbSI_Exactly: 3621ab64890Smrg match= (interp->mods==mods); 3631ab64890Smrg break; 3641ab64890Smrg default: 3651ab64890Smrg match= 0; 3661ab64890Smrg break; 3671ab64890Smrg } 3681ab64890Smrg if (match) { 3691ab64890Smrg if (interp->sym!=NoSymbol) { 3701ab64890Smrg return interp; 3711ab64890Smrg } 3721ab64890Smrg else if (rtrn==NULL) { 3731ab64890Smrg rtrn= interp; 3741ab64890Smrg } 3751ab64890Smrg } 3761ab64890Smrg } 3771ab64890Smrg } 3781ab64890Smrg return rtrn; 3791ab64890Smrg} 3801ab64890Smrg 3811ab64890Smrgstatic void 3821ab64890Smrg_XkbAddKeyChange(KeyCode *pFirst,unsigned char *pNum,KeyCode newKey) 3831ab64890Smrg{ 3841ab64890SmrgKeyCode last; 3851ab64890Smrg 3861ab64890Smrg last= (*pFirst)+(*pNum); 3871ab64890Smrg if (newKey<*pFirst) { 3881ab64890Smrg *pFirst= newKey; 3891ab64890Smrg *pNum= (last-newKey)+1; 3901ab64890Smrg } 3911ab64890Smrg else if (newKey>last) { 3921ab64890Smrg *pNum= (last-*pFirst)+1; 3931ab64890Smrg } 3941ab64890Smrg return; 3951ab64890Smrg} 3961ab64890Smrg 3971ab64890Smrgstatic void 3981ab64890Smrg_XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods) 3991ab64890Smrg{ 4001ab64890Smrgunsigned tmp; 4011ab64890Smrg 4021ab64890Smrg switch (act->type) { 4031ab64890Smrg case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods: 4041ab64890Smrg if (act->mods.flags&XkbSA_UseModMapMods) 4051ab64890Smrg act->mods.real_mods= act->mods.mask= mods; 4061ab64890Smrg if ((tmp= XkbModActionVMods(&act->mods))!=0) { 4071ab64890Smrg XkbVirtualModsToReal(xkb,tmp,&tmp); 4081ab64890Smrg act->mods.mask|= tmp; 4091ab64890Smrg } 4101ab64890Smrg break; 4111ab64890Smrg case XkbSA_ISOLock: 4121ab64890Smrg if (act->iso.flags&XkbSA_UseModMapMods) 4131ab64890Smrg act->iso.real_mods= act->iso.mask= mods; 4141ab64890Smrg if ((tmp= XkbModActionVMods(&act->iso))!=0) { 4151ab64890Smrg XkbVirtualModsToReal(xkb,tmp,&tmp); 4161ab64890Smrg act->iso.mask|= tmp; 4171ab64890Smrg } 4181ab64890Smrg break; 4191ab64890Smrg } 4201ab64890Smrg return; 4211ab64890Smrg} 4221ab64890Smrg 4231ab64890Smrg#define IBUF_SIZE 8 4241ab64890Smrg 4251ab64890SmrgBool 4261ab64890SmrgXkbApplyCompatMapToKey(XkbDescPtr xkb,KeyCode key,XkbChangesPtr changes) 4271ab64890Smrg{ 4281ab64890SmrgKeySym * syms; 4291ab64890Smrgunsigned char explicit,mods; 43061b2299dSmrgXkbSymInterpretPtr *interps,ibuf[IBUF_SIZE]; 4311ab64890Smrgint n,nSyms,found; 4321ab64890Smrgunsigned changed,tmp; 4331ab64890Smrg 4341ab64890Smrg if ((!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)|| 4351ab64890Smrg (!xkb->compat)||(!xkb->compat->sym_interpret)|| 4361ab64890Smrg (key<xkb->min_key_code)||(key>xkb->max_key_code)) { 4371ab64890Smrg return False; 4381ab64890Smrg } 4391ab64890Smrg if (((!xkb->server)||(!xkb->server->key_acts))&& 4401ab64890Smrg (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success)) { 4411ab64890Smrg return False; 4421ab64890Smrg } 4431ab64890Smrg changed= 0; /* keeps track of what has changed in _this_ call */ 4441ab64890Smrg explicit= xkb->server->explicit[key]; 4451ab64890Smrg if (explicit&XkbExplicitInterpretMask) /* nothing to do */ 4461ab64890Smrg return True; 4471ab64890Smrg mods= (xkb->map->modmap?xkb->map->modmap[key]:0); 4481ab64890Smrg nSyms= XkbKeyNumSyms(xkb,key); 4491ab64890Smrg syms= XkbKeySymsPtr(xkb,key); 4501ab64890Smrg if (nSyms>IBUF_SIZE) { 4511ab64890Smrg interps= _XkbTypedCalloc(nSyms,XkbSymInterpretPtr); 4521ab64890Smrg if (interps==NULL) { 4531ab64890Smrg interps= ibuf; 4541ab64890Smrg nSyms= IBUF_SIZE; 4551ab64890Smrg } 4561ab64890Smrg } 4571ab64890Smrg else { 4581ab64890Smrg interps= ibuf; 4591ab64890Smrg } 4601ab64890Smrg found= 0; 4611ab64890Smrg for (n=0;n<nSyms;n++) { 4621ab64890Smrg unsigned level= (n%XkbKeyGroupsWidth(xkb,key)); 4631ab64890Smrg interps[n]= NULL; 4641ab64890Smrg if (syms[n]!=NoSymbol) { 4651ab64890Smrg interps[n]= _XkbFindMatchingInterp(xkb,syms[n],mods,level); 4661ab64890Smrg if (interps[n]&&interps[n]->act.type!=XkbSA_NoAction) 4671ab64890Smrg found++; 4681ab64890Smrg else interps[n]= NULL; 4691ab64890Smrg } 4701ab64890Smrg } 4711ab64890Smrg /* 1/28/96 (ef) -- XXX! WORKING HERE */ 4721ab64890Smrg if (!found) { 4731ab64890Smrg if (xkb->server->key_acts[key]!=0) { 4741ab64890Smrg xkb->server->key_acts[key]= 0; 4751ab64890Smrg changed|= XkbKeyActionsMask; 4761ab64890Smrg } 4771ab64890Smrg } 4781ab64890Smrg else { 4791ab64890Smrg XkbAction *pActs; 4801ab64890Smrg unsigned int new_vmodmask; 4811ab64890Smrg changed|= XkbKeyActionsMask; 4821ab64890Smrg pActs= XkbResizeKeyActions(xkb,key,nSyms); 4831ab64890Smrg if (!pActs) { 4841ab64890Smrg if (nSyms > IBUF_SIZE) 4851ab64890Smrg Xfree(interps); 4861ab64890Smrg return False; 4871ab64890Smrg } 4881ab64890Smrg new_vmodmask= 0; 4891ab64890Smrg for (n=0;n<nSyms;n++) { 4901ab64890Smrg if (interps[n]) { 4911ab64890Smrg unsigned effMods; 4921ab64890Smrg 4931ab64890Smrg pActs[n]= *((XkbAction *)&interps[n]->act); 4941ab64890Smrg if ((n==0)||((interps[n]->match&XkbSI_LevelOneOnly)==0)) { 4951ab64890Smrg effMods= mods; 4961ab64890Smrg if (interps[n]->virtual_mod!=XkbNoModifier) 4971ab64890Smrg new_vmodmask|= (1<<interps[n]->virtual_mod); 4981ab64890Smrg } 4991ab64890Smrg else effMods= 0; 5001ab64890Smrg _XkbSetActionKeyMods(xkb,&pActs[n],effMods); 5011ab64890Smrg } 5021ab64890Smrg else pActs[n].type= XkbSA_NoAction; 5031ab64890Smrg } 5041ab64890Smrg if (((explicit&XkbExplicitVModMapMask)==0)&& 5051ab64890Smrg (xkb->server->vmodmap[key]!=new_vmodmask)) { 5061ab64890Smrg changed|= XkbVirtualModMapMask; 5071ab64890Smrg xkb->server->vmodmap[key]= new_vmodmask; 5081ab64890Smrg } 5091ab64890Smrg if (interps[0]) { 5101ab64890Smrg if ((interps[0]->flags&XkbSI_LockingKey)&& 5111ab64890Smrg ((explicit&XkbExplicitBehaviorMask)==0)) { 5121ab64890Smrg xkb->server->behaviors[key].type= XkbKB_Lock; 5131ab64890Smrg changed|= XkbKeyBehaviorsMask; 5141ab64890Smrg } 5151ab64890Smrg if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) { 5161ab64890Smrg CARD8 old; 5171ab64890Smrg old= xkb->ctrls->per_key_repeat[key/8]; 5181ab64890Smrg if (interps[0]->flags&XkbSI_AutoRepeat) 5191ab64890Smrg xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8)); 5201ab64890Smrg else xkb->ctrls->per_key_repeat[key/8]&= ~(1<<(key%8)); 5211ab64890Smrg if (changes && (old!=xkb->ctrls->per_key_repeat[key/8])) 5221ab64890Smrg changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask; 5231ab64890Smrg } 5241ab64890Smrg } 5251ab64890Smrg } 5261ab64890Smrg if ((!found)||(interps[0]==NULL)) { 5271ab64890Smrg if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) { 5281ab64890Smrg CARD8 old; 5291ab64890Smrg old= xkb->ctrls->per_key_repeat[key/8]; 5301ab64890Smrg#ifdef RETURN_SHOULD_REPEAT 5311ab64890Smrg if (*XkbKeySymsPtr(xkb,key) != XK_Return) 5321ab64890Smrg#endif 5331ab64890Smrg xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8)); 5341ab64890Smrg if (changes && (old!=xkb->ctrls->per_key_repeat[key/8])) 5351ab64890Smrg changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask; 5361ab64890Smrg } 5371ab64890Smrg if (((explicit&XkbExplicitBehaviorMask)==0)&& 5381ab64890Smrg (xkb->server->behaviors[key].type==XkbKB_Lock)) { 5391ab64890Smrg xkb->server->behaviors[key].type= XkbKB_Default; 5401ab64890Smrg changed|= XkbKeyBehaviorsMask; 5411ab64890Smrg } 5421ab64890Smrg } 5431ab64890Smrg if (changes) { 5441ab64890Smrg XkbMapChangesPtr mc; 5451ab64890Smrg mc= &changes->map; 5461ab64890Smrg tmp= (changed&mc->changed); 5471ab64890Smrg if (tmp&XkbKeyActionsMask) 5481ab64890Smrg _XkbAddKeyChange(&mc->first_key_act,&mc->num_key_acts,key); 5491ab64890Smrg else if (changed&XkbKeyActionsMask) { 5501ab64890Smrg mc->changed|= XkbKeyActionsMask; 5511ab64890Smrg mc->first_key_act= key; 5521ab64890Smrg mc->num_key_acts= 1; 5531ab64890Smrg } 5541ab64890Smrg if (tmp&XkbKeyBehaviorsMask) { 5551ab64890Smrg _XkbAddKeyChange(&mc->first_key_behavior,&mc->num_key_behaviors, 5561ab64890Smrg key); 5571ab64890Smrg } 5581ab64890Smrg else if (changed&XkbKeyBehaviorsMask) { 5591ab64890Smrg mc->changed|= XkbKeyBehaviorsMask; 5601ab64890Smrg mc->first_key_behavior= key; 5611ab64890Smrg mc->num_key_behaviors= 1; 5621ab64890Smrg } 5631ab64890Smrg if (tmp&XkbVirtualModMapMask) 5641ab64890Smrg _XkbAddKeyChange(&mc->first_vmodmap_key,&mc->num_vmodmap_keys,key); 5651ab64890Smrg else if (changed&XkbVirtualModMapMask) { 5661ab64890Smrg mc->changed|= XkbVirtualModMapMask; 5671ab64890Smrg mc->first_vmodmap_key= key; 5681ab64890Smrg mc->num_vmodmap_keys= 1; 5691ab64890Smrg } 5701ab64890Smrg mc->changed|= changed; 5711ab64890Smrg } 5721ab64890Smrg if (interps!=ibuf) 5731ab64890Smrg _XkbFree(interps); 5741ab64890Smrg return True; 5751ab64890Smrg} 5761ab64890Smrg 5771ab64890SmrgBool 5781ab64890SmrgXkbUpdateMapFromCore( XkbDescPtr xkb, 5791ab64890Smrg KeyCode first_key, 5801ab64890Smrg int num_keys, 5811ab64890Smrg int map_width, 5821ab64890Smrg KeySym * core_keysyms, 5831ab64890Smrg XkbChangesPtr changes) 5841ab64890Smrg{ 5851ab64890Smrgregister int key,last_key; 5861ab64890SmrgKeySym * syms; 5871ab64890Smrg 5881ab64890Smrg syms= &core_keysyms[(first_key-xkb->min_key_code)*map_width]; 5891ab64890Smrg if (changes) { 5901ab64890Smrg if (changes->map.changed&XkbKeySymsMask) { 5911ab64890Smrg _XkbAddKeyChange(&changes->map.first_key_sym, 5921ab64890Smrg &changes->map.num_key_syms,first_key); 5931ab64890Smrg if (num_keys>1) { 5941ab64890Smrg _XkbAddKeyChange(&changes->map.first_key_sym, 5951ab64890Smrg &changes->map.num_key_syms, 5961ab64890Smrg first_key+num_keys-1); 5971ab64890Smrg } 5981ab64890Smrg } 5991ab64890Smrg else { 6001ab64890Smrg changes->map.changed|= XkbKeySymsMask; 6011ab64890Smrg changes->map.first_key_sym= first_key; 6021ab64890Smrg changes->map.num_key_syms= num_keys; 6031ab64890Smrg } 6041ab64890Smrg } 6051ab64890Smrg last_key= first_key+num_keys-1; 6061ab64890Smrg for (key=first_key;key<=last_key;key++,syms+= map_width) { 6071ab64890Smrg XkbMapChangesPtr mc; 6081ab64890Smrg unsigned explicit; 6091ab64890Smrg KeySym tsyms[XkbMaxSymsPerKey]; 6101ab64890Smrg int types[XkbNumKbdGroups]; 6111ab64890Smrg int nG; 6121ab64890Smrg 6131ab64890Smrg explicit= xkb->server->explicit[key]&XkbExplicitKeyTypesMask; 6141ab64890Smrg types[XkbGroup1Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index); 6151ab64890Smrg types[XkbGroup2Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup2Index); 6161ab64890Smrg types[XkbGroup3Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup3Index); 6171ab64890Smrg types[XkbGroup4Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup4Index); 6181ab64890Smrg nG= XkbKeyTypesForCoreSymbols(xkb,map_width,syms,explicit,types,tsyms); 6191ab64890Smrg if (changes) 6201ab64890Smrg mc= &changes->map; 6211ab64890Smrg else mc= NULL; 6221ab64890Smrg XkbChangeTypesOfKey(xkb,key,nG,XkbAllGroupsMask,types,mc); 6231ab64890Smrg memcpy((char *)XkbKeySymsPtr(xkb,key),(char *)tsyms, 6241ab64890Smrg XkbKeyNumSyms(xkb,key)*sizeof(KeySym)); 6251ab64890Smrg XkbApplyCompatMapToKey(xkb,key,changes); 6261ab64890Smrg } 6271ab64890Smrg 6281ab64890Smrg if ((xkb->server->vmods!=NULL)&&(xkb->map->modmap!=NULL)&&(changes)&& 6291ab64890Smrg (changes->map.changed&(XkbVirtualModMapMask|XkbModifierMapMask))) { 6301ab64890Smrg unsigned char newVMods[XkbNumVirtualMods]; 6311ab64890Smrg register unsigned bit,i; 6321ab64890Smrg unsigned present; 6331ab64890Smrg 6341ab64890Smrg bzero(newVMods,XkbNumVirtualMods); 6351ab64890Smrg present= 0; 6361ab64890Smrg for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) { 6371ab64890Smrg if (xkb->server->vmodmap[key]==0) 6381ab64890Smrg continue; 6391ab64890Smrg for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 6401ab64890Smrg if (bit&xkb->server->vmodmap[key]) { 6411ab64890Smrg present|= bit; 6421ab64890Smrg newVMods[i]|= xkb->map->modmap[key]; 6431ab64890Smrg } 6441ab64890Smrg } 6451ab64890Smrg } 6461ab64890Smrg for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 6471ab64890Smrg if ((bit&present)&&(newVMods[i]!=xkb->server->vmods[i])) { 6481ab64890Smrg changes->map.changed|= XkbVirtualModsMask; 6491ab64890Smrg changes->map.vmods|= bit; 6501ab64890Smrg xkb->server->vmods[i]= newVMods[i]; 6511ab64890Smrg } 6521ab64890Smrg } 6531ab64890Smrg } 6541ab64890Smrg if (changes && (changes->map.changed&XkbVirtualModsMask)) 6551ab64890Smrg XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes); 6561ab64890Smrg return True; 6571ab64890Smrg} 6581ab64890Smrg 6591ab64890SmrgStatus 6601ab64890SmrgXkbChangeTypesOfKey( XkbDescPtr xkb, 6611ab64890Smrg int key, 6621ab64890Smrg int nGroups, 6631ab64890Smrg unsigned groups, 6641ab64890Smrg int * newTypesIn, 6651ab64890Smrg XkbMapChangesPtr changes) 6661ab64890Smrg{ 6671ab64890SmrgXkbKeyTypePtr pOldType,pNewType; 6681ab64890Smrgregister int i; 6691ab64890Smrgint width,nOldGroups,oldWidth,newTypes[XkbNumKbdGroups]; 6701ab64890Smrg 6711ab64890Smrg if ((!xkb) || (!XkbKeycodeInRange(xkb,key)) || (!xkb->map) || 67261b2299dSmrg (!xkb->map->types)||((groups&XkbAllGroupsMask)==0)|| 6731ab64890Smrg (nGroups>XkbNumKbdGroups)) { 6741ab64890Smrg return BadMatch; 6751ab64890Smrg } 6761ab64890Smrg if (nGroups==0) { 6771ab64890Smrg for (i=0;i<XkbNumKbdGroups;i++) { 6781ab64890Smrg xkb->map->key_sym_map[key].kt_index[i]= XkbOneLevelIndex; 6791ab64890Smrg } 6801ab64890Smrg i= xkb->map->key_sym_map[key].group_info; 6811ab64890Smrg i= XkbSetNumGroups(i,0); 6821ab64890Smrg xkb->map->key_sym_map[key].group_info= i; 6831ab64890Smrg XkbResizeKeySyms(xkb,key,0); 6841ab64890Smrg return Success; 6851ab64890Smrg } 6861ab64890Smrg 6871ab64890Smrg nOldGroups= XkbKeyNumGroups(xkb,key); 6881ab64890Smrg oldWidth= XkbKeyGroupsWidth(xkb,key); 6891ab64890Smrg for (width=i=0;i<nGroups;i++) { 6901ab64890Smrg if (groups&(1<<i)) 6911ab64890Smrg newTypes[i]= newTypesIn[i]; 6921ab64890Smrg else if (i<nOldGroups) 6931ab64890Smrg newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,i); 6941ab64890Smrg else if (nOldGroups>0) 6951ab64890Smrg newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index); 6961ab64890Smrg else newTypes[i]= XkbTwoLevelIndex; 6971ab64890Smrg if (newTypes[i]>xkb->map->num_types) 6981ab64890Smrg return BadMatch; 6991ab64890Smrg pNewType= &xkb->map->types[newTypes[i]]; 7001ab64890Smrg if (pNewType->num_levels>width) 7011ab64890Smrg width= pNewType->num_levels; 7021ab64890Smrg } 7031ab64890Smrg if ((xkb->ctrls)&&(nGroups>xkb->ctrls->num_groups)) 7041ab64890Smrg xkb->ctrls->num_groups= nGroups; 7051ab64890Smrg if ((width!=oldWidth)||(nGroups!=nOldGroups)) { 7061ab64890Smrg KeySym oldSyms[XkbMaxSymsPerKey],*pSyms; 7071ab64890Smrg int nCopy; 7081ab64890Smrg 7091ab64890Smrg if (nOldGroups==0) { 7101ab64890Smrg pSyms= XkbResizeKeySyms(xkb,key,width*nGroups); 7111ab64890Smrg if (pSyms!=NULL) { 7121ab64890Smrg i= xkb->map->key_sym_map[key].group_info; 7131ab64890Smrg i= XkbSetNumGroups(i,nGroups); 7141ab64890Smrg xkb->map->key_sym_map[key].group_info= i; 7151ab64890Smrg xkb->map->key_sym_map[key].width= width; 7161ab64890Smrg for (i=0;i<nGroups;i++) { 7171ab64890Smrg xkb->map->key_sym_map[key].kt_index[i]= newTypes[i]; 7181ab64890Smrg } 7191ab64890Smrg return Success; 7201ab64890Smrg } 7211ab64890Smrg return BadAlloc; 7221ab64890Smrg } 7231ab64890Smrg pSyms= XkbKeySymsPtr(xkb,key); 7241ab64890Smrg memcpy(oldSyms,pSyms,XkbKeyNumSyms(xkb,key)*sizeof(KeySym)); 7251ab64890Smrg pSyms= XkbResizeKeySyms(xkb,key,width*nGroups); 7261ab64890Smrg if (pSyms==NULL) 7271ab64890Smrg return BadAlloc; 7281ab64890Smrg bzero(pSyms,width*nGroups*sizeof(KeySym)); 7291ab64890Smrg for (i=0;(i<nGroups)&&(i<nOldGroups);i++) { 7301ab64890Smrg pOldType= XkbKeyKeyType(xkb,key,i); 7311ab64890Smrg pNewType= &xkb->map->types[newTypes[i]]; 7321ab64890Smrg if (pNewType->num_levels>pOldType->num_levels) 7331ab64890Smrg nCopy= pOldType->num_levels; 7341ab64890Smrg else nCopy= pNewType->num_levels; 7351ab64890Smrg memcpy(&pSyms[i*width],&oldSyms[i*oldWidth],nCopy*sizeof(KeySym)); 7361ab64890Smrg } 7371ab64890Smrg if (XkbKeyHasActions(xkb,key)) { 7381ab64890Smrg XkbAction oldActs[XkbMaxSymsPerKey],*pActs; 7391ab64890Smrg pActs= XkbKeyActionsPtr(xkb,key); 7401ab64890Smrg memcpy(oldActs,pActs,XkbKeyNumSyms(xkb,key)*sizeof(XkbAction)); 7411ab64890Smrg pActs= XkbResizeKeyActions(xkb,key,width*nGroups); 7421ab64890Smrg if (pActs==NULL) 7431ab64890Smrg return BadAlloc; 7441ab64890Smrg bzero(pActs,width*nGroups*sizeof(XkbAction)); 7451ab64890Smrg for (i=0;(i<nGroups)&&(i<nOldGroups);i++) { 7461ab64890Smrg pOldType= XkbKeyKeyType(xkb,key,i); 7471ab64890Smrg pNewType= &xkb->map->types[newTypes[i]]; 7481ab64890Smrg if (pNewType->num_levels>pOldType->num_levels) 7491ab64890Smrg nCopy= pOldType->num_levels; 7501ab64890Smrg else nCopy= pNewType->num_levels; 7511ab64890Smrg memcpy(&pActs[i*width],&oldActs[i*oldWidth], 7521ab64890Smrg nCopy*sizeof(XkbAction)); 7531ab64890Smrg } 7541ab64890Smrg } 7551ab64890Smrg i= xkb->map->key_sym_map[key].group_info; 7561ab64890Smrg i= XkbSetNumGroups(i,nGroups); 7571ab64890Smrg xkb->map->key_sym_map[key].group_info= i; 7581ab64890Smrg xkb->map->key_sym_map[key].width= width; 7591ab64890Smrg } 7601ab64890Smrg width= 0; 7611ab64890Smrg for (i=0;i<nGroups;i++) { 7621ab64890Smrg xkb->map->key_sym_map[key].kt_index[i]= newTypes[i]; 7631ab64890Smrg if (xkb->map->types[newTypes[i]].num_levels>width) 7641ab64890Smrg width= xkb->map->types[newTypes[i]].num_levels; 7651ab64890Smrg } 7661ab64890Smrg xkb->map->key_sym_map[key].width= width; 7671ab64890Smrg if (changes!=NULL) { 7681ab64890Smrg if (changes->changed&XkbKeySymsMask) { 7691ab64890Smrg _XkbAddKeyChange(&changes->first_key_sym,&changes->num_key_syms, 7701ab64890Smrg key); 7711ab64890Smrg } 7721ab64890Smrg else { 7731ab64890Smrg changes->changed|= XkbKeySymsMask; 7741ab64890Smrg changes->first_key_sym= key; 7751ab64890Smrg changes->num_key_syms= 1; 7761ab64890Smrg } 7771ab64890Smrg } 7781ab64890Smrg return Success; 7791ab64890Smrg} 7801ab64890Smrg 7811ab64890Smrg/***====================================================================***/ 7821ab64890Smrg 7831ab64890SmrgBool 7841ab64890SmrgXkbVirtualModsToReal(XkbDescPtr xkb,unsigned virtual_mask,unsigned *mask_rtrn) 7851ab64890Smrg{ 7861ab64890Smrgregister int i,bit; 7871ab64890Smrgregister unsigned mask; 7881ab64890Smrg 7891ab64890Smrg if (xkb==NULL) 7901ab64890Smrg return False; 7911ab64890Smrg if (virtual_mask==0) { 7921ab64890Smrg *mask_rtrn= 0; 7931ab64890Smrg return True; 7941ab64890Smrg } 7951ab64890Smrg if (xkb->server==NULL) 7961ab64890Smrg return False; 7971ab64890Smrg for (i=mask=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { 7981ab64890Smrg if (virtual_mask&bit) 7991ab64890Smrg mask|= xkb->server->vmods[i]; 8001ab64890Smrg } 8011ab64890Smrg *mask_rtrn= mask; 8021ab64890Smrg return True; 8031ab64890Smrg} 8041ab64890Smrg 8051ab64890Smrg/***====================================================================***/ 8061ab64890Smrg 8071ab64890SmrgBool 8081ab64890SmrgXkbUpdateActionVirtualMods(XkbDescPtr xkb,XkbAction *act,unsigned changed) 8091ab64890Smrg{ 8101ab64890Smrgunsigned int tmp; 8111ab64890Smrg 8121ab64890Smrg switch (act->type) { 8131ab64890Smrg case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods: 8141ab64890Smrg if (((tmp= XkbModActionVMods(&act->mods))&changed)!=0) { 8151ab64890Smrg XkbVirtualModsToReal(xkb,tmp,&tmp); 8161ab64890Smrg act->mods.mask= act->mods.real_mods; 8171ab64890Smrg act->mods.mask|= tmp; 8181ab64890Smrg return True; 8191ab64890Smrg } 8201ab64890Smrg break; 8211ab64890Smrg case XkbSA_ISOLock: 8221ab64890Smrg if ((((tmp= XkbModActionVMods(&act->iso))!=0)&changed)!=0) { 8231ab64890Smrg XkbVirtualModsToReal(xkb,tmp,&tmp); 8241ab64890Smrg act->iso.mask= act->iso.real_mods; 8251ab64890Smrg act->iso.mask|= tmp; 8261ab64890Smrg return True; 8271ab64890Smrg } 8281ab64890Smrg break; 8291ab64890Smrg } 8301ab64890Smrg return False; 8311ab64890Smrg} 8321ab64890Smrg 8331ab64890Smrgvoid 8341ab64890SmrgXkbUpdateKeyTypeVirtualMods( XkbDescPtr xkb, 8351ab64890Smrg XkbKeyTypePtr type, 8361ab64890Smrg unsigned int changed, 8371ab64890Smrg XkbChangesPtr changes) 8381ab64890Smrg{ 8391ab64890Smrgregister unsigned int i; 8401ab64890Smrgunsigned int mask; 8411ab64890Smrg 8421ab64890Smrg XkbVirtualModsToReal(xkb,type->mods.vmods,&mask); 8431ab64890Smrg type->mods.mask= type->mods.real_mods|mask; 8441ab64890Smrg if ((type->map_count>0)&&(type->mods.vmods!=0)) { 8451ab64890Smrg XkbKTMapEntryPtr entry; 8461ab64890Smrg for (i=0,entry=type->map;i<type->map_count;i++,entry++) { 8471ab64890Smrg if (entry->mods.vmods!=0) { 8481ab64890Smrg XkbVirtualModsToReal(xkb,entry->mods.vmods,&mask); 8491ab64890Smrg entry->mods.mask=entry->mods.real_mods|mask; 8501ab64890Smrg /* entry is active if vmods are bound*/ 8511ab64890Smrg entry->active= (mask!=0); 8521ab64890Smrg } 8531ab64890Smrg else entry->active= 1; 8541ab64890Smrg } 8551ab64890Smrg } 8561ab64890Smrg if (changes) { 8571ab64890Smrg int type_ndx; 8581ab64890Smrg type_ndx= type-xkb->map->types; 8591ab64890Smrg if ((type_ndx<0)||(type_ndx>xkb->map->num_types)) 8601ab64890Smrg return; 8611ab64890Smrg if (changes->map.changed&XkbKeyTypesMask) { 8621ab64890Smrg int last; 8631ab64890Smrg last= changes->map.first_type+changes->map.num_types-1; 8641ab64890Smrg if (type_ndx<changes->map.first_type) { 8651ab64890Smrg changes->map.first_type= type_ndx; 8661ab64890Smrg changes->map.num_types= (last-type_ndx)+1; 8671ab64890Smrg } 8681ab64890Smrg else if (type_ndx>last) { 8691ab64890Smrg changes->map.num_types= (type_ndx-changes->map.first_type)+1; 8701ab64890Smrg } 8711ab64890Smrg } 8721ab64890Smrg else { 8731ab64890Smrg changes->map.changed|= XkbKeyTypesMask; 8741ab64890Smrg changes->map.first_type= type_ndx; 8751ab64890Smrg changes->map.num_types= 1; 8761ab64890Smrg } 8771ab64890Smrg } 8781ab64890Smrg return; 8791ab64890Smrg} 8801ab64890Smrg 8811ab64890SmrgBool 8821ab64890SmrgXkbApplyVirtualModChanges(XkbDescPtr xkb,unsigned changed,XkbChangesPtr changes) 8831ab64890Smrg{ 8841ab64890Smrgregister int i; 8851ab64890Smrgunsigned int checkState = 0; 8861ab64890Smrg 8871ab64890Smrg if ((!xkb) || (!xkb->map) || (changed==0)) 8881ab64890Smrg return False; 8891ab64890Smrg for (i=0;i<xkb->map->num_types;i++) { 8901ab64890Smrg if (xkb->map->types[i].mods.vmods & changed) 8911ab64890Smrg XkbUpdateKeyTypeVirtualMods(xkb,&xkb->map->types[i],changed,changes); 8921ab64890Smrg } 8931ab64890Smrg if (changed&xkb->ctrls->internal.vmods) { 8941ab64890Smrg unsigned int newMask; 8951ab64890Smrg XkbVirtualModsToReal(xkb,xkb->ctrls->internal.vmods,&newMask); 8961ab64890Smrg newMask|= xkb->ctrls->internal.real_mods; 8971ab64890Smrg if (xkb->ctrls->internal.mask!=newMask) { 8981ab64890Smrg xkb->ctrls->internal.mask= newMask; 8991ab64890Smrg if (changes) { 9001ab64890Smrg changes->ctrls.changed_ctrls|= XkbInternalModsMask; 9011ab64890Smrg checkState= True; 9021ab64890Smrg } 9031ab64890Smrg } 9041ab64890Smrg } 9051ab64890Smrg if (changed&xkb->ctrls->ignore_lock.vmods) { 9061ab64890Smrg unsigned int newMask; 9071ab64890Smrg XkbVirtualModsToReal(xkb,xkb->ctrls->ignore_lock.vmods,&newMask); 9081ab64890Smrg newMask|= xkb->ctrls->ignore_lock.real_mods; 9091ab64890Smrg if (xkb->ctrls->ignore_lock.mask!=newMask) { 9101ab64890Smrg xkb->ctrls->ignore_lock.mask= newMask; 9111ab64890Smrg if (changes) { 9121ab64890Smrg changes->ctrls.changed_ctrls|= XkbIgnoreLockModsMask; 9131ab64890Smrg checkState= True; 9141ab64890Smrg } 9151ab64890Smrg } 9161ab64890Smrg } 9171ab64890Smrg if (xkb->indicators!=NULL) { 9181ab64890Smrg XkbIndicatorMapPtr map; 9191ab64890Smrg map= &xkb->indicators->maps[0]; 9201ab64890Smrg for (i=0;i<XkbNumIndicators;i++,map++) { 9211ab64890Smrg if (map->mods.vmods&changed) { 9221ab64890Smrg unsigned int newMask; 9231ab64890Smrg XkbVirtualModsToReal(xkb,map->mods.vmods,&newMask); 9241ab64890Smrg newMask|= map->mods.real_mods; 9251ab64890Smrg if (newMask!=map->mods.mask) { 9261ab64890Smrg map->mods.mask= newMask; 9271ab64890Smrg if (changes) { 9281ab64890Smrg changes->indicators.map_changes|= (1<<i); 9291ab64890Smrg checkState= True; 9301ab64890Smrg } 9311ab64890Smrg } 9321ab64890Smrg } 9331ab64890Smrg } 9341ab64890Smrg } 9351ab64890Smrg if (xkb->compat!=NULL) { 9361ab64890Smrg XkbCompatMapPtr compat; 9371ab64890Smrg compat= xkb->compat; 9381ab64890Smrg for (i=0;i<XkbNumKbdGroups;i++) { 9391ab64890Smrg unsigned int newMask; 9401ab64890Smrg XkbVirtualModsToReal(xkb,compat->groups[i].vmods,&newMask); 9411ab64890Smrg newMask|= compat->groups[i].real_mods; 9421ab64890Smrg if (compat->groups[i].mask!=newMask) { 9431ab64890Smrg compat->groups[i].mask= newMask; 9441ab64890Smrg if (changes) { 9451ab64890Smrg changes->compat.changed_groups|= (1<<i); 9461ab64890Smrg checkState= True; 9471ab64890Smrg } 9481ab64890Smrg } 9491ab64890Smrg } 9501ab64890Smrg } 9511ab64890Smrg if (xkb->map && xkb->server) { 9521ab64890Smrg int highChange = 0, lowChange = -1; 9531ab64890Smrg for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { 9541ab64890Smrg if (XkbKeyHasActions(xkb,i)) { 9551ab64890Smrg register XkbAction *pAct; 9561ab64890Smrg register int n; 9571ab64890Smrg 9581ab64890Smrg pAct= XkbKeyActionsPtr(xkb,i); 9591ab64890Smrg for (n=XkbKeyNumActions(xkb,i);n>0;n--,pAct++) { 9601ab64890Smrg if ((pAct->type!=XkbSA_NoAction)&& 9611ab64890Smrg XkbUpdateActionVirtualMods(xkb,pAct,changed)) { 9621ab64890Smrg if (lowChange<0) 9631ab64890Smrg lowChange= i; 9641ab64890Smrg highChange= i; 9651ab64890Smrg } 9661ab64890Smrg } 9671ab64890Smrg } 9681ab64890Smrg } 9691ab64890Smrg if (changes && (lowChange>0)) { /* something changed */ 9701ab64890Smrg if (changes->map.changed&XkbKeyActionsMask) { 9711ab64890Smrg int last; 9721ab64890Smrg if (changes->map.first_key_act<lowChange) 9731ab64890Smrg lowChange= changes->map.first_key_act; 9741ab64890Smrg last= changes->map.first_key_act+changes->map.num_key_acts-1; 9751ab64890Smrg if (last>highChange) 9761ab64890Smrg highChange= last; 9771ab64890Smrg } 9781ab64890Smrg changes->map.changed|= XkbKeyActionsMask; 9791ab64890Smrg changes->map.first_key_act= lowChange; 9801ab64890Smrg changes->map.num_key_acts= (highChange-lowChange)+1; 9811ab64890Smrg } 9821ab64890Smrg } 9831ab64890Smrg return checkState; 9841ab64890Smrg} 985