/* $Xorg: xkbUtils.c,v 1.3 2000/08/17 19:53:48 cpqbld Exp $ */ /************************************************************ 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. ********************************************************/ /* $XFree86: xc/programs/Xserver/xkb/xkbUtils.c,v 3.13 2001/08/23 14:33:26 alanh Exp $ */ #include #include #include #define NEED_EVENTS 1 #include #include #define XK_CYRILLIC #include #include "misc.h" #include "inputstr.h" #define XKBSRV_NEED_FILE_FUNCS #include "XKBsrv.h" #include "extensions/XKBgeom.h" #ifdef MODE_SWITCH extern Bool noKME; /* defined in os/utils.c */ #endif int XkbDisableLockActions = 0; /***====================================================================***/ #ifndef RETURN_SHOULD_REPEAT #if (defined(__osf__) && defined(__alpha)) #define RETURN_SHOULD_REPEAT 1 #else #define RETURN_SHOULD_REPEAT 0 #endif #endif /***====================================================================***/ DeviceIntPtr #if NeedFunctionPrototypes _XkbLookupAnyDevice(int id,int *why_rtrn) #else _XkbLookupAnyDevice(id,why_rtrn) int id; int *why_rtrn; #endif { DeviceIntPtr dev = NULL; dev= (DeviceIntPtr)LookupKeyboardDevice(); if ((id==XkbUseCoreKbd)||(dev->id==id)) return dev; dev= (DeviceIntPtr)LookupPointerDevice(); if ((id==XkbUseCorePtr)||(dev->id==id)) return dev; if (id&(~0xff)) dev = NULL; dev= (DeviceIntPtr)LookupDevice(id); if (dev!=NULL) return dev; if ((!dev)&&(why_rtrn)) *why_rtrn= XkbErr_BadDevice; return dev; } DeviceIntPtr #if NeedFunctionPrototypes _XkbLookupKeyboard(int id,int *why_rtrn) #else _XkbLookupKeyboard(id,why_rtrn) int id; int *why_rtrn; #endif { DeviceIntPtr dev = NULL; if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL) return NULL; else if ((!dev->key)||(!dev->key->xkbInfo)) { if (why_rtrn) *why_rtrn= XkbErr_BadClass; return NULL; } return dev; } DeviceIntPtr #if NeedFunctionPrototypes _XkbLookupBellDevice(int id,int *why_rtrn) #else _XkbLookupBellDevice(id,why_rtrn) int id; int *why_rtrn; #endif { DeviceIntPtr dev = NULL; if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL) return NULL; else if ((!dev->kbdfeed)&&(!dev->bell)) { if (why_rtrn) *why_rtrn= XkbErr_BadClass; return NULL; } return dev; } DeviceIntPtr #if NeedFunctionPrototypes _XkbLookupLedDevice(int id,int *why_rtrn) #else _XkbLookupLedDevice(id,why_rtrn) int id; int *why_rtrn; #endif { DeviceIntPtr dev = NULL; if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL) return NULL; else if ((!dev->kbdfeed)&&(!dev->leds)) { if (why_rtrn) *why_rtrn= XkbErr_BadClass; return NULL; } return dev; } DeviceIntPtr #if NeedFunctionPrototypes _XkbLookupButtonDevice(int id,int *why_rtrn) #else _XkbLookupButtonDevice(id,why_rtrn) int id; int *why_rtrn; #endif { DeviceIntPtr dev = NULL; if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL) return NULL; else if (!dev->button) { if (why_rtrn) *why_rtrn= XkbErr_BadClass; return NULL; } return dev; } void #if NeedFunctionPrototypes XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods) #else XkbSetActionKeyMods(xkb,act,mods) XkbDescPtr xkb; XkbAction * act; unsigned mods; #endif { register 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) act->mods.mask|= XkbMaskForVMask(xkb,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) act->iso.mask|= XkbMaskForVMask(xkb,tmp); break; } return; } unsigned #if NeedFunctionPrototypes XkbMaskForVMask(XkbDescPtr xkb,unsigned vmask) #else XkbMaskForVMask(xkb,vmask) XkbDescPtr xkb; unsigned vmask; #endif { register int i,bit; register unsigned mask; for (mask=i=0,bit=1;iserver->vmods[i]; } return mask; } Bool #if NeedFunctionPrototypes XkbApplyVModChanges( XkbSrvInfoPtr xkbi, unsigned changed, XkbChangesPtr changes, unsigned * needChecksRtrn, XkbEventCausePtr cause) #else XkbApplyVModChanges(xkbi,changed,changes,needChecksRtrn,cause) XkbSrvInfoPtr xkbi; unsigned changed; XkbChangesPtr changes; unsigned * needChecksRtrn; XkbEventCausePtr cause; #endif { XkbDescPtr xkb; Bool check; xkb= xkbi->desc; #ifdef DEBUG { register unsigned i,bit; for (i=0,bit=1;iserver->vmods[i]); } } #endif check= XkbApplyVirtualModChanges(xkb,changed,changes); XkbApplyVModChangesToAllDevices(xkbi->device,xkb,changed,cause); if (needChecksRtrn!=NULL) { if (check) *needChecksRtrn= XkbStateNotifyMask|XkbIndicatorStateNotifyMask; else *needChecksRtrn= 0; } else if (check) { /* 7/12/95 (ef) -- XXX check compatibility and/or indicator state */ } return 1; } /***====================================================================***/ #if NeedFunctionPrototypes void XkbUpdateKeyTypesFromCore( DeviceIntPtr pXDev, KeyCode first, CARD8 num, XkbChangesPtr changes) #else void XkbUpdateKeyTypesFromCore(pXDev,first,num,changes) DeviceIntPtr pXDev; KeyCode first; CARD8 num; XkbChangesPtr changes; #endif { XkbDescPtr xkb; unsigned key,nG,explicit; KeySymsPtr pCore; int types[XkbNumKbdGroups]; KeySym tsyms[XkbMaxSymsPerKey],*syms; XkbMapChangesPtr mc; xkb= pXDev->key->xkbInfo->desc; #ifdef NOTYET if (firstmin_key_code) { if (first>=XkbMinLegalKeyCode) { xkb->min_key_code= first; /* 1/12/95 (ef) -- XXX! should zero out the new maps */ changes->map.changed|= XkbKeycodesMask; generate a NewKeyboard notify here? } } #endif if (first+num-1>xkb->max_key_code) { /* 1/12/95 (ef) -- XXX! should allow XKB structures to grow */ num= xkb->max_key_code-first+1; } mc= (changes?(&changes->map):NULL); pCore= &pXDev->key->curKeySyms; syms= &pCore->map[(first-xkb->min_key_code)*pCore->mapWidth]; for (key=first; key<(first+num); key++,syms+= pCore->mapWidth) { 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,pCore->mapWidth,syms,explicit,types, tsyms); XkbChangeTypesOfKey(xkb,key,nG,XkbAllGroupsMask,types,mc); memcpy((char *)XkbKeySymsPtr(xkb,key),(char *)tsyms, XkbKeyNumSyms(xkb,key)*sizeof(KeySym)); } if (changes->map.changed&XkbKeySymsMask) { CARD8 oldLast,newLast; oldLast = changes->map.first_key_sym+changes->map.num_key_syms-1; newLast = first+num-1; if (firstmap.first_key_sym) changes->map.first_key_sym = first; if (oldLast>newLast) newLast= oldLast; changes->map.num_key_syms = newLast-changes->map.first_key_sym+1; } else { changes->map.changed|= XkbKeySymsMask; changes->map.first_key_sym = first; changes->map.num_key_syms = num; } return; } void #if NeedFunctionPrototypes XkbUpdateDescActions( XkbDescPtr xkb, KeyCode first, CARD8 num, XkbChangesPtr changes) #else XkbUpdateDescActions(xkb,first,num,changes) XkbDescPtr xkb; KeyCode first; CARD8 num; XkbChangesPtr changes; #endif { register unsigned key; for (key=first;key<(first+num);key++) { XkbApplyCompatMapToKey(xkb,key,changes); } if (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->map.changed&XkbVirtualModsMask) XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes); if (changes->map.changed&XkbKeyActionsMask) { CARD8 oldLast,newLast; oldLast= changes->map.first_key_act+changes->map.num_key_acts-1; newLast = first+num-1; if (firstmap.first_key_act) changes->map.first_key_act = first; if (newLast>oldLast) newLast= oldLast; changes->map.num_key_acts= newLast-changes->map.first_key_act+1; } else { changes->map.changed|= XkbKeyActionsMask; changes->map.first_key_act = first; changes->map.num_key_acts = num; } return; } #if NeedFunctionPrototypes void XkbUpdateActions( DeviceIntPtr pXDev, KeyCode first, CARD8 num, XkbChangesPtr changes, unsigned * needChecksRtrn, XkbEventCausePtr cause) #else void XkbUpdateActions(pXDev,first,num,changes,needChecksRtrn,cause) DeviceIntPtr pXDev; KeyCode first; CARD8 num; XkbChangesPtr changes; unsigned * needChecksRtrn; XkbEventCausePtr cause; #endif { XkbSrvInfoPtr xkbi; XkbDescPtr xkb; CARD8 * repeat; if (needChecksRtrn) *needChecksRtrn= 0; xkbi= pXDev->key->xkbInfo; xkb= xkbi->desc; repeat= xkb->ctrls->per_key_repeat; if (pXDev->kbdfeed) memcpy(repeat,pXDev->kbdfeed->ctrl.autoRepeats,32); XkbUpdateDescActions(xkb,first,num,changes); if ((pXDev->kbdfeed)&& (changes->ctrls.enabled_ctrls_changes&XkbPerKeyRepeatMask)) { memcpy(pXDev->kbdfeed->ctrl.autoRepeats,repeat, 32); (*pXDev->kbdfeed->CtrlProc)(pXDev, &pXDev->kbdfeed->ctrl); } return; } void #if NeedFunctionPrototypes XkbUpdateCoreDescription(DeviceIntPtr keybd,Bool resize) #else XkbUpdateCoreDescription(keybd,resize) DeviceIntPtr keybd; Bool resize; #endif { register int key,tmp; int maxSymsPerKey,maxKeysPerMod; int first,last,firstCommon,lastCommon; XkbDescPtr xkb; KeyClassPtr keyc; CARD8 keysPerMod[XkbNumModifiers]; if (!keybd || !keybd->key || !keybd->key->xkbInfo) return; xkb= keybd->key->xkbInfo->desc; keyc= keybd->key; maxSymsPerKey= maxKeysPerMod= 0; bzero(keysPerMod,sizeof(keysPerMod)); memcpy(keyc->modifierMap,xkb->map->modmap,xkb->max_key_code+1); if ((xkb->min_key_code==keyc->curKeySyms.minKeyCode)&& (xkb->max_key_code==keyc->curKeySyms.maxKeyCode)) { first= firstCommon= xkb->min_key_code; last= lastCommon= xkb->max_key_code; } else if (resize) { keyc->curKeySyms.minKeyCode= xkb->min_key_code; keyc->curKeySyms.maxKeyCode= xkb->max_key_code; tmp= keyc->curKeySyms.mapWidth*_XkbCoreNumKeys(keyc); keyc->curKeySyms.map= _XkbTypedRealloc(keyc->curKeySyms.map,tmp,KeySym); if (!keyc->curKeySyms.map) FatalError("Couldn't allocate keysyms\n"); first= firstCommon= xkb->min_key_code; last= lastCommon= xkb->max_key_code; } else { if (xkb->min_key_codecurKeySyms.minKeyCode) { first= xkb->min_key_code; firstCommon= keyc->curKeySyms.minKeyCode; } else { firstCommon= xkb->min_key_code; first= keyc->curKeySyms.minKeyCode; } if (xkb->max_key_code>keyc->curKeySyms.maxKeyCode) { lastCommon= keyc->curKeySyms.maxKeyCode; last= xkb->max_key_code; } else { lastCommon= xkb->max_key_code; last= keyc->curKeySyms.maxKeyCode; } } /* determine sizes */ for (key=first;key<=last;key++) { if (XkbKeycodeInRange(xkb,key)) { int nGroups; int w; nGroups= XkbKeyNumGroups(xkb,key); tmp= 0; if (nGroups>0) { if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup1Index))<2) tmp+= 2; else tmp+= w; } if (nGroups>1) { if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup2Index))<2) tmp+= 2; else tmp+= w; } if (nGroups>2) tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup3Index); if (nGroups>3) tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup4Index); if (tmp>maxSymsPerKey) maxSymsPerKey= tmp; } if (_XkbCoreKeycodeInRange(keyc,key)) { if (keyc->modifierMap[key]!=0) { register unsigned bit,i,mask; mask= keyc->modifierMap[key]; for (i=0,bit=1;imaxKeysPerMod) maxKeysPerMod= keysPerMod[i]; } } } } } if (maxKeysPerMod>0) { tmp= maxKeysPerMod*XkbNumModifiers; if (keyc->modifierKeyMap==NULL) keyc->modifierKeyMap= (KeyCode *)_XkbCalloc(1, tmp); else if (keyc->maxKeysPerModifiermodifierKeyMap= (KeyCode *)_XkbRealloc(keyc->modifierKeyMap,tmp); if (keyc->modifierKeyMap==NULL) FatalError("Couldn't allocate modifierKeyMap in UpdateCore\n"); bzero(keyc->modifierKeyMap,tmp); } else if ((keyc->maxKeysPerModifier>0)&&(keyc->modifierKeyMap!=NULL)) { _XkbFree(keyc->modifierKeyMap); keyc->modifierKeyMap= NULL; } keyc->maxKeysPerModifier= maxKeysPerMod; if (maxSymsPerKey>0) { tmp= maxSymsPerKey*_XkbCoreNumKeys(keyc); keyc->curKeySyms.map= _XkbTypedRealloc(keyc->curKeySyms.map,tmp,KeySym); if (keyc->curKeySyms.map==NULL) FatalError("Couldn't allocate symbols map in UpdateCore\n"); } else if ((keyc->curKeySyms.mapWidth>0)&&(keyc->curKeySyms.map!=NULL)) { _XkbFree(keyc->curKeySyms.map); keyc->curKeySyms.map= NULL; } keyc->curKeySyms.mapWidth= maxSymsPerKey; bzero(keysPerMod,sizeof(keysPerMod)); for (key=firstCommon;key<=lastCommon;key++) { if (keyc->curKeySyms.map!=NULL) { KeySym *pCore,*pXKB; unsigned nGroups,groupWidth,n,nOut; nGroups= XkbKeyNumGroups(xkb,key); n= (key-keyc->curKeySyms.minKeyCode)*maxSymsPerKey; pCore= &keyc->curKeySyms.map[n]; bzero(pCore,maxSymsPerKey*sizeof(KeySym)); pXKB= XkbKeySymsPtr(xkb,key); nOut= 2; if (nGroups>0) { groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup1Index); if (groupWidth>0) pCore[0]= pXKB[0]; if (groupWidth>1) pCore[1]= pXKB[1]; for (n=2;n2) nOut= groupWidth; } pXKB+= XkbKeyGroupsWidth(xkb,key); nOut+= 2; if (nGroups>1) { groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup2Index); if (groupWidth>0) pCore[2]= pXKB[0]; if (groupWidth>1) pCore[3]= pXKB[1]; for (n=2;n2) nOut+= (groupWidth-2); } pXKB+= XkbKeyGroupsWidth(xkb,key); for (n=XkbGroup3Index;nmodifierMap[key]!=0) { register unsigned bit,i,mask; mask= keyc->modifierMap[key]; for (i=0,bit=1;imodifierKeyMap[tmp]= key; keysPerMod[i]++; } } } } #ifdef MODE_SWITCH /* Fix up any of the KME stuff if we changed the core description. */ if (!noKME) HandleKeyBinding(keyc, &keyc->curKeySyms); #endif return; } void #if NeedFunctionPrototypes XkbSetRepeatKeys(DeviceIntPtr pXDev,int key,int onoff) #else XkbSetRepeatKeys(pXDev,key,onoff) DeviceIntPtr pXDev; int key; int onoff; #endif { if (pXDev && pXDev->key && pXDev->key->xkbInfo) { xkbControlsNotify cn; XkbControlsPtr ctrls = pXDev->key->xkbInfo->desc->ctrls; XkbControlsRec old; old = *ctrls; if (key== -1) { /* global autorepeat setting changed */ if (onoff) ctrls->enabled_ctrls |= XkbRepeatKeysMask; else ctrls->enabled_ctrls &= ~XkbRepeatKeysMask; } else if (pXDev->kbdfeed) { ctrls->per_key_repeat[key/8] = pXDev->kbdfeed->ctrl.autoRepeats[key/8]; } if (XkbComputeControlsNotify(pXDev,&old,ctrls,&cn,True)) XkbSendControlsNotify(pXDev,&cn); } return; } #if NeedFunctionPrototypes void XkbApplyMappingChange( DeviceIntPtr kbd, CARD8 request, KeyCode firstKey, CARD8 num, ClientPtr client) #else void XkbApplyMappingChange(kbd,request,firstKey,num,client) DeviceIntPtr kbd; CARD8 request; KeyCode firstKey; CARD8 num; ClientPtr client; #endif { XkbEventCauseRec cause; XkbChangesRec changes; unsigned check; if (kbd->key->xkbInfo==NULL) XkbInitDevice(kbd); bzero(&changes,sizeof(XkbChangesRec)); check= 0; if (request==MappingKeyboard) { XkbSetCauseCoreReq(&cause,X_ChangeKeyboardMapping,client); XkbUpdateKeyTypesFromCore(kbd,firstKey,num,&changes); XkbUpdateActions(kbd,firstKey,num,&changes,&check,&cause); if (check) XkbCheckSecondaryEffects(kbd->key->xkbInfo,check,&changes,&cause); } else if (request==MappingModifier) { XkbDescPtr xkb= kbd->key->xkbInfo->desc; XkbSetCauseCoreReq(&cause,X_SetModifierMapping,client); num = xkb->max_key_code-xkb->min_key_code+1; memcpy(xkb->map->modmap,kbd->key->modifierMap,xkb->max_key_code+1); changes.map.changed|= XkbModifierMapMask; changes.map.first_modmap_key= xkb->min_key_code; changes.map.num_modmap_keys= num; XkbUpdateActions(kbd,xkb->min_key_code,num,&changes,&check,&cause); if (check) XkbCheckSecondaryEffects(kbd->key->xkbInfo,check,&changes,&cause); } /* 3/26/94 (ef) -- XXX! Doesn't deal with input extension requests */ XkbSendNotification(kbd,&changes,&cause); return; } void #if NeedFunctionPrototypes XkbDisableComputedAutoRepeats(DeviceIntPtr dev,unsigned key) #else XkbDisableComputedAutoRepeats(dev,key) DeviceIntPtr dev; unsigned key; #endif { XkbSrvInfoPtr xkbi = dev->key->xkbInfo; xkbMapNotify mn; xkbi->desc->server->explicit[key]|= XkbExplicitAutoRepeatMask; bzero(&mn,sizeof(mn)); mn.changed= XkbExplicitComponentsMask; mn.firstKeyExplicit= key; mn.nKeyExplicit= 1; XkbSendMapNotify(dev,&mn); return; } unsigned #if NeedFunctionPrototypes XkbStateChangedFlags(XkbStatePtr old,XkbStatePtr new) #else XkbStateChangedFlags(old,new) XkbStatePtr old; XkbStatePtr new; #endif { int changed; changed=(old->group!=new->group?XkbGroupStateMask:0); changed|=(old->base_group!=new->base_group?XkbGroupBaseMask:0); changed|=(old->latched_group!=new->latched_group?XkbGroupLatchMask:0); changed|=(old->locked_group!=new->locked_group?XkbGroupLockMask:0); changed|=(old->mods!=new->mods?XkbModifierStateMask:0); changed|=(old->base_mods!=new->base_mods?XkbModifierBaseMask:0); changed|=(old->latched_mods!=new->latched_mods?XkbModifierLatchMask:0); changed|=(old->locked_mods!=new->locked_mods?XkbModifierLockMask:0); changed|=(old->compat_state!=new->compat_state?XkbCompatStateMask:0); changed|=(old->grab_mods!=new->grab_mods?XkbGrabModsMask:0); if (old->compat_grab_mods!=new->compat_grab_mods) changed|= XkbCompatGrabModsMask; changed|=(old->lookup_mods!=new->lookup_mods?XkbLookupModsMask:0); if (old->compat_lookup_mods!=new->compat_lookup_mods) changed|= XkbCompatLookupModsMask; changed|=(old->ptr_buttons!=new->ptr_buttons?XkbPointerButtonMask:0); return changed; } void #if NeedFunctionPrototypes XkbComputeCompatState(XkbSrvInfoPtr xkbi) #else XkbComputeCompatState(xkbi) XkbSrvInfoPtr xkbi; #endif { CARD16 grp_mask; XkbStatePtr state= &xkbi->state; XkbCompatMapPtr map; map= xkbi->desc->compat; grp_mask= map->groups[state->group].mask; state->compat_state = state->mods|grp_mask; state->compat_lookup_mods= state->lookup_mods|grp_mask; if (xkbi->desc->ctrls->enabled_ctrls&XkbIgnoreGroupLockMask) grp_mask= map->groups[state->base_group].mask; state->compat_grab_mods= state->grab_mods|grp_mask; return; } unsigned #if NeedFunctionPrototypes XkbAdjustGroup(int group,XkbControlsPtr ctrls) #else XkbAdjustGroup(group,ctrls) int group; XkbControlsPtr ctrls; #endif { unsigned act; act= XkbOutOfRangeGroupAction(ctrls->groups_wrap); if (group<0) { while ( group < 0 ) { if (act==XkbClampIntoRange) { group= XkbGroup1Index; } else if (act==XkbRedirectIntoRange) { int newGroup; newGroup= XkbOutOfRangeGroupNumber(ctrls->groups_wrap); if (newGroup>=ctrls->num_groups) group= XkbGroup1Index; else group= newGroup; } else { group+= ctrls->num_groups; } } } else if (group>=ctrls->num_groups) { if (act==XkbClampIntoRange) { group= ctrls->num_groups-1; } else if (act==XkbRedirectIntoRange) { int newGroup; newGroup= XkbOutOfRangeGroupNumber(ctrls->groups_wrap); if (newGroup>=ctrls->num_groups) group= XkbGroup1Index; else group= newGroup; } else { group%= ctrls->num_groups; } } return group; } void #if NeedFunctionPrototypes XkbComputeDerivedState(XkbSrvInfoPtr xkbi) #else XkbComputeDerivedState(xkbi) XkbSrvInfoPtr xkbi; #endif { XkbStatePtr state= &xkbi->state; XkbControlsPtr ctrls= xkbi->desc->ctrls; char grp; state->mods= (state->base_mods|state->latched_mods); state->mods|= state->locked_mods; state->lookup_mods= state->mods&(~ctrls->internal.mask); state->grab_mods= state->lookup_mods&(~ctrls->ignore_lock.mask); state->grab_mods|= ((state->base_mods|state->latched_mods)&ctrls->ignore_lock.mask); grp= state->locked_group; if ((grp>=ctrls->num_groups) || (grp<0)) state->locked_group= XkbAdjustGroup(grp,ctrls); grp= state->locked_group+state->base_group+state->latched_group; if ((grp>=ctrls->num_groups) || (grp<0)) state->group= XkbAdjustGroup(grp,ctrls); else state->group= grp; XkbComputeCompatState(xkbi); return; } /***====================================================================***/ void #if NeedFunctionPrototypes XkbCheckSecondaryEffects( XkbSrvInfoPtr xkbi, unsigned which, XkbChangesPtr changes, XkbEventCausePtr cause) #else XkbCheckSecondaryEffects(xkbi,which,changes,cause) XkbSrvInfoPtr xkbi; unsigned which; XkbChangesPtr changes; XkbEventCausePtr cause; #endif { if (which&XkbStateNotifyMask) { XkbStateRec old; old= xkbi->state; changes->state_changes|= XkbStateChangedFlags(&old,&xkbi->state); XkbComputeDerivedState(xkbi); } if (which&XkbIndicatorStateNotifyMask) XkbUpdateIndicators(xkbi->device,XkbAllIndicatorsMask,True,changes, cause); return; } /***====================================================================***/ void #if NeedFunctionPrototypes XkbSetPhysicalLockingKey(DeviceIntPtr dev,unsigned key) #else XkbSetPhysicalLockingKey(dev,key) DeviceIntPtr dev; unsigned key; #endif { XkbDescPtr xkb; xkb= dev->key->xkbInfo->desc; if ((key>=xkb->min_key_code) && (key<=xkb->max_key_code)) { xkb->server->behaviors[key].type= XkbKB_Lock|XkbKB_Permanent; } else ErrorF("Internal Error! Bad XKB info in SetPhysicalLockingKey\n"); return; } /***====================================================================***/ Bool #if NeedFunctionPrototypes XkbEnableDisableControls( XkbSrvInfoPtr xkbi, unsigned long change, unsigned long newValues, XkbChangesPtr changes, XkbEventCausePtr cause) #else XkbEnableDisableControls(xkbi,change,newValues,changes,cause) XkbSrvInfoPtr xkbi; unsigned long change; unsigned long newValues; XkbChangesPtr changes; XkbEventCausePtr cause; #endif { XkbControlsPtr ctrls; unsigned old; XkbSrvLedInfoPtr sli; ctrls= xkbi->desc->ctrls; old= ctrls->enabled_ctrls; ctrls->enabled_ctrls&= ~change; ctrls->enabled_ctrls|= (change&newValues); if (old==ctrls->enabled_ctrls) return False; if (cause!=NULL) { xkbControlsNotify cn; cn.numGroups= ctrls->num_groups; cn.changedControls|= XkbControlsEnabledMask; cn.enabledControls= ctrls->enabled_ctrls; cn.enabledControlChanges= (ctrls->enabled_ctrls^old); cn.keycode= cause->kc; cn.eventType= cause->event; cn.requestMajor= cause->mjr; cn.requestMinor= cause->mnr; XkbSendControlsNotify(xkbi->device,&cn); } else { /* Yes, this really should be an XOR. If ctrls->enabled_ctrls_changes*/ /* is non-zero, the controls in question changed already in "this" */ /* request and this change merely undoes the previous one. By the */ /* same token, we have to figure out whether or not ControlsEnabled */ /* should be set or not in the changes structure */ changes->ctrls.enabled_ctrls_changes^= (ctrls->enabled_ctrls^old); if (changes->ctrls.enabled_ctrls_changes) changes->ctrls.changed_ctrls|= XkbControlsEnabledMask; else changes->ctrls.changed_ctrls&= ~XkbControlsEnabledMask; } sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0); XkbUpdateIndicators(xkbi->device,sli->usesControls,True,changes,cause); return True; } /***====================================================================***/ #define MAX_TOC 16 XkbGeometryPtr #if NeedFunctionPrototypes XkbLookupNamedGeometry(DeviceIntPtr dev,Atom name,Bool *shouldFree) #else XkbLookupNamedGeometry(dev,name,shouldFree) DeviceIntPtr dev; Atom name; Bool * shouldFree; #endif { XkbSrvInfoPtr xkbi= dev->key->xkbInfo; XkbDescPtr xkb= xkbi->desc; *shouldFree= 0; if (name==None) { if (xkb->geom!=NULL) return xkb->geom; name= xkb->names->geometry; } if ((xkb->geom!=NULL)&&(xkb->geom->name==name)) return xkb->geom; else if ((name==xkb->names->geometry)&&(xkb->geom==NULL)) { FILE *file= XkbDDXOpenConfigFile(XkbInitialMap,NULL,0); if (file!=NULL) { XkbFileInfo xkbFInfo; xkmFileInfo finfo; xkmSectionInfo toc[MAX_TOC],*entry; bzero(&xkbFInfo,sizeof(xkbFInfo)); xkbFInfo.xkb= xkb; if (XkmReadTOC(file,&finfo,MAX_TOC,toc)) { entry= XkmFindTOCEntry(&finfo,toc,XkmGeometryIndex); if (entry!=NULL) XkmReadFileSection(file,entry,&xkbFInfo,NULL); } fclose(file); if (xkb->geom) { *shouldFree= 0; return xkb->geom; } } } *shouldFree= 1; return NULL; } void #if NeedFunctionPrototypes XkbConvertCase(register KeySym sym, KeySym *lower, KeySym *upper) #else XkbConvertCase(sym, lower, upper) register KeySym sym; KeySym *lower; KeySym *upper; #endif { *lower = sym; *upper = sym; switch(sym >> 8) { case 0: /* Latin 1 */ if ((sym >= XK_A) && (sym <= XK_Z)) *lower += (XK_a - XK_A); else if ((sym >= XK_a) && (sym <= XK_z)) *upper -= (XK_a - XK_A); else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis)) *lower += (XK_agrave - XK_Agrave); else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis)) *upper -= (XK_agrave - XK_Agrave); else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn)) *lower += (XK_oslash - XK_Ooblique); else if ((sym >= XK_oslash) && (sym <= XK_thorn)) *upper -= (XK_oslash - XK_Ooblique); break; case 1: /* Latin 2 */ /* Assume the KeySym is a legal value (ignore discontinuities) */ if (sym == XK_Aogonek) *lower = XK_aogonek; else if (sym >= XK_Lstroke && sym <= XK_Sacute) *lower += (XK_lstroke - XK_Lstroke); else if (sym >= XK_Scaron && sym <= XK_Zacute) *lower += (XK_scaron - XK_Scaron); else if (sym >= XK_Zcaron && sym <= XK_Zabovedot) *lower += (XK_zcaron - XK_Zcaron); else if (sym == XK_aogonek) *upper = XK_Aogonek; else if (sym >= XK_lstroke && sym <= XK_sacute) *upper -= (XK_lstroke - XK_Lstroke); else if (sym >= XK_scaron && sym <= XK_zacute) *upper -= (XK_scaron - XK_Scaron); else if (sym >= XK_zcaron && sym <= XK_zabovedot) *upper -= (XK_zcaron - XK_Zcaron); else if (sym >= XK_Racute && sym <= XK_Tcedilla) *lower += (XK_racute - XK_Racute); else if (sym >= XK_racute && sym <= XK_tcedilla) *upper -= (XK_racute - XK_Racute); break; case 2: /* Latin 3 */ /* Assume the KeySym is a legal value (ignore discontinuities) */ if (sym >= XK_Hstroke && sym <= XK_Hcircumflex) *lower += (XK_hstroke - XK_Hstroke); else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex) *lower += (XK_gbreve - XK_Gbreve); else if (sym >= XK_hstroke && sym <= XK_hcircumflex) *upper -= (XK_hstroke - XK_Hstroke); else if (sym >= XK_gbreve && sym <= XK_jcircumflex) *upper -= (XK_gbreve - XK_Gbreve); else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex) *lower += (XK_cabovedot - XK_Cabovedot); else if (sym >= XK_cabovedot && sym <= XK_scircumflex) *upper -= (XK_cabovedot - XK_Cabovedot); break; case 3: /* Latin 4 */ /* Assume the KeySym is a legal value (ignore discontinuities) */ if (sym >= XK_Rcedilla && sym <= XK_Tslash) *lower += (XK_rcedilla - XK_Rcedilla); else if (sym >= XK_rcedilla && sym <= XK_tslash) *upper -= (XK_rcedilla - XK_Rcedilla); else if (sym == XK_ENG) *lower = XK_eng; else if (sym == XK_eng) *upper = XK_ENG; else if (sym >= XK_Amacron && sym <= XK_Umacron) *lower += (XK_amacron - XK_Amacron); else if (sym >= XK_amacron && sym <= XK_umacron) *upper -= (XK_amacron - XK_Amacron); break; case 6: /* Cyrillic */ /* Assume the KeySym is a legal value (ignore discontinuities) */ if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE) *lower -= (XK_Serbian_DJE - XK_Serbian_dje); else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze) *upper += (XK_Serbian_DJE - XK_Serbian_dje); else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN) *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu); else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign) *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu); break; case 7: /* Greek */ /* Assume the KeySym is a legal value (ignore discontinuities) */ if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent) *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent); else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent && sym != XK_Greek_iotaaccentdieresis && sym != XK_Greek_upsilonaccentdieresis) *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent); else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA) *lower += (XK_Greek_alpha - XK_Greek_ALPHA); else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega && sym != XK_Greek_finalsmallsigma) *upper -= (XK_Greek_alpha - XK_Greek_ALPHA); break; } }