From d1e8cd61e0fa02a5b415a5c161b355c95f45ae14 Mon Sep 17 00:00:00 2001 From: marha Date: Thu, 8 Jul 2010 06:58:33 +0000 Subject: git update 8/7/2010 --- libX11/src/xkb/XKBMisc.c | 1960 +++++++++++++++++++++++----------------------- 1 file changed, 978 insertions(+), 982 deletions(-) (limited to 'libX11/src/xkb/XKBMisc.c') diff --git a/libX11/src/xkb/XKBMisc.c b/libX11/src/xkb/XKBMisc.c index 587d8f9a0..f3d1d1f1b 100644 --- a/libX11/src/xkb/XKBMisc.c +++ b/libX11/src/xkb/XKBMisc.c @@ -1,982 +1,978 @@ -/************************************************************ -Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. - -Permission to use, copy, modify, and distribute this -software and its documentation for any purpose and without -fee is hereby granted, provided that the above copyright -notice appear in all copies and that both that copyright -notice and this permission notice appear in supporting -documentation, and that the name of Silicon Graphics not be -used in advertising or publicity pertaining to distribution -of the software without specific prior written permission. -Silicon Graphics makes no representation about the suitability -of this software for any purpose. It is provided "as is" -without any express or implied warranty. - -SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON -GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH -THE USE OR PERFORMANCE OF THIS SOFTWARE. - -********************************************************/ - -#ifdef HAVE_DIX_CONFIG_H -#include -#elif defined(HAVE_CONFIG_H) -#include -#endif - -#ifndef XKB_IN_SERVER - -#include -#define NEED_REPLIES -#define NEED_EVENTS -#include "Xlibint.h" -#include -#include -#include "XKBlibint.h" - -#else - -#include -#include -#define NEED_EVENTS -#define NEED_REPLIES -#include -#include "misc.h" -#include "inputstr.h" -#include -#define XKBSRV_NEED_FILE_FUNCS -#include - -#endif /* XKB_IN_SERVER */ - -/***====================================================================***/ - -#define mapSize(m) (sizeof(m)/sizeof(XkbKTMapEntryRec)) -static XkbKTMapEntryRec map2Level[]= { - { True, ShiftMask, {1, ShiftMask, 0} } -}; - -static XkbKTMapEntryRec mapAlpha[]= { - { True, ShiftMask, { 1, ShiftMask, 0 } }, - { True, LockMask, { 0, LockMask, 0 } } -}; - -static XkbModsRec preAlpha[]= { - { 0, 0, 0 }, - { LockMask, LockMask, 0 } -}; - -#define NL_VMOD_MASK 0 -static XkbKTMapEntryRec mapKeypad[]= { - { True, ShiftMask, { 1, ShiftMask, 0 } }, - { False, 0, { 1, 0, NL_VMOD_MASK } } -}; - -static XkbKeyTypeRec canonicalTypes[XkbNumRequiredTypes] = { - { { 0, 0, 0 }, - 1, /* num_levels */ - 0, /* map_count */ - NULL, NULL, - None, NULL - }, - { { ShiftMask, ShiftMask, 0 }, - 2, /* num_levels */ - mapSize(map2Level), /* map_count */ - map2Level, NULL, - None, NULL - }, - { { ShiftMask|LockMask, ShiftMask|LockMask, 0 }, - 2, /* num_levels */ - mapSize(mapAlpha), /* map_count */ - mapAlpha, preAlpha, - None, NULL - }, - { { ShiftMask, ShiftMask, NL_VMOD_MASK }, - 2, /* num_levels */ - mapSize(mapKeypad), /* map_count */ - mapKeypad, NULL, - None, NULL - } -}; - -Status -XkbInitCanonicalKeyTypes(XkbDescPtr xkb,unsigned which,int keypadVMod) -{ -XkbClientMapPtr map; -XkbKeyTypePtr from,to; -Status rtrn; - - if (!xkb) - return BadMatch; - rtrn= XkbAllocClientMap(xkb,XkbKeyTypesMask,XkbNumRequiredTypes); - if (rtrn!=Success) - return rtrn; - map= xkb->map; - if ((which&XkbAllRequiredTypes)==0) - return Success; - rtrn= Success; - from= canonicalTypes; - to= map->types; - if (which&XkbOneLevelMask) - rtrn= XkbCopyKeyType(&from[XkbOneLevelIndex],&to[XkbOneLevelIndex]); - if ((which&XkbTwoLevelMask)&&(rtrn==Success)) - rtrn= XkbCopyKeyType(&from[XkbTwoLevelIndex],&to[XkbTwoLevelIndex]); - if ((which&XkbAlphabeticMask)&&(rtrn==Success)) - rtrn= XkbCopyKeyType(&from[XkbAlphabeticIndex],&to[XkbAlphabeticIndex]); - if ((which&XkbKeypadMask)&&(rtrn==Success)) { - XkbKeyTypePtr type; - rtrn= XkbCopyKeyType(&from[XkbKeypadIndex],&to[XkbKeypadIndex]); - type= &to[XkbKeypadIndex]; - if ((keypadVMod>=0)&&(keypadVModmods.vmods= (1<map[0].active= True; - type->map[0].mods.mask= ShiftMask; - type->map[0].mods.real_mods= ShiftMask; - type->map[0].mods.vmods= 0; - type->map[0].level= 1; - type->map[1].active= False; - type->map[1].mods.mask= 0; - type->map[1].mods.real_mods= 0; - type->map[1].mods.vmods= (1<map[1].level= 1; - } - } - return Success; -} - -/***====================================================================***/ - -#define CORE_SYM(i) (imap->num_types)) { - nSyms[i]= xkb->map->types[types_inout[i]].num_levels; - if (nSyms[i]>groupsWidth) - groupsWidth= nSyms[i]; - } - else { - types_inout[i]= XkbTwoLevelIndex; /* don't really know, yet */ - nSyms[i]= 2; - } - } - if (nSyms[XkbGroup1Index]<2) - nSyms[XkbGroup1Index]= 2; - if (nSyms[XkbGroup2Index]<2) - nSyms[XkbGroup2Index]= 2; - /* Step 2: Copy the symbols from the core ordering to XKB ordering */ - /* symbols in the core are in the order: */ - /* G1L1 G1L2 G2L1 G2L2 [G1L[3-n]] [G2L[3-n]] [G3L*] [G3L*] */ - xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,0)]= CORE_SYM(0); - xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,1)]= CORE_SYM(1); - for (i=2;i=map_width)&& - ((protected&(XkbExplicitKeyType3Mask|XkbExplicitKeyType4Mask))==0)) { - nSyms[XkbGroup3Index]= 0; - nSyms[XkbGroup4Index]= 0; - nGroups= 2; - } - else { - nGroups= 3; - for (i=0;i1)&&(syms[1]==NoSymbol)&&(syms[0]!=NoSymbol)) { - KeySym upper,lower; - XConvertCase(syms[0],&lower,&upper); - if (upper!=lower) { - xkb_syms_rtrn[XKB_OFFSET(i,0)]= lower; - xkb_syms_rtrn[XKB_OFFSET(i,1)]= upper; - if ((protected&(1<=0;i--) { - if (((empty&(1<1)&&((empty&(XkbGroup1Mask|XkbGroup2Mask))==XkbGroup2Mask)) { - if ((protected&(XkbExplicitKeyType1Mask|XkbExplicitKeyType2Mask))==0) { - nSyms[XkbGroup2Index]= nSyms[XkbGroup1Index]; - types_inout[XkbGroup2Index]= types_inout[XkbGroup1Index]; - memcpy((char *)&xkb_syms_rtrn[2],(char *)xkb_syms_rtrn, - 2*sizeof(KeySym)); - } - else if (types_inout[XkbGroup1Index]==types_inout[XkbGroup2Index]) { - memcpy((char *)&xkb_syms_rtrn[nSyms[XkbGroup1Index]], - (char *)xkb_syms_rtrn, - nSyms[XkbGroup1Index]*sizeof(KeySym)); - } - } - - /* step 7: check for all groups identical or all width 1 */ - if (nGroups>1) { - Bool sameType,allOneLevel; - allOneLevel= (xkb->map->types[types_inout[0]].num_levels==1); - for (i=1,sameType=True;(allOneLevel||sameType)&&(imap->types[types_inout[i]].num_levels==1); - } - if ((sameType)&& - (!(protected&(XkbExplicitKeyTypesMask&~XkbExplicitKeyType1Mask)))){ - register int s; - Bool identical; - for (i=1,identical=True;identical&&(i1)) { - KeySym *syms; - syms= &xkb_syms_rtrn[nSyms[XkbGroup1Index]]; - nSyms[XkbGroup1Index]= 1; - for (i=1;icompat->sym_interpret; - for (i=0;icompat->num_si;i++,interp++) { - if ((interp->sym==NoSymbol)||(sym==interp->sym)) { - int match; - if ((level==0)||((interp->match&XkbSI_LevelOneOnly)==0)) - mods= real_mods; - else mods= 0; - switch (interp->match&XkbSI_OpMask) { - case XkbSI_NoneOf: - match= ((interp->mods&mods)==0); - break; - case XkbSI_AnyOfOrNone: - match= ((mods==0)||((interp->mods&mods)!=0)); - break; - case XkbSI_AnyOf: - match= ((interp->mods&mods)!=0); - break; - case XkbSI_AllOf: - match= ((interp->mods&mods)==interp->mods); - break; - case XkbSI_Exactly: - match= (interp->mods==mods); - break; - default: - match= 0; - break; - } - if (match) { - if (interp->sym!=NoSymbol) { - return interp; - } - else if (rtrn==NULL) { - rtrn= interp; - } - } - } - } - return rtrn; -} - -static void -_XkbAddKeyChange(KeyCode *pFirst,unsigned char *pNum,KeyCode newKey) -{ -KeyCode last; - - last= (*pFirst)+(*pNum); - if (newKey<*pFirst) { - *pFirst= newKey; - *pNum= (last-newKey)+1; - } - else if (newKey>last) { - *pNum= (last-*pFirst)+1; - } - return; -} - -static void -_XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods) -{ -unsigned tmp; - - switch (act->type) { - case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods: - if (act->mods.flags&XkbSA_UseModMapMods) - act->mods.real_mods= act->mods.mask= mods; - if ((tmp= XkbModActionVMods(&act->mods))!=0) { - XkbVirtualModsToReal(xkb,tmp,&tmp); - act->mods.mask|= tmp; - } - break; - case XkbSA_ISOLock: - if (act->iso.flags&XkbSA_UseModMapMods) - act->iso.real_mods= act->iso.mask= mods; - if ((tmp= XkbModActionVMods(&act->iso))!=0) { - XkbVirtualModsToReal(xkb,tmp,&tmp); - act->iso.mask|= tmp; - } - break; - } - return; -} - -#define IBUF_SIZE 8 - -Bool -XkbApplyCompatMapToKey(XkbDescPtr xkb,KeyCode key,XkbChangesPtr changes) -{ -KeySym * syms; -unsigned char explicit,mods; -XkbSymInterpretPtr *interps,ibuf[IBUF_SIZE]; -int n,nSyms,found; -unsigned changed,tmp; - - if ((!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)|| - (!xkb->compat)||(!xkb->compat->sym_interpret)|| - (keymin_key_code)||(key>xkb->max_key_code)) { - return False; - } - if (((!xkb->server)||(!xkb->server->key_acts))&& - (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success)) { - return False; - } - changed= 0; /* keeps track of what has changed in _this_ call */ - explicit= xkb->server->explicit[key]; - if (explicit&XkbExplicitInterpretMask) /* nothing to do */ - return True; - mods= (xkb->map->modmap?xkb->map->modmap[key]:0); - nSyms= XkbKeyNumSyms(xkb,key); - syms= XkbKeySymsPtr(xkb,key); - if (nSyms>IBUF_SIZE) { - interps= _XkbTypedCalloc(nSyms,XkbSymInterpretPtr); - if (interps==NULL) { - interps= ibuf; - nSyms= IBUF_SIZE; - } - } - else { - interps= ibuf; - } - found= 0; - for (n=0;nact.type!=XkbSA_NoAction) - found++; - else interps[n]= NULL; - } - } - /* 1/28/96 (ef) -- XXX! WORKING HERE */ - if (!found) { - if (xkb->server->key_acts[key]!=0) { - xkb->server->key_acts[key]= 0; - changed|= XkbKeyActionsMask; - } - } - else { - XkbAction *pActs; - unsigned int new_vmodmask; - changed|= XkbKeyActionsMask; - pActs= XkbResizeKeyActions(xkb,key,nSyms); - if (!pActs) { - if (nSyms > IBUF_SIZE) - Xfree(interps); - return False; - } - new_vmodmask= 0; - for (n=0;nact); - if ((n==0)||((interps[n]->match&XkbSI_LevelOneOnly)==0)) { - effMods= mods; - if (interps[n]->virtual_mod!=XkbNoModifier) - new_vmodmask|= (1<virtual_mod); - } - else effMods= 0; - _XkbSetActionKeyMods(xkb,&pActs[n],effMods); - } - else pActs[n].type= XkbSA_NoAction; - } - if (((explicit&XkbExplicitVModMapMask)==0)&& - (xkb->server->vmodmap[key]!=new_vmodmask)) { - changed|= XkbVirtualModMapMask; - xkb->server->vmodmap[key]= new_vmodmask; - } - if (interps[0]) { - if ((interps[0]->flags&XkbSI_LockingKey)&& - ((explicit&XkbExplicitBehaviorMask)==0)) { - xkb->server->behaviors[key].type= XkbKB_Lock; - changed|= XkbKeyBehaviorsMask; - } - if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) { - CARD8 old; - old= xkb->ctrls->per_key_repeat[key/8]; - if (interps[0]->flags&XkbSI_AutoRepeat) - xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8)); - else xkb->ctrls->per_key_repeat[key/8]&= ~(1<<(key%8)); - if (changes && (old!=xkb->ctrls->per_key_repeat[key/8])) - changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask; - } - } - } - if ((!found)||(interps[0]==NULL)) { - if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) { - CARD8 old; - old= xkb->ctrls->per_key_repeat[key/8]; -#ifdef RETURN_SHOULD_REPEAT - if (*XkbKeySymsPtr(xkb,key) != XK_Return) -#endif - xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8)); - if (changes && (old!=xkb->ctrls->per_key_repeat[key/8])) - changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask; - } - if (((explicit&XkbExplicitBehaviorMask)==0)&& - (xkb->server->behaviors[key].type==XkbKB_Lock)) { - xkb->server->behaviors[key].type= XkbKB_Default; - changed|= XkbKeyBehaviorsMask; - } - } - if (changes) { - XkbMapChangesPtr mc; - mc= &changes->map; - tmp= (changed&mc->changed); - if (tmp&XkbKeyActionsMask) - _XkbAddKeyChange(&mc->first_key_act,&mc->num_key_acts,key); - else if (changed&XkbKeyActionsMask) { - mc->changed|= XkbKeyActionsMask; - mc->first_key_act= key; - mc->num_key_acts= 1; - } - if (tmp&XkbKeyBehaviorsMask) { - _XkbAddKeyChange(&mc->first_key_behavior,&mc->num_key_behaviors, - key); - } - else if (changed&XkbKeyBehaviorsMask) { - mc->changed|= XkbKeyBehaviorsMask; - mc->first_key_behavior= key; - mc->num_key_behaviors= 1; - } - if (tmp&XkbVirtualModMapMask) - _XkbAddKeyChange(&mc->first_vmodmap_key,&mc->num_vmodmap_keys,key); - else if (changed&XkbVirtualModMapMask) { - mc->changed|= XkbVirtualModMapMask; - mc->first_vmodmap_key= key; - mc->num_vmodmap_keys= 1; - } - mc->changed|= changed; - } - if (interps!=ibuf) - _XkbFree(interps); - return True; -} - -Bool -XkbUpdateMapFromCore( XkbDescPtr xkb, - KeyCode first_key, - int num_keys, - int map_width, - KeySym * core_keysyms, - XkbChangesPtr changes) -{ -register int key,last_key; -KeySym * syms; - - syms= &core_keysyms[(first_key-xkb->min_key_code)*map_width]; - if (changes) { - if (changes->map.changed&XkbKeySymsMask) { - _XkbAddKeyChange(&changes->map.first_key_sym, - &changes->map.num_key_syms,first_key); - if (num_keys>1) { - _XkbAddKeyChange(&changes->map.first_key_sym, - &changes->map.num_key_syms, - first_key+num_keys-1); - } - } - else { - changes->map.changed|= XkbKeySymsMask; - changes->map.first_key_sym= first_key; - changes->map.num_key_syms= num_keys; - } - } - last_key= first_key+num_keys-1; - for (key=first_key;key<=last_key;key++,syms+= map_width) { - XkbMapChangesPtr mc; - unsigned explicit; - KeySym tsyms[XkbMaxSymsPerKey]; - int types[XkbNumKbdGroups]; - int nG; - - explicit= xkb->server->explicit[key]&XkbExplicitKeyTypesMask; - types[XkbGroup1Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index); - types[XkbGroup2Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup2Index); - types[XkbGroup3Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup3Index); - types[XkbGroup4Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup4Index); - nG= XkbKeyTypesForCoreSymbols(xkb,map_width,syms,explicit,types,tsyms); - if (changes) - mc= &changes->map; - else mc= NULL; - XkbChangeTypesOfKey(xkb,key,nG,XkbAllGroupsMask,types,mc); - memcpy((char *)XkbKeySymsPtr(xkb,key),(char *)tsyms, - XkbKeyNumSyms(xkb,key)*sizeof(KeySym)); - XkbApplyCompatMapToKey(xkb,key,changes); - } - - if ((xkb->server->vmods!=NULL)&&(xkb->map->modmap!=NULL)&&(changes)&& - (changes->map.changed&(XkbVirtualModMapMask|XkbModifierMapMask))) { - unsigned char newVMods[XkbNumVirtualMods]; - register unsigned bit,i; - unsigned present; - - bzero(newVMods,XkbNumVirtualMods); - present= 0; - for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) { - if (xkb->server->vmodmap[key]==0) - continue; - for (i=0,bit=1;iserver->vmodmap[key]) { - present|= bit; - newVMods[i]|= xkb->map->modmap[key]; - } - } - } - for (i=0,bit=1;iserver->vmods[i])) { - changes->map.changed|= XkbVirtualModsMask; - changes->map.vmods|= bit; - xkb->server->vmods[i]= newVMods[i]; - } - } - } - if (changes && (changes->map.changed&XkbVirtualModsMask)) - XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes); - return True; -} - -Status -XkbChangeTypesOfKey( XkbDescPtr xkb, - int key, - int nGroups, - unsigned groups, - int * newTypesIn, - XkbMapChangesPtr changes) -{ -XkbKeyTypePtr pOldType,pNewType; -register int i; -int width,nOldGroups,oldWidth,newTypes[XkbNumKbdGroups]; - - if ((!xkb) || (!XkbKeycodeInRange(xkb,key)) || (!xkb->map) || - (!xkb->map->types)||((groups&XkbAllGroupsMask)==0)|| - (nGroups>XkbNumKbdGroups)) { - return BadMatch; - } - if (nGroups==0) { - for (i=0;imap->key_sym_map[key].kt_index[i]= XkbOneLevelIndex; - } - i= xkb->map->key_sym_map[key].group_info; - i= XkbSetNumGroups(i,0); - xkb->map->key_sym_map[key].group_info= i; - XkbResizeKeySyms(xkb,key,0); - return Success; - } - - nOldGroups= XkbKeyNumGroups(xkb,key); - oldWidth= XkbKeyGroupsWidth(xkb,key); - for (width=i=0;i0) - newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index); - else newTypes[i]= XkbTwoLevelIndex; - if (newTypes[i]>xkb->map->num_types) - return BadMatch; - pNewType= &xkb->map->types[newTypes[i]]; - if (pNewType->num_levels>width) - width= pNewType->num_levels; - } - if ((xkb->ctrls)&&(nGroups>xkb->ctrls->num_groups)) - xkb->ctrls->num_groups= nGroups; - if ((width!=oldWidth)||(nGroups!=nOldGroups)) { - KeySym oldSyms[XkbMaxSymsPerKey],*pSyms; - int nCopy; - - if (nOldGroups==0) { - pSyms= XkbResizeKeySyms(xkb,key,width*nGroups); - if (pSyms!=NULL) { - i= xkb->map->key_sym_map[key].group_info; - i= XkbSetNumGroups(i,nGroups); - xkb->map->key_sym_map[key].group_info= i; - xkb->map->key_sym_map[key].width= width; - for (i=0;imap->key_sym_map[key].kt_index[i]= newTypes[i]; - } - return Success; - } - return BadAlloc; - } - pSyms= XkbKeySymsPtr(xkb,key); - memcpy(oldSyms,pSyms,XkbKeyNumSyms(xkb,key)*sizeof(KeySym)); - pSyms= XkbResizeKeySyms(xkb,key,width*nGroups); - if (pSyms==NULL) - return BadAlloc; - bzero(pSyms,width*nGroups*sizeof(KeySym)); - for (i=0;(imap->types[newTypes[i]]; - if (pNewType->num_levels>pOldType->num_levels) - nCopy= pOldType->num_levels; - else nCopy= pNewType->num_levels; - memcpy(&pSyms[i*width],&oldSyms[i*oldWidth],nCopy*sizeof(KeySym)); - } - if (XkbKeyHasActions(xkb,key)) { - XkbAction oldActs[XkbMaxSymsPerKey],*pActs; - pActs= XkbKeyActionsPtr(xkb,key); - memcpy(oldActs,pActs,XkbKeyNumSyms(xkb,key)*sizeof(XkbAction)); - pActs= XkbResizeKeyActions(xkb,key,width*nGroups); - if (pActs==NULL) - return BadAlloc; - bzero(pActs,width*nGroups*sizeof(XkbAction)); - for (i=0;(imap->types[newTypes[i]]; - if (pNewType->num_levels>pOldType->num_levels) - nCopy= pOldType->num_levels; - else nCopy= pNewType->num_levels; - memcpy(&pActs[i*width],&oldActs[i*oldWidth], - nCopy*sizeof(XkbAction)); - } - } - i= xkb->map->key_sym_map[key].group_info; - i= XkbSetNumGroups(i,nGroups); - xkb->map->key_sym_map[key].group_info= i; - xkb->map->key_sym_map[key].width= width; - } - width= 0; - for (i=0;imap->key_sym_map[key].kt_index[i]= newTypes[i]; - if (xkb->map->types[newTypes[i]].num_levels>width) - width= xkb->map->types[newTypes[i]].num_levels; - } - xkb->map->key_sym_map[key].width= width; - if (changes!=NULL) { - if (changes->changed&XkbKeySymsMask) { - _XkbAddKeyChange(&changes->first_key_sym,&changes->num_key_syms, - key); - } - else { - changes->changed|= XkbKeySymsMask; - changes->first_key_sym= key; - changes->num_key_syms= 1; - } - } - return Success; -} - -/***====================================================================***/ - -Bool -XkbVirtualModsToReal(XkbDescPtr xkb,unsigned virtual_mask,unsigned *mask_rtrn) -{ -register int i,bit; -register unsigned mask; - - if (xkb==NULL) - return False; - if (virtual_mask==0) { - *mask_rtrn= 0; - return True; - } - if (xkb->server==NULL) - return False; - for (i=mask=0,bit=1;iserver->vmods[i]; - } - *mask_rtrn= mask; - return True; -} - -/***====================================================================***/ - -Bool -XkbUpdateActionVirtualMods(XkbDescPtr xkb,XkbAction *act,unsigned changed) -{ -unsigned int tmp; - - switch (act->type) { - case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods: - if (((tmp= XkbModActionVMods(&act->mods))&changed)!=0) { - XkbVirtualModsToReal(xkb,tmp,&tmp); - act->mods.mask= act->mods.real_mods; - act->mods.mask|= tmp; - return True; - } - break; - case XkbSA_ISOLock: - if ((((tmp= XkbModActionVMods(&act->iso))!=0)&changed)!=0) { - XkbVirtualModsToReal(xkb,tmp,&tmp); - act->iso.mask= act->iso.real_mods; - act->iso.mask|= tmp; - return True; - } - break; - } - return False; -} - -void -XkbUpdateKeyTypeVirtualMods( XkbDescPtr xkb, - XkbKeyTypePtr type, - unsigned int changed, - XkbChangesPtr changes) -{ -register unsigned int i; -unsigned int mask; - - XkbVirtualModsToReal(xkb,type->mods.vmods,&mask); - type->mods.mask= type->mods.real_mods|mask; - if ((type->map_count>0)&&(type->mods.vmods!=0)) { - XkbKTMapEntryPtr entry; - for (i=0,entry=type->map;imap_count;i++,entry++) { - if (entry->mods.vmods!=0) { - XkbVirtualModsToReal(xkb,entry->mods.vmods,&mask); - entry->mods.mask=entry->mods.real_mods|mask; - /* entry is active if vmods are bound*/ - entry->active= (mask!=0); - } - else entry->active= 1; - } - } - if (changes) { - int type_ndx; - type_ndx= type-xkb->map->types; - if ((type_ndx<0)||(type_ndx>xkb->map->num_types)) - return; - if (changes->map.changed&XkbKeyTypesMask) { - int last; - last= changes->map.first_type+changes->map.num_types-1; - if (type_ndxmap.first_type) { - changes->map.first_type= type_ndx; - changes->map.num_types= (last-type_ndx)+1; - } - else if (type_ndx>last) { - changes->map.num_types= (type_ndx-changes->map.first_type)+1; - } - } - else { - changes->map.changed|= XkbKeyTypesMask; - changes->map.first_type= type_ndx; - changes->map.num_types= 1; - } - } - return; -} - -Bool -XkbApplyVirtualModChanges(XkbDescPtr xkb,unsigned changed,XkbChangesPtr changes) -{ -register int i; -unsigned int checkState = 0; - - if ((!xkb) || (!xkb->map) || (changed==0)) - return False; - for (i=0;imap->num_types;i++) { - if (xkb->map->types[i].mods.vmods & changed) - XkbUpdateKeyTypeVirtualMods(xkb,&xkb->map->types[i],changed,changes); - } - if (changed&xkb->ctrls->internal.vmods) { - unsigned int newMask; - XkbVirtualModsToReal(xkb,xkb->ctrls->internal.vmods,&newMask); - newMask|= xkb->ctrls->internal.real_mods; - if (xkb->ctrls->internal.mask!=newMask) { - xkb->ctrls->internal.mask= newMask; - if (changes) { - changes->ctrls.changed_ctrls|= XkbInternalModsMask; - checkState= True; - } - } - } - if (changed&xkb->ctrls->ignore_lock.vmods) { - unsigned int newMask; - XkbVirtualModsToReal(xkb,xkb->ctrls->ignore_lock.vmods,&newMask); - newMask|= xkb->ctrls->ignore_lock.real_mods; - if (xkb->ctrls->ignore_lock.mask!=newMask) { - xkb->ctrls->ignore_lock.mask= newMask; - if (changes) { - changes->ctrls.changed_ctrls|= XkbIgnoreLockModsMask; - checkState= True; - } - } - } - if (xkb->indicators!=NULL) { - XkbIndicatorMapPtr map; - map= &xkb->indicators->maps[0]; - for (i=0;imods.vmods&changed) { - unsigned int newMask; - XkbVirtualModsToReal(xkb,map->mods.vmods,&newMask); - newMask|= map->mods.real_mods; - if (newMask!=map->mods.mask) { - map->mods.mask= newMask; - if (changes) { - changes->indicators.map_changes|= (1<compat!=NULL) { - XkbCompatMapPtr compat; - compat= xkb->compat; - for (i=0;igroups[i].vmods,&newMask); - newMask|= compat->groups[i].real_mods; - if (compat->groups[i].mask!=newMask) { - compat->groups[i].mask= newMask; - if (changes) { - changes->compat.changed_groups|= (1<map && xkb->server) { - int highChange = 0, lowChange = -1; - for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { - if (XkbKeyHasActions(xkb,i)) { - register XkbAction *pAct; - register int n; - - pAct= XkbKeyActionsPtr(xkb,i); - for (n=XkbKeyNumActions(xkb,i);n>0;n--,pAct++) { - if ((pAct->type!=XkbSA_NoAction)&& - XkbUpdateActionVirtualMods(xkb,pAct,changed)) { - if (lowChange<0) - lowChange= i; - highChange= i; - } - } - } - } - if (changes && (lowChange>0)) { /* something changed */ - if (changes->map.changed&XkbKeyActionsMask) { - int last; - if (changes->map.first_key_actmap.first_key_act; - last= changes->map.first_key_act+changes->map.num_key_acts-1; - if (last>highChange) - highChange= last; - } - changes->map.changed|= XkbKeyActionsMask; - changes->map.first_key_act= lowChange; - changes->map.num_key_acts= (highChange-lowChange)+1; - } - } - return checkState; -} +/************************************************************ +Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. + +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and without +fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright +notice and this permission notice appear in supporting +documentation, and that the name of Silicon Graphics not be +used in advertising or publicity pertaining to distribution +of the software without specific prior written permission. +Silicon Graphics makes no representation about the suitability +of this software for any purpose. It is provided "as is" +without any express or implied warranty. + +SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON +GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH +THE USE OR PERFORMANCE OF THIS SOFTWARE. + +********************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include +#elif defined(HAVE_CONFIG_H) +#include +#endif + +#ifndef XKB_IN_SERVER + +#include +#include "Xlibint.h" +#include +#include +#include "XKBlibint.h" + +#else + +#include +#include +#include +#include "misc.h" +#include "inputstr.h" +#include +#define XKBSRV_NEED_FILE_FUNCS +#include + +#endif /* XKB_IN_SERVER */ + +/***====================================================================***/ + +#define mapSize(m) (sizeof(m)/sizeof(XkbKTMapEntryRec)) +static XkbKTMapEntryRec map2Level[]= { + { True, ShiftMask, {1, ShiftMask, 0} } +}; + +static XkbKTMapEntryRec mapAlpha[]= { + { True, ShiftMask, { 1, ShiftMask, 0 } }, + { True, LockMask, { 0, LockMask, 0 } } +}; + +static XkbModsRec preAlpha[]= { + { 0, 0, 0 }, + { LockMask, LockMask, 0 } +}; + +#define NL_VMOD_MASK 0 +static XkbKTMapEntryRec mapKeypad[]= { + { True, ShiftMask, { 1, ShiftMask, 0 } }, + { False, 0, { 1, 0, NL_VMOD_MASK } } +}; + +static XkbKeyTypeRec canonicalTypes[XkbNumRequiredTypes] = { + { { 0, 0, 0 }, + 1, /* num_levels */ + 0, /* map_count */ + NULL, NULL, + None, NULL + }, + { { ShiftMask, ShiftMask, 0 }, + 2, /* num_levels */ + mapSize(map2Level), /* map_count */ + map2Level, NULL, + None, NULL + }, + { { ShiftMask|LockMask, ShiftMask|LockMask, 0 }, + 2, /* num_levels */ + mapSize(mapAlpha), /* map_count */ + mapAlpha, preAlpha, + None, NULL + }, + { { ShiftMask, ShiftMask, NL_VMOD_MASK }, + 2, /* num_levels */ + mapSize(mapKeypad), /* map_count */ + mapKeypad, NULL, + None, NULL + } +}; + +Status +XkbInitCanonicalKeyTypes(XkbDescPtr xkb,unsigned which,int keypadVMod) +{ +XkbClientMapPtr map; +XkbKeyTypePtr from,to; +Status rtrn; + + if (!xkb) + return BadMatch; + rtrn= XkbAllocClientMap(xkb,XkbKeyTypesMask,XkbNumRequiredTypes); + if (rtrn!=Success) + return rtrn; + map= xkb->map; + if ((which&XkbAllRequiredTypes)==0) + return Success; + rtrn= Success; + from= canonicalTypes; + to= map->types; + if (which&XkbOneLevelMask) + rtrn= XkbCopyKeyType(&from[XkbOneLevelIndex],&to[XkbOneLevelIndex]); + if ((which&XkbTwoLevelMask)&&(rtrn==Success)) + rtrn= XkbCopyKeyType(&from[XkbTwoLevelIndex],&to[XkbTwoLevelIndex]); + if ((which&XkbAlphabeticMask)&&(rtrn==Success)) + rtrn= XkbCopyKeyType(&from[XkbAlphabeticIndex],&to[XkbAlphabeticIndex]); + if ((which&XkbKeypadMask)&&(rtrn==Success)) { + XkbKeyTypePtr type; + rtrn= XkbCopyKeyType(&from[XkbKeypadIndex],&to[XkbKeypadIndex]); + type= &to[XkbKeypadIndex]; + if ((keypadVMod>=0)&&(keypadVModmods.vmods= (1<map[0].active= True; + type->map[0].mods.mask= ShiftMask; + type->map[0].mods.real_mods= ShiftMask; + type->map[0].mods.vmods= 0; + type->map[0].level= 1; + type->map[1].active= False; + type->map[1].mods.mask= 0; + type->map[1].mods.real_mods= 0; + type->map[1].mods.vmods= (1<map[1].level= 1; + } + } + return Success; +} + +/***====================================================================***/ + +#define CORE_SYM(i) (imap->num_types)) { + nSyms[i]= xkb->map->types[types_inout[i]].num_levels; + if (nSyms[i]>groupsWidth) + groupsWidth= nSyms[i]; + } + else { + types_inout[i]= XkbTwoLevelIndex; /* don't really know, yet */ + nSyms[i]= 2; + } + } + if (nSyms[XkbGroup1Index]<2) + nSyms[XkbGroup1Index]= 2; + if (nSyms[XkbGroup2Index]<2) + nSyms[XkbGroup2Index]= 2; + /* Step 2: Copy the symbols from the core ordering to XKB ordering */ + /* symbols in the core are in the order: */ + /* G1L1 G1L2 G2L1 G2L2 [G1L[3-n]] [G2L[3-n]] [G3L*] [G3L*] */ + xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,0)]= CORE_SYM(0); + xkb_syms_rtrn[XKB_OFFSET(XkbGroup1Index,1)]= CORE_SYM(1); + for (i=2;i=map_width)&& + ((protected&(XkbExplicitKeyType3Mask|XkbExplicitKeyType4Mask))==0)) { + nSyms[XkbGroup3Index]= 0; + nSyms[XkbGroup4Index]= 0; + nGroups= 2; + } + else { + nGroups= 3; + for (i=0;i1)&&(syms[1]==NoSymbol)&&(syms[0]!=NoSymbol)) { + KeySym upper,lower; + XConvertCase(syms[0],&lower,&upper); + if (upper!=lower) { + xkb_syms_rtrn[XKB_OFFSET(i,0)]= lower; + xkb_syms_rtrn[XKB_OFFSET(i,1)]= upper; + if ((protected&(1<=0;i--) { + if (((empty&(1<1)&&((empty&(XkbGroup1Mask|XkbGroup2Mask))==XkbGroup2Mask)) { + if ((protected&(XkbExplicitKeyType1Mask|XkbExplicitKeyType2Mask))==0) { + nSyms[XkbGroup2Index]= nSyms[XkbGroup1Index]; + types_inout[XkbGroup2Index]= types_inout[XkbGroup1Index]; + memcpy((char *)&xkb_syms_rtrn[2],(char *)xkb_syms_rtrn, + 2*sizeof(KeySym)); + } + else if (types_inout[XkbGroup1Index]==types_inout[XkbGroup2Index]) { + memcpy((char *)&xkb_syms_rtrn[nSyms[XkbGroup1Index]], + (char *)xkb_syms_rtrn, + nSyms[XkbGroup1Index]*sizeof(KeySym)); + } + } + + /* step 7: check for all groups identical or all width 1 */ + if (nGroups>1) { + Bool sameType,allOneLevel; + allOneLevel= (xkb->map->types[types_inout[0]].num_levels==1); + for (i=1,sameType=True;(allOneLevel||sameType)&&(imap->types[types_inout[i]].num_levels==1); + } + if ((sameType)&& + (!(protected&(XkbExplicitKeyTypesMask&~XkbExplicitKeyType1Mask)))){ + register int s; + Bool identical; + for (i=1,identical=True;identical&&(i1)) { + KeySym *syms; + syms= &xkb_syms_rtrn[nSyms[XkbGroup1Index]]; + nSyms[XkbGroup1Index]= 1; + for (i=1;icompat->sym_interpret; + for (i=0;icompat->num_si;i++,interp++) { + if ((interp->sym==NoSymbol)||(sym==interp->sym)) { + int match; + if ((level==0)||((interp->match&XkbSI_LevelOneOnly)==0)) + mods= real_mods; + else mods= 0; + switch (interp->match&XkbSI_OpMask) { + case XkbSI_NoneOf: + match= ((interp->mods&mods)==0); + break; + case XkbSI_AnyOfOrNone: + match= ((mods==0)||((interp->mods&mods)!=0)); + break; + case XkbSI_AnyOf: + match= ((interp->mods&mods)!=0); + break; + case XkbSI_AllOf: + match= ((interp->mods&mods)==interp->mods); + break; + case XkbSI_Exactly: + match= (interp->mods==mods); + break; + default: + match= 0; + break; + } + if (match) { + if (interp->sym!=NoSymbol) { + return interp; + } + else if (rtrn==NULL) { + rtrn= interp; + } + } + } + } + return rtrn; +} + +static void +_XkbAddKeyChange(KeyCode *pFirst,unsigned char *pNum,KeyCode newKey) +{ +KeyCode last; + + last= (*pFirst)+(*pNum); + if (newKey<*pFirst) { + *pFirst= newKey; + *pNum= (last-newKey)+1; + } + else if (newKey>last) { + *pNum= (last-*pFirst)+1; + } + return; +} + +static void +_XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods) +{ +unsigned tmp; + + switch (act->type) { + case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods: + if (act->mods.flags&XkbSA_UseModMapMods) + act->mods.real_mods= act->mods.mask= mods; + if ((tmp= XkbModActionVMods(&act->mods))!=0) { + XkbVirtualModsToReal(xkb,tmp,&tmp); + act->mods.mask|= tmp; + } + break; + case XkbSA_ISOLock: + if (act->iso.flags&XkbSA_UseModMapMods) + act->iso.real_mods= act->iso.mask= mods; + if ((tmp= XkbModActionVMods(&act->iso))!=0) { + XkbVirtualModsToReal(xkb,tmp,&tmp); + act->iso.mask|= tmp; + } + break; + } + return; +} + +#define IBUF_SIZE 8 + +Bool +XkbApplyCompatMapToKey(XkbDescPtr xkb,KeyCode key,XkbChangesPtr changes) +{ +KeySym * syms; +unsigned char explicit,mods; +XkbSymInterpretPtr *interps,ibuf[IBUF_SIZE]; +int n,nSyms,found; +unsigned changed,tmp; + + if ((!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)|| + (!xkb->compat)||(!xkb->compat->sym_interpret)|| + (keymin_key_code)||(key>xkb->max_key_code)) { + return False; + } + if (((!xkb->server)||(!xkb->server->key_acts))&& + (XkbAllocServerMap(xkb,XkbAllServerInfoMask,0)!=Success)) { + return False; + } + changed= 0; /* keeps track of what has changed in _this_ call */ + explicit= xkb->server->explicit[key]; + if (explicit&XkbExplicitInterpretMask) /* nothing to do */ + return True; + mods= (xkb->map->modmap?xkb->map->modmap[key]:0); + nSyms= XkbKeyNumSyms(xkb,key); + syms= XkbKeySymsPtr(xkb,key); + if (nSyms>IBUF_SIZE) { + interps= _XkbTypedCalloc(nSyms,XkbSymInterpretPtr); + if (interps==NULL) { + interps= ibuf; + nSyms= IBUF_SIZE; + } + } + else { + interps= ibuf; + } + found= 0; + for (n=0;nact.type!=XkbSA_NoAction) + found++; + else interps[n]= NULL; + } + } + /* 1/28/96 (ef) -- XXX! WORKING HERE */ + if (!found) { + if (xkb->server->key_acts[key]!=0) { + xkb->server->key_acts[key]= 0; + changed|= XkbKeyActionsMask; + } + } + else { + XkbAction *pActs; + unsigned int new_vmodmask; + changed|= XkbKeyActionsMask; + pActs= XkbResizeKeyActions(xkb,key,nSyms); + if (!pActs) { + if (nSyms > IBUF_SIZE) + Xfree(interps); + return False; + } + new_vmodmask= 0; + for (n=0;nact); + if ((n==0)||((interps[n]->match&XkbSI_LevelOneOnly)==0)) { + effMods= mods; + if (interps[n]->virtual_mod!=XkbNoModifier) + new_vmodmask|= (1<virtual_mod); + } + else effMods= 0; + _XkbSetActionKeyMods(xkb,&pActs[n],effMods); + } + else pActs[n].type= XkbSA_NoAction; + } + if (((explicit&XkbExplicitVModMapMask)==0)&& + (xkb->server->vmodmap[key]!=new_vmodmask)) { + changed|= XkbVirtualModMapMask; + xkb->server->vmodmap[key]= new_vmodmask; + } + if (interps[0]) { + if ((interps[0]->flags&XkbSI_LockingKey)&& + ((explicit&XkbExplicitBehaviorMask)==0)) { + xkb->server->behaviors[key].type= XkbKB_Lock; + changed|= XkbKeyBehaviorsMask; + } + if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) { + CARD8 old; + old= xkb->ctrls->per_key_repeat[key/8]; + if (interps[0]->flags&XkbSI_AutoRepeat) + xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8)); + else xkb->ctrls->per_key_repeat[key/8]&= ~(1<<(key%8)); + if (changes && (old!=xkb->ctrls->per_key_repeat[key/8])) + changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask; + } + } + } + if ((!found)||(interps[0]==NULL)) { + if (((explicit&XkbExplicitAutoRepeatMask)==0)&&(xkb->ctrls)) { + CARD8 old; + old= xkb->ctrls->per_key_repeat[key/8]; +#ifdef RETURN_SHOULD_REPEAT + if (*XkbKeySymsPtr(xkb,key) != XK_Return) +#endif + xkb->ctrls->per_key_repeat[key/8]|= (1<<(key%8)); + if (changes && (old!=xkb->ctrls->per_key_repeat[key/8])) + changes->ctrls.changed_ctrls|= XkbPerKeyRepeatMask; + } + if (((explicit&XkbExplicitBehaviorMask)==0)&& + (xkb->server->behaviors[key].type==XkbKB_Lock)) { + xkb->server->behaviors[key].type= XkbKB_Default; + changed|= XkbKeyBehaviorsMask; + } + } + if (changes) { + XkbMapChangesPtr mc; + mc= &changes->map; + tmp= (changed&mc->changed); + if (tmp&XkbKeyActionsMask) + _XkbAddKeyChange(&mc->first_key_act,&mc->num_key_acts,key); + else if (changed&XkbKeyActionsMask) { + mc->changed|= XkbKeyActionsMask; + mc->first_key_act= key; + mc->num_key_acts= 1; + } + if (tmp&XkbKeyBehaviorsMask) { + _XkbAddKeyChange(&mc->first_key_behavior,&mc->num_key_behaviors, + key); + } + else if (changed&XkbKeyBehaviorsMask) { + mc->changed|= XkbKeyBehaviorsMask; + mc->first_key_behavior= key; + mc->num_key_behaviors= 1; + } + if (tmp&XkbVirtualModMapMask) + _XkbAddKeyChange(&mc->first_vmodmap_key,&mc->num_vmodmap_keys,key); + else if (changed&XkbVirtualModMapMask) { + mc->changed|= XkbVirtualModMapMask; + mc->first_vmodmap_key= key; + mc->num_vmodmap_keys= 1; + } + mc->changed|= changed; + } + if (interps!=ibuf) + _XkbFree(interps); + return True; +} + +Bool +XkbUpdateMapFromCore( XkbDescPtr xkb, + KeyCode first_key, + int num_keys, + int map_width, + KeySym * core_keysyms, + XkbChangesPtr changes) +{ +register int key,last_key; +KeySym * syms; + + syms= &core_keysyms[(first_key-xkb->min_key_code)*map_width]; + if (changes) { + if (changes->map.changed&XkbKeySymsMask) { + _XkbAddKeyChange(&changes->map.first_key_sym, + &changes->map.num_key_syms,first_key); + if (num_keys>1) { + _XkbAddKeyChange(&changes->map.first_key_sym, + &changes->map.num_key_syms, + first_key+num_keys-1); + } + } + else { + changes->map.changed|= XkbKeySymsMask; + changes->map.first_key_sym= first_key; + changes->map.num_key_syms= num_keys; + } + } + last_key= first_key+num_keys-1; + for (key=first_key;key<=last_key;key++,syms+= map_width) { + XkbMapChangesPtr mc; + unsigned explicit; + KeySym tsyms[XkbMaxSymsPerKey]; + int types[XkbNumKbdGroups]; + int nG; + + explicit= xkb->server->explicit[key]&XkbExplicitKeyTypesMask; + types[XkbGroup1Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index); + types[XkbGroup2Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup2Index); + types[XkbGroup3Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup3Index); + types[XkbGroup4Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup4Index); + nG= XkbKeyTypesForCoreSymbols(xkb,map_width,syms,explicit,types,tsyms); + if (changes) + mc= &changes->map; + else mc= NULL; + XkbChangeTypesOfKey(xkb,key,nG,XkbAllGroupsMask,types,mc); + memcpy((char *)XkbKeySymsPtr(xkb,key),(char *)tsyms, + XkbKeyNumSyms(xkb,key)*sizeof(KeySym)); + XkbApplyCompatMapToKey(xkb,key,changes); + } + + if ((xkb->server->vmods!=NULL)&&(xkb->map->modmap!=NULL)&&(changes)&& + (changes->map.changed&(XkbVirtualModMapMask|XkbModifierMapMask))) { + unsigned char newVMods[XkbNumVirtualMods]; + register unsigned bit,i; + unsigned present; + + bzero(newVMods,XkbNumVirtualMods); + present= 0; + for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) { + if (xkb->server->vmodmap[key]==0) + continue; + for (i=0,bit=1;iserver->vmodmap[key]) { + present|= bit; + newVMods[i]|= xkb->map->modmap[key]; + } + } + } + for (i=0,bit=1;iserver->vmods[i])) { + changes->map.changed|= XkbVirtualModsMask; + changes->map.vmods|= bit; + xkb->server->vmods[i]= newVMods[i]; + } + } + } + if (changes && (changes->map.changed&XkbVirtualModsMask)) + XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes); + return True; +} + +Status +XkbChangeTypesOfKey( XkbDescPtr xkb, + int key, + int nGroups, + unsigned groups, + int * newTypesIn, + XkbMapChangesPtr changes) +{ +XkbKeyTypePtr pOldType,pNewType; +register int i; +int width,nOldGroups,oldWidth,newTypes[XkbNumKbdGroups]; + + if ((!xkb) || (!XkbKeycodeInRange(xkb,key)) || (!xkb->map) || + (!xkb->map->types)||((groups&XkbAllGroupsMask)==0)|| + (nGroups>XkbNumKbdGroups)) { + return BadMatch; + } + if (nGroups==0) { + for (i=0;imap->key_sym_map[key].kt_index[i]= XkbOneLevelIndex; + } + i= xkb->map->key_sym_map[key].group_info; + i= XkbSetNumGroups(i,0); + xkb->map->key_sym_map[key].group_info= i; + XkbResizeKeySyms(xkb,key,0); + return Success; + } + + nOldGroups= XkbKeyNumGroups(xkb,key); + oldWidth= XkbKeyGroupsWidth(xkb,key); + for (width=i=0;i0) + newTypes[i]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index); + else newTypes[i]= XkbTwoLevelIndex; + if (newTypes[i]>xkb->map->num_types) + return BadMatch; + pNewType= &xkb->map->types[newTypes[i]]; + if (pNewType->num_levels>width) + width= pNewType->num_levels; + } + if ((xkb->ctrls)&&(nGroups>xkb->ctrls->num_groups)) + xkb->ctrls->num_groups= nGroups; + if ((width!=oldWidth)||(nGroups!=nOldGroups)) { + KeySym oldSyms[XkbMaxSymsPerKey],*pSyms; + int nCopy; + + if (nOldGroups==0) { + pSyms= XkbResizeKeySyms(xkb,key,width*nGroups); + if (pSyms!=NULL) { + i= xkb->map->key_sym_map[key].group_info; + i= XkbSetNumGroups(i,nGroups); + xkb->map->key_sym_map[key].group_info= i; + xkb->map->key_sym_map[key].width= width; + for (i=0;imap->key_sym_map[key].kt_index[i]= newTypes[i]; + } + return Success; + } + return BadAlloc; + } + pSyms= XkbKeySymsPtr(xkb,key); + memcpy(oldSyms,pSyms,XkbKeyNumSyms(xkb,key)*sizeof(KeySym)); + pSyms= XkbResizeKeySyms(xkb,key,width*nGroups); + if (pSyms==NULL) + return BadAlloc; + bzero(pSyms,width*nGroups*sizeof(KeySym)); + for (i=0;(imap->types[newTypes[i]]; + if (pNewType->num_levels>pOldType->num_levels) + nCopy= pOldType->num_levels; + else nCopy= pNewType->num_levels; + memcpy(&pSyms[i*width],&oldSyms[i*oldWidth],nCopy*sizeof(KeySym)); + } + if (XkbKeyHasActions(xkb,key)) { + XkbAction oldActs[XkbMaxSymsPerKey],*pActs; + pActs= XkbKeyActionsPtr(xkb,key); + memcpy(oldActs,pActs,XkbKeyNumSyms(xkb,key)*sizeof(XkbAction)); + pActs= XkbResizeKeyActions(xkb,key,width*nGroups); + if (pActs==NULL) + return BadAlloc; + bzero(pActs,width*nGroups*sizeof(XkbAction)); + for (i=0;(imap->types[newTypes[i]]; + if (pNewType->num_levels>pOldType->num_levels) + nCopy= pOldType->num_levels; + else nCopy= pNewType->num_levels; + memcpy(&pActs[i*width],&oldActs[i*oldWidth], + nCopy*sizeof(XkbAction)); + } + } + i= xkb->map->key_sym_map[key].group_info; + i= XkbSetNumGroups(i,nGroups); + xkb->map->key_sym_map[key].group_info= i; + xkb->map->key_sym_map[key].width= width; + } + width= 0; + for (i=0;imap->key_sym_map[key].kt_index[i]= newTypes[i]; + if (xkb->map->types[newTypes[i]].num_levels>width) + width= xkb->map->types[newTypes[i]].num_levels; + } + xkb->map->key_sym_map[key].width= width; + if (changes!=NULL) { + if (changes->changed&XkbKeySymsMask) { + _XkbAddKeyChange(&changes->first_key_sym,&changes->num_key_syms, + key); + } + else { + changes->changed|= XkbKeySymsMask; + changes->first_key_sym= key; + changes->num_key_syms= 1; + } + } + return Success; +} + +/***====================================================================***/ + +Bool +XkbVirtualModsToReal(XkbDescPtr xkb,unsigned virtual_mask,unsigned *mask_rtrn) +{ +register int i,bit; +register unsigned mask; + + if (xkb==NULL) + return False; + if (virtual_mask==0) { + *mask_rtrn= 0; + return True; + } + if (xkb->server==NULL) + return False; + for (i=mask=0,bit=1;iserver->vmods[i]; + } + *mask_rtrn= mask; + return True; +} + +/***====================================================================***/ + +Bool +XkbUpdateActionVirtualMods(XkbDescPtr xkb,XkbAction *act,unsigned changed) +{ +unsigned int tmp; + + switch (act->type) { + case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods: + if (((tmp= XkbModActionVMods(&act->mods))&changed)!=0) { + XkbVirtualModsToReal(xkb,tmp,&tmp); + act->mods.mask= act->mods.real_mods; + act->mods.mask|= tmp; + return True; + } + break; + case XkbSA_ISOLock: + if ((((tmp= XkbModActionVMods(&act->iso))!=0)&changed)!=0) { + XkbVirtualModsToReal(xkb,tmp,&tmp); + act->iso.mask= act->iso.real_mods; + act->iso.mask|= tmp; + return True; + } + break; + } + return False; +} + +void +XkbUpdateKeyTypeVirtualMods( XkbDescPtr xkb, + XkbKeyTypePtr type, + unsigned int changed, + XkbChangesPtr changes) +{ +register unsigned int i; +unsigned int mask; + + XkbVirtualModsToReal(xkb,type->mods.vmods,&mask); + type->mods.mask= type->mods.real_mods|mask; + if ((type->map_count>0)&&(type->mods.vmods!=0)) { + XkbKTMapEntryPtr entry; + for (i=0,entry=type->map;imap_count;i++,entry++) { + if (entry->mods.vmods!=0) { + XkbVirtualModsToReal(xkb,entry->mods.vmods,&mask); + entry->mods.mask=entry->mods.real_mods|mask; + /* entry is active if vmods are bound*/ + entry->active= (mask!=0); + } + else entry->active= 1; + } + } + if (changes) { + int type_ndx; + type_ndx= type-xkb->map->types; + if ((type_ndx<0)||(type_ndx>xkb->map->num_types)) + return; + if (changes->map.changed&XkbKeyTypesMask) { + int last; + last= changes->map.first_type+changes->map.num_types-1; + if (type_ndxmap.first_type) { + changes->map.first_type= type_ndx; + changes->map.num_types= (last-type_ndx)+1; + } + else if (type_ndx>last) { + changes->map.num_types= (type_ndx-changes->map.first_type)+1; + } + } + else { + changes->map.changed|= XkbKeyTypesMask; + changes->map.first_type= type_ndx; + changes->map.num_types= 1; + } + } + return; +} + +Bool +XkbApplyVirtualModChanges(XkbDescPtr xkb,unsigned changed,XkbChangesPtr changes) +{ +register int i; +unsigned int checkState = 0; + + if ((!xkb) || (!xkb->map) || (changed==0)) + return False; + for (i=0;imap->num_types;i++) { + if (xkb->map->types[i].mods.vmods & changed) + XkbUpdateKeyTypeVirtualMods(xkb,&xkb->map->types[i],changed,changes); + } + if (changed&xkb->ctrls->internal.vmods) { + unsigned int newMask; + XkbVirtualModsToReal(xkb,xkb->ctrls->internal.vmods,&newMask); + newMask|= xkb->ctrls->internal.real_mods; + if (xkb->ctrls->internal.mask!=newMask) { + xkb->ctrls->internal.mask= newMask; + if (changes) { + changes->ctrls.changed_ctrls|= XkbInternalModsMask; + checkState= True; + } + } + } + if (changed&xkb->ctrls->ignore_lock.vmods) { + unsigned int newMask; + XkbVirtualModsToReal(xkb,xkb->ctrls->ignore_lock.vmods,&newMask); + newMask|= xkb->ctrls->ignore_lock.real_mods; + if (xkb->ctrls->ignore_lock.mask!=newMask) { + xkb->ctrls->ignore_lock.mask= newMask; + if (changes) { + changes->ctrls.changed_ctrls|= XkbIgnoreLockModsMask; + checkState= True; + } + } + } + if (xkb->indicators!=NULL) { + XkbIndicatorMapPtr map; + map= &xkb->indicators->maps[0]; + for (i=0;imods.vmods&changed) { + unsigned int newMask; + XkbVirtualModsToReal(xkb,map->mods.vmods,&newMask); + newMask|= map->mods.real_mods; + if (newMask!=map->mods.mask) { + map->mods.mask= newMask; + if (changes) { + changes->indicators.map_changes|= (1<compat!=NULL) { + XkbCompatMapPtr compat; + compat= xkb->compat; + for (i=0;igroups[i].vmods,&newMask); + newMask|= compat->groups[i].real_mods; + if (compat->groups[i].mask!=newMask) { + compat->groups[i].mask= newMask; + if (changes) { + changes->compat.changed_groups|= (1<map && xkb->server) { + int highChange = 0, lowChange = -1; + for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { + if (XkbKeyHasActions(xkb,i)) { + register XkbAction *pAct; + register int n; + + pAct= XkbKeyActionsPtr(xkb,i); + for (n=XkbKeyNumActions(xkb,i);n>0;n--,pAct++) { + if ((pAct->type!=XkbSA_NoAction)&& + XkbUpdateActionVirtualMods(xkb,pAct,changed)) { + if (lowChange<0) + lowChange= i; + highChange= i; + } + } + } + } + if (changes && (lowChange>0)) { /* something changed */ + if (changes->map.changed&XkbKeyActionsMask) { + int last; + if (changes->map.first_key_actmap.first_key_act; + last= changes->map.first_key_act+changes->map.num_key_acts-1; + if (last>highChange) + highChange= last; + } + changes->map.changed|= XkbKeyActionsMask; + changes->map.first_key_act= lowChange; + changes->map.num_key_acts= (highChange-lowChange)+1; + } + } + return checkState; +} -- cgit v1.2.3