1 /************************************************************
2 Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
4 Permission to use, copy, modify, and distribute this
5 software and its documentation for any purpose and without
6 fee is hereby granted, provided that the above copyright
7 notice appear in all copies and that both that copyright
8 notice and this permission notice appear in supporting
9 documentation, and that the name of Silicon Graphics not be
10 used in advertising or publicity pertaining to distribution
11 of the software without specific prior written permission.
12 Silicon Graphics makes no representation about the suitability
13 of this software for any purpose. It is provided "as is"
14 without any express or implied warranty.
16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 ********************************************************/
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
36 #include <X11/Xproto.h>
40 #include <X11/extensions/XI.h>
44 /***====================================================================***/
48 * XkbIndicatorsToUpdate(dev,changed,check_devs_rtrn)
50 * Given a keyboard and a set of state components that have changed,
51 * this function returns the indicators on the default keyboard
52 * feedback that might be affected. It also reports whether or not
53 * any extension devices might be affected in check_devs_rtrn.
57 XkbIndicatorsToUpdate( DeviceIntPtr dev
,
58 unsigned long state_changes
,
61 register unsigned update
= 0;
64 sli
= XkbFindSrvLedInfo(dev
,XkbDfltXIClass
,XkbDfltXIId
,0);
66 if (state_changes
&(XkbModifierStateMask
|XkbGroupStateMask
))
67 update
|= sli
->usesEffective
;
68 if (state_changes
&(XkbModifierBaseMask
|XkbGroupBaseMask
))
69 update
|= sli
->usesBase
;
70 if (state_changes
&(XkbModifierLatchMask
|XkbGroupLatchMask
))
71 update
|= sli
->usesLatched
;
72 if (state_changes
&(XkbModifierLockMask
|XkbGroupLockMask
))
73 update
|= sli
->usesLocked
;
74 if (state_changes
&XkbCompatStateMask
)
75 update
|= sli
->usesCompat
;
77 update
|= sli
->usesControls
;
81 /***====================================================================***/
85 *XkbApplyLEDChangeToKeyboard(xkbi,map,on,change)
87 * Some indicators "drive" the keyboard when their state is explicitly
88 * changed, as described in section 9.2.1 of the XKB protocol spec.
89 * This function updates the state and controls for the keyboard
90 * specified by 'xkbi' to reflect any changes that are required
91 * when the indicator described by 'map' is turned on or off. The
92 * extent of the changes is reported in change, which must be defined.
95 XkbApplyLEDChangeToKeyboard( XkbSrvInfoPtr xkbi
,
96 XkbIndicatorMapPtr map
,
100 Bool ctrlChange
,stateChange
;
103 if ((map
->flags
&XkbIM_NoExplicit
)||((map
->flags
&XkbIM_LEDDrivesKB
)==0))
105 ctrlChange
= stateChange
= False
;
107 XkbControlsPtr ctrls
= xkbi
->desc
->ctrls
;
110 old
= ctrls
->enabled_ctrls
;
111 if (on
) ctrls
->enabled_ctrls
|= map
->ctrls
;
112 else ctrls
->enabled_ctrls
&= ~map
->ctrls
;
113 if (old
!=ctrls
->enabled_ctrls
) {
114 change
->ctrls
.changed_ctrls
= XkbControlsEnabledMask
;
115 change
->ctrls
.enabled_ctrls_changes
= old
^ctrls
->enabled_ctrls
;
120 if ((map
->groups
)&&((map
->which_groups
&(~XkbIM_UseBase
))!=0)) {
122 register unsigned bit
,match
;
124 if (on
) match
= (map
->groups
)&XkbAllGroupsMask
;
125 else match
= (~map
->groups
)&XkbAllGroupsMask
;
126 if (map
->which_groups
&(XkbIM_UseLocked
|XkbIM_UseEffective
)) {
127 for (i
=0,bit
=1;i
<XkbNumKbdGroups
;i
++,bit
<<=1) {
131 if (map
->which_groups
&XkbIM_UseLatched
)
132 XkbLatchGroup(xkbi
->device
,0); /* unlatch group */
133 state
->locked_group
= i
;
136 else if (map
->which_groups
&(XkbIM_UseLatched
|XkbIM_UseEffective
)) {
137 for (i
=0,bit
=1;i
<XkbNumKbdGroups
;i
++,bit
<<=1) {
141 state
->locked_group
= 0;
142 XkbLatchGroup(xkbi
->device
,i
);
146 if ((map
->mods
.mask
)&&((map
->which_mods
&(~XkbIM_UseBase
))!=0)) {
147 if (map
->which_mods
&(XkbIM_UseLocked
|XkbIM_UseEffective
)) {
148 register unsigned long old
;
149 old
= state
->locked_mods
;
150 if (on
) state
->locked_mods
|= map
->mods
.mask
;
151 else state
->locked_mods
&= ~map
->mods
.mask
;
152 if (state
->locked_mods
!=old
)
155 if (map
->which_mods
&(XkbIM_UseLatched
|XkbIM_UseEffective
)) {
156 register unsigned long newmods
;
157 newmods
= state
->latched_mods
;
158 if (on
) newmods
|= map
->mods
.mask
;
159 else newmods
&= ~map
->mods
.mask
;
160 if (newmods
!=state
->locked_mods
) {
161 newmods
&= map
->mods
.mask
;
162 XkbLatchModifiers(xkbi
->device
,map
->mods
.mask
,newmods
);
167 return (stateChange
|| ctrlChange
);
172 * ComputeAutoState(map,state,ctrls)
174 * This function reports the effect of applying the specified
175 * indicator map given the specified state and controls, as
176 * described in section 9.2 of the XKB protocol specification.
180 ComputeAutoState( XkbIndicatorMapPtr map
,
182 XkbControlsPtr ctrls
)
189 if (map
->which_mods
&XkbIM_UseAnyMods
) {
190 if (map
->which_mods
&XkbIM_UseBase
)
191 mods
|= state
->base_mods
;
192 if (map
->which_mods
&XkbIM_UseLatched
)
193 mods
|= state
->latched_mods
;
194 if (map
->which_mods
&XkbIM_UseLocked
)
195 mods
|= state
->locked_mods
;
196 if (map
->which_mods
&XkbIM_UseEffective
)
198 if (map
->which_mods
&XkbIM_UseCompat
)
199 mods
|= state
->compat_state
;
200 on
= ((map
->mods
.mask
&mods
)!=0);
201 on
= on
||((mods
==0)&&(map
->mods
.mask
==0)&&(map
->mods
.vmods
==0));
203 if (map
->which_groups
&XkbIM_UseAnyGroup
) {
204 if (map
->which_groups
&XkbIM_UseBase
)
205 group
|= (1L << state
->base_group
);
206 if (map
->which_groups
&XkbIM_UseLatched
)
207 group
|= (1L << state
->latched_group
);
208 if (map
->which_groups
&XkbIM_UseLocked
)
209 group
|= (1L << state
->locked_group
);
210 if (map
->which_groups
&XkbIM_UseEffective
)
211 group
|= (1L << state
->group
);
212 on
= on
||(((map
->groups
&group
)!=0)||(map
->groups
==0));
215 on
= on
||(ctrls
->enabled_ctrls
&map
->ctrls
);
221 XkbUpdateLedAutoState( DeviceIntPtr dev
,
222 XkbSrvLedInfoPtr sli
,
223 unsigned maps_to_check
,
224 xkbExtensionDeviceNotify
* ed
,
225 XkbChangesPtr changes
,
226 XkbEventCausePtr cause
)
230 XkbControlsPtr ctrls
;
231 XkbChangesRec my_changes
;
232 xkbExtensionDeviceNotify my_ed
;
233 register unsigned i
,bit
,affected
;
234 register XkbIndicatorMapPtr map
;
237 if ((maps_to_check
==0)||(sli
->maps
==NULL
)||(sli
->mapsPresent
==0))
240 if (dev
->key
&& dev
->key
->xkbInfo
)
242 else kbd
= (DeviceIntPtr
)LookupKeyboardDevice();
244 state
= &kbd
->key
->xkbInfo
->state
;
245 ctrls
= kbd
->key
->xkbInfo
->desc
->ctrls
;
246 affected
= maps_to_check
;
247 oldState
= sli
->effectiveState
;
248 sli
->autoState
&= ~affected
;
249 for (i
=0,bit
=1;(i
<XkbNumIndicators
)&&(affected
);i
++,bit
<<=1) {
250 if ((affected
&bit
)==0)
254 if((!(map
->flags
&XkbIM_NoAutomatic
))&&ComputeAutoState(map
,state
,ctrls
))
255 sli
->autoState
|= bit
;
257 sli
->effectiveState
= (sli
->autoState
|sli
->explicitState
);
258 affected
= sli
->effectiveState
^oldState
;
264 bzero((char *)ed
,sizeof(xkbExtensionDeviceNotify
));
266 else if ((ed
->reason
&XkbXI_IndicatorsMask
)&&
267 ((ed
->ledClass
!=sli
->class)||(ed
->ledID
!=sli
->id
))) {
268 XkbFlushLedEvents(dev
,kbd
,sli
,ed
,changes
,cause
);
271 if ((kbd
==dev
)&&(sli
->flags
&XkbSLI_IsDefault
)) {
273 changes
= &my_changes
;
274 bzero((char *)changes
,sizeof(XkbChangesRec
));
276 changes
->indicators
.state_changes
|= affected
;
279 ed
->reason
|= XkbXI_IndicatorStateMask
;
280 ed
->ledClass
= sli
->class;
282 ed
->ledsDefined
= sli
->namesPresent
|sli
->mapsPresent
;
283 ed
->ledState
= sli
->effectiveState
;
284 ed
->unsupported
|= XkbXI_IndicatorStateMask
;
285 ed
->supported
= XkbXI_AllFeaturesMask
;
287 if (changes
!=&my_changes
) changes
= NULL
;
288 if (ed
!=&my_ed
) ed
= NULL
;
290 XkbFlushLedEvents(dev
,kbd
,sli
,ed
,changes
,cause
);
295 XkbUpdateAllDeviceIndicators(XkbChangesPtr changes
,XkbEventCausePtr cause
)
298 XkbSrvLedInfoPtr sli
;
300 for (edev
=inputInfo
.devices
;edev
!=NULL
;edev
=edev
->next
) {
303 for (kf
=edev
->kbdfeed
;kf
!=NULL
;kf
=kf
->next
) {
304 if ((kf
->xkb_sli
==NULL
)||(kf
->xkb_sli
->maps
==NULL
))
307 XkbUpdateLedAutoState(edev
,sli
,sli
->mapsPresent
,NULL
,
314 for (lf
=edev
->leds
;lf
!=NULL
;lf
=lf
->next
) {
315 if ((lf
->xkb_sli
==NULL
)||(lf
->xkb_sli
->maps
==NULL
))
318 XkbUpdateLedAutoState(edev
,sli
,sli
->mapsPresent
,NULL
,
328 /***====================================================================***/
332 * XkbSetIndicators(dev,affect,values,cause)
334 * Attempts to change the indicators specified in 'affect' to the
335 * states specified in 'values' for the default keyboard feedback
336 * on the keyboard specified by 'dev.' Attempts to change indicator
337 * state might be ignored or have no affect, depending on the XKB
338 * indicator map for any affected indicators, as described in section
339 * 9.2 of the XKB protocol specification.
341 * If 'changes' is non-NULL, this function notes any changes to the
342 * keyboard state, controls, or indicator state that result from this
343 * attempted change. If 'changes' is NULL, this function generates
344 * XKB events to report any such changes to interested clients.
346 * If 'cause' is non-NULL, it specifies the reason for the change,
347 * as reported in some XKB events. If it is NULL, this function
348 * assumes that the change is the result of a core protocol
349 * ChangeKeyboardMapping request.
353 XkbSetIndicators( DeviceIntPtr dev
,
356 XkbEventCausePtr cause
)
358 XkbSrvLedInfoPtr sli
;
359 XkbChangesRec changes
;
360 xkbExtensionDeviceNotify ed
;
361 unsigned side_affected
;
363 bzero((char *)&changes
,sizeof(XkbChangesRec
));
364 bzero((char *)&ed
,sizeof(xkbExtensionDeviceNotify
));
365 sli
= XkbFindSrvLedInfo(dev
,XkbDfltXIClass
,XkbDfltXIId
,0);
366 sli
->explicitState
&= ~affect
;
367 sli
->explicitState
|= (affect
&values
);
368 XkbApplyLedStateChanges(dev
,sli
,affect
,&ed
,&changes
,cause
);
371 if (changes
.state_changes
!=0)
372 side_affected
|= XkbIndicatorsToUpdate(dev
,changes
.state_changes
,False
);
373 if (changes
.ctrls
.enabled_ctrls_changes
)
374 side_affected
|= sli
->usesControls
;
377 XkbUpdateLedAutoState(dev
,sli
,side_affected
,&ed
,&changes
,cause
);
378 affect
|= side_affected
;
380 if (changes
.state_changes
|| changes
.ctrls
.enabled_ctrls_changes
)
381 XkbUpdateAllDeviceIndicators(NULL
,cause
);
383 XkbFlushLedEvents(dev
,dev
,sli
,&ed
,&changes
,cause
);
387 /***====================================================================***/
389 /***====================================================================***/
393 * XkbUpdateIndicators(dev,update,check_edevs,changes,cause)
395 * Applies the indicator maps for any indicators specified in
396 * 'update' from the default keyboard feedback on the device
397 * specified by 'dev.'
399 * If 'changes' is NULL, this function generates and XKB events
400 * required to report the necessary changes, otherwise it simply
401 * notes the indicators with changed state.
403 * If 'check_edevs' is True, this function also checks the indicator
404 * maps for any open extension devices that have them, and updates
405 * the state of any extension device indicators as necessary.
409 XkbUpdateIndicators( DeviceIntPtr dev
,
410 register CARD32 update
,
412 XkbChangesPtr changes
,
413 XkbEventCausePtr cause
)
415 XkbSrvLedInfoPtr sli
;
417 sli
= XkbFindSrvLedInfo(dev
,XkbDfltXIClass
,XkbDfltXIId
,0);
418 XkbUpdateLedAutoState(dev
,sli
,update
,NULL
,changes
,cause
);
420 XkbUpdateAllDeviceIndicators(changes
,cause
);
424 /***====================================================================***/
426 /***====================================================================***/
430 * XkbCheckIndicatorMaps(dev,sli,which)
432 * Updates the 'indicator accelerators' for the indicators specified
433 * by 'which' in the feedback specified by 'sli.' The indicator
434 * accelerators are internal to the server and are used to simplify
435 * and speed up the process of figuring out which indicators might
436 * be affected by a particular change in keyboard state or controls.
440 XkbCheckIndicatorMaps(DeviceIntPtr dev
,XkbSrvLedInfoPtr sli
,unsigned which
)
442 register unsigned i
,bit
;
443 XkbIndicatorMapPtr map
;
446 if ((sli
->flags
&XkbSLI_HasOwnState
)==0)
447 dev
= (DeviceIntPtr
)LookupKeyboardDevice();
449 sli
->usesBase
&= ~which
;
450 sli
->usesLatched
&= ~which
;
451 sli
->usesLocked
&= ~which
;
452 sli
->usesEffective
&= ~which
;
453 sli
->usesCompat
&= ~which
;
454 sli
->usesControls
&= ~which
;
455 sli
->mapsPresent
&= ~which
;
457 xkb
= dev
->key
->xkbInfo
->desc
;
458 for (i
=0,bit
=1,map
=sli
->maps
;i
<XkbNumIndicators
;i
++,bit
<<=1,map
++) {
462 if (!XkbIM_InUse(map
))
464 sli
->mapsPresent
|= bit
;
466 what
= (map
->which_mods
|map
->which_groups
);
467 if (what
&XkbIM_UseBase
)
469 if (what
&XkbIM_UseLatched
)
470 sli
->usesLatched
|= bit
;
471 if (what
&XkbIM_UseLocked
)
472 sli
->usesLocked
|= bit
;
473 if (what
&XkbIM_UseEffective
)
474 sli
->usesEffective
|= bit
;
475 if (what
&XkbIM_UseCompat
)
476 sli
->usesCompat
|= bit
;
478 sli
->usesControls
|= bit
;
480 map
->mods
.mask
= map
->mods
.real_mods
;
481 if (map
->mods
.vmods
!=0) {
482 map
->mods
.mask
|= XkbMaskForVMask(xkb
,map
->mods
.vmods
);
486 sli
->usedComponents
= 0;
488 sli
->usedComponents
|= XkbModifierBaseMask
|XkbGroupBaseMask
;
489 if (sli
->usesLatched
)
490 sli
->usedComponents
|= XkbModifierLatchMask
|XkbGroupLatchMask
;
492 sli
->usedComponents
|= XkbModifierLockMask
|XkbGroupLockMask
;
493 if (sli
->usesEffective
)
494 sli
->usedComponents
|= XkbModifierStateMask
|XkbGroupStateMask
;
496 sli
->usedComponents
|= XkbCompatStateMask
;
500 /***====================================================================***/
504 * XkbAllocSrvLedInfo(dev,kf,lf,needed_parts)
506 * Allocates an XkbSrvLedInfoPtr for the feedback specified by either
507 * 'kf' or 'lf' on the keyboard specified by 'dev.'
509 * If 'needed_parts' is non-zero, this function makes sure that any
510 * of the parts speicified therein are allocated.
513 XkbAllocSrvLedInfo( DeviceIntPtr dev
,
516 unsigned needed_parts
)
518 XkbSrvLedInfoPtr sli
;
523 checkAccel
= checkNames
= False
;
524 if ((kf
!=NULL
)&&(kf
->xkb_sli
==NULL
)) {
525 kf
->xkb_sli
= sli
= _XkbTypedCalloc(1,XkbSrvLedInfoRec
);
527 return NULL
; /* ALLOCATION ERROR */
528 if (dev
->key
&& dev
->key
->xkbInfo
)
529 sli
->flags
= XkbSLI_HasOwnState
;
531 sli
->class= KbdFeedbackClass
;
532 sli
->id
= kf
->ctrl
.id
;
536 sli
->explicitState
= kf
->ctrl
.leds
;
537 sli
->effectiveState
= kf
->ctrl
.leds
;
539 if ((kf
==dev
->kbdfeed
) && (dev
->key
) && (dev
->key
->xkbInfo
)) {
541 xkb
= dev
->key
->xkbInfo
->desc
;
542 sli
->flags
|= XkbSLI_IsDefault
;
543 sli
->physIndicators
= xkb
->indicators
->phys_indicators
;
544 sli
->names
= xkb
->names
->indicators
;
545 sli
->maps
= xkb
->indicators
->maps
;
546 checkNames
= checkAccel
= True
;
549 sli
->physIndicators
= XkbAllIndicatorsMask
;
554 else if ((kf
!=NULL
)&&((kf
->xkb_sli
->flags
&XkbSLI_IsDefault
)!=0)) {
556 xkb
= dev
->key
->xkbInfo
->desc
;
557 sli
->physIndicators
= xkb
->indicators
->phys_indicators
;
558 if (xkb
->names
->indicators
!=sli
->names
) {
560 sli
->names
= xkb
->names
->indicators
;
562 if (xkb
->indicators
->maps
!=sli
->maps
) {
564 sli
->maps
= xkb
->indicators
->maps
;
567 else if ((lf
!=NULL
)&&(lf
->xkb_sli
==NULL
)) {
568 lf
->xkb_sli
= sli
= _XkbTypedCalloc(1,XkbSrvLedInfoRec
);
570 return NULL
; /* ALLOCATION ERROR */
571 if (dev
->key
&& dev
->key
->xkbInfo
)
572 sli
->flags
= XkbSLI_HasOwnState
;
574 sli
->class= LedFeedbackClass
;
575 sli
->id
= lf
->ctrl
.id
;
578 sli
->physIndicators
= lf
->ctrl
.led_mask
;
580 sli
->explicitState
= lf
->ctrl
.led_values
;
581 sli
->effectiveState
= lf
->ctrl
.led_values
;
585 if ((sli
->names
==NULL
)&&(needed_parts
&XkbXI_IndicatorNamesMask
))
586 sli
->names
= _XkbTypedCalloc(XkbNumIndicators
,Atom
);
587 if ((sli
->maps
==NULL
)&&(needed_parts
&XkbXI_IndicatorMapsMask
))
588 sli
->maps
= _XkbTypedCalloc(XkbNumIndicators
,XkbIndicatorMapRec
);
590 register unsigned i
,bit
;
591 sli
->namesPresent
= 0;
592 for (i
=0,bit
=1;i
<XkbNumIndicators
;i
++,bit
<<=1) {
593 if (sli
->names
[i
]!=None
)
594 sli
->namesPresent
|= bit
;
598 XkbCheckIndicatorMaps(dev
,sli
,XkbAllIndicatorsMask
);
603 XkbFreeSrvLedInfo(XkbSrvLedInfoPtr sli
)
605 if ((sli
->flags
&XkbSLI_IsDefault
)==0) {
606 if (sli
->maps
) _XkbFree(sli
->maps
);
607 if (sli
->names
) _XkbFree(sli
->names
);
616 /***====================================================================***/
620 * XkbFindSrvLedInfo(dev,class,id,needed_parts)
622 * Finds the XkbSrvLedInfoPtr for the specified 'class' and 'id'
623 * on the device specified by 'dev.' If the class and id specify
624 * a valid device feedback, this function returns the existing
625 * feedback or allocates a new one.
630 XkbFindSrvLedInfo( DeviceIntPtr dev
,
633 unsigned needed_parts
)
635 XkbSrvLedInfoPtr sli
;
637 /* optimization to check for most common case */
638 if (((class==XkbDfltXIClass
)&&(id
==XkbDfltXIId
))&&(dev
->kbdfeed
)) {
639 XkbSrvLedInfoPtr sli
;
640 sli
= dev
->kbdfeed
->xkb_sli
;
641 if (dev
->kbdfeed
->xkb_sli
==NULL
) {
642 sli
= XkbAllocSrvLedInfo(dev
,dev
->kbdfeed
,NULL
,needed_parts
);
643 dev
->kbdfeed
->xkb_sli
= sli
;
645 return dev
->kbdfeed
->xkb_sli
;
649 if (class==XkbDfltXIClass
) {
650 if (dev
->kbdfeed
) class= KbdFeedbackClass
;
651 else if (dev
->leds
) class= LedFeedbackClass
;
654 if (class==KbdFeedbackClass
) {
656 for (kf
=dev
->kbdfeed
;kf
!=NULL
;kf
=kf
->next
) {
657 if ((id
==XkbDfltXIId
)||(id
==kf
->ctrl
.id
)) {
658 if (kf
->xkb_sli
==NULL
)
659 kf
->xkb_sli
= XkbAllocSrvLedInfo(dev
,kf
,NULL
,needed_parts
);
665 else if (class==LedFeedbackClass
) {
667 for (lf
=dev
->leds
;lf
!=NULL
;lf
=lf
->next
) {
668 if ((id
==XkbDfltXIId
)||(id
==lf
->ctrl
.id
)) {
669 if (lf
->xkb_sli
==NULL
)
670 lf
->xkb_sli
= XkbAllocSrvLedInfo(dev
,NULL
,lf
,needed_parts
);
676 if ((sli
->names
==NULL
)&&(needed_parts
&XkbXI_IndicatorNamesMask
))
677 sli
->names
= _XkbTypedCalloc(XkbNumIndicators
,Atom
);
678 if ((sli
->maps
==NULL
)&&(needed_parts
&XkbXI_IndicatorMapsMask
))
679 sli
->maps
= _XkbTypedCalloc(XkbNumIndicators
,XkbIndicatorMapRec
);
683 /***====================================================================***/
686 XkbFlushLedEvents( DeviceIntPtr dev
,
688 XkbSrvLedInfoPtr sli
,
689 xkbExtensionDeviceNotify
* ed
,
690 XkbChangesPtr changes
,
691 XkbEventCausePtr cause
)
694 if (changes
->indicators
.state_changes
)
695 XkbDDXUpdateDeviceIndicators(dev
,sli
,sli
->effectiveState
);
696 XkbSendNotification(kbd
,changes
,cause
);
697 bzero((char *)changes
,sizeof(XkbChangesRec
));
699 if (XkbAX_NeedFeedback(kbd
->key
->xkbInfo
->desc
->ctrls
, XkbAX_IndicatorFBMask
)) {
700 if (sli
->effectiveState
)
701 /* it appears that the which parameter is not used */
702 XkbDDXAccessXBeep(dev
, _BEEP_LED_ON
, XkbAccessXFeedbackMask
);
704 XkbDDXAccessXBeep(dev
, _BEEP_LED_OFF
, XkbAccessXFeedbackMask
);
707 if (ed
&& (ed
->reason
)) {
708 if ((dev
!=kbd
)&&(ed
->reason
&XkbXI_IndicatorStateMask
))
709 XkbDDXUpdateDeviceIndicators(dev
,sli
,sli
->effectiveState
);
710 XkbSendExtensionDeviceNotify(dev
,cause
->client
,ed
);
712 bzero((char *)ed
,sizeof(XkbExtensionDeviceNotify
));
716 /***====================================================================***/
719 XkbApplyLedNameChanges( DeviceIntPtr dev
,
720 XkbSrvLedInfoPtr sli
,
721 unsigned changed_names
,
722 xkbExtensionDeviceNotify
* ed
,
723 XkbChangesPtr changes
,
724 XkbEventCausePtr cause
)
727 XkbChangesRec my_changes
;
728 xkbExtensionDeviceNotify my_ed
;
730 if (changed_names
==0)
732 if (dev
->key
&& dev
->key
->xkbInfo
)
734 else kbd
= (DeviceIntPtr
)LookupKeyboardDevice();
738 bzero((char *)ed
,sizeof(xkbExtensionDeviceNotify
));
740 else if ((ed
->reason
&XkbXI_IndicatorsMask
)&&
741 ((ed
->ledClass
!=sli
->class)||(ed
->ledID
!=sli
->id
))) {
742 XkbFlushLedEvents(dev
,kbd
,sli
,ed
,changes
,cause
);
745 if ((kbd
==dev
)&&(sli
->flags
&XkbSLI_IsDefault
)) {
747 changes
= &my_changes
;
748 bzero((char *)changes
,sizeof(XkbChangesRec
));
750 changes
->names
.changed
|= XkbIndicatorNamesMask
;
751 changes
->names
.changed_indicators
|= changed_names
;
754 ed
->reason
|= XkbXI_IndicatorNamesMask
;
755 ed
->ledClass
= sli
->class;
757 ed
->ledsDefined
= sli
->namesPresent
|sli
->mapsPresent
;
758 ed
->ledState
= sli
->effectiveState
;
760 ed
->supported
= XkbXI_AllFeaturesMask
;
762 if (changes
!=&my_changes
) changes
= NULL
;
763 if (ed
!=&my_ed
) ed
= NULL
;
765 XkbFlushLedEvents(dev
,kbd
,sli
,ed
,changes
,cause
);
768 /***====================================================================***/
772 * XkbApplyLedMapChanges(dev,sli,changed_maps,changes,cause)
774 * Handles all of the secondary effects of the changes to the
775 * feedback specified by 'sli' on the device specified by 'dev.'
777 * If 'changed_maps' specifies any indicators, this function generates
778 * XkbExtensionDeviceNotify events and possibly IndicatorMapNotify
779 * events to report the changes, and recalculates the effective
780 * state of each indicator with a changed map. If any indicators
781 * change state, the server generates XkbExtensionDeviceNotify and
782 * XkbIndicatorStateNotify events as appropriate.
784 * If 'changes' is non-NULL, this function updates it to reflect
785 * any changes to the keyboard state or controls or to the 'core'
786 * indicator names, maps, or state. If 'changes' is NULL, this
787 * function generates XKB events as needed to report the changes.
788 * If 'dev' is not a keyboard device, any changes are reported
789 * for the core keyboard.
791 * The 'cause' specifies the reason for the event (key event or
792 * request) for the change, as reported in some XKB events.
796 XkbApplyLedMapChanges( DeviceIntPtr dev
,
797 XkbSrvLedInfoPtr sli
,
798 unsigned changed_maps
,
799 xkbExtensionDeviceNotify
* ed
,
800 XkbChangesPtr changes
,
801 XkbEventCausePtr cause
)
804 XkbChangesRec my_changes
;
805 xkbExtensionDeviceNotify my_ed
;
809 if (dev
->key
&& dev
->key
->xkbInfo
)
811 else kbd
= (DeviceIntPtr
)LookupKeyboardDevice();
815 bzero((char *)ed
,sizeof(xkbExtensionDeviceNotify
));
817 else if ((ed
->reason
&XkbXI_IndicatorsMask
)&&
818 ((ed
->ledClass
!=sli
->class)||(ed
->ledID
!=sli
->id
))) {
819 XkbFlushLedEvents(dev
,kbd
,sli
,ed
,changes
,cause
);
822 if ((kbd
==dev
)&&(sli
->flags
&XkbSLI_IsDefault
)) {
824 changes
= &my_changes
;
825 bzero((char *)changes
,sizeof(XkbChangesRec
));
827 changes
->indicators
.map_changes
|= changed_maps
;
830 XkbCheckIndicatorMaps(dev
,sli
,changed_maps
);
832 ed
->reason
|= XkbXI_IndicatorMapsMask
;
833 ed
->ledClass
= sli
->class;
835 ed
->ledsDefined
= sli
->namesPresent
|sli
->mapsPresent
;
836 ed
->ledState
= sli
->effectiveState
;
837 ed
->unsupported
|= XkbXI_IndicatorMapsMask
;
838 ed
->supported
= XkbXI_AllFeaturesMask
;
840 XkbUpdateLedAutoState(dev
,sli
,changed_maps
,ed
,changes
,cause
);
842 if (changes
!=&my_changes
) changes
= NULL
;
843 if (ed
!=&my_ed
) ed
= NULL
;
845 XkbFlushLedEvents(dev
,kbd
,sli
,ed
,changes
,cause
);
849 /***====================================================================***/
852 XkbApplyLedStateChanges(DeviceIntPtr dev
,
853 XkbSrvLedInfoPtr sli
,
854 unsigned changed_leds
,
855 xkbExtensionDeviceNotify
* ed
,
856 XkbChangesPtr changes
,
857 XkbEventCausePtr cause
)
861 XkbChangesRec my_changes
;
862 xkbExtensionDeviceNotify my_ed
;
863 register unsigned i
,bit
,affected
;
864 XkbIndicatorMapPtr map
;
870 if (dev
->key
&& dev
->key
->xkbInfo
)
872 else kbd
= (DeviceIntPtr
)LookupKeyboardDevice();
873 xkbi
= kbd
->key
->xkbInfo
;
876 changes
= &my_changes
;
877 bzero((char *)changes
,sizeof(XkbChangesRec
));
881 affected
= changed_leds
;
882 oldState
= sli
->effectiveState
;
883 for (i
=0,bit
=1;(i
<XkbNumIndicators
)&&(affected
);i
++,bit
<<=1) {
884 if ((affected
&bit
)==0)
888 if (map
->flags
&XkbIM_NoExplicit
) {
889 sli
->explicitState
&= ~bit
;
892 if (map
->flags
&XkbIM_LEDDrivesKB
) {
893 Bool on
= ((sli
->explicitState
&bit
)!=0);
894 if (XkbApplyLEDChangeToKeyboard(xkbi
,map
,on
,changes
))
898 sli
->effectiveState
= (sli
->autoState
|sli
->explicitState
);
899 affected
= sli
->effectiveState
^oldState
;
903 bzero((char *)ed
,sizeof(xkbExtensionDeviceNotify
));
905 else if (affected
&&(ed
->reason
&XkbXI_IndicatorsMask
)&&
906 ((ed
->ledClass
!=sli
->class)||(ed
->ledID
!=sli
->id
))) {
907 XkbFlushLedEvents(dev
,kbd
,sli
,ed
,changes
,cause
);
910 if ((kbd
==dev
)&&(sli
->flags
&XkbSLI_IsDefault
))
911 changes
->indicators
.state_changes
|= affected
;
913 ed
->reason
|= XkbXI_IndicatorStateMask
;
914 ed
->ledClass
= sli
->class;
916 ed
->ledsDefined
= sli
->namesPresent
|sli
->mapsPresent
;
917 ed
->ledState
= sli
->effectiveState
;
918 ed
->unsupported
|= XkbXI_IndicatorStateMask
;
919 ed
->supported
= XkbXI_AllFeaturesMask
;
923 XkbComputeDerivedState(kbd
->key
->xkbInfo
);
924 XkbUpdateLedAutoState(dev
,sli
,sli
->mapsPresent
,ed
,changes
,cause
);
927 if (changes
!=&my_changes
) changes
= NULL
;
928 if (ed
!=&my_ed
) ed
= NULL
;
930 XkbFlushLedEvents(dev
,kbd
,sli
,ed
,changes
,cause
);
932 XkbUpdateAllDeviceIndicators(NULL
,cause
);