xkbLEDs.c revision 6747b715
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#include <X11/X.h> 3505b261ecSmrg#include <X11/Xproto.h> 3605b261ecSmrg#include "misc.h" 3705b261ecSmrg#include "inputstr.h" 3805b261ecSmrg 3905b261ecSmrg#include <X11/extensions/XI.h> 4005b261ecSmrg#include <xkbsrv.h> 4105b261ecSmrg#include "xkb.h" 4205b261ecSmrg 4305b261ecSmrg/***====================================================================***/ 4405b261ecSmrg 4505b261ecSmrg /* 4605b261ecSmrg * unsigned 4705b261ecSmrg * XkbIndicatorsToUpdate(dev,changed,check_devs_rtrn) 4805b261ecSmrg * 4905b261ecSmrg * Given a keyboard and a set of state components that have changed, 5005b261ecSmrg * this function returns the indicators on the default keyboard 5105b261ecSmrg * feedback that might be affected. It also reports whether or not 5205b261ecSmrg * any extension devices might be affected in check_devs_rtrn. 5305b261ecSmrg */ 5405b261ecSmrg 5505b261ecSmrgunsigned 5605b261ecSmrgXkbIndicatorsToUpdate( DeviceIntPtr dev, 5705b261ecSmrg unsigned long state_changes, 5805b261ecSmrg Bool enable_changes) 5905b261ecSmrg{ 6005b261ecSmrgregister unsigned update= 0; 6105b261ecSmrgXkbSrvLedInfoPtr sli; 6205b261ecSmrg 6305b261ecSmrg sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0); 6405b261ecSmrg 6505b261ecSmrg if (!sli) 6605b261ecSmrg return update; 6705b261ecSmrg 6805b261ecSmrg if (state_changes&(XkbModifierStateMask|XkbGroupStateMask)) 6905b261ecSmrg update|= sli->usesEffective; 7005b261ecSmrg if (state_changes&(XkbModifierBaseMask|XkbGroupBaseMask)) 7105b261ecSmrg update|= sli->usesBase; 7205b261ecSmrg if (state_changes&(XkbModifierLatchMask|XkbGroupLatchMask)) 7305b261ecSmrg update|= sli->usesLatched; 7405b261ecSmrg if (state_changes&(XkbModifierLockMask|XkbGroupLockMask)) 7505b261ecSmrg update|= sli->usesLocked; 7605b261ecSmrg if (state_changes&XkbCompatStateMask) 7705b261ecSmrg update|= sli->usesCompat; 7805b261ecSmrg if (enable_changes) 7905b261ecSmrg update|= sli->usesControls; 8005b261ecSmrg return update; 8105b261ecSmrg} 8205b261ecSmrg 8305b261ecSmrg/***====================================================================***/ 8405b261ecSmrg 8505b261ecSmrg /* 8605b261ecSmrg * Bool 8705b261ecSmrg *XkbApplyLEDChangeToKeyboard(xkbi,map,on,change) 8805b261ecSmrg * 8905b261ecSmrg * Some indicators "drive" the keyboard when their state is explicitly 9005b261ecSmrg * changed, as described in section 9.2.1 of the XKB protocol spec. 9105b261ecSmrg * This function updates the state and controls for the keyboard 9205b261ecSmrg * specified by 'xkbi' to reflect any changes that are required 9305b261ecSmrg * when the indicator described by 'map' is turned on or off. The 9405b261ecSmrg * extent of the changes is reported in change, which must be defined. 9505b261ecSmrg */ 9605b261ecSmrgstatic Bool 9705b261ecSmrgXkbApplyLEDChangeToKeyboard( XkbSrvInfoPtr xkbi, 9805b261ecSmrg XkbIndicatorMapPtr map, 9905b261ecSmrg Bool on, 10005b261ecSmrg XkbChangesPtr change) 10105b261ecSmrg{ 10205b261ecSmrgBool ctrlChange,stateChange; 10305b261ecSmrgXkbStatePtr state; 10405b261ecSmrg 10505b261ecSmrg if ((map->flags&XkbIM_NoExplicit)||((map->flags&XkbIM_LEDDrivesKB)==0)) 1066747b715Smrg return FALSE; 1076747b715Smrg ctrlChange= stateChange= FALSE; 10805b261ecSmrg if (map->ctrls) { 10905b261ecSmrg XkbControlsPtr ctrls= xkbi->desc->ctrls; 11005b261ecSmrg unsigned old; 11105b261ecSmrg 11205b261ecSmrg old= ctrls->enabled_ctrls; 11305b261ecSmrg if (on) ctrls->enabled_ctrls|= map->ctrls; 11405b261ecSmrg else ctrls->enabled_ctrls&= ~map->ctrls; 11505b261ecSmrg if (old!=ctrls->enabled_ctrls) { 11605b261ecSmrg change->ctrls.changed_ctrls= XkbControlsEnabledMask; 11705b261ecSmrg change->ctrls.enabled_ctrls_changes= old^ctrls->enabled_ctrls; 1186747b715Smrg ctrlChange= TRUE; 11905b261ecSmrg } 12005b261ecSmrg } 12105b261ecSmrg state= &xkbi->state; 12205b261ecSmrg if ((map->groups)&&((map->which_groups&(~XkbIM_UseBase))!=0)) { 12305b261ecSmrg register int i; 12405b261ecSmrg register unsigned bit,match; 12505b261ecSmrg 12605b261ecSmrg if (on) match= (map->groups)&XkbAllGroupsMask; 12705b261ecSmrg else match= (~map->groups)&XkbAllGroupsMask; 12805b261ecSmrg if (map->which_groups&(XkbIM_UseLocked|XkbIM_UseEffective)) { 12905b261ecSmrg for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 13005b261ecSmrg if (bit&match) 13105b261ecSmrg break; 13205b261ecSmrg } 13305b261ecSmrg if (map->which_groups&XkbIM_UseLatched) 13405b261ecSmrg XkbLatchGroup(xkbi->device,0); /* unlatch group */ 13505b261ecSmrg state->locked_group= i; 1366747b715Smrg stateChange= TRUE; 13705b261ecSmrg } 13805b261ecSmrg else if (map->which_groups&(XkbIM_UseLatched|XkbIM_UseEffective)) { 13905b261ecSmrg for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { 14005b261ecSmrg if (bit&match) 14105b261ecSmrg break; 14205b261ecSmrg } 14305b261ecSmrg state->locked_group= 0; 14405b261ecSmrg XkbLatchGroup(xkbi->device,i); 1456747b715Smrg stateChange= TRUE; 14605b261ecSmrg } 14705b261ecSmrg } 14805b261ecSmrg if ((map->mods.mask)&&((map->which_mods&(~XkbIM_UseBase))!=0)) { 14905b261ecSmrg if (map->which_mods&(XkbIM_UseLocked|XkbIM_UseEffective)) { 15005b261ecSmrg register unsigned long old; 15105b261ecSmrg old= state->locked_mods; 15205b261ecSmrg if (on) state->locked_mods|= map->mods.mask; 15305b261ecSmrg else state->locked_mods&= ~map->mods.mask; 15405b261ecSmrg if (state->locked_mods!=old) 1556747b715Smrg stateChange= TRUE; 15605b261ecSmrg } 15705b261ecSmrg if (map->which_mods&(XkbIM_UseLatched|XkbIM_UseEffective)) { 15805b261ecSmrg register unsigned long newmods; 15905b261ecSmrg newmods= state->latched_mods; 16005b261ecSmrg if (on) newmods|= map->mods.mask; 16105b261ecSmrg else newmods&= ~map->mods.mask; 16205b261ecSmrg if (newmods!=state->locked_mods) { 16305b261ecSmrg newmods&= map->mods.mask; 16405b261ecSmrg XkbLatchModifiers(xkbi->device,map->mods.mask,newmods); 1656747b715Smrg stateChange= TRUE; 16605b261ecSmrg } 16705b261ecSmrg } 16805b261ecSmrg } 1696747b715Smrg return stateChange || ctrlChange; 17005b261ecSmrg} 17105b261ecSmrg 17205b261ecSmrg /* 17305b261ecSmrg * Bool 17405b261ecSmrg * ComputeAutoState(map,state,ctrls) 17505b261ecSmrg * 17605b261ecSmrg * This function reports the effect of applying the specified 17705b261ecSmrg * indicator map given the specified state and controls, as 17805b261ecSmrg * described in section 9.2 of the XKB protocol specification. 17905b261ecSmrg */ 18005b261ecSmrg 18105b261ecSmrgstatic Bool 18205b261ecSmrgComputeAutoState( XkbIndicatorMapPtr map, 18305b261ecSmrg XkbStatePtr state, 18405b261ecSmrg XkbControlsPtr ctrls) 18505b261ecSmrg{ 18605b261ecSmrgBool on; 18705b261ecSmrgCARD8 mods,group; 18805b261ecSmrg 1896747b715Smrg on= FALSE; 19005b261ecSmrg mods= group= 0; 19105b261ecSmrg if (map->which_mods&XkbIM_UseAnyMods) { 19205b261ecSmrg if (map->which_mods&XkbIM_UseBase) 19305b261ecSmrg mods|= state->base_mods; 19405b261ecSmrg if (map->which_mods&XkbIM_UseLatched) 19505b261ecSmrg mods|= state->latched_mods; 19605b261ecSmrg if (map->which_mods&XkbIM_UseLocked) 19705b261ecSmrg mods|= state->locked_mods; 19805b261ecSmrg if (map->which_mods&XkbIM_UseEffective) 19905b261ecSmrg mods|= state->mods; 20005b261ecSmrg if (map->which_mods&XkbIM_UseCompat) 20105b261ecSmrg mods|= state->compat_state; 20205b261ecSmrg on = ((map->mods.mask&mods)!=0); 20305b261ecSmrg on = on||((mods==0)&&(map->mods.mask==0)&&(map->mods.vmods==0)); 20405b261ecSmrg } 20505b261ecSmrg if (map->which_groups&XkbIM_UseAnyGroup) { 20605b261ecSmrg if (map->which_groups&XkbIM_UseBase) 20705b261ecSmrg group|= (1L << state->base_group); 20805b261ecSmrg if (map->which_groups&XkbIM_UseLatched) 20905b261ecSmrg group|= (1L << state->latched_group); 21005b261ecSmrg if (map->which_groups&XkbIM_UseLocked) 21105b261ecSmrg group|= (1L << state->locked_group); 21205b261ecSmrg if (map->which_groups&XkbIM_UseEffective) 21305b261ecSmrg group|= (1L << state->group); 21405b261ecSmrg on = on||(((map->groups&group)!=0)||(map->groups==0)); 21505b261ecSmrg } 21605b261ecSmrg if (map->ctrls) 21705b261ecSmrg on = on||(ctrls->enabled_ctrls&map->ctrls); 21805b261ecSmrg return on; 21905b261ecSmrg} 22005b261ecSmrg 22105b261ecSmrg 22205b261ecSmrgstatic void 22305b261ecSmrgXkbUpdateLedAutoState( DeviceIntPtr dev, 22405b261ecSmrg XkbSrvLedInfoPtr sli, 22505b261ecSmrg unsigned maps_to_check, 22605b261ecSmrg xkbExtensionDeviceNotify * ed, 22705b261ecSmrg XkbChangesPtr changes, 22805b261ecSmrg XkbEventCausePtr cause) 22905b261ecSmrg{ 23005b261ecSmrgDeviceIntPtr kbd; 23105b261ecSmrgXkbStatePtr state; 23205b261ecSmrgXkbControlsPtr ctrls; 23305b261ecSmrgXkbChangesRec my_changes; 23405b261ecSmrgxkbExtensionDeviceNotify my_ed; 23505b261ecSmrgregister unsigned i,bit,affected; 23605b261ecSmrgregister XkbIndicatorMapPtr map; 23705b261ecSmrgunsigned oldState; 23805b261ecSmrg 23905b261ecSmrg if ((maps_to_check==0)||(sli->maps==NULL)||(sli->mapsPresent==0)) 24005b261ecSmrg return; 24105b261ecSmrg 24205b261ecSmrg if (dev->key && dev->key->xkbInfo) 24305b261ecSmrg kbd= dev; 2444642e01fSmrg else kbd= inputInfo.keyboard; 24505b261ecSmrg 24605b261ecSmrg state= &kbd->key->xkbInfo->state; 24705b261ecSmrg ctrls= kbd->key->xkbInfo->desc->ctrls; 24805b261ecSmrg affected= maps_to_check; 24905b261ecSmrg oldState= sli->effectiveState; 25005b261ecSmrg sli->autoState&= ~affected; 25105b261ecSmrg for (i=0,bit=1;(i<XkbNumIndicators)&&(affected);i++,bit<<=1) { 25205b261ecSmrg if ((affected&bit)==0) 25305b261ecSmrg continue; 25405b261ecSmrg affected&= ~bit; 25505b261ecSmrg map= &sli->maps[i]; 25605b261ecSmrg if((!(map->flags&XkbIM_NoAutomatic))&&ComputeAutoState(map,state,ctrls)) 25705b261ecSmrg sli->autoState|= bit; 25805b261ecSmrg } 25905b261ecSmrg sli->effectiveState= (sli->autoState|sli->explicitState); 26005b261ecSmrg affected= sli->effectiveState^oldState; 26105b261ecSmrg if (affected==0) 26205b261ecSmrg return; 26305b261ecSmrg 26405b261ecSmrg if (ed==NULL) { 26505b261ecSmrg ed= &my_ed; 2666747b715Smrg memset((char *)ed, 0, sizeof(xkbExtensionDeviceNotify)); 26705b261ecSmrg } 26805b261ecSmrg else if ((ed->reason&XkbXI_IndicatorsMask)&& 26905b261ecSmrg ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) { 27005b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause); 27105b261ecSmrg } 27205b261ecSmrg 27305b261ecSmrg if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) { 27405b261ecSmrg if (changes==NULL) { 27505b261ecSmrg changes= &my_changes; 2766747b715Smrg memset((char *)changes, 0, sizeof(XkbChangesRec)); 27705b261ecSmrg } 27805b261ecSmrg changes->indicators.state_changes|= affected; 27905b261ecSmrg } 28005b261ecSmrg 28105b261ecSmrg ed->reason|= XkbXI_IndicatorStateMask; 28205b261ecSmrg ed->ledClass= sli->class; 28305b261ecSmrg ed->ledID= sli->id; 28405b261ecSmrg ed->ledsDefined= sli->namesPresent|sli->mapsPresent; 28505b261ecSmrg ed->ledState= sli->effectiveState; 2866747b715Smrg ed->unsupported= 0; 28705b261ecSmrg ed->supported= XkbXI_AllFeaturesMask; 28805b261ecSmrg 28905b261ecSmrg if (changes!=&my_changes) changes= NULL; 29005b261ecSmrg if (ed!=&my_ed) ed= NULL; 29105b261ecSmrg if (changes || ed) 29205b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause); 29305b261ecSmrg return; 29405b261ecSmrg} 29505b261ecSmrg 29605b261ecSmrgstatic void 29705b261ecSmrgXkbUpdateAllDeviceIndicators(XkbChangesPtr changes,XkbEventCausePtr cause) 29805b261ecSmrg{ 29905b261ecSmrgDeviceIntPtr edev; 30005b261ecSmrgXkbSrvLedInfoPtr sli; 30105b261ecSmrg 30205b261ecSmrg for (edev=inputInfo.devices;edev!=NULL;edev=edev->next) { 30305b261ecSmrg if (edev->kbdfeed) { 30405b261ecSmrg KbdFeedbackPtr kf; 30505b261ecSmrg for (kf=edev->kbdfeed;kf!=NULL;kf=kf->next) { 30605b261ecSmrg if ((kf->xkb_sli==NULL)||(kf->xkb_sli->maps==NULL)) 30705b261ecSmrg continue; 30805b261ecSmrg sli= kf->xkb_sli; 30905b261ecSmrg XkbUpdateLedAutoState(edev,sli,sli->mapsPresent,NULL, 31005b261ecSmrg changes,cause); 31105b261ecSmrg 31205b261ecSmrg } 31305b261ecSmrg } 31405b261ecSmrg if (edev->leds) { 31505b261ecSmrg LedFeedbackPtr lf; 31605b261ecSmrg for (lf=edev->leds;lf!=NULL;lf=lf->next) { 31705b261ecSmrg if ((lf->xkb_sli==NULL)||(lf->xkb_sli->maps==NULL)) 31805b261ecSmrg continue; 31905b261ecSmrg sli= lf->xkb_sli; 32005b261ecSmrg XkbUpdateLedAutoState(edev,sli,sli->mapsPresent,NULL, 32105b261ecSmrg changes,cause); 32205b261ecSmrg 32305b261ecSmrg } 32405b261ecSmrg } 32505b261ecSmrg } 32605b261ecSmrg return; 32705b261ecSmrg} 32805b261ecSmrg 32905b261ecSmrg 33005b261ecSmrg/***====================================================================***/ 33105b261ecSmrg 33205b261ecSmrg /* 33305b261ecSmrg * void 33405b261ecSmrg * XkbSetIndicators(dev,affect,values,cause) 33505b261ecSmrg * 33605b261ecSmrg * Attempts to change the indicators specified in 'affect' to the 33705b261ecSmrg * states specified in 'values' for the default keyboard feedback 33805b261ecSmrg * on the keyboard specified by 'dev.' Attempts to change indicator 33905b261ecSmrg * state might be ignored or have no affect, depending on the XKB 34005b261ecSmrg * indicator map for any affected indicators, as described in section 34105b261ecSmrg * 9.2 of the XKB protocol specification. 34205b261ecSmrg * 34305b261ecSmrg * If 'changes' is non-NULL, this function notes any changes to the 34405b261ecSmrg * keyboard state, controls, or indicator state that result from this 34505b261ecSmrg * attempted change. If 'changes' is NULL, this function generates 34605b261ecSmrg * XKB events to report any such changes to interested clients. 34705b261ecSmrg * 34805b261ecSmrg * If 'cause' is non-NULL, it specifies the reason for the change, 34905b261ecSmrg * as reported in some XKB events. If it is NULL, this function 35005b261ecSmrg * assumes that the change is the result of a core protocol 35105b261ecSmrg * ChangeKeyboardMapping request. 35205b261ecSmrg */ 35305b261ecSmrg 35405b261ecSmrgvoid 35505b261ecSmrgXkbSetIndicators( DeviceIntPtr dev, 35605b261ecSmrg CARD32 affect, 35705b261ecSmrg CARD32 values, 35805b261ecSmrg XkbEventCausePtr cause) 35905b261ecSmrg{ 36005b261ecSmrgXkbSrvLedInfoPtr sli; 36105b261ecSmrgXkbChangesRec changes; 36205b261ecSmrgxkbExtensionDeviceNotify ed; 36305b261ecSmrgunsigned side_affected; 36405b261ecSmrg 3656747b715Smrg memset((char *)&changes, 0, sizeof(XkbChangesRec)); 3666747b715Smrg memset((char *)&ed, 0, sizeof(xkbExtensionDeviceNotify)); 36705b261ecSmrg sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0); 36805b261ecSmrg sli->explicitState&= ~affect; 36905b261ecSmrg sli->explicitState|= (affect&values); 37005b261ecSmrg XkbApplyLedStateChanges(dev,sli,affect,&ed,&changes,cause); 37105b261ecSmrg 37205b261ecSmrg side_affected= 0; 37305b261ecSmrg if (changes.state_changes!=0) 3746747b715Smrg side_affected|= XkbIndicatorsToUpdate(dev,changes.state_changes,FALSE); 37505b261ecSmrg if (changes.ctrls.enabled_ctrls_changes) 37605b261ecSmrg side_affected|= sli->usesControls; 37705b261ecSmrg 37805b261ecSmrg if (side_affected) { 37905b261ecSmrg XkbUpdateLedAutoState(dev,sli,side_affected,&ed,&changes,cause); 38005b261ecSmrg affect|= side_affected; 38105b261ecSmrg } 38205b261ecSmrg if (changes.state_changes || changes.ctrls.enabled_ctrls_changes) 38305b261ecSmrg XkbUpdateAllDeviceIndicators(NULL,cause); 38405b261ecSmrg 38505b261ecSmrg XkbFlushLedEvents(dev,dev,sli,&ed,&changes,cause); 38605b261ecSmrg return; 38705b261ecSmrg} 38805b261ecSmrg 38905b261ecSmrg/***====================================================================***/ 39005b261ecSmrg 39105b261ecSmrg/***====================================================================***/ 39205b261ecSmrg 39305b261ecSmrg /* 39405b261ecSmrg * void 39505b261ecSmrg * XkbUpdateIndicators(dev,update,check_edevs,changes,cause) 39605b261ecSmrg * 39705b261ecSmrg * Applies the indicator maps for any indicators specified in 39805b261ecSmrg * 'update' from the default keyboard feedback on the device 39905b261ecSmrg * specified by 'dev.' 40005b261ecSmrg * 40105b261ecSmrg * If 'changes' is NULL, this function generates and XKB events 40205b261ecSmrg * required to report the necessary changes, otherwise it simply 40305b261ecSmrg * notes the indicators with changed state. 40405b261ecSmrg * 4056747b715Smrg * If 'check_edevs' is TRUE, this function also checks the indicator 40605b261ecSmrg * maps for any open extension devices that have them, and updates 40705b261ecSmrg * the state of any extension device indicators as necessary. 40805b261ecSmrg */ 40905b261ecSmrg 41005b261ecSmrgvoid 41105b261ecSmrgXkbUpdateIndicators( DeviceIntPtr dev, 41205b261ecSmrg register CARD32 update, 41305b261ecSmrg Bool check_edevs, 41405b261ecSmrg XkbChangesPtr changes, 41505b261ecSmrg XkbEventCausePtr cause) 41605b261ecSmrg{ 41705b261ecSmrgXkbSrvLedInfoPtr sli; 41805b261ecSmrg 41905b261ecSmrg sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0); 42005b261ecSmrg XkbUpdateLedAutoState(dev,sli,update,NULL,changes,cause); 42105b261ecSmrg if (check_edevs) 42205b261ecSmrg XkbUpdateAllDeviceIndicators(changes,cause); 42305b261ecSmrg return; 42405b261ecSmrg} 42505b261ecSmrg 42605b261ecSmrg/***====================================================================***/ 42705b261ecSmrg 42805b261ecSmrg/***====================================================================***/ 42905b261ecSmrg 43005b261ecSmrg /* 43105b261ecSmrg * void 43205b261ecSmrg * XkbCheckIndicatorMaps(dev,sli,which) 43305b261ecSmrg * 43405b261ecSmrg * Updates the 'indicator accelerators' for the indicators specified 43505b261ecSmrg * by 'which' in the feedback specified by 'sli.' The indicator 43605b261ecSmrg * accelerators are internal to the server and are used to simplify 43705b261ecSmrg * and speed up the process of figuring out which indicators might 43805b261ecSmrg * be affected by a particular change in keyboard state or controls. 43905b261ecSmrg */ 44005b261ecSmrg 44105b261ecSmrgvoid 44205b261ecSmrgXkbCheckIndicatorMaps(DeviceIntPtr dev,XkbSrvLedInfoPtr sli,unsigned which) 44305b261ecSmrg{ 44405b261ecSmrgregister unsigned i,bit; 44505b261ecSmrgXkbIndicatorMapPtr map; 44605b261ecSmrgXkbDescPtr xkb; 44705b261ecSmrg 44805b261ecSmrg if ((sli->flags&XkbSLI_HasOwnState)==0) 4494642e01fSmrg return; 45005b261ecSmrg 45105b261ecSmrg sli->usesBase&= ~which; 45205b261ecSmrg sli->usesLatched&= ~which; 45305b261ecSmrg sli->usesLocked&= ~which; 45405b261ecSmrg sli->usesEffective&= ~which; 45505b261ecSmrg sli->usesCompat&= ~which; 45605b261ecSmrg sli->usesControls&= ~which; 45705b261ecSmrg sli->mapsPresent&= ~which; 45805b261ecSmrg 45905b261ecSmrg xkb= dev->key->xkbInfo->desc; 46005b261ecSmrg for (i=0,bit=1,map=sli->maps;i<XkbNumIndicators;i++,bit<<=1,map++) { 46105b261ecSmrg if (which&bit) { 46205b261ecSmrg CARD8 what; 46305b261ecSmrg 4644642e01fSmrg if (!map || !XkbIM_InUse(map)) 46505b261ecSmrg continue; 46605b261ecSmrg sli->mapsPresent|= bit; 46705b261ecSmrg 46805b261ecSmrg what= (map->which_mods|map->which_groups); 46905b261ecSmrg if (what&XkbIM_UseBase) 47005b261ecSmrg sli->usesBase|= bit; 47105b261ecSmrg if (what&XkbIM_UseLatched) 47205b261ecSmrg sli->usesLatched|= bit; 47305b261ecSmrg if (what&XkbIM_UseLocked) 47405b261ecSmrg sli->usesLocked|= bit; 47505b261ecSmrg if (what&XkbIM_UseEffective) 47605b261ecSmrg sli->usesEffective|= bit; 47705b261ecSmrg if (what&XkbIM_UseCompat) 47805b261ecSmrg sli->usesCompat|= bit; 47905b261ecSmrg if (map->ctrls) 48005b261ecSmrg sli->usesControls|= bit; 48105b261ecSmrg 48205b261ecSmrg map->mods.mask= map->mods.real_mods; 48305b261ecSmrg if (map->mods.vmods!=0) { 48405b261ecSmrg map->mods.mask|= XkbMaskForVMask(xkb,map->mods.vmods); 48505b261ecSmrg } 48605b261ecSmrg } 48705b261ecSmrg } 48805b261ecSmrg sli->usedComponents= 0; 48905b261ecSmrg if (sli->usesBase) 49005b261ecSmrg sli->usedComponents|= XkbModifierBaseMask|XkbGroupBaseMask; 49105b261ecSmrg if (sli->usesLatched) 49205b261ecSmrg sli->usedComponents|= XkbModifierLatchMask|XkbGroupLatchMask; 49305b261ecSmrg if (sli->usesLocked) 49405b261ecSmrg sli->usedComponents|= XkbModifierLockMask|XkbGroupLockMask; 49505b261ecSmrg if (sli->usesEffective) 49605b261ecSmrg sli->usedComponents|= XkbModifierStateMask|XkbGroupStateMask; 49705b261ecSmrg if (sli->usesCompat) 49805b261ecSmrg sli->usedComponents|= XkbCompatStateMask; 49905b261ecSmrg return; 50005b261ecSmrg} 50105b261ecSmrg 50205b261ecSmrg/***====================================================================***/ 50305b261ecSmrg 50405b261ecSmrg /* 50505b261ecSmrg * XkbSrvLedInfoPtr 50605b261ecSmrg * XkbAllocSrvLedInfo(dev,kf,lf,needed_parts) 50705b261ecSmrg * 50805b261ecSmrg * Allocates an XkbSrvLedInfoPtr for the feedback specified by either 50905b261ecSmrg * 'kf' or 'lf' on the keyboard specified by 'dev.' 51005b261ecSmrg * 51105b261ecSmrg * If 'needed_parts' is non-zero, this function makes sure that any 51205b261ecSmrg * of the parts speicified therein are allocated. 51305b261ecSmrg */ 51405b261ecSmrgXkbSrvLedInfoPtr 51505b261ecSmrgXkbAllocSrvLedInfo( DeviceIntPtr dev, 51605b261ecSmrg KbdFeedbackPtr kf, 51705b261ecSmrg LedFeedbackPtr lf, 51805b261ecSmrg unsigned needed_parts) 51905b261ecSmrg{ 52005b261ecSmrgXkbSrvLedInfoPtr sli; 52105b261ecSmrgBool checkAccel; 52205b261ecSmrgBool checkNames; 52305b261ecSmrg 52405b261ecSmrg sli= NULL; 5256747b715Smrg checkAccel= checkNames= FALSE; 52605b261ecSmrg if ((kf!=NULL)&&(kf->xkb_sli==NULL)) { 5276747b715Smrg kf->xkb_sli= sli= calloc(1, sizeof(XkbSrvLedInfoRec)); 52805b261ecSmrg if (sli==NULL) 52905b261ecSmrg return NULL; /* ALLOCATION ERROR */ 53005b261ecSmrg if (dev->key && dev->key->xkbInfo) 53105b261ecSmrg sli->flags= XkbSLI_HasOwnState; 53205b261ecSmrg else sli->flags= 0; 53305b261ecSmrg sli->class= KbdFeedbackClass; 53405b261ecSmrg sli->id= kf->ctrl.id; 53505b261ecSmrg sli->fb.kf= kf; 53605b261ecSmrg 53705b261ecSmrg sli->autoState= 0; 53805b261ecSmrg sli->explicitState= kf->ctrl.leds; 53905b261ecSmrg sli->effectiveState= kf->ctrl.leds; 54005b261ecSmrg 54105b261ecSmrg if ((kf==dev->kbdfeed) && (dev->key) && (dev->key->xkbInfo)) { 54205b261ecSmrg XkbDescPtr xkb; 54305b261ecSmrg xkb= dev->key->xkbInfo->desc; 54405b261ecSmrg sli->flags|= XkbSLI_IsDefault; 54505b261ecSmrg sli->physIndicators= xkb->indicators->phys_indicators; 54605b261ecSmrg sli->names= xkb->names->indicators; 54705b261ecSmrg sli->maps= xkb->indicators->maps; 5486747b715Smrg checkNames= checkAccel= TRUE; 54905b261ecSmrg } 55005b261ecSmrg else { 55105b261ecSmrg sli->physIndicators= XkbAllIndicatorsMask; 55205b261ecSmrg sli->names= NULL; 55305b261ecSmrg sli->maps= NULL; 55405b261ecSmrg } 55505b261ecSmrg } 55605b261ecSmrg else if ((kf!=NULL)&&((kf->xkb_sli->flags&XkbSLI_IsDefault)!=0)) { 55705b261ecSmrg XkbDescPtr xkb; 55805b261ecSmrg xkb= dev->key->xkbInfo->desc; 55905b261ecSmrg sli->physIndicators= xkb->indicators->phys_indicators; 56005b261ecSmrg if (xkb->names->indicators!=sli->names) { 5616747b715Smrg checkNames= TRUE; 56205b261ecSmrg sli->names= xkb->names->indicators; 56305b261ecSmrg } 56405b261ecSmrg if (xkb->indicators->maps!=sli->maps) { 5656747b715Smrg checkAccel= TRUE; 56605b261ecSmrg sli->maps= xkb->indicators->maps; 56705b261ecSmrg } 56805b261ecSmrg } 56905b261ecSmrg else if ((lf!=NULL)&&(lf->xkb_sli==NULL)) { 5706747b715Smrg lf->xkb_sli= sli= calloc(1, sizeof(XkbSrvLedInfoRec)); 57105b261ecSmrg if (sli==NULL) 57205b261ecSmrg return NULL; /* ALLOCATION ERROR */ 57305b261ecSmrg if (dev->key && dev->key->xkbInfo) 57405b261ecSmrg sli->flags= XkbSLI_HasOwnState; 57505b261ecSmrg else sli->flags= 0; 57605b261ecSmrg sli->class= LedFeedbackClass; 57705b261ecSmrg sli->id= lf->ctrl.id; 57805b261ecSmrg sli->fb.lf= lf; 57905b261ecSmrg 58005b261ecSmrg sli->physIndicators= lf->ctrl.led_mask; 58105b261ecSmrg sli->autoState= 0; 58205b261ecSmrg sli->explicitState= lf->ctrl.led_values; 58305b261ecSmrg sli->effectiveState= lf->ctrl.led_values; 58405b261ecSmrg sli->maps= NULL; 58505b261ecSmrg sli->names= NULL; 58605b261ecSmrg } 58705b261ecSmrg if ((sli->names==NULL)&&(needed_parts&XkbXI_IndicatorNamesMask)) 5886747b715Smrg sli->names= calloc(XkbNumIndicators, sizeof(Atom)); 58905b261ecSmrg if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask)) 5906747b715Smrg sli->maps= calloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec)); 59105b261ecSmrg if (checkNames) { 59205b261ecSmrg register unsigned i,bit; 59305b261ecSmrg sli->namesPresent= 0; 59405b261ecSmrg for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { 59505b261ecSmrg if (sli->names[i]!=None) 59605b261ecSmrg sli->namesPresent|= bit; 59705b261ecSmrg } 59805b261ecSmrg } 59905b261ecSmrg if (checkAccel) 60005b261ecSmrg XkbCheckIndicatorMaps(dev,sli,XkbAllIndicatorsMask); 60105b261ecSmrg return sli; 60205b261ecSmrg} 60305b261ecSmrg 60405b261ecSmrgvoid 60505b261ecSmrgXkbFreeSrvLedInfo(XkbSrvLedInfoPtr sli) 60605b261ecSmrg{ 60705b261ecSmrg if ((sli->flags&XkbSLI_IsDefault)==0) { 6086747b715Smrg free(sli->maps); 6096747b715Smrg free(sli->names); 61005b261ecSmrg } 61105b261ecSmrg sli->maps= NULL; 61205b261ecSmrg sli->names= NULL; 6136747b715Smrg free(sli); 61405b261ecSmrg return; 61505b261ecSmrg} 61605b261ecSmrg 6174642e01fSmrg/* 6184642e01fSmrg * XkbSrvLedInfoPtr 6194642e01fSmrg * XkbCopySrvLedInfo(dev,src,kf,lf) 6204642e01fSmrg * 6214642e01fSmrg * Takes the given XkbSrvLedInfoPtr and duplicates it. A deep copy is made, 6224642e01fSmrg * thus the new copy behaves like the original one and can be freed with 6234642e01fSmrg * XkbFreeSrvLedInfo. 6244642e01fSmrg */ 6254642e01fSmrgXkbSrvLedInfoPtr 6264642e01fSmrgXkbCopySrvLedInfo( DeviceIntPtr from, 6274642e01fSmrg XkbSrvLedInfoPtr src, 6284642e01fSmrg KbdFeedbackPtr kf, 6294642e01fSmrg LedFeedbackPtr lf) 6304642e01fSmrg{ 6314642e01fSmrg XkbSrvLedInfoPtr sli_new = NULL; 6324642e01fSmrg 6334642e01fSmrg if (!src) 6344642e01fSmrg goto finish; 6354642e01fSmrg 6366747b715Smrg sli_new = calloc(1, sizeof( XkbSrvLedInfoRec)); 6374642e01fSmrg if (!sli_new) 6384642e01fSmrg goto finish; 6394642e01fSmrg 6404642e01fSmrg memcpy(sli_new, src, sizeof(XkbSrvLedInfoRec)); 6414642e01fSmrg if (sli_new->class == KbdFeedbackClass) 6424642e01fSmrg sli_new->fb.kf = kf; 6434642e01fSmrg else 6444642e01fSmrg sli_new->fb.lf = lf; 6454642e01fSmrg 6466747b715Smrg if (!(sli_new->flags & XkbSLI_IsDefault)) { 6476747b715Smrg sli_new->names= calloc(XkbNumIndicators, sizeof(Atom)); 6486747b715Smrg sli_new->maps= calloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec)); 6494642e01fSmrg } /* else sli_new->names/maps is pointing to 6504642e01fSmrg dev->key->xkbInfo->desc->names->indicators; 6514642e01fSmrg dev->key->xkbInfo->desc->names->indicators; */ 6524642e01fSmrg 6534642e01fSmrgfinish: 6544642e01fSmrg return sli_new; 6554642e01fSmrg} 65605b261ecSmrg 65705b261ecSmrg/***====================================================================***/ 65805b261ecSmrg 65905b261ecSmrg /* 66005b261ecSmrg * XkbSrvLedInfoPtr 66105b261ecSmrg * XkbFindSrvLedInfo(dev,class,id,needed_parts) 66205b261ecSmrg * 66305b261ecSmrg * Finds the XkbSrvLedInfoPtr for the specified 'class' and 'id' 66405b261ecSmrg * on the device specified by 'dev.' If the class and id specify 66505b261ecSmrg * a valid device feedback, this function returns the existing 66605b261ecSmrg * feedback or allocates a new one. 66705b261ecSmrg * 66805b261ecSmrg */ 66905b261ecSmrg 6706747b715SmrgXkbSrvLedInfoPtr 67105b261ecSmrgXkbFindSrvLedInfo( DeviceIntPtr dev, 67205b261ecSmrg unsigned class, 67305b261ecSmrg unsigned id, 67405b261ecSmrg unsigned needed_parts) 67505b261ecSmrg{ 67605b261ecSmrgXkbSrvLedInfoPtr sli; 67705b261ecSmrg 67805b261ecSmrg /* optimization to check for most common case */ 67905b261ecSmrg if (((class==XkbDfltXIClass)&&(id==XkbDfltXIId))&&(dev->kbdfeed)) { 68005b261ecSmrg XkbSrvLedInfoPtr sli; 68105b261ecSmrg sli= dev->kbdfeed->xkb_sli; 68205b261ecSmrg if (dev->kbdfeed->xkb_sli==NULL) { 68305b261ecSmrg sli= XkbAllocSrvLedInfo(dev,dev->kbdfeed,NULL,needed_parts); 68405b261ecSmrg dev->kbdfeed->xkb_sli= sli; 68505b261ecSmrg } 68605b261ecSmrg return dev->kbdfeed->xkb_sli; 68705b261ecSmrg } 68805b261ecSmrg 68905b261ecSmrg sli= NULL; 69005b261ecSmrg if (class==XkbDfltXIClass) { 69105b261ecSmrg if (dev->kbdfeed) class= KbdFeedbackClass; 69205b261ecSmrg else if (dev->leds) class= LedFeedbackClass; 69305b261ecSmrg else return NULL; 69405b261ecSmrg } 69505b261ecSmrg if (class==KbdFeedbackClass) { 69605b261ecSmrg KbdFeedbackPtr kf; 69705b261ecSmrg for (kf=dev->kbdfeed;kf!=NULL;kf=kf->next) { 69805b261ecSmrg if ((id==XkbDfltXIId)||(id==kf->ctrl.id)) { 69905b261ecSmrg if (kf->xkb_sli==NULL) 70005b261ecSmrg kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,needed_parts); 70105b261ecSmrg sli= kf->xkb_sli; 70205b261ecSmrg break; 70305b261ecSmrg } 70405b261ecSmrg } 70505b261ecSmrg } 70605b261ecSmrg else if (class==LedFeedbackClass) { 70705b261ecSmrg LedFeedbackPtr lf; 70805b261ecSmrg for (lf=dev->leds;lf!=NULL;lf=lf->next) { 70905b261ecSmrg if ((id==XkbDfltXIId)||(id==lf->ctrl.id)) { 71005b261ecSmrg if (lf->xkb_sli==NULL) 71105b261ecSmrg lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,needed_parts); 71205b261ecSmrg sli= lf->xkb_sli; 71305b261ecSmrg break; 71405b261ecSmrg } 71505b261ecSmrg } 71605b261ecSmrg } 71705b261ecSmrg if ((sli->names==NULL)&&(needed_parts&XkbXI_IndicatorNamesMask)) 7186747b715Smrg sli->names= calloc(XkbNumIndicators, sizeof(Atom)); 71905b261ecSmrg if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask)) 7206747b715Smrg sli->maps= calloc(XkbNumIndicators, sizeof(XkbIndicatorMapRec)); 72105b261ecSmrg return sli; 72205b261ecSmrg} 72305b261ecSmrg 72405b261ecSmrg/***====================================================================***/ 72505b261ecSmrg 72605b261ecSmrgvoid 72705b261ecSmrgXkbFlushLedEvents( DeviceIntPtr dev, 72805b261ecSmrg DeviceIntPtr kbd, 72905b261ecSmrg XkbSrvLedInfoPtr sli, 73005b261ecSmrg xkbExtensionDeviceNotify * ed, 73105b261ecSmrg XkbChangesPtr changes, 73205b261ecSmrg XkbEventCausePtr cause) 73305b261ecSmrg{ 73405b261ecSmrg if (changes) { 73505b261ecSmrg if (changes->indicators.state_changes) 73605b261ecSmrg XkbDDXUpdateDeviceIndicators(dev,sli,sli->effectiveState); 73705b261ecSmrg XkbSendNotification(kbd,changes,cause); 7386747b715Smrg memset((char *)changes, 0, sizeof(XkbChangesRec)); 73905b261ecSmrg 74005b261ecSmrg if (XkbAX_NeedFeedback(kbd->key->xkbInfo->desc->ctrls, XkbAX_IndicatorFBMask)) { 74105b261ecSmrg if (sli->effectiveState) 74205b261ecSmrg /* it appears that the which parameter is not used */ 74305b261ecSmrg XkbDDXAccessXBeep(dev, _BEEP_LED_ON, XkbAccessXFeedbackMask); 74405b261ecSmrg else 74505b261ecSmrg XkbDDXAccessXBeep(dev, _BEEP_LED_OFF, XkbAccessXFeedbackMask); 74605b261ecSmrg } 74705b261ecSmrg } 7486747b715Smrg if (ed) { 7496747b715Smrg if (ed->reason) { 7506747b715Smrg if ((dev!=kbd)&&(ed->reason&XkbXI_IndicatorStateMask)) 7516747b715Smrg XkbDDXUpdateDeviceIndicators(dev,sli,sli->effectiveState); 7526747b715Smrg XkbSendExtensionDeviceNotify(dev,cause->client,ed); 7536747b715Smrg } 7546747b715Smrg memset((char *)ed, 0, sizeof(XkbExtensionDeviceNotify)); 75505b261ecSmrg } 75605b261ecSmrg return; 75705b261ecSmrg} 75805b261ecSmrg 75905b261ecSmrg/***====================================================================***/ 76005b261ecSmrg 76105b261ecSmrgvoid 76205b261ecSmrgXkbApplyLedNameChanges( DeviceIntPtr dev, 76305b261ecSmrg XkbSrvLedInfoPtr sli, 76405b261ecSmrg unsigned changed_names, 76505b261ecSmrg xkbExtensionDeviceNotify * ed, 76605b261ecSmrg XkbChangesPtr changes, 76705b261ecSmrg XkbEventCausePtr cause) 76805b261ecSmrg{ 76905b261ecSmrgDeviceIntPtr kbd; 77005b261ecSmrgXkbChangesRec my_changes; 77105b261ecSmrgxkbExtensionDeviceNotify my_ed; 77205b261ecSmrg 77305b261ecSmrg if (changed_names==0) 77405b261ecSmrg return; 77505b261ecSmrg if (dev->key && dev->key->xkbInfo) 77605b261ecSmrg kbd= dev; 7774642e01fSmrg else kbd= inputInfo.keyboard; 77805b261ecSmrg 77905b261ecSmrg if (ed==NULL) { 78005b261ecSmrg ed= &my_ed; 7816747b715Smrg memset((char *)ed, 0, sizeof(xkbExtensionDeviceNotify)); 78205b261ecSmrg } 78305b261ecSmrg else if ((ed->reason&XkbXI_IndicatorsMask)&& 78405b261ecSmrg ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) { 78505b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause); 78605b261ecSmrg } 78705b261ecSmrg 78805b261ecSmrg if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) { 78905b261ecSmrg if (changes==NULL) { 79005b261ecSmrg changes= &my_changes; 7916747b715Smrg memset((char *)changes, 0, sizeof(XkbChangesRec)); 79205b261ecSmrg } 79305b261ecSmrg changes->names.changed|= XkbIndicatorNamesMask; 79405b261ecSmrg changes->names.changed_indicators|= changed_names; 79505b261ecSmrg } 79605b261ecSmrg 79705b261ecSmrg ed->reason|= XkbXI_IndicatorNamesMask; 79805b261ecSmrg ed->ledClass= sli->class; 79905b261ecSmrg ed->ledID= sli->id; 80005b261ecSmrg ed->ledsDefined= sli->namesPresent|sli->mapsPresent; 80105b261ecSmrg ed->ledState= sli->effectiveState; 80205b261ecSmrg ed->unsupported= 0; 80305b261ecSmrg ed->supported= XkbXI_AllFeaturesMask; 80405b261ecSmrg 80505b261ecSmrg if (changes!=&my_changes) changes= NULL; 80605b261ecSmrg if (ed!=&my_ed) ed= NULL; 80705b261ecSmrg if (changes || ed) 80805b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause); 80905b261ecSmrg return; 81005b261ecSmrg} 81105b261ecSmrg/***====================================================================***/ 81205b261ecSmrg 81305b261ecSmrg /* 81405b261ecSmrg * void 81505b261ecSmrg * XkbApplyLedMapChanges(dev,sli,changed_maps,changes,cause) 81605b261ecSmrg * 81705b261ecSmrg * Handles all of the secondary effects of the changes to the 81805b261ecSmrg * feedback specified by 'sli' on the device specified by 'dev.' 81905b261ecSmrg * 82005b261ecSmrg * If 'changed_maps' specifies any indicators, this function generates 82105b261ecSmrg * XkbExtensionDeviceNotify events and possibly IndicatorMapNotify 82205b261ecSmrg * events to report the changes, and recalculates the effective 82305b261ecSmrg * state of each indicator with a changed map. If any indicators 82405b261ecSmrg * change state, the server generates XkbExtensionDeviceNotify and 82505b261ecSmrg * XkbIndicatorStateNotify events as appropriate. 82605b261ecSmrg * 82705b261ecSmrg * If 'changes' is non-NULL, this function updates it to reflect 82805b261ecSmrg * any changes to the keyboard state or controls or to the 'core' 82905b261ecSmrg * indicator names, maps, or state. If 'changes' is NULL, this 83005b261ecSmrg * function generates XKB events as needed to report the changes. 83105b261ecSmrg * If 'dev' is not a keyboard device, any changes are reported 83205b261ecSmrg * for the core keyboard. 83305b261ecSmrg * 83405b261ecSmrg * The 'cause' specifies the reason for the event (key event or 83505b261ecSmrg * request) for the change, as reported in some XKB events. 83605b261ecSmrg */ 83705b261ecSmrg 83805b261ecSmrgvoid 83905b261ecSmrgXkbApplyLedMapChanges( DeviceIntPtr dev, 84005b261ecSmrg XkbSrvLedInfoPtr sli, 84105b261ecSmrg unsigned changed_maps, 84205b261ecSmrg xkbExtensionDeviceNotify * ed, 84305b261ecSmrg XkbChangesPtr changes, 84405b261ecSmrg XkbEventCausePtr cause) 84505b261ecSmrg{ 84605b261ecSmrgDeviceIntPtr kbd; 84705b261ecSmrgXkbChangesRec my_changes; 84805b261ecSmrgxkbExtensionDeviceNotify my_ed; 84905b261ecSmrg 85005b261ecSmrg if (changed_maps==0) 85105b261ecSmrg return; 85205b261ecSmrg if (dev->key && dev->key->xkbInfo) 85305b261ecSmrg kbd= dev; 8544642e01fSmrg else kbd= inputInfo.keyboard; 85505b261ecSmrg 85605b261ecSmrg if (ed==NULL) { 85705b261ecSmrg ed= &my_ed; 8586747b715Smrg memset((char *)ed, 0, sizeof(xkbExtensionDeviceNotify)); 85905b261ecSmrg } 86005b261ecSmrg else if ((ed->reason&XkbXI_IndicatorsMask)&& 86105b261ecSmrg ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) { 86205b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause); 86305b261ecSmrg } 86405b261ecSmrg 86505b261ecSmrg if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) { 86605b261ecSmrg if (changes==NULL) { 86705b261ecSmrg changes= &my_changes; 8686747b715Smrg memset((char *)changes, 0, sizeof(XkbChangesRec)); 86905b261ecSmrg } 87005b261ecSmrg changes->indicators.map_changes|= changed_maps; 87105b261ecSmrg } 87205b261ecSmrg 87305b261ecSmrg XkbCheckIndicatorMaps(dev,sli,changed_maps); 87405b261ecSmrg 87505b261ecSmrg ed->reason|= XkbXI_IndicatorMapsMask; 87605b261ecSmrg ed->ledClass= sli->class; 87705b261ecSmrg ed->ledID= sli->id; 87805b261ecSmrg ed->ledsDefined= sli->namesPresent|sli->mapsPresent; 87905b261ecSmrg ed->ledState= sli->effectiveState; 8806747b715Smrg ed->unsupported= 0; 88105b261ecSmrg ed->supported= XkbXI_AllFeaturesMask; 88205b261ecSmrg 88305b261ecSmrg XkbUpdateLedAutoState(dev,sli,changed_maps,ed,changes,cause); 88405b261ecSmrg 88505b261ecSmrg if (changes!=&my_changes) changes= NULL; 88605b261ecSmrg if (ed!=&my_ed) ed= NULL; 88705b261ecSmrg if (changes || ed) 88805b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause); 88905b261ecSmrg return; 89005b261ecSmrg} 89105b261ecSmrg 89205b261ecSmrg/***====================================================================***/ 89305b261ecSmrg 89405b261ecSmrgvoid 89505b261ecSmrgXkbApplyLedStateChanges(DeviceIntPtr dev, 89605b261ecSmrg XkbSrvLedInfoPtr sli, 89705b261ecSmrg unsigned changed_leds, 89805b261ecSmrg xkbExtensionDeviceNotify * ed, 89905b261ecSmrg XkbChangesPtr changes, 90005b261ecSmrg XkbEventCausePtr cause) 90105b261ecSmrg{ 90205b261ecSmrgXkbSrvInfoPtr xkbi; 90305b261ecSmrgDeviceIntPtr kbd; 90405b261ecSmrgXkbChangesRec my_changes; 90505b261ecSmrgxkbExtensionDeviceNotify my_ed; 90605b261ecSmrgregister unsigned i,bit,affected; 90705b261ecSmrgXkbIndicatorMapPtr map; 90805b261ecSmrgunsigned oldState; 90905b261ecSmrgBool kb_changed; 91005b261ecSmrg 91105b261ecSmrg if (changed_leds==0) 91205b261ecSmrg return; 91305b261ecSmrg if (dev->key && dev->key->xkbInfo) 91405b261ecSmrg kbd= dev; 9154642e01fSmrg else kbd= inputInfo.keyboard; 91605b261ecSmrg xkbi= kbd->key->xkbInfo; 91705b261ecSmrg 91805b261ecSmrg if (changes==NULL) { 91905b261ecSmrg changes= &my_changes; 9206747b715Smrg memset((char *)changes, 0, sizeof(XkbChangesRec)); 92105b261ecSmrg } 92205b261ecSmrg 9236747b715Smrg kb_changed= FALSE; 92405b261ecSmrg affected= changed_leds; 92505b261ecSmrg oldState= sli->effectiveState; 92605b261ecSmrg for (i=0,bit=1;(i<XkbNumIndicators)&&(affected);i++,bit<<=1) { 92705b261ecSmrg if ((affected&bit)==0) 92805b261ecSmrg continue; 92905b261ecSmrg affected&= ~bit; 93005b261ecSmrg map= &sli->maps[i]; 93105b261ecSmrg if (map->flags&XkbIM_NoExplicit) { 93205b261ecSmrg sli->explicitState&= ~bit; 93305b261ecSmrg continue; 93405b261ecSmrg } 93505b261ecSmrg if (map->flags&XkbIM_LEDDrivesKB) { 93605b261ecSmrg Bool on= ((sli->explicitState&bit)!=0); 93705b261ecSmrg if (XkbApplyLEDChangeToKeyboard(xkbi,map,on,changes)) 9386747b715Smrg kb_changed= TRUE; 93905b261ecSmrg } 94005b261ecSmrg } 94105b261ecSmrg sli->effectiveState= (sli->autoState|sli->explicitState); 94205b261ecSmrg affected= sli->effectiveState^oldState; 94305b261ecSmrg 94405b261ecSmrg if (ed==NULL) { 94505b261ecSmrg ed= &my_ed; 9466747b715Smrg memset((char *)ed, 0, sizeof(xkbExtensionDeviceNotify)); 94705b261ecSmrg } 94805b261ecSmrg else if (affected&&(ed->reason&XkbXI_IndicatorsMask)&& 94905b261ecSmrg ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) { 95005b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause); 95105b261ecSmrg } 95205b261ecSmrg 95305b261ecSmrg if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) 95405b261ecSmrg changes->indicators.state_changes|= affected; 95505b261ecSmrg if (affected) { 95605b261ecSmrg ed->reason|= XkbXI_IndicatorStateMask; 95705b261ecSmrg ed->ledClass= sli->class; 95805b261ecSmrg ed->ledID= sli->id; 95905b261ecSmrg ed->ledsDefined= sli->namesPresent|sli->mapsPresent; 96005b261ecSmrg ed->ledState= sli->effectiveState; 9616747b715Smrg ed->unsupported= 0; 96205b261ecSmrg ed->supported= XkbXI_AllFeaturesMask; 96305b261ecSmrg } 96405b261ecSmrg 96505b261ecSmrg if (kb_changed) { 96605b261ecSmrg XkbComputeDerivedState(kbd->key->xkbInfo); 96705b261ecSmrg XkbUpdateLedAutoState(dev,sli,sli->mapsPresent,ed,changes,cause); 96805b261ecSmrg } 96905b261ecSmrg 97005b261ecSmrg if (changes!=&my_changes) changes= NULL; 97105b261ecSmrg if (ed!=&my_ed) ed= NULL; 97205b261ecSmrg if (changes || ed) 97305b261ecSmrg XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause); 97405b261ecSmrg if (kb_changed) 97505b261ecSmrg XkbUpdateAllDeviceIndicators(NULL,cause); 97605b261ecSmrg return; 97705b261ecSmrg} 978