xkbLEDs.c revision 05b261ec
105b261ecSmrg/************************************************************ 205b261ecSmrgCopyright (c) 1995 by Silicon Graphics Computer Systems, Inc. 305b261ecSmrg 405b261ecSmrgPermission to use, copy, modify, and distribute this 505b261ecSmrgsoftware and its documentation for any purpose and without 605b261ecSmrgfee is hereby granted, provided that the above copyright 705b261ecSmrgnotice appear in all copies and that both that copyright 805b261ecSmrgnotice and this permission notice appear in supporting 905b261ecSmrgdocumentation, and that the name of Silicon Graphics not be 1005b261ecSmrgused in advertising or publicity pertaining to distribution 1105b261ecSmrgof the software without specific prior written permission. 1205b261ecSmrgSilicon Graphics makes no representation about the suitability 1305b261ecSmrgof this software for any purpose. It is provided "as is" 1405b261ecSmrgwithout any express or implied warranty. 1505b261ecSmrg 1605b261ecSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 1705b261ecSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 1805b261ecSmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 1905b261ecSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 2005b261ecSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2105b261ecSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 2205b261ecSmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 2305b261ecSmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 2405b261ecSmrg 2505b261ecSmrg********************************************************/ 2605b261ecSmrg 2705b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2805b261ecSmrg#include <dix-config.h> 2905b261ecSmrg#endif 3005b261ecSmrg 3105b261ecSmrg#include <stdio.h> 3205b261ecSmrg#include <ctype.h> 3305b261ecSmrg#include <math.h> 3405b261ecSmrg#define NEED_EVENTS 1 3505b261ecSmrg#include <X11/X.h> 3605b261ecSmrg#include <X11/Xproto.h> 3705b261ecSmrg#include "misc.h" 3805b261ecSmrg#include "inputstr.h" 3905b261ecSmrg 4005b261ecSmrg#include <X11/extensions/XI.h> 4105b261ecSmrg#include <xkbsrv.h> 4205b261ecSmrg#include "xkb.h" 4305b261ecSmrg 4405b261ecSmrg/***====================================================================***/ 4505b261ecSmrg 4605b261ecSmrg /* 4705b261ecSmrg * unsigned 4805b261ecSmrg * XkbIndicatorsToUpdate(dev,changed,check_devs_rtrn) 4905b261ecSmrg * 5005b261ecSmrg * Given a keyboard and a set of state components that have changed, 5105b261ecSmrg * this function returns the indicators on the default keyboard 5205b261ecSmrg * feedback that might be affected. It also reports whether or not 5305b261ecSmrg * any extension devices might be affected in check_devs_rtrn. 5405b261ecSmrg */ 5505b261ecSmrg 5605b261ecSmrgunsigned 5705b261ecSmrgXkbIndicatorsToUpdate( DeviceIntPtr dev, 5805b261ecSmrg unsigned long state_changes, 5905b261ecSmrg Bool enable_changes) 6005b261ecSmrg{ 6105b261ecSmrgregister unsigned update= 0; 6205b261ecSmrgXkbSrvLedInfoPtr sli; 6305b261ecSmrg 6405b261ecSmrg sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0); 6505b261ecSmrg 6605b261ecSmrg if (!sli) 6705b261ecSmrg return update; 6805b261ecSmrg 6905b261ecSmrg if (state_changes&(XkbModifierStateMask|XkbGroupStateMask)) 7005b261ecSmrg update|= sli->usesEffective; 7105b261ecSmrg if (state_changes&(XkbModifierBaseMask|XkbGroupBaseMask)) 7205b261ecSmrg update|= sli->usesBase; 7305b261ecSmrg if (state_changes&(XkbModifierLatchMask|XkbGroupLatchMask)) 7405b261ecSmrg update|= sli->usesLatched; 7505b261ecSmrg if (state_changes&(XkbModifierLockMask|XkbGroupLockMask)) 7605b261ecSmrg update|= sli->usesLocked; 7705b261ecSmrg if (state_changes&XkbCompatStateMask) 7805b261ecSmrg update|= sli->usesCompat; 7905b261ecSmrg if (enable_changes) 8005b261ecSmrg update|= sli->usesControls; 8105b261ecSmrg return update; 8205b261ecSmrg} 8305b261ecSmrg 8405b261ecSmrg/***====================================================================***/ 8505b261ecSmrg 8605b261ecSmrg /* 8705b261ecSmrg * Bool 8805b261ecSmrg *XkbApplyLEDChangeToKeyboard(xkbi,map,on,change) 8905b261ecSmrg * 9005b261ecSmrg * Some indicators "drive" the keyboard when their state is explicitly 9105b261ecSmrg * changed, as described in section 9.2.1 of the XKB protocol spec. 9205b261ecSmrg * This function updates the state and controls for the keyboard 9305b261ecSmrg * specified by 'xkbi' to reflect any changes that are required 9405b261ecSmrg * when the indicator described by 'map' is turned on or off. The 9505b261ecSmrg * extent of the changes is reported in change, which must be defined. 9605b261ecSmrg */ 9705b261ecSmrgstatic Bool 9805b261ecSmrgXkbApplyLEDChangeToKeyboard( XkbSrvInfoPtr xkbi, 9905b261ecSmrg XkbIndicatorMapPtr map, 10005b261ecSmrg Bool on, 10105b261ecSmrg XkbChangesPtr change) 10205b261ecSmrg{ 10305b261ecSmrgBool ctrlChange,stateChange; 10405b261ecSmrgXkbStatePtr state; 10505b261ecSmrg 10605b261ecSmrg if ((map->flags&XkbIM_NoExplicit)||((map->flags&XkbIM_LEDDrivesKB)==0)) 10705b261ecSmrg return False; 10805b261ecSmrg ctrlChange= stateChange= False; 10905b261ecSmrg if (map->ctrls) { 11005b261ecSmrg XkbControlsPtr ctrls= xkbi->desc->ctrls; 11105b261ecSmrg unsigned old; 11205b261ecSmrg 11305b261ecSmrg old= ctrls->enabled_ctrls; 11405b261ecSmrg if (on) ctrls->enabled_ctrls|= map->ctrls; 11505b261ecSmrg else ctrls->enabled_ctrls&= ~map->ctrls; 11605b261ecSmrg if (old!=ctrls->enabled_ctrls) { 11705b261ecSmrg change->ctrls.changed_ctrls= XkbControlsEnabledMask; 11805b261ecSmrg change->ctrls.enabled_ctrls_changes= old^ctrls->enabled_ctrls; 11905b261ecSmrg ctrlChange= True; 12005b261ecSmrg } 12105b261ecSmrg } 12205b261ecSmrg state= &xkbi->state; 12305b261ecSmrg if ((map->groups)&&((map->which_groups&(~XkbIM_UseBase))!=0)) { 12405b261ecSmrg register int i; 12505b261ecSmrg register unsigned bit,match; 12605b261ecSmrg 12705b261ecSmrg if (on) match= (map->groups)&XkbAllGroupsMask; 12805b261ecSmrg else match= (~map->groups)&XkbAllGroupsMask; 12905b261ecSmrg if (map->which_groups&(XkbIM_UseLocked|XkbIM_UseEffective)) { 13005b261ecSmrg for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 13105b261ecSmrg if (bit&match) 13205b261ecSmrg break; 13305b261ecSmrg } 13405b261ecSmrg if (map->which_groups&XkbIM_UseLatched) 13505b261ecSmrg XkbLatchGroup(xkbi->device,0); /* unlatch group */ 13605b261ecSmrg state->locked_group= i; 13705b261ecSmrg stateChange= True; 13805b261ecSmrg } 13905b261ecSmrg else if (map->which_groups&(XkbIM_UseLatched|XkbIM_UseEffective)) { 14005b261ecSmrg for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 14105b261ecSmrg if (bit&match) 14205b261ecSmrg break; 14305b261ecSmrg } 14405b261ecSmrg state->locked_group= 0; 14505b261ecSmrg XkbLatchGroup(xkbi->device,i); 14605b261ecSmrg stateChange= True; 14705b261ecSmrg } 14805b261ecSmrg } 14905b261ecSmrg if ((map->mods.mask)&&((map->which_mods&(~XkbIM_UseBase))!=0)) { 15005b261ecSmrg if (map->which_mods&(XkbIM_UseLocked|XkbIM_UseEffective)) { 15105b261ecSmrg register unsigned long old; 15205b261ecSmrg old= state->locked_mods; 15305b261ecSmrg if (on) state->locked_mods|= map->mods.mask; 15405b261ecSmrg else state->locked_mods&= ~map->mods.mask; 15505b261ecSmrg if (state->locked_mods!=old) 15605b261ecSmrg stateChange= True; 15705b261ecSmrg } 15805b261ecSmrg if (map->which_mods&(XkbIM_UseLatched|XkbIM_UseEffective)) { 15905b261ecSmrg register unsigned long newmods; 16005b261ecSmrg newmods= state->latched_mods; 16105b261ecSmrg if (on) newmods|= map->mods.mask; 16205b261ecSmrg else newmods&= ~map->mods.mask; 16305b261ecSmrg if (newmods!=state->locked_mods) { 16405b261ecSmrg newmods&= map->mods.mask; 16505b261ecSmrg XkbLatchModifiers(xkbi->device,map->mods.mask,newmods); 16605b261ecSmrg stateChange= True; 16705b261ecSmrg } 16805b261ecSmrg } 16905b261ecSmrg } 17005b261ecSmrg return (stateChange || ctrlChange); 17105b261ecSmrg} 17205b261ecSmrg 17305b261ecSmrg /* 17405b261ecSmrg * Bool 17505b261ecSmrg * ComputeAutoState(map,state,ctrls) 17605b261ecSmrg * 17705b261ecSmrg * This function reports the effect of applying the specified 17805b261ecSmrg * indicator map given the specified state and controls, as 17905b261ecSmrg * described in section 9.2 of the XKB protocol specification. 18005b261ecSmrg */ 18105b261ecSmrg 18205b261ecSmrgstatic Bool 18305b261ecSmrgComputeAutoState( XkbIndicatorMapPtr map, 18405b261ecSmrg XkbStatePtr state, 18505b261ecSmrg XkbControlsPtr ctrls) 18605b261ecSmrg{ 18705b261ecSmrgBool on; 18805b261ecSmrgCARD8 mods,group; 18905b261ecSmrg 19005b261ecSmrg on= False; 19105b261ecSmrg mods= group= 0; 19205b261ecSmrg if (map->which_mods&XkbIM_UseAnyMods) { 19305b261ecSmrg if (map->which_mods&XkbIM_UseBase) 19405b261ecSmrg mods|= state->base_mods; 19505b261ecSmrg if (map->which_mods&XkbIM_UseLatched) 19605b261ecSmrg mods|= state->latched_mods; 19705b261ecSmrg if (map->which_mods&XkbIM_UseLocked) 19805b261ecSmrg mods|= state->locked_mods; 19905b261ecSmrg if (map->which_mods&XkbIM_UseEffective) 20005b261ecSmrg mods|= state->mods; 20105b261ecSmrg if (map->which_mods&XkbIM_UseCompat) 20205b261ecSmrg mods|= state->compat_state; 20305b261ecSmrg on = ((map->mods.mask&mods)!=0); 20405b261ecSmrg on = on||((mods==0)&&(map->mods.mask==0)&&(map->mods.vmods==0)); 20505b261ecSmrg } 20605b261ecSmrg if (map->which_groups&XkbIM_UseAnyGroup) { 20705b261ecSmrg if (map->which_groups&XkbIM_UseBase) 20805b261ecSmrg group|= (1L << state->base_group); 20905b261ecSmrg if (map->which_groups&XkbIM_UseLatched) 21005b261ecSmrg group|= (1L << state->latched_group); 21105b261ecSmrg if (map->which_groups&XkbIM_UseLocked) 21205b261ecSmrg group|= (1L << state->locked_group); 21305b261ecSmrg if (map->which_groups&XkbIM_UseEffective) 21405b261ecSmrg group|= (1L << state->group); 21505b261ecSmrg on = on||(((map->groups&group)!=0)||(map->groups==0)); 21605b261ecSmrg } 21705b261ecSmrg if (map->ctrls) 21805b261ecSmrg on = on||(ctrls->enabled_ctrls&map->ctrls); 21905b261ecSmrg return on; 22005b261ecSmrg} 22105b261ecSmrg 22205b261ecSmrg 22305b261ecSmrgstatic void 22405b261ecSmrgXkbUpdateLedAutoState( DeviceIntPtr dev, 22505b261ecSmrg XkbSrvLedInfoPtr sli, 22605b261ecSmrg unsigned maps_to_check, 22705b261ecSmrg xkbExtensionDeviceNotify * ed, 22805b261ecSmrg XkbChangesPtr changes, 22905b261ecSmrg XkbEventCausePtr cause) 23005b261ecSmrg{ 23105b261ecSmrgDeviceIntPtr kbd; 23205b261ecSmrgXkbStatePtr state; 23305b261ecSmrgXkbControlsPtr ctrls; 23405b261ecSmrgXkbChangesRec my_changes; 23505b261ecSmrgxkbExtensionDeviceNotify my_ed; 23605b261ecSmrgregister unsigned i,bit,affected; 23705b261ecSmrgregister XkbIndicatorMapPtr map; 23805b261ecSmrgunsigned oldState; 23905b261ecSmrg 24005b261ecSmrg if ((maps_to_check==0)||(sli->maps==NULL)||(sli->mapsPresent==0)) 24105b261ecSmrg return; 24205b261ecSmrg 24305b261ecSmrg if (dev->key && dev->key->xkbInfo) 24405b261ecSmrg kbd= dev; 24505b261ecSmrg else kbd= (DeviceIntPtr)LookupKeyboardDevice(); 24605b261ecSmrg 24705b261ecSmrg state= &kbd->key->xkbInfo->state; 24805b261ecSmrg ctrls= kbd->key->xkbInfo->desc->ctrls; 24905b261ecSmrg affected= maps_to_check; 25005b261ecSmrg oldState= sli->effectiveState; 25105b261ecSmrg sli->autoState&= ~affected; 25205b261ecSmrg for (i=0,bit=1;(i<XkbNumIndicators)&&(affected);i++,bit<<=1) { 25305b261ecSmrg if ((affected&bit)==0) 25405b261ecSmrg continue; 25505b261ecSmrg affected&= ~bit; 25605b261ecSmrg map= &sli->maps[i]; 25705b261ecSmrg if((!(map->flags&XkbIM_NoAutomatic))&&ComputeAutoState(map,state,ctrls)) 25805b261ecSmrg sli->autoState|= bit; 25905b261ecSmrg } 26005b261ecSmrg sli->effectiveState= (sli->autoState|sli->explicitState); 26105b261ecSmrg affected= sli->effectiveState^oldState; 26205b261ecSmrg if (affected==0) 26305b261ecSmrg return; 26405b261ecSmrg 26505b261ecSmrg if (ed==NULL) { 26605b261ecSmrg ed= &my_ed; 26705b261ecSmrg bzero((char *)ed,sizeof(xkbExtensionDeviceNotify)); 26805b261ecSmrg } 26905b261ecSmrg else if ((ed->reason&XkbXI_IndicatorsMask)&& 27005b261ecSmrg ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) { 27105b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause); 27205b261ecSmrg } 27305b261ecSmrg 27405b261ecSmrg if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) { 27505b261ecSmrg if (changes==NULL) { 27605b261ecSmrg changes= &my_changes; 27705b261ecSmrg bzero((char *)changes,sizeof(XkbChangesRec)); 27805b261ecSmrg } 27905b261ecSmrg changes->indicators.state_changes|= affected; 28005b261ecSmrg } 28105b261ecSmrg 28205b261ecSmrg ed->reason|= XkbXI_IndicatorStateMask; 28305b261ecSmrg ed->ledClass= sli->class; 28405b261ecSmrg ed->ledID= sli->id; 28505b261ecSmrg ed->ledsDefined= sli->namesPresent|sli->mapsPresent; 28605b261ecSmrg ed->ledState= sli->effectiveState; 28705b261ecSmrg ed->unsupported|= XkbXI_IndicatorStateMask; 28805b261ecSmrg ed->supported= XkbXI_AllFeaturesMask; 28905b261ecSmrg 29005b261ecSmrg if (changes!=&my_changes) changes= NULL; 29105b261ecSmrg if (ed!=&my_ed) ed= NULL; 29205b261ecSmrg if (changes || ed) 29305b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause); 29405b261ecSmrg return; 29505b261ecSmrg} 29605b261ecSmrg 29705b261ecSmrgstatic void 29805b261ecSmrgXkbUpdateAllDeviceIndicators(XkbChangesPtr changes,XkbEventCausePtr cause) 29905b261ecSmrg{ 30005b261ecSmrgDeviceIntPtr edev; 30105b261ecSmrgXkbSrvLedInfoPtr sli; 30205b261ecSmrg 30305b261ecSmrg for (edev=inputInfo.devices;edev!=NULL;edev=edev->next) { 30405b261ecSmrg if (edev->kbdfeed) { 30505b261ecSmrg KbdFeedbackPtr kf; 30605b261ecSmrg for (kf=edev->kbdfeed;kf!=NULL;kf=kf->next) { 30705b261ecSmrg if ((kf->xkb_sli==NULL)||(kf->xkb_sli->maps==NULL)) 30805b261ecSmrg continue; 30905b261ecSmrg sli= kf->xkb_sli; 31005b261ecSmrg XkbUpdateLedAutoState(edev,sli,sli->mapsPresent,NULL, 31105b261ecSmrg changes,cause); 31205b261ecSmrg 31305b261ecSmrg } 31405b261ecSmrg } 31505b261ecSmrg if (edev->leds) { 31605b261ecSmrg LedFeedbackPtr lf; 31705b261ecSmrg for (lf=edev->leds;lf!=NULL;lf=lf->next) { 31805b261ecSmrg if ((lf->xkb_sli==NULL)||(lf->xkb_sli->maps==NULL)) 31905b261ecSmrg continue; 32005b261ecSmrg sli= lf->xkb_sli; 32105b261ecSmrg XkbUpdateLedAutoState(edev,sli,sli->mapsPresent,NULL, 32205b261ecSmrg changes,cause); 32305b261ecSmrg 32405b261ecSmrg } 32505b261ecSmrg } 32605b261ecSmrg } 32705b261ecSmrg return; 32805b261ecSmrg} 32905b261ecSmrg 33005b261ecSmrg 33105b261ecSmrg/***====================================================================***/ 33205b261ecSmrg 33305b261ecSmrg /* 33405b261ecSmrg * void 33505b261ecSmrg * XkbSetIndicators(dev,affect,values,cause) 33605b261ecSmrg * 33705b261ecSmrg * Attempts to change the indicators specified in 'affect' to the 33805b261ecSmrg * states specified in 'values' for the default keyboard feedback 33905b261ecSmrg * on the keyboard specified by 'dev.' Attempts to change indicator 34005b261ecSmrg * state might be ignored or have no affect, depending on the XKB 34105b261ecSmrg * indicator map for any affected indicators, as described in section 34205b261ecSmrg * 9.2 of the XKB protocol specification. 34305b261ecSmrg * 34405b261ecSmrg * If 'changes' is non-NULL, this function notes any changes to the 34505b261ecSmrg * keyboard state, controls, or indicator state that result from this 34605b261ecSmrg * attempted change. If 'changes' is NULL, this function generates 34705b261ecSmrg * XKB events to report any such changes to interested clients. 34805b261ecSmrg * 34905b261ecSmrg * If 'cause' is non-NULL, it specifies the reason for the change, 35005b261ecSmrg * as reported in some XKB events. If it is NULL, this function 35105b261ecSmrg * assumes that the change is the result of a core protocol 35205b261ecSmrg * ChangeKeyboardMapping request. 35305b261ecSmrg */ 35405b261ecSmrg 35505b261ecSmrgvoid 35605b261ecSmrgXkbSetIndicators( DeviceIntPtr dev, 35705b261ecSmrg CARD32 affect, 35805b261ecSmrg CARD32 values, 35905b261ecSmrg XkbEventCausePtr cause) 36005b261ecSmrg{ 36105b261ecSmrgXkbSrvLedInfoPtr sli; 36205b261ecSmrgXkbChangesRec changes; 36305b261ecSmrgxkbExtensionDeviceNotify ed; 36405b261ecSmrgunsigned side_affected; 36505b261ecSmrg 36605b261ecSmrg bzero((char *)&changes,sizeof(XkbChangesRec)); 36705b261ecSmrg bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify)); 36805b261ecSmrg sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0); 36905b261ecSmrg sli->explicitState&= ~affect; 37005b261ecSmrg sli->explicitState|= (affect&values); 37105b261ecSmrg XkbApplyLedStateChanges(dev,sli,affect,&ed,&changes,cause); 37205b261ecSmrg 37305b261ecSmrg side_affected= 0; 37405b261ecSmrg if (changes.state_changes!=0) 37505b261ecSmrg side_affected|= XkbIndicatorsToUpdate(dev,changes.state_changes,False); 37605b261ecSmrg if (changes.ctrls.enabled_ctrls_changes) 37705b261ecSmrg side_affected|= sli->usesControls; 37805b261ecSmrg 37905b261ecSmrg if (side_affected) { 38005b261ecSmrg XkbUpdateLedAutoState(dev,sli,side_affected,&ed,&changes,cause); 38105b261ecSmrg affect|= side_affected; 38205b261ecSmrg } 38305b261ecSmrg if (changes.state_changes || changes.ctrls.enabled_ctrls_changes) 38405b261ecSmrg XkbUpdateAllDeviceIndicators(NULL,cause); 38505b261ecSmrg 38605b261ecSmrg XkbFlushLedEvents(dev,dev,sli,&ed,&changes,cause); 38705b261ecSmrg return; 38805b261ecSmrg} 38905b261ecSmrg 39005b261ecSmrg/***====================================================================***/ 39105b261ecSmrg 39205b261ecSmrg/***====================================================================***/ 39305b261ecSmrg 39405b261ecSmrg /* 39505b261ecSmrg * void 39605b261ecSmrg * XkbUpdateIndicators(dev,update,check_edevs,changes,cause) 39705b261ecSmrg * 39805b261ecSmrg * Applies the indicator maps for any indicators specified in 39905b261ecSmrg * 'update' from the default keyboard feedback on the device 40005b261ecSmrg * specified by 'dev.' 40105b261ecSmrg * 40205b261ecSmrg * If 'changes' is NULL, this function generates and XKB events 40305b261ecSmrg * required to report the necessary changes, otherwise it simply 40405b261ecSmrg * notes the indicators with changed state. 40505b261ecSmrg * 40605b261ecSmrg * If 'check_edevs' is True, this function also checks the indicator 40705b261ecSmrg * maps for any open extension devices that have them, and updates 40805b261ecSmrg * the state of any extension device indicators as necessary. 40905b261ecSmrg */ 41005b261ecSmrg 41105b261ecSmrgvoid 41205b261ecSmrgXkbUpdateIndicators( DeviceIntPtr dev, 41305b261ecSmrg register CARD32 update, 41405b261ecSmrg Bool check_edevs, 41505b261ecSmrg XkbChangesPtr changes, 41605b261ecSmrg XkbEventCausePtr cause) 41705b261ecSmrg{ 41805b261ecSmrgXkbSrvLedInfoPtr sli; 41905b261ecSmrg 42005b261ecSmrg sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0); 42105b261ecSmrg XkbUpdateLedAutoState(dev,sli,update,NULL,changes,cause); 42205b261ecSmrg if (check_edevs) 42305b261ecSmrg XkbUpdateAllDeviceIndicators(changes,cause); 42405b261ecSmrg return; 42505b261ecSmrg} 42605b261ecSmrg 42705b261ecSmrg/***====================================================================***/ 42805b261ecSmrg 42905b261ecSmrg/***====================================================================***/ 43005b261ecSmrg 43105b261ecSmrg /* 43205b261ecSmrg * void 43305b261ecSmrg * XkbCheckIndicatorMaps(dev,sli,which) 43405b261ecSmrg * 43505b261ecSmrg * Updates the 'indicator accelerators' for the indicators specified 43605b261ecSmrg * by 'which' in the feedback specified by 'sli.' The indicator 43705b261ecSmrg * accelerators are internal to the server and are used to simplify 43805b261ecSmrg * and speed up the process of figuring out which indicators might 43905b261ecSmrg * be affected by a particular change in keyboard state or controls. 44005b261ecSmrg */ 44105b261ecSmrg 44205b261ecSmrgvoid 44305b261ecSmrgXkbCheckIndicatorMaps(DeviceIntPtr dev,XkbSrvLedInfoPtr sli,unsigned which) 44405b261ecSmrg{ 44505b261ecSmrgregister unsigned i,bit; 44605b261ecSmrgXkbIndicatorMapPtr map; 44705b261ecSmrgXkbDescPtr xkb; 44805b261ecSmrg 44905b261ecSmrg if ((sli->flags&XkbSLI_HasOwnState)==0) 45005b261ecSmrg dev= (DeviceIntPtr)LookupKeyboardDevice(); 45105b261ecSmrg 45205b261ecSmrg sli->usesBase&= ~which; 45305b261ecSmrg sli->usesLatched&= ~which; 45405b261ecSmrg sli->usesLocked&= ~which; 45505b261ecSmrg sli->usesEffective&= ~which; 45605b261ecSmrg sli->usesCompat&= ~which; 45705b261ecSmrg sli->usesControls&= ~which; 45805b261ecSmrg sli->mapsPresent&= ~which; 45905b261ecSmrg 46005b261ecSmrg xkb= dev->key->xkbInfo->desc; 46105b261ecSmrg for (i=0,bit=1,map=sli->maps;i<XkbNumIndicators;i++,bit<<=1,map++) { 46205b261ecSmrg if (which&bit) { 46305b261ecSmrg CARD8 what; 46405b261ecSmrg 46505b261ecSmrg if (!XkbIM_InUse(map)) 46605b261ecSmrg continue; 46705b261ecSmrg sli->mapsPresent|= bit; 46805b261ecSmrg 46905b261ecSmrg what= (map->which_mods|map->which_groups); 47005b261ecSmrg if (what&XkbIM_UseBase) 47105b261ecSmrg sli->usesBase|= bit; 47205b261ecSmrg if (what&XkbIM_UseLatched) 47305b261ecSmrg sli->usesLatched|= bit; 47405b261ecSmrg if (what&XkbIM_UseLocked) 47505b261ecSmrg sli->usesLocked|= bit; 47605b261ecSmrg if (what&XkbIM_UseEffective) 47705b261ecSmrg sli->usesEffective|= bit; 47805b261ecSmrg if (what&XkbIM_UseCompat) 47905b261ecSmrg sli->usesCompat|= bit; 48005b261ecSmrg if (map->ctrls) 48105b261ecSmrg sli->usesControls|= bit; 48205b261ecSmrg 48305b261ecSmrg map->mods.mask= map->mods.real_mods; 48405b261ecSmrg if (map->mods.vmods!=0) { 48505b261ecSmrg map->mods.mask|= XkbMaskForVMask(xkb,map->mods.vmods); 48605b261ecSmrg } 48705b261ecSmrg } 48805b261ecSmrg } 48905b261ecSmrg sli->usedComponents= 0; 49005b261ecSmrg if (sli->usesBase) 49105b261ecSmrg sli->usedComponents|= XkbModifierBaseMask|XkbGroupBaseMask; 49205b261ecSmrg if (sli->usesLatched) 49305b261ecSmrg sli->usedComponents|= XkbModifierLatchMask|XkbGroupLatchMask; 49405b261ecSmrg if (sli->usesLocked) 49505b261ecSmrg sli->usedComponents|= XkbModifierLockMask|XkbGroupLockMask; 49605b261ecSmrg if (sli->usesEffective) 49705b261ecSmrg sli->usedComponents|= XkbModifierStateMask|XkbGroupStateMask; 49805b261ecSmrg if (sli->usesCompat) 49905b261ecSmrg sli->usedComponents|= XkbCompatStateMask; 50005b261ecSmrg return; 50105b261ecSmrg} 50205b261ecSmrg 50305b261ecSmrg/***====================================================================***/ 50405b261ecSmrg 50505b261ecSmrg /* 50605b261ecSmrg * XkbSrvLedInfoPtr 50705b261ecSmrg * XkbAllocSrvLedInfo(dev,kf,lf,needed_parts) 50805b261ecSmrg * 50905b261ecSmrg * Allocates an XkbSrvLedInfoPtr for the feedback specified by either 51005b261ecSmrg * 'kf' or 'lf' on the keyboard specified by 'dev.' 51105b261ecSmrg * 51205b261ecSmrg * If 'needed_parts' is non-zero, this function makes sure that any 51305b261ecSmrg * of the parts speicified therein are allocated. 51405b261ecSmrg */ 51505b261ecSmrgXkbSrvLedInfoPtr 51605b261ecSmrgXkbAllocSrvLedInfo( DeviceIntPtr dev, 51705b261ecSmrg KbdFeedbackPtr kf, 51805b261ecSmrg LedFeedbackPtr lf, 51905b261ecSmrg unsigned needed_parts) 52005b261ecSmrg{ 52105b261ecSmrgXkbSrvLedInfoPtr sli; 52205b261ecSmrgBool checkAccel; 52305b261ecSmrgBool checkNames; 52405b261ecSmrg 52505b261ecSmrg sli= NULL; 52605b261ecSmrg checkAccel= checkNames= False; 52705b261ecSmrg if ((kf!=NULL)&&(kf->xkb_sli==NULL)) { 52805b261ecSmrg kf->xkb_sli= sli= _XkbTypedCalloc(1,XkbSrvLedInfoRec); 52905b261ecSmrg if (sli==NULL) 53005b261ecSmrg return NULL; /* ALLOCATION ERROR */ 53105b261ecSmrg if (dev->key && dev->key->xkbInfo) 53205b261ecSmrg sli->flags= XkbSLI_HasOwnState; 53305b261ecSmrg else sli->flags= 0; 53405b261ecSmrg sli->class= KbdFeedbackClass; 53505b261ecSmrg sli->id= kf->ctrl.id; 53605b261ecSmrg sli->fb.kf= kf; 53705b261ecSmrg 53805b261ecSmrg sli->autoState= 0; 53905b261ecSmrg sli->explicitState= kf->ctrl.leds; 54005b261ecSmrg sli->effectiveState= kf->ctrl.leds; 54105b261ecSmrg 54205b261ecSmrg if ((kf==dev->kbdfeed) && (dev->key) && (dev->key->xkbInfo)) { 54305b261ecSmrg XkbDescPtr xkb; 54405b261ecSmrg xkb= dev->key->xkbInfo->desc; 54505b261ecSmrg sli->flags|= XkbSLI_IsDefault; 54605b261ecSmrg sli->physIndicators= xkb->indicators->phys_indicators; 54705b261ecSmrg sli->names= xkb->names->indicators; 54805b261ecSmrg sli->maps= xkb->indicators->maps; 54905b261ecSmrg checkNames= checkAccel= True; 55005b261ecSmrg } 55105b261ecSmrg else { 55205b261ecSmrg sli->physIndicators= XkbAllIndicatorsMask; 55305b261ecSmrg sli->names= NULL; 55405b261ecSmrg sli->maps= NULL; 55505b261ecSmrg } 55605b261ecSmrg } 55705b261ecSmrg else if ((kf!=NULL)&&((kf->xkb_sli->flags&XkbSLI_IsDefault)!=0)) { 55805b261ecSmrg XkbDescPtr xkb; 55905b261ecSmrg xkb= dev->key->xkbInfo->desc; 56005b261ecSmrg sli->physIndicators= xkb->indicators->phys_indicators; 56105b261ecSmrg if (xkb->names->indicators!=sli->names) { 56205b261ecSmrg checkNames= True; 56305b261ecSmrg sli->names= xkb->names->indicators; 56405b261ecSmrg } 56505b261ecSmrg if (xkb->indicators->maps!=sli->maps) { 56605b261ecSmrg checkAccel= True; 56705b261ecSmrg sli->maps= xkb->indicators->maps; 56805b261ecSmrg } 56905b261ecSmrg } 57005b261ecSmrg else if ((lf!=NULL)&&(lf->xkb_sli==NULL)) { 57105b261ecSmrg lf->xkb_sli= sli= _XkbTypedCalloc(1,XkbSrvLedInfoRec); 57205b261ecSmrg if (sli==NULL) 57305b261ecSmrg return NULL; /* ALLOCATION ERROR */ 57405b261ecSmrg if (dev->key && dev->key->xkbInfo) 57505b261ecSmrg sli->flags= XkbSLI_HasOwnState; 57605b261ecSmrg else sli->flags= 0; 57705b261ecSmrg sli->class= LedFeedbackClass; 57805b261ecSmrg sli->id= lf->ctrl.id; 57905b261ecSmrg sli->fb.lf= lf; 58005b261ecSmrg 58105b261ecSmrg sli->physIndicators= lf->ctrl.led_mask; 58205b261ecSmrg sli->autoState= 0; 58305b261ecSmrg sli->explicitState= lf->ctrl.led_values; 58405b261ecSmrg sli->effectiveState= lf->ctrl.led_values; 58505b261ecSmrg sli->maps= NULL; 58605b261ecSmrg sli->names= NULL; 58705b261ecSmrg } 58805b261ecSmrg if ((sli->names==NULL)&&(needed_parts&XkbXI_IndicatorNamesMask)) 58905b261ecSmrg sli->names= _XkbTypedCalloc(XkbNumIndicators,Atom); 59005b261ecSmrg if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask)) 59105b261ecSmrg sli->maps= _XkbTypedCalloc(XkbNumIndicators,XkbIndicatorMapRec); 59205b261ecSmrg if (checkNames) { 59305b261ecSmrg register unsigned i,bit; 59405b261ecSmrg sli->namesPresent= 0; 59505b261ecSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 59605b261ecSmrg if (sli->names[i]!=None) 59705b261ecSmrg sli->namesPresent|= bit; 59805b261ecSmrg } 59905b261ecSmrg } 60005b261ecSmrg if (checkAccel) 60105b261ecSmrg XkbCheckIndicatorMaps(dev,sli,XkbAllIndicatorsMask); 60205b261ecSmrg return sli; 60305b261ecSmrg} 60405b261ecSmrg 60505b261ecSmrgvoid 60605b261ecSmrgXkbFreeSrvLedInfo(XkbSrvLedInfoPtr sli) 60705b261ecSmrg{ 60805b261ecSmrg if ((sli->flags&XkbSLI_IsDefault)==0) { 60905b261ecSmrg if (sli->maps) _XkbFree(sli->maps); 61005b261ecSmrg if (sli->names) _XkbFree(sli->names); 61105b261ecSmrg } 61205b261ecSmrg sli->maps= NULL; 61305b261ecSmrg sli->names= NULL; 61405b261ecSmrg _XkbFree(sli); 61505b261ecSmrg return; 61605b261ecSmrg} 61705b261ecSmrg 61805b261ecSmrg 61905b261ecSmrg/***====================================================================***/ 62005b261ecSmrg 62105b261ecSmrg /* 62205b261ecSmrg * XkbSrvLedInfoPtr 62305b261ecSmrg * XkbFindSrvLedInfo(dev,class,id,needed_parts) 62405b261ecSmrg * 62505b261ecSmrg * Finds the XkbSrvLedInfoPtr for the specified 'class' and 'id' 62605b261ecSmrg * on the device specified by 'dev.' If the class and id specify 62705b261ecSmrg * a valid device feedback, this function returns the existing 62805b261ecSmrg * feedback or allocates a new one. 62905b261ecSmrg * 63005b261ecSmrg */ 63105b261ecSmrg 63205b261ecSmrgXkbSrvLedInfoPtr 63305b261ecSmrgXkbFindSrvLedInfo( DeviceIntPtr dev, 63405b261ecSmrg unsigned class, 63505b261ecSmrg unsigned id, 63605b261ecSmrg unsigned needed_parts) 63705b261ecSmrg{ 63805b261ecSmrgXkbSrvLedInfoPtr sli; 63905b261ecSmrg 64005b261ecSmrg /* optimization to check for most common case */ 64105b261ecSmrg if (((class==XkbDfltXIClass)&&(id==XkbDfltXIId))&&(dev->kbdfeed)) { 64205b261ecSmrg XkbSrvLedInfoPtr sli; 64305b261ecSmrg sli= dev->kbdfeed->xkb_sli; 64405b261ecSmrg if (dev->kbdfeed->xkb_sli==NULL) { 64505b261ecSmrg sli= XkbAllocSrvLedInfo(dev,dev->kbdfeed,NULL,needed_parts); 64605b261ecSmrg dev->kbdfeed->xkb_sli= sli; 64705b261ecSmrg } 64805b261ecSmrg return dev->kbdfeed->xkb_sli; 64905b261ecSmrg } 65005b261ecSmrg 65105b261ecSmrg sli= NULL; 65205b261ecSmrg if (class==XkbDfltXIClass) { 65305b261ecSmrg if (dev->kbdfeed) class= KbdFeedbackClass; 65405b261ecSmrg else if (dev->leds) class= LedFeedbackClass; 65505b261ecSmrg else return NULL; 65605b261ecSmrg } 65705b261ecSmrg if (class==KbdFeedbackClass) { 65805b261ecSmrg KbdFeedbackPtr kf; 65905b261ecSmrg for (kf=dev->kbdfeed;kf!=NULL;kf=kf->next) { 66005b261ecSmrg if ((id==XkbDfltXIId)||(id==kf->ctrl.id)) { 66105b261ecSmrg if (kf->xkb_sli==NULL) 66205b261ecSmrg kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,needed_parts); 66305b261ecSmrg sli= kf->xkb_sli; 66405b261ecSmrg break; 66505b261ecSmrg } 66605b261ecSmrg } 66705b261ecSmrg } 66805b261ecSmrg else if (class==LedFeedbackClass) { 66905b261ecSmrg LedFeedbackPtr lf; 67005b261ecSmrg for (lf=dev->leds;lf!=NULL;lf=lf->next) { 67105b261ecSmrg if ((id==XkbDfltXIId)||(id==lf->ctrl.id)) { 67205b261ecSmrg if (lf->xkb_sli==NULL) 67305b261ecSmrg lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,needed_parts); 67405b261ecSmrg sli= lf->xkb_sli; 67505b261ecSmrg break; 67605b261ecSmrg } 67705b261ecSmrg } 67805b261ecSmrg } 67905b261ecSmrg if ((sli->names==NULL)&&(needed_parts&XkbXI_IndicatorNamesMask)) 68005b261ecSmrg sli->names= _XkbTypedCalloc(XkbNumIndicators,Atom); 68105b261ecSmrg if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask)) 68205b261ecSmrg sli->maps= _XkbTypedCalloc(XkbNumIndicators,XkbIndicatorMapRec); 68305b261ecSmrg return sli; 68405b261ecSmrg} 68505b261ecSmrg 68605b261ecSmrg/***====================================================================***/ 68705b261ecSmrg 68805b261ecSmrgvoid 68905b261ecSmrgXkbFlushLedEvents( DeviceIntPtr dev, 69005b261ecSmrg DeviceIntPtr kbd, 69105b261ecSmrg XkbSrvLedInfoPtr sli, 69205b261ecSmrg xkbExtensionDeviceNotify * ed, 69305b261ecSmrg XkbChangesPtr changes, 69405b261ecSmrg XkbEventCausePtr cause) 69505b261ecSmrg{ 69605b261ecSmrg if (changes) { 69705b261ecSmrg if (changes->indicators.state_changes) 69805b261ecSmrg XkbDDXUpdateDeviceIndicators(dev,sli,sli->effectiveState); 69905b261ecSmrg XkbSendNotification(kbd,changes,cause); 70005b261ecSmrg bzero((char *)changes,sizeof(XkbChangesRec)); 70105b261ecSmrg 70205b261ecSmrg if (XkbAX_NeedFeedback(kbd->key->xkbInfo->desc->ctrls, XkbAX_IndicatorFBMask)) { 70305b261ecSmrg if (sli->effectiveState) 70405b261ecSmrg /* it appears that the which parameter is not used */ 70505b261ecSmrg XkbDDXAccessXBeep(dev, _BEEP_LED_ON, XkbAccessXFeedbackMask); 70605b261ecSmrg else 70705b261ecSmrg XkbDDXAccessXBeep(dev, _BEEP_LED_OFF, XkbAccessXFeedbackMask); 70805b261ecSmrg } 70905b261ecSmrg } 71005b261ecSmrg if (ed && (ed->reason)) { 71105b261ecSmrg if ((dev!=kbd)&&(ed->reason&XkbXI_IndicatorStateMask)) 71205b261ecSmrg XkbDDXUpdateDeviceIndicators(dev,sli,sli->effectiveState); 71305b261ecSmrg XkbSendExtensionDeviceNotify(dev,cause->client,ed); 71405b261ecSmrg } 71505b261ecSmrg bzero((char *)ed,sizeof(XkbExtensionDeviceNotify)); 71605b261ecSmrg return; 71705b261ecSmrg} 71805b261ecSmrg 71905b261ecSmrg/***====================================================================***/ 72005b261ecSmrg 72105b261ecSmrgvoid 72205b261ecSmrgXkbApplyLedNameChanges( DeviceIntPtr dev, 72305b261ecSmrg XkbSrvLedInfoPtr sli, 72405b261ecSmrg unsigned changed_names, 72505b261ecSmrg xkbExtensionDeviceNotify * ed, 72605b261ecSmrg XkbChangesPtr changes, 72705b261ecSmrg XkbEventCausePtr cause) 72805b261ecSmrg{ 72905b261ecSmrgDeviceIntPtr kbd; 73005b261ecSmrgXkbChangesRec my_changes; 73105b261ecSmrgxkbExtensionDeviceNotify my_ed; 73205b261ecSmrg 73305b261ecSmrg if (changed_names==0) 73405b261ecSmrg return; 73505b261ecSmrg if (dev->key && dev->key->xkbInfo) 73605b261ecSmrg kbd= dev; 73705b261ecSmrg else kbd= (DeviceIntPtr)LookupKeyboardDevice(); 73805b261ecSmrg 73905b261ecSmrg if (ed==NULL) { 74005b261ecSmrg ed= &my_ed; 74105b261ecSmrg bzero((char *)ed,sizeof(xkbExtensionDeviceNotify)); 74205b261ecSmrg } 74305b261ecSmrg else if ((ed->reason&XkbXI_IndicatorsMask)&& 74405b261ecSmrg ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) { 74505b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause); 74605b261ecSmrg } 74705b261ecSmrg 74805b261ecSmrg if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) { 74905b261ecSmrg if (changes==NULL) { 75005b261ecSmrg changes= &my_changes; 75105b261ecSmrg bzero((char *)changes,sizeof(XkbChangesRec)); 75205b261ecSmrg } 75305b261ecSmrg changes->names.changed|= XkbIndicatorNamesMask; 75405b261ecSmrg changes->names.changed_indicators|= changed_names; 75505b261ecSmrg } 75605b261ecSmrg 75705b261ecSmrg ed->reason|= XkbXI_IndicatorNamesMask; 75805b261ecSmrg ed->ledClass= sli->class; 75905b261ecSmrg ed->ledID= sli->id; 76005b261ecSmrg ed->ledsDefined= sli->namesPresent|sli->mapsPresent; 76105b261ecSmrg ed->ledState= sli->effectiveState; 76205b261ecSmrg ed->unsupported= 0; 76305b261ecSmrg ed->supported= XkbXI_AllFeaturesMask; 76405b261ecSmrg 76505b261ecSmrg if (changes!=&my_changes) changes= NULL; 76605b261ecSmrg if (ed!=&my_ed) ed= NULL; 76705b261ecSmrg if (changes || ed) 76805b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause); 76905b261ecSmrg return; 77005b261ecSmrg} 77105b261ecSmrg/***====================================================================***/ 77205b261ecSmrg 77305b261ecSmrg /* 77405b261ecSmrg * void 77505b261ecSmrg * XkbApplyLedMapChanges(dev,sli,changed_maps,changes,cause) 77605b261ecSmrg * 77705b261ecSmrg * Handles all of the secondary effects of the changes to the 77805b261ecSmrg * feedback specified by 'sli' on the device specified by 'dev.' 77905b261ecSmrg * 78005b261ecSmrg * If 'changed_maps' specifies any indicators, this function generates 78105b261ecSmrg * XkbExtensionDeviceNotify events and possibly IndicatorMapNotify 78205b261ecSmrg * events to report the changes, and recalculates the effective 78305b261ecSmrg * state of each indicator with a changed map. If any indicators 78405b261ecSmrg * change state, the server generates XkbExtensionDeviceNotify and 78505b261ecSmrg * XkbIndicatorStateNotify events as appropriate. 78605b261ecSmrg * 78705b261ecSmrg * If 'changes' is non-NULL, this function updates it to reflect 78805b261ecSmrg * any changes to the keyboard state or controls or to the 'core' 78905b261ecSmrg * indicator names, maps, or state. If 'changes' is NULL, this 79005b261ecSmrg * function generates XKB events as needed to report the changes. 79105b261ecSmrg * If 'dev' is not a keyboard device, any changes are reported 79205b261ecSmrg * for the core keyboard. 79305b261ecSmrg * 79405b261ecSmrg * The 'cause' specifies the reason for the event (key event or 79505b261ecSmrg * request) for the change, as reported in some XKB events. 79605b261ecSmrg */ 79705b261ecSmrg 79805b261ecSmrgvoid 79905b261ecSmrgXkbApplyLedMapChanges( DeviceIntPtr dev, 80005b261ecSmrg XkbSrvLedInfoPtr sli, 80105b261ecSmrg unsigned changed_maps, 80205b261ecSmrg xkbExtensionDeviceNotify * ed, 80305b261ecSmrg XkbChangesPtr changes, 80405b261ecSmrg XkbEventCausePtr cause) 80505b261ecSmrg{ 80605b261ecSmrgDeviceIntPtr kbd; 80705b261ecSmrgXkbChangesRec my_changes; 80805b261ecSmrgxkbExtensionDeviceNotify my_ed; 80905b261ecSmrg 81005b261ecSmrg if (changed_maps==0) 81105b261ecSmrg return; 81205b261ecSmrg if (dev->key && dev->key->xkbInfo) 81305b261ecSmrg kbd= dev; 81405b261ecSmrg else kbd= (DeviceIntPtr)LookupKeyboardDevice(); 81505b261ecSmrg 81605b261ecSmrg if (ed==NULL) { 81705b261ecSmrg ed= &my_ed; 81805b261ecSmrg bzero((char *)ed,sizeof(xkbExtensionDeviceNotify)); 81905b261ecSmrg } 82005b261ecSmrg else if ((ed->reason&XkbXI_IndicatorsMask)&& 82105b261ecSmrg ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) { 82205b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause); 82305b261ecSmrg } 82405b261ecSmrg 82505b261ecSmrg if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) { 82605b261ecSmrg if (changes==NULL) { 82705b261ecSmrg changes= &my_changes; 82805b261ecSmrg bzero((char *)changes,sizeof(XkbChangesRec)); 82905b261ecSmrg } 83005b261ecSmrg changes->indicators.map_changes|= changed_maps; 83105b261ecSmrg } 83205b261ecSmrg 83305b261ecSmrg XkbCheckIndicatorMaps(dev,sli,changed_maps); 83405b261ecSmrg 83505b261ecSmrg ed->reason|= XkbXI_IndicatorMapsMask; 83605b261ecSmrg ed->ledClass= sli->class; 83705b261ecSmrg ed->ledID= sli->id; 83805b261ecSmrg ed->ledsDefined= sli->namesPresent|sli->mapsPresent; 83905b261ecSmrg ed->ledState= sli->effectiveState; 84005b261ecSmrg ed->unsupported|= XkbXI_IndicatorMapsMask; 84105b261ecSmrg ed->supported= XkbXI_AllFeaturesMask; 84205b261ecSmrg 84305b261ecSmrg XkbUpdateLedAutoState(dev,sli,changed_maps,ed,changes,cause); 84405b261ecSmrg 84505b261ecSmrg if (changes!=&my_changes) changes= NULL; 84605b261ecSmrg if (ed!=&my_ed) ed= NULL; 84705b261ecSmrg if (changes || ed) 84805b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause); 84905b261ecSmrg return; 85005b261ecSmrg} 85105b261ecSmrg 85205b261ecSmrg/***====================================================================***/ 85305b261ecSmrg 85405b261ecSmrgvoid 85505b261ecSmrgXkbApplyLedStateChanges(DeviceIntPtr dev, 85605b261ecSmrg XkbSrvLedInfoPtr sli, 85705b261ecSmrg unsigned changed_leds, 85805b261ecSmrg xkbExtensionDeviceNotify * ed, 85905b261ecSmrg XkbChangesPtr changes, 86005b261ecSmrg XkbEventCausePtr cause) 86105b261ecSmrg{ 86205b261ecSmrgXkbSrvInfoPtr xkbi; 86305b261ecSmrgDeviceIntPtr kbd; 86405b261ecSmrgXkbChangesRec my_changes; 86505b261ecSmrgxkbExtensionDeviceNotify my_ed; 86605b261ecSmrgregister unsigned i,bit,affected; 86705b261ecSmrgXkbIndicatorMapPtr map; 86805b261ecSmrgunsigned oldState; 86905b261ecSmrgBool kb_changed; 87005b261ecSmrg 87105b261ecSmrg if (changed_leds==0) 87205b261ecSmrg return; 87305b261ecSmrg if (dev->key && dev->key->xkbInfo) 87405b261ecSmrg kbd= dev; 87505b261ecSmrg else kbd= (DeviceIntPtr)LookupKeyboardDevice(); 87605b261ecSmrg xkbi= kbd->key->xkbInfo; 87705b261ecSmrg 87805b261ecSmrg if (changes==NULL) { 87905b261ecSmrg changes= &my_changes; 88005b261ecSmrg bzero((char *)changes,sizeof(XkbChangesRec)); 88105b261ecSmrg } 88205b261ecSmrg 88305b261ecSmrg kb_changed= False; 88405b261ecSmrg affected= changed_leds; 88505b261ecSmrg oldState= sli->effectiveState; 88605b261ecSmrg for (i=0,bit=1;(i<XkbNumIndicators)&&(affected);i++,bit<<=1) { 88705b261ecSmrg if ((affected&bit)==0) 88805b261ecSmrg continue; 88905b261ecSmrg affected&= ~bit; 89005b261ecSmrg map= &sli->maps[i]; 89105b261ecSmrg if (map->flags&XkbIM_NoExplicit) { 89205b261ecSmrg sli->explicitState&= ~bit; 89305b261ecSmrg continue; 89405b261ecSmrg } 89505b261ecSmrg if (map->flags&XkbIM_LEDDrivesKB) { 89605b261ecSmrg Bool on= ((sli->explicitState&bit)!=0); 89705b261ecSmrg if (XkbApplyLEDChangeToKeyboard(xkbi,map,on,changes)) 89805b261ecSmrg kb_changed= True; 89905b261ecSmrg } 90005b261ecSmrg } 90105b261ecSmrg sli->effectiveState= (sli->autoState|sli->explicitState); 90205b261ecSmrg affected= sli->effectiveState^oldState; 90305b261ecSmrg 90405b261ecSmrg if (ed==NULL) { 90505b261ecSmrg ed= &my_ed; 90605b261ecSmrg bzero((char *)ed,sizeof(xkbExtensionDeviceNotify)); 90705b261ecSmrg } 90805b261ecSmrg else if (affected&&(ed->reason&XkbXI_IndicatorsMask)&& 90905b261ecSmrg ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) { 91005b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause); 91105b261ecSmrg } 91205b261ecSmrg 91305b261ecSmrg if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) 91405b261ecSmrg changes->indicators.state_changes|= affected; 91505b261ecSmrg if (affected) { 91605b261ecSmrg ed->reason|= XkbXI_IndicatorStateMask; 91705b261ecSmrg ed->ledClass= sli->class; 91805b261ecSmrg ed->ledID= sli->id; 91905b261ecSmrg ed->ledsDefined= sli->namesPresent|sli->mapsPresent; 92005b261ecSmrg ed->ledState= sli->effectiveState; 92105b261ecSmrg ed->unsupported|= XkbXI_IndicatorStateMask; 92205b261ecSmrg ed->supported= XkbXI_AllFeaturesMask; 92305b261ecSmrg } 92405b261ecSmrg 92505b261ecSmrg if (kb_changed) { 92605b261ecSmrg XkbComputeDerivedState(kbd->key->xkbInfo); 92705b261ecSmrg XkbUpdateLedAutoState(dev,sli,sli->mapsPresent,ed,changes,cause); 92805b261ecSmrg } 92905b261ecSmrg 93005b261ecSmrg if (changes!=&my_changes) changes= NULL; 93105b261ecSmrg if (ed!=&my_ed) ed= NULL; 93205b261ecSmrg if (changes || ed) 93305b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause); 93405b261ecSmrg if (kb_changed) 93505b261ecSmrg XkbUpdateAllDeviceIndicators(NULL,cause); 93605b261ecSmrg return; 93705b261ecSmrg} 938