1 /************************************************************
2 Copyright (c) 1993 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>
34 #include <X11/Xproto.h>
35 #include <X11/keysym.h>
44 #include "mipointer.h"
45 #include "inpututils.h"
46 #define EXTENSION_EVENT_BASE 64
48 DevPrivateKeyRec xkbDevicePrivateKeyRec
;
50 static void XkbFakePointerMotion(DeviceIntPtr dev
, unsigned flags
, int x
,
54 xkbUnwrapProc(DeviceIntPtr device
, DeviceHandleProc proc
, pointer data
)
56 xkbDeviceInfoPtr xkbPrivPtr
= XKBDEVICEINFO(device
);
57 ProcessInputProc backupproc
;
59 if (xkbPrivPtr
->unwrapProc
)
60 xkbPrivPtr
->unwrapProc
= NULL
;
62 UNWRAP_PROCESS_INPUT_PROC(device
, xkbPrivPtr
, backupproc
);
64 COND_WRAP_PROCESS_INPUT_PROC(device
, xkbPrivPtr
, backupproc
, xkbUnwrapProc
);
70 return dixRegisterPrivateKey(&xkbDevicePrivateKeyRec
, PRIVATE_DEVICE
,
71 sizeof(xkbDeviceInfoRec
));
75 XkbSetExtension(DeviceIntPtr device
, ProcessInputProc proc
)
77 xkbDeviceInfoPtr xkbPrivPtr
= XKBDEVICEINFO(device
);
79 WRAP_PROCESS_INPUT_PROC(device
, xkbPrivPtr
, proc
, xkbUnwrapProc
);
82 /***====================================================================***/
85 _FixUpAction(XkbDescPtr xkb
, XkbAction
*act
)
87 static XkbAction fake
;
89 if (XkbIsPtrAction(act
) &&
90 (!(xkb
->ctrls
->enabled_ctrls
& XkbMouseKeysMask
))) {
91 fake
.type
= XkbSA_NoAction
;
94 if (xkb
->ctrls
->enabled_ctrls
& XkbStickyKeysMask
) {
95 if (act
->any
.type
== XkbSA_SetMods
) {
96 fake
.mods
.type
= XkbSA_LatchMods
;
97 fake
.mods
.mask
= act
->mods
.mask
;
98 if (XkbAX_NeedOption(xkb
->ctrls
, XkbAX_LatchToLockMask
))
99 fake
.mods
.flags
= XkbSA_ClearLocks
| XkbSA_LatchToLock
;
101 fake
.mods
.flags
= XkbSA_ClearLocks
;
104 if (act
->any
.type
== XkbSA_SetGroup
) {
105 fake
.group
.type
= XkbSA_LatchGroup
;
106 if (XkbAX_NeedOption(xkb
->ctrls
, XkbAX_LatchToLockMask
))
107 fake
.group
.flags
= XkbSA_ClearLocks
| XkbSA_LatchToLock
;
109 fake
.group
.flags
= XkbSA_ClearLocks
;
110 XkbSASetGroup(&fake
.group
, XkbSAGroup(&act
->group
));
118 XkbGetKeyAction(XkbSrvInfoPtr xkbi
, XkbStatePtr xkbState
, CARD8 key
)
125 static XkbAction fake
;
128 if (!XkbKeyHasActions(xkb
, key
) || !XkbKeycodeInRange(xkb
, key
)) {
129 fake
.type
= XkbSA_NoAction
;
132 pActs
= XkbKeyActionsPtr(xkb
, key
);
135 effectiveGroup
= XkbGetEffectiveGroup(xkbi
, xkbState
, key
);
136 if (effectiveGroup
!= XkbGroup1Index
)
137 col
+= (effectiveGroup
* XkbKeyGroupsWidth(xkb
, key
));
139 type
= XkbKeyKeyType(xkb
, key
, effectiveGroup
);
140 if (type
->map
!= NULL
) {
141 register unsigned i
, mods
;
142 register XkbKTMapEntryPtr entry
;
144 mods
= xkbState
->mods
& type
->mods
.mask
;
145 for (entry
= type
->map
, i
= 0; i
< type
->map_count
; i
++, entry
++) {
146 if ((entry
->active
) && (entry
->mods
.mask
== mods
)) {
152 if (pActs
[col
].any
.type
== XkbSA_NoAction
)
154 fake
= _FixUpAction(xkb
, &pActs
[col
]);
159 XkbGetButtonAction(DeviceIntPtr kbd
, DeviceIntPtr dev
, int button
)
163 if ((dev
->button
) && (dev
->button
->xkb_acts
)) {
164 if (dev
->button
->xkb_acts
[button
- 1].any
.type
!= XkbSA_NoAction
) {
165 fake
= _FixUpAction(kbd
->key
->xkbInfo
->desc
,
166 &dev
->button
->xkb_acts
[button
- 1]);
170 fake
.any
.type
= XkbSA_NoAction
;
174 /***====================================================================***/
176 #define SYNTHETIC_KEYCODE 1
177 #define BTN_ACT_FLAG 0x100
180 _XkbFilterSetState(XkbSrvInfoPtr xkbi
,
181 XkbFilterPtr filter
, unsigned keycode
, XkbAction
*pAction
)
183 if (filter
->keycode
== 0) { /* initial press */
184 filter
->keycode
= keycode
;
186 filter
->filterOthers
= ((pAction
->mods
.mask
& XkbSA_ClearLocks
) != 0);
188 filter
->filter
= _XkbFilterSetState
;
189 if (pAction
->type
== XkbSA_SetMods
) {
190 filter
->upAction
= *pAction
;
191 xkbi
->setMods
= pAction
->mods
.mask
;
194 xkbi
->groupChange
= XkbSAGroup(&pAction
->group
);
195 if (pAction
->group
.flags
& XkbSA_GroupAbsolute
)
196 xkbi
->groupChange
-= xkbi
->state
.base_group
;
197 filter
->upAction
= *pAction
;
198 XkbSASetGroup(&filter
->upAction
.group
, xkbi
->groupChange
);
201 else if (filter
->keycode
== keycode
) {
202 if (filter
->upAction
.type
== XkbSA_SetMods
) {
203 xkbi
->clearMods
= filter
->upAction
.mods
.mask
;
204 if (filter
->upAction
.mods
.flags
& XkbSA_ClearLocks
) {
205 xkbi
->state
.locked_mods
&= ~filter
->upAction
.mods
.mask
;
209 if (filter
->upAction
.group
.flags
& XkbSA_ClearLocks
) {
210 xkbi
->state
.locked_group
= 0;
212 xkbi
->groupChange
= -XkbSAGroup(&filter
->upAction
.group
);
217 filter
->upAction
.mods
.flags
&= ~XkbSA_ClearLocks
;
218 filter
->filterOthers
= 0;
223 #define LATCH_KEY_DOWN 1
224 #define LATCH_PENDING 2
227 _XkbFilterLatchState(XkbSrvInfoPtr xkbi
,
228 XkbFilterPtr filter
, unsigned keycode
, XkbAction
*pAction
)
231 if (filter
->keycode
== 0) { /* initial press */
232 AccessXCancelRepeatKey(xkbi
,keycode
);
233 filter
->keycode
= keycode
;
235 filter
->filterOthers
= 1;
236 filter
->priv
= LATCH_KEY_DOWN
;
237 filter
->filter
= _XkbFilterLatchState
;
238 if (pAction
->type
== XkbSA_LatchMods
) {
239 filter
->upAction
= *pAction
;
240 xkbi
->setMods
= pAction
->mods
.mask
;
243 xkbi
->groupChange
= XkbSAGroup(&pAction
->group
);
244 if (pAction
->group
.flags
& XkbSA_GroupAbsolute
)
245 xkbi
->groupChange
-= xkbi
->state
.base_group
;
246 filter
->upAction
= *pAction
;
247 XkbSASetGroup(&filter
->upAction
.group
, xkbi
->groupChange
);
250 else if (pAction
&& (filter
->priv
== LATCH_PENDING
)) {
251 if (((1 << pAction
->type
) & XkbSA_BreakLatch
) != 0) {
253 /* If one latch is broken, all latches are broken, so it's no use
254 to find out which particular latch this filter tracks. */
255 xkbi
->state
.latched_mods
= 0;
256 xkbi
->state
.latched_group
= 0;
259 else if (filter
->keycode
== keycode
&& filter
->priv
!= LATCH_PENDING
){
260 /* The test above for LATCH_PENDING skips subsequent releases of the
261 key after it has been released first time and the latch became
263 XkbControlsPtr ctrls
= xkbi
->desc
->ctrls
;
264 int needBeep
= ((ctrls
->enabled_ctrls
& XkbStickyKeysMask
) &&
265 XkbAX_NeedFeedback(ctrls
, XkbAX_StickyKeysFBMask
));
267 if (filter
->upAction
.type
== XkbSA_LatchMods
) {
268 unsigned char mask
= filter
->upAction
.mods
.mask
;
269 unsigned char common
;
271 xkbi
->clearMods
= mask
;
274 common
= mask
& xkbi
->state
.locked_mods
;
275 if ((filter
->upAction
.mods
.flags
& XkbSA_ClearLocks
) && common
) {
277 xkbi
->state
.locked_mods
&= ~common
;
279 XkbDDXAccessXBeep(xkbi
->device
, _BEEP_STICKY_UNLOCK
,
283 common
= mask
& xkbi
->state
.latched_mods
;
284 if ((filter
->upAction
.mods
.flags
& XkbSA_LatchToLock
) && common
) {
285 unsigned char newlocked
;
288 newlocked
= common
& ~xkbi
->state
.locked_mods
;
290 xkbi
->state
.locked_mods
|= newlocked
;
292 XkbDDXAccessXBeep(xkbi
->device
, _BEEP_STICKY_LOCK
,
296 xkbi
->state
.latched_mods
&= ~common
;
298 /* Latch remaining modifiers, if any. */
300 xkbi
->state
.latched_mods
|= mask
;
301 filter
->priv
= LATCH_PENDING
;
303 XkbDDXAccessXBeep(xkbi
->device
, _BEEP_STICKY_LATCH
,
308 xkbi
->groupChange
= -XkbSAGroup(&filter
->upAction
.group
);
310 if ((filter
->upAction
.group
.flags
& XkbSA_ClearLocks
) &&
311 (xkbi
->state
.locked_group
)) {
312 xkbi
->state
.locked_group
= 0;
314 XkbDDXAccessXBeep(xkbi
->device
, _BEEP_STICKY_UNLOCK
,
318 else if ((filter
->upAction
.group
.flags
& XkbSA_LatchToLock
)
319 && (xkbi
->state
.latched_group
)) {
320 xkbi
->state
.locked_group
+= XkbSAGroup(&filter
->upAction
.group
);
321 xkbi
->state
.latched_group
-= XkbSAGroup(&filter
->upAction
.group
);
322 if(XkbSAGroup(&filter
->upAction
.group
) && needBeep
)
323 XkbDDXAccessXBeep(xkbi
->device
, _BEEP_STICKY_LOCK
,
327 else if(XkbSAGroup(&filter
->upAction
.group
)){
328 xkbi
->state
.latched_group
+= XkbSAGroup(&filter
->upAction
.group
);
329 filter
->priv
= LATCH_PENDING
;
331 XkbDDXAccessXBeep(xkbi
->device
, _BEEP_STICKY_LATCH
,
336 if (filter
->priv
!= LATCH_PENDING
)
339 else if (pAction
&& (filter
->priv
== LATCH_KEY_DOWN
)) {
340 /* Latch was broken before it became pending: degrade to a
342 if (filter
->upAction
.type
== XkbSA_LatchMods
)
343 filter
->upAction
.type
= XkbSA_SetMods
;
345 filter
->upAction
.type
= XkbSA_SetGroup
;
346 filter
->filter
= _XkbFilterSetState
;
348 return filter
->filter(xkbi
, filter
, keycode
, pAction
);
354 _XkbFilterLockState(XkbSrvInfoPtr xkbi
,
355 XkbFilterPtr filter
, unsigned keycode
, XkbAction
*pAction
)
357 if (pAction
&& (pAction
->type
== XkbSA_LockGroup
)) {
358 if (pAction
->group
.flags
& XkbSA_GroupAbsolute
)
359 xkbi
->state
.locked_group
= XkbSAGroup(&pAction
->group
);
361 xkbi
->state
.locked_group
+= XkbSAGroup(&pAction
->group
);
364 if (filter
->keycode
== 0) { /* initial press */
365 filter
->keycode
= keycode
;
367 filter
->filterOthers
= 0;
368 filter
->priv
= xkbi
->state
.locked_mods
& pAction
->mods
.mask
;
369 filter
->filter
= _XkbFilterLockState
;
370 filter
->upAction
= *pAction
;
371 if (!(filter
->upAction
.mods
.flags
& XkbSA_LockNoLock
))
372 xkbi
->state
.locked_mods
|= pAction
->mods
.mask
;
373 xkbi
->setMods
= pAction
->mods
.mask
;
375 else if (filter
->keycode
== keycode
) {
377 xkbi
->clearMods
= filter
->upAction
.mods
.mask
;
378 if (!(filter
->upAction
.mods
.flags
& XkbSA_LockNoUnlock
))
379 xkbi
->state
.locked_mods
&= ~filter
->priv
;
384 #define ISO_KEY_DOWN 0
385 #define NO_ISO_LOCK 1
388 _XkbFilterISOLock(XkbSrvInfoPtr xkbi
,
389 XkbFilterPtr filter
, unsigned keycode
, XkbAction
*pAction
)
392 if (filter
->keycode
== 0) { /* initial press */
393 CARD8 flags
= pAction
->iso
.flags
;
395 filter
->keycode
= keycode
;
397 filter
->filterOthers
= 1;
398 filter
->priv
= ISO_KEY_DOWN
;
399 filter
->upAction
= *pAction
;
400 filter
->filter
= _XkbFilterISOLock
;
401 if (flags
& XkbSA_ISODfltIsGroup
) {
402 xkbi
->groupChange
= XkbSAGroup(&pAction
->iso
);
406 xkbi
->setMods
= pAction
->iso
.mask
;
407 xkbi
->groupChange
= 0;
409 if ((!(flags
& XkbSA_ISONoAffectMods
)) && (xkbi
->state
.base_mods
)) {
410 filter
->priv
= NO_ISO_LOCK
;
411 xkbi
->state
.locked_mods
^= xkbi
->state
.base_mods
;
413 if ((!(flags
& XkbSA_ISONoAffectGroup
)) && (xkbi
->state
.base_group
)) {
414 /* 6/22/93 (ef) -- lock groups if group key is down first */
416 if (!(flags
& XkbSA_ISONoAffectPtr
)) {
417 /* 6/22/93 (ef) -- lock mouse buttons if they're down */
420 else if (filter
->keycode
== keycode
) {
421 CARD8 flags
= filter
->upAction
.iso
.flags
;
423 if (flags
& XkbSA_ISODfltIsGroup
) {
424 xkbi
->groupChange
= -XkbSAGroup(&filter
->upAction
.iso
);
426 if (filter
->priv
== ISO_KEY_DOWN
)
427 xkbi
->state
.locked_group
+= XkbSAGroup(&filter
->upAction
.iso
);
430 xkbi
->clearMods
= filter
->upAction
.iso
.mask
;
431 xkbi
->groupChange
= 0;
432 if (filter
->priv
== ISO_KEY_DOWN
)
433 xkbi
->state
.locked_mods
^= filter
->upAction
.iso
.mask
;
438 CARD8 flags
= filter
->upAction
.iso
.flags
;
440 switch (pAction
->type
) {
442 case XkbSA_LatchMods
:
443 if (!(flags
& XkbSA_ISONoAffectMods
)) {
444 pAction
->type
= XkbSA_LockMods
;
445 filter
->priv
= NO_ISO_LOCK
;
449 case XkbSA_LatchGroup
:
450 if (!(flags
& XkbSA_ISONoAffectGroup
)) {
451 pAction
->type
= XkbSA_LockGroup
;
452 filter
->priv
= NO_ISO_LOCK
;
456 if (!(flags
& XkbSA_ISONoAffectPtr
)) {
457 pAction
->type
= XkbSA_LockPtrBtn
;
458 filter
->priv
= NO_ISO_LOCK
;
461 case XkbSA_SetControls
:
462 if (!(flags
& XkbSA_ISONoAffectCtrls
)) {
463 pAction
->type
= XkbSA_LockControls
;
464 filter
->priv
= NO_ISO_LOCK
;
473 _XkbPtrAccelExpire(OsTimerPtr timer
, CARD32 now
, pointer arg
)
475 XkbSrvInfoPtr xkbi
= (XkbSrvInfoPtr
) arg
;
476 XkbControlsPtr ctrls
= xkbi
->desc
->ctrls
;
479 if (xkbi
->mouseKey
== 0)
482 if (xkbi
->mouseKeysAccel
) {
483 if ((xkbi
->mouseKeysCounter
) < ctrls
->mk_time_to_max
) {
486 xkbi
->mouseKeysCounter
++;
487 step
= xkbi
->mouseKeysCurveFactor
*
488 pow((double) xkbi
->mouseKeysCounter
, xkbi
->mouseKeysCurve
);
489 if (xkbi
->mouseKeysDX
< 0)
490 dx
= floor(((double) xkbi
->mouseKeysDX
) * step
);
492 dx
= ceil(((double) xkbi
->mouseKeysDX
) * step
);
493 if (xkbi
->mouseKeysDY
< 0)
494 dy
= floor(((double) xkbi
->mouseKeysDY
) * step
);
496 dy
= ceil(((double) xkbi
->mouseKeysDY
) * step
);
499 dx
= xkbi
->mouseKeysDX
* ctrls
->mk_max_speed
;
500 dy
= xkbi
->mouseKeysDY
* ctrls
->mk_max_speed
;
502 if (xkbi
->mouseKeysFlags
& XkbSA_MoveAbsoluteX
)
503 dx
= xkbi
->mouseKeysDX
;
504 if (xkbi
->mouseKeysFlags
& XkbSA_MoveAbsoluteY
)
505 dy
= xkbi
->mouseKeysDY
;
508 dx
= xkbi
->mouseKeysDX
;
509 dy
= xkbi
->mouseKeysDY
;
511 XkbFakePointerMotion(xkbi
->device
, xkbi
->mouseKeysFlags
, dx
, dy
);
512 return xkbi
->desc
->ctrls
->mk_interval
;
516 _XkbFilterPointerMove(XkbSrvInfoPtr xkbi
,
517 XkbFilterPtr filter
, unsigned keycode
, XkbAction
*pAction
)
522 if (filter
->keycode
== 0) { /* initial press */
523 filter
->keycode
= keycode
;
525 filter
->filterOthers
= 0;
527 filter
->filter
= _XkbFilterPointerMove
;
528 filter
->upAction
= *pAction
;
529 xkbi
->mouseKeysCounter
= 0;
530 xkbi
->mouseKey
= keycode
;
531 accel
= ((pAction
->ptr
.flags
& XkbSA_NoAcceleration
) == 0);
532 x
= XkbPtrActionX(&pAction
->ptr
);
533 y
= XkbPtrActionY(&pAction
->ptr
);
534 XkbFakePointerMotion(xkbi
->device
, pAction
->ptr
.flags
, x
, y
);
535 AccessXCancelRepeatKey(xkbi
, keycode
);
536 xkbi
->mouseKeysAccel
= accel
&&
537 (xkbi
->desc
->ctrls
->enabled_ctrls
& XkbMouseKeysAccelMask
);
538 xkbi
->mouseKeysFlags
= pAction
->ptr
.flags
;
539 xkbi
->mouseKeysDX
= XkbPtrActionX(&pAction
->ptr
);
540 xkbi
->mouseKeysDY
= XkbPtrActionY(&pAction
->ptr
);
541 xkbi
->mouseKeyTimer
= TimerSet(xkbi
->mouseKeyTimer
, 0,
542 xkbi
->desc
->ctrls
->mk_delay
,
543 _XkbPtrAccelExpire
, (pointer
) xkbi
);
545 else if (filter
->keycode
== keycode
) {
547 if (xkbi
->mouseKey
== keycode
) {
549 xkbi
->mouseKeyTimer
= TimerSet(xkbi
->mouseKeyTimer
, 0, 0,
557 _XkbFilterPointerBtn(XkbSrvInfoPtr xkbi
,
558 XkbFilterPtr filter
, unsigned keycode
, XkbAction
*pAction
)
560 if (filter
->keycode
== 0) { /* initial press */
561 int button
= pAction
->btn
.button
;
563 if (button
== XkbSA_UseDfltButton
)
564 button
= xkbi
->desc
->ctrls
->mk_dflt_btn
;
566 filter
->keycode
= keycode
;
568 filter
->filterOthers
= 0;
570 filter
->filter
= _XkbFilterPointerBtn
;
571 filter
->upAction
= *pAction
;
572 filter
->upAction
.btn
.button
= button
;
573 switch (pAction
->type
) {
574 case XkbSA_LockPtrBtn
:
575 if (((xkbi
->lockedPtrButtons
& (1 << button
)) == 0) &&
576 ((pAction
->btn
.flags
& XkbSA_LockNoLock
) == 0)) {
577 xkbi
->lockedPtrButtons
|= (1 << button
);
578 AccessXCancelRepeatKey(xkbi
, keycode
);
579 XkbFakeDeviceButton(xkbi
->device
, 1, button
);
580 filter
->upAction
.type
= XkbSA_NoAction
;
585 register int i
, nClicks
;
587 AccessXCancelRepeatKey(xkbi
, keycode
);
588 if (pAction
->btn
.count
> 0) {
589 nClicks
= pAction
->btn
.count
;
590 for (i
= 0; i
< nClicks
; i
++) {
591 XkbFakeDeviceButton(xkbi
->device
, 1, button
);
592 XkbFakeDeviceButton(xkbi
->device
, 0, button
);
594 filter
->upAction
.type
= XkbSA_NoAction
;
597 XkbFakeDeviceButton(xkbi
->device
, 1, button
);
600 case XkbSA_SetPtrDflt
:
602 XkbControlsPtr ctrls
= xkbi
->desc
->ctrls
;
604 xkbControlsNotify cn
;
607 AccessXCancelRepeatKey(xkbi
, keycode
);
608 switch (pAction
->dflt
.affect
) {
609 case XkbSA_AffectDfltBtn
:
610 if (pAction
->dflt
.flags
& XkbSA_DfltBtnAbsolute
)
611 ctrls
->mk_dflt_btn
= XkbSAPtrDfltValue(&pAction
->dflt
);
613 ctrls
->mk_dflt_btn
+= XkbSAPtrDfltValue(&pAction
->dflt
);
614 if (ctrls
->mk_dflt_btn
> 5)
615 ctrls
->mk_dflt_btn
= 5;
616 else if (ctrls
->mk_dflt_btn
< 1)
617 ctrls
->mk_dflt_btn
= 1;
622 ("Attempt to change unknown pointer default (%d) ignored\n",
623 pAction
->dflt
.affect
);
626 if (XkbComputeControlsNotify(xkbi
->device
,
627 &old
, xkbi
->desc
->ctrls
, &cn
, FALSE
)) {
628 cn
.keycode
= keycode
;
629 /* XXX: what about DeviceKeyPress? */
630 cn
.eventType
= KeyPress
;
633 XkbSendControlsNotify(xkbi
->device
, &cn
);
639 else if (filter
->keycode
== keycode
) {
640 int button
= filter
->upAction
.btn
.button
;
642 switch (filter
->upAction
.type
) {
643 case XkbSA_LockPtrBtn
:
644 if (((filter
->upAction
.btn
.flags
& XkbSA_LockNoUnlock
) != 0) ||
645 ((xkbi
->lockedPtrButtons
& (1 << button
)) == 0)) {
648 xkbi
->lockedPtrButtons
&= ~(1 << button
);
650 if (IsMaster(xkbi
->device
)) {
651 XkbMergeLockedPtrBtns(xkbi
->device
);
652 /* One SD still has lock set, don't post event */
653 if ((xkbi
->lockedPtrButtons
& (1 << button
)) != 0)
659 XkbFakeDeviceButton(xkbi
->device
, 0, button
);
668 _XkbFilterControls(XkbSrvInfoPtr xkbi
,
669 XkbFilterPtr filter
, unsigned keycode
, XkbAction
*pAction
)
672 XkbControlsPtr ctrls
;
675 XkbEventCauseRec cause
;
678 ctrls
= xkbi
->desc
->ctrls
;
680 if (filter
->keycode
== 0) { /* initial press */
681 filter
->keycode
= keycode
;
683 filter
->filterOthers
= 0;
684 change
= XkbActionCtrls(&pAction
->ctrls
);
685 filter
->priv
= change
;
686 filter
->filter
= _XkbFilterControls
;
687 filter
->upAction
= *pAction
;
689 if (pAction
->type
== XkbSA_LockControls
) {
690 filter
->priv
= (ctrls
->enabled_ctrls
& change
);
691 change
&= ~ctrls
->enabled_ctrls
;
695 xkbControlsNotify cn
;
696 XkbSrvLedInfoPtr sli
;
698 ctrls
->enabled_ctrls
|= change
;
699 if (XkbComputeControlsNotify(kbd
, &old
, ctrls
, &cn
, FALSE
)) {
700 cn
.keycode
= keycode
;
701 /* XXX: what about DeviceKeyPress? */
702 cn
.eventType
= KeyPress
;
705 XkbSendControlsNotify(kbd
, &cn
);
708 XkbSetCauseKey(&cause
, keycode
, KeyPress
);
710 /* If sticky keys were disabled, clear all locks and latches */
711 if ((old
.enabled_ctrls
& XkbStickyKeysMask
) &&
712 (!(ctrls
->enabled_ctrls
& XkbStickyKeysMask
))) {
713 XkbClearAllLatchesAndLocks(kbd
, xkbi
, FALSE
, &cause
);
715 sli
= XkbFindSrvLedInfo(kbd
, XkbDfltXIClass
, XkbDfltXIId
, 0);
716 XkbUpdateIndicators(kbd
, sli
->usesControls
, TRUE
, NULL
, &cause
);
717 if (XkbAX_NeedFeedback(ctrls
, XkbAX_FeatureFBMask
))
718 XkbDDXAccessXBeep(kbd
, _BEEP_FEATURE_ON
, change
);
721 else if (filter
->keycode
== keycode
) {
722 change
= filter
->priv
;
724 xkbControlsNotify cn
;
725 XkbSrvLedInfoPtr sli
;
727 ctrls
->enabled_ctrls
&= ~change
;
728 if (XkbComputeControlsNotify(kbd
, &old
, ctrls
, &cn
, FALSE
)) {
729 cn
.keycode
= keycode
;
730 cn
.eventType
= KeyRelease
;
733 XkbSendControlsNotify(kbd
, &cn
);
736 XkbSetCauseKey(&cause
, keycode
, KeyRelease
);
737 /* If sticky keys were disabled, clear all locks and latches */
738 if ((old
.enabled_ctrls
& XkbStickyKeysMask
) &&
739 (!(ctrls
->enabled_ctrls
& XkbStickyKeysMask
))) {
740 XkbClearAllLatchesAndLocks(kbd
, xkbi
, FALSE
, &cause
);
742 sli
= XkbFindSrvLedInfo(kbd
, XkbDfltXIClass
, XkbDfltXIId
, 0);
743 XkbUpdateIndicators(kbd
, sli
->usesControls
, TRUE
, NULL
, &cause
);
744 if (XkbAX_NeedFeedback(ctrls
, XkbAX_FeatureFBMask
))
745 XkbDDXAccessXBeep(kbd
, _BEEP_FEATURE_OFF
, change
);
754 _XkbFilterActionMessage(XkbSrvInfoPtr xkbi
,
756 unsigned keycode
, XkbAction
*pAction
)
758 XkbMessageAction
*pMsg
;
761 if ((filter
->keycode
!= 0) && (filter
->keycode
!= keycode
))
764 /* This can happen if the key repeats, and the state (modifiers or group)
765 changes meanwhile. */
766 if ((filter
->keycode
== keycode
) && pAction
&&
767 (pAction
->type
!= XkbSA_ActionMessage
))
771 if (filter
->keycode
== 0) { /* initial press */
772 pMsg
= &pAction
->msg
;
773 if ((pMsg
->flags
& XkbSA_MessageOnRelease
) ||
774 ((pMsg
->flags
& XkbSA_MessageGenKeyEvent
) == 0)) {
775 filter
->keycode
= keycode
;
777 filter
->filterOthers
= 0;
779 filter
->filter
= _XkbFilterActionMessage
;
780 filter
->upAction
= *pAction
;
782 if (pMsg
->flags
& XkbSA_MessageOnPress
) {
783 xkbActionMessage msg
;
785 msg
.keycode
= keycode
;
787 msg
.keyEventFollows
=
788 ((pMsg
->flags
& XkbSA_MessageGenKeyEvent
) != 0);
789 memcpy((char *) msg
.message
, (char *) pMsg
->message
,
790 XkbActionMessageLength
);
791 XkbSendActionMessage(kbd
, &msg
);
793 return ((pAction
->msg
.flags
& XkbSA_MessageGenKeyEvent
) != 0);
795 else if (filter
->keycode
== keycode
) {
796 pMsg
= &filter
->upAction
.msg
;
797 if (pAction
== NULL
) {
798 if (pMsg
->flags
& XkbSA_MessageOnRelease
) {
799 xkbActionMessage msg
;
801 msg
.keycode
= keycode
;
803 msg
.keyEventFollows
=
804 ((pMsg
->flags
& XkbSA_MessageGenKeyEvent
) != 0);
805 memcpy((char *) msg
.message
, (char *) pMsg
->message
,
806 XkbActionMessageLength
);
807 XkbSendActionMessage(kbd
, &msg
);
811 return ((pMsg
->flags
& XkbSA_MessageGenKeyEvent
) != 0);
812 } else if (memcmp(pMsg
, pAction
, 8) == 0) {
813 /* Repeat: If we send the same message, avoid multiple messages
814 on release from piling up. */
823 _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi
,
824 XkbFilterPtr filter
, unsigned keycode
, XkbAction
*pAction
)
828 XkbStateRec old
, old_prev
;
830 xkbDeviceInfoPtr xkbPrivPtr
= XKBDEVICEINFO(xkbi
->device
);
831 ProcessInputProc backupproc
;
833 if ((filter
->keycode
!= 0) && (filter
->keycode
!= keycode
))
836 /* This can happen if the key repeats, and the state (modifiers or group)
837 changes meanwhile. */
838 if ((filter
->keycode
== keycode
) && pAction
&&
839 (pAction
->type
!= XkbSA_RedirectKey
))
842 /* never actually used uninitialised, but gcc isn't smart enough
843 * to work that out. */
844 memset(&old
, 0, sizeof(old
));
845 memset(&old_prev
, 0, sizeof(old_prev
));
846 memset(&ev
, 0, sizeof(ev
));
848 GetSpritePosition(xkbi
->device
, &x
, &y
);
849 ev
.header
= ET_Internal
;
850 ev
.length
= sizeof(DeviceEvent
);
851 ev
.time
= GetTimeInMillis();
854 /* redirect actions do not work across devices, therefore the following is
856 ev
.deviceid
= xkbi
->device
->id
;
857 /* filter->priv must be set up by the caller for the initial press. */
858 ev
.sourceid
= filter
->priv
;
860 if (filter
->keycode
== 0) { /* initial press */
861 if ((pAction
->redirect
.new_key
< xkbi
->desc
->min_key_code
) ||
862 (pAction
->redirect
.new_key
> xkbi
->desc
->max_key_code
)) {
865 filter
->keycode
= keycode
;
867 filter
->filterOthers
= 0;
868 filter
->filter
= _XkbFilterRedirectKey
;
869 filter
->upAction
= *pAction
;
871 ev
.type
= ET_KeyPress
;
872 ev
.detail
.key
= pAction
->redirect
.new_key
;
874 mask
= XkbSARedirectVModsMask(&pAction
->redirect
);
875 mods
= XkbSARedirectVMods(&pAction
->redirect
);
877 XkbVirtualModsToReal(xkbi
->desc
, mask
, &mask
);
879 XkbVirtualModsToReal(xkbi
->desc
, mods
, &mods
);
880 mask
|= pAction
->redirect
.mods_mask
;
881 mods
|= pAction
->redirect
.mods
;
885 old_prev
= xkbi
->prev_state
;
886 xkbi
->state
.base_mods
&= ~mask
;
887 xkbi
->state
.base_mods
|= (mods
& mask
);
888 xkbi
->state
.latched_mods
&= ~mask
;
889 xkbi
->state
.latched_mods
|= (mods
& mask
);
890 xkbi
->state
.locked_mods
&= ~mask
;
891 xkbi
->state
.locked_mods
|= (mods
& mask
);
892 XkbComputeDerivedState(xkbi
);
893 xkbi
->prev_state
= xkbi
->state
;
896 UNWRAP_PROCESS_INPUT_PROC(xkbi
->device
, xkbPrivPtr
, backupproc
);
897 xkbi
->device
->public.processInputProc((InternalEvent
*) &ev
,
899 COND_WRAP_PROCESS_INPUT_PROC(xkbi
->device
, xkbPrivPtr
, backupproc
,
904 xkbi
->prev_state
= old_prev
;
909 /* If it is a key release, or we redirect to another key, release the
910 previous new_key. Otherwise, repeat. */
911 ev
.detail
.key
= filter
->upAction
.redirect
.new_key
;
912 if (pAction
== NULL
|| ev
.detail
.key
!= pAction
->redirect
.new_key
) {
913 ev
.type
= ET_KeyRelease
;
917 ev
.type
= ET_KeyPress
;
918 ev
.key_repeat
= TRUE
;
921 mask
= XkbSARedirectVModsMask(&filter
->upAction
.redirect
);
922 mods
= XkbSARedirectVMods(&filter
->upAction
.redirect
);
924 XkbVirtualModsToReal(xkbi
->desc
, mask
, &mask
);
926 XkbVirtualModsToReal(xkbi
->desc
, mods
, &mods
);
927 mask
|= filter
->upAction
.redirect
.mods_mask
;
928 mods
|= filter
->upAction
.redirect
.mods
;
932 old_prev
= xkbi
->prev_state
;
933 xkbi
->state
.base_mods
&= ~mask
;
934 xkbi
->state
.base_mods
|= (mods
& mask
);
935 xkbi
->state
.latched_mods
&= ~mask
;
936 xkbi
->state
.latched_mods
|= (mods
& mask
);
937 xkbi
->state
.locked_mods
&= ~mask
;
938 xkbi
->state
.locked_mods
|= (mods
& mask
);
939 XkbComputeDerivedState(xkbi
);
940 xkbi
->prev_state
= xkbi
->state
;
943 UNWRAP_PROCESS_INPUT_PROC(xkbi
->device
, xkbPrivPtr
, backupproc
);
944 xkbi
->device
->public.processInputProc((InternalEvent
*) &ev
,
946 COND_WRAP_PROCESS_INPUT_PROC(xkbi
->device
, xkbPrivPtr
, backupproc
,
951 xkbi
->prev_state
= old_prev
;
954 /* We return 1 in case we have sent a release event because the new_key
955 has changed. Then, subsequently, we will call this function again
956 with the same pAction, which will create the press for the new
958 return (pAction
&& ev
.detail
.key
!= pAction
->redirect
.new_key
);
963 _XkbFilterSwitchScreen(XkbSrvInfoPtr xkbi
,
965 unsigned keycode
, XkbAction
*pAction
)
967 DeviceIntPtr dev
= xkbi
->device
;
969 if (dev
== inputInfo
.keyboard
)
972 if (filter
->keycode
== 0) { /* initial press */
973 filter
->keycode
= keycode
;
975 filter
->filterOthers
= 0;
976 filter
->filter
= _XkbFilterSwitchScreen
;
977 AccessXCancelRepeatKey(xkbi
, keycode
);
978 XkbDDXSwitchScreen(dev
, keycode
, pAction
);
981 else if (filter
->keycode
== keycode
) {
989 _XkbFilterXF86Private(XkbSrvInfoPtr xkbi
,
990 XkbFilterPtr filter
, unsigned keycode
, XkbAction
*pAction
)
992 DeviceIntPtr dev
= xkbi
->device
;
994 if (dev
== inputInfo
.keyboard
)
997 if (filter
->keycode
== 0) { /* initial press */
998 filter
->keycode
= keycode
;
1000 filter
->filterOthers
= 0;
1001 filter
->filter
= _XkbFilterXF86Private
;
1002 XkbDDXPrivate(dev
, keycode
, pAction
);
1005 else if (filter
->keycode
== keycode
) {
1013 _XkbFilterDeviceBtn(XkbSrvInfoPtr xkbi
,
1014 XkbFilterPtr filter
, unsigned keycode
, XkbAction
*pAction
)
1016 if (xkbi
->device
== inputInfo
.keyboard
)
1019 if (filter
->keycode
== 0) { /* initial press */
1023 _XkbLookupButtonDevice(&dev
, pAction
->devbtn
.device
, serverClient
,
1024 DixUnknownAccess
, &button
);
1025 if (!dev
|| !dev
->public.on
)
1028 button
= pAction
->devbtn
.button
;
1029 if ((button
< 1) || (button
> dev
->button
->numButtons
))
1032 filter
->keycode
= keycode
;
1034 filter
->filterOthers
= 0;
1036 filter
->filter
= _XkbFilterDeviceBtn
;
1037 filter
->upAction
= *pAction
;
1038 switch (pAction
->type
) {
1039 case XkbSA_LockDeviceBtn
:
1040 if ((pAction
->devbtn
.flags
& XkbSA_LockNoLock
) ||
1041 BitIsOn(dev
->button
->down
, button
))
1043 XkbFakeDeviceButton(dev
, TRUE
, button
);
1044 filter
->upAction
.type
= XkbSA_NoAction
;
1046 case XkbSA_DeviceBtn
:
1047 if (pAction
->devbtn
.count
> 0) {
1050 nClicks
= pAction
->btn
.count
;
1051 for (i
= 0; i
< nClicks
; i
++) {
1052 XkbFakeDeviceButton(dev
, TRUE
, button
);
1053 XkbFakeDeviceButton(dev
, FALSE
, button
);
1055 filter
->upAction
.type
= XkbSA_NoAction
;
1058 XkbFakeDeviceButton(dev
, TRUE
, button
);
1062 else if (filter
->keycode
== keycode
) {
1067 _XkbLookupButtonDevice(&dev
, filter
->upAction
.devbtn
.device
,
1068 serverClient
, DixUnknownAccess
, &button
);
1069 if (!dev
|| !dev
->public.on
)
1072 button
= filter
->upAction
.btn
.button
;
1073 switch (filter
->upAction
.type
) {
1074 case XkbSA_LockDeviceBtn
:
1075 if ((filter
->upAction
.devbtn
.flags
& XkbSA_LockNoUnlock
) ||
1076 !BitIsOn(dev
->button
->down
, button
))
1078 XkbFakeDeviceButton(dev
, FALSE
, button
);
1080 case XkbSA_DeviceBtn
:
1081 XkbFakeDeviceButton(dev
, FALSE
, button
);
1090 _XkbNextFreeFilter(XkbSrvInfoPtr xkbi
)
1094 if (xkbi
->szFilters
== 0) {
1095 xkbi
->szFilters
= 4;
1096 xkbi
->filters
= calloc(xkbi
->szFilters
, sizeof(XkbFilterRec
));
1097 /* 6/21/93 (ef) -- XXX! deal with allocation failure */
1099 for (i
= 0; i
< xkbi
->szFilters
; i
++) {
1100 if (!xkbi
->filters
[i
].active
) {
1101 xkbi
->filters
[i
].keycode
= 0;
1102 return &xkbi
->filters
[i
];
1105 xkbi
->szFilters
*= 2;
1106 xkbi
->filters
= realloc(xkbi
->filters
,
1107 xkbi
->szFilters
* sizeof(XkbFilterRec
));
1108 /* 6/21/93 (ef) -- XXX! deal with allocation failure */
1109 memset(&xkbi
->filters
[xkbi
->szFilters
/ 2], 0,
1110 (xkbi
->szFilters
/ 2) * sizeof(XkbFilterRec
));
1111 return &xkbi
->filters
[xkbi
->szFilters
/ 2];
1115 _XkbApplyFilters(XkbSrvInfoPtr xkbi
, unsigned kc
, XkbAction
*pAction
)
1117 register int i
, send
;
1120 for (i
= 0; i
< xkbi
->szFilters
; i
++) {
1121 if ((xkbi
->filters
[i
].active
) && (xkbi
->filters
[i
].filter
))
1123 ((*xkbi
->filters
[i
].filter
) (xkbi
, &xkbi
->filters
[i
], kc
,
1131 XkbHandleActions(DeviceIntPtr dev
, DeviceIntPtr kbd
, DeviceEvent
*event
)
1136 int changed
, sendEvent
;
1137 Bool genStateNotify
;
1139 XkbFilterPtr filter
;
1142 ProcessInputProc backupproc
;
1144 xkbDeviceInfoPtr xkbPrivPtr
= XKBDEVICEINFO(dev
);
1147 xkbi
= keyc
->xkbInfo
;
1148 key
= event
->detail
.key
;
1149 /* The state may change, so if we're not in the middle of sending a state
1150 * notify, prepare for it */
1151 if ((xkbi
->flags
& _XkbStateNotifyInProgress
) == 0) {
1152 xkbi
->prev_state
= xkbi
->state
;
1153 xkbi
->flags
|= _XkbStateNotifyInProgress
;
1154 genStateNotify
= TRUE
;
1157 genStateNotify
= FALSE
;
1159 xkbi
->clearMods
= xkbi
->setMods
= 0;
1160 xkbi
->groupChange
= 0;
1163 keyEvent
= ((event
->type
== ET_KeyPress
) || (event
->type
== ET_KeyRelease
));
1164 pressEvent
= ((event
->type
== ET_KeyPress
) ||
1165 (event
->type
== ET_ButtonPress
));
1169 act
= XkbGetKeyAction(xkbi
, &xkbi
->state
, key
);
1171 act
= XkbGetButtonAction(kbd
, dev
, key
);
1172 key
|= BTN_ACT_FLAG
;
1174 sendEvent
= _XkbApplyFilters(xkbi
, key
, &act
);
1178 case XkbSA_SetGroup
:
1179 filter
= _XkbNextFreeFilter(xkbi
);
1180 sendEvent
= _XkbFilterSetState(xkbi
, filter
, key
, &act
);
1182 case XkbSA_LatchMods
:
1183 case XkbSA_LatchGroup
:
1184 filter
= _XkbNextFreeFilter(xkbi
);
1185 sendEvent
= _XkbFilterLatchState(xkbi
, filter
, key
, &act
);
1187 case XkbSA_LockMods
:
1188 case XkbSA_LockGroup
:
1189 filter
= _XkbNextFreeFilter(xkbi
);
1190 sendEvent
= _XkbFilterLockState(xkbi
, filter
, key
, &act
);
1193 filter
= _XkbNextFreeFilter(xkbi
);
1194 sendEvent
= _XkbFilterISOLock(xkbi
, filter
, key
, &act
);
1197 filter
= _XkbNextFreeFilter(xkbi
);
1198 sendEvent
= _XkbFilterPointerMove(xkbi
, filter
, key
, &act
);
1201 case XkbSA_LockPtrBtn
:
1202 case XkbSA_SetPtrDflt
:
1203 filter
= _XkbNextFreeFilter(xkbi
);
1204 sendEvent
= _XkbFilterPointerBtn(xkbi
, filter
, key
, &act
);
1206 case XkbSA_Terminate
:
1207 sendEvent
= XkbDDXTerminateServer(dev
, key
, &act
);
1209 case XkbSA_SwitchScreen
:
1210 filter
= _XkbNextFreeFilter(xkbi
);
1211 sendEvent
= _XkbFilterSwitchScreen(xkbi
, filter
, key
, &act
);
1213 case XkbSA_SetControls
:
1214 case XkbSA_LockControls
:
1215 filter
= _XkbNextFreeFilter(xkbi
);
1216 sendEvent
= _XkbFilterControls(xkbi
, filter
, key
, &act
);
1218 case XkbSA_ActionMessage
:
1219 filter
= _XkbNextFreeFilter(xkbi
);
1220 sendEvent
= _XkbFilterActionMessage(xkbi
, filter
, key
, &act
);
1222 case XkbSA_RedirectKey
:
1223 filter
= _XkbNextFreeFilter(xkbi
);
1224 /* redirect actions must create a new DeviceEvent. The
1225 * source device id for this event cannot be obtained from
1226 * xkbi, so we pass it here explicitly. The field deviceid
1227 * equals to xkbi->device->id. */
1228 filter
->priv
= event
->sourceid
;
1229 sendEvent
= _XkbFilterRedirectKey(xkbi
, filter
, key
, &act
);
1231 case XkbSA_DeviceBtn
:
1232 case XkbSA_LockDeviceBtn
:
1233 filter
= _XkbNextFreeFilter(xkbi
);
1234 sendEvent
= _XkbFilterDeviceBtn(xkbi
, filter
, key
, &act
);
1236 case XkbSA_XFree86Private
:
1237 filter
= _XkbNextFreeFilter(xkbi
);
1238 sendEvent
= _XkbFilterXF86Private(xkbi
, filter
, key
, &act
);
1245 key
|= BTN_ACT_FLAG
;
1246 sendEvent
= _XkbApplyFilters(xkbi
, key
, NULL
);
1249 if (xkbi
->groupChange
!= 0)
1250 xkbi
->state
.base_group
+= xkbi
->groupChange
;
1251 if (xkbi
->setMods
) {
1252 for (i
= 0, bit
= 1; xkbi
->setMods
; i
++, bit
<<= 1) {
1253 if (xkbi
->setMods
& bit
) {
1254 keyc
->modifierKeyCount
[i
]++;
1255 xkbi
->state
.base_mods
|= bit
;
1256 xkbi
->setMods
&= ~bit
;
1260 if (xkbi
->clearMods
) {
1261 for (i
= 0, bit
= 1; xkbi
->clearMods
; i
++, bit
<<= 1) {
1262 if (xkbi
->clearMods
& bit
) {
1263 keyc
->modifierKeyCount
[i
]--;
1264 if (keyc
->modifierKeyCount
[i
] <= 0) {
1265 xkbi
->state
.base_mods
&= ~bit
;
1266 keyc
->modifierKeyCount
[i
] = 0;
1268 xkbi
->clearMods
&= ~bit
;
1274 DeviceIntPtr tmpdev
;
1279 tmpdev
= GetMaster(dev
, POINTER_OR_FLOAT
);
1281 UNWRAP_PROCESS_INPUT_PROC(tmpdev
, xkbPrivPtr
, backupproc
);
1282 dev
->public.processInputProc((InternalEvent
*) event
, tmpdev
);
1283 COND_WRAP_PROCESS_INPUT_PROC(tmpdev
, xkbPrivPtr
,
1284 backupproc
, xkbUnwrapProc
);
1286 else if (keyEvent
) {
1287 FixKeyState(event
, dev
);
1290 XkbComputeDerivedState(xkbi
);
1291 changed
= XkbStateChangedFlags(&xkbi
->prev_state
, &xkbi
->state
);
1292 if (genStateNotify
) {
1297 sn
.eventType
= event
->type
;
1298 sn
.requestMajor
= sn
.requestMinor
= 0;
1299 sn
.changed
= changed
;
1300 XkbSendStateNotify(dev
, &sn
);
1302 xkbi
->flags
&= ~_XkbStateNotifyInProgress
;
1304 changed
= XkbIndicatorsToUpdate(dev
, changed
, FALSE
);
1306 XkbEventCauseRec cause
;
1308 XkbSetCauseKey(&cause
, key
, event
->type
);
1309 XkbUpdateIndicators(dev
, changed
, FALSE
, NULL
, &cause
);
1315 XkbLatchModifiers(DeviceIntPtr pXDev
, CARD8 mask
, CARD8 latches
)
1318 XkbFilterPtr filter
;
1322 if (pXDev
&& pXDev
->key
&& pXDev
->key
->xkbInfo
) {
1323 xkbi
= pXDev
->key
->xkbInfo
;
1324 clear
= (mask
& (~latches
));
1325 xkbi
->state
.latched_mods
&= ~clear
;
1326 /* Clear any pending latch to locks.
1328 act
.type
= XkbSA_NoAction
;
1329 _XkbApplyFilters(xkbi
, SYNTHETIC_KEYCODE
, &act
);
1330 act
.type
= XkbSA_LatchMods
;
1332 act
.mods
.mask
= mask
& latches
;
1333 filter
= _XkbNextFreeFilter(xkbi
);
1334 _XkbFilterLatchState(xkbi
, filter
, SYNTHETIC_KEYCODE
, &act
);
1335 _XkbFilterLatchState(xkbi
, filter
, SYNTHETIC_KEYCODE
,
1336 (XkbAction
*) NULL
);
1343 XkbLatchGroup(DeviceIntPtr pXDev
, int group
)
1346 XkbFilterPtr filter
;
1349 if (pXDev
&& pXDev
->key
&& pXDev
->key
->xkbInfo
) {
1350 xkbi
= pXDev
->key
->xkbInfo
;
1351 act
.type
= XkbSA_LatchGroup
;
1352 act
.group
.flags
= 0;
1353 XkbSASetGroup(&act
.group
, group
);
1354 filter
= _XkbNextFreeFilter(xkbi
);
1355 _XkbFilterLatchState(xkbi
, filter
, SYNTHETIC_KEYCODE
, &act
);
1356 _XkbFilterLatchState(xkbi
, filter
, SYNTHETIC_KEYCODE
,
1357 (XkbAction
*) NULL
);
1363 /***====================================================================***/
1366 XkbClearAllLatchesAndLocks(DeviceIntPtr dev
,
1368 Bool genEv
, XkbEventCausePtr cause
)
1375 if (os
.latched_mods
) { /* clear all latches */
1376 XkbLatchModifiers(dev
, ~0, 0);
1377 sn
.changed
|= XkbModifierLatchMask
;
1379 if (os
.latched_group
) {
1380 XkbLatchGroup(dev
, 0);
1381 sn
.changed
|= XkbGroupLatchMask
;
1383 if (os
.locked_mods
) {
1384 xkbi
->state
.locked_mods
= 0;
1385 sn
.changed
|= XkbModifierLockMask
;
1387 if (os
.locked_group
) {
1388 xkbi
->state
.locked_group
= 0;
1389 sn
.changed
|= XkbGroupLockMask
;
1391 if (genEv
&& sn
.changed
) {
1394 XkbComputeDerivedState(xkbi
);
1395 sn
.keycode
= cause
->kc
;
1396 sn
.eventType
= cause
->event
;
1397 sn
.requestMajor
= cause
->mjr
;
1398 sn
.requestMinor
= cause
->mnr
;
1399 sn
.changed
= XkbStateChangedFlags(&os
, &xkbi
->state
);
1400 XkbSendStateNotify(dev
, &sn
);
1401 changed
= XkbIndicatorsToUpdate(dev
, sn
.changed
, FALSE
);
1403 XkbUpdateIndicators(dev
, changed
, TRUE
, NULL
, cause
);
1410 * The event is injected into the event processing, not the EQ. Thus,
1411 * ensure that we restore the master after the event sequence to the
1412 * original set of classes. Otherwise, the master remains on the XTEST
1413 * classes and drops events that don't fit into the XTEST layout (e.g.
1414 * events with more than 2 valuators).
1416 * FIXME: EQ injection in the processing stage is not designed for, so this
1417 * is a rather awkward hack. The event list returned by GetPointerEvents()
1418 * and friends is always prefixed with a DCE if the last _posted_ device was
1419 * different. For normal events, this sequence then resets the master during
1420 * the processing stage. Since we inject the PointerKey events in the
1421 * processing stage though, we need to manually reset to restore the
1422 * previous order, because the events already in the EQ must be sent for the
1424 * So we post-fix the event list we get from GPE with a DCE back to the
1425 * previous slave device.
1427 * First one on drinking island wins!
1430 InjectPointerKeyEvents(DeviceIntPtr dev
, int type
, int button
, int flags
,
1434 InternalEvent
*events
;
1436 DeviceIntPtr ptr
, mpointer
, lastSlave
= NULL
;
1439 if (IsMaster(dev
)) {
1440 mpointer
= GetMaster(dev
, MASTER_POINTER
);
1441 lastSlave
= mpointer
->lastSlave
;
1442 ptr
= GetXTestDevice(mpointer
);
1444 else if (IsFloating(dev
))
1449 events
= InitEventList(GetMaximumEventsNum() + 1);
1451 pScreen
= miPointerGetScreen(ptr
);
1452 saveWait
= miPointerSetWaitForUpdate(pScreen
, FALSE
);
1453 nevents
= GetPointerEvents(events
, ptr
, type
, button
, flags
, mask
);
1454 if (IsMaster(dev
) && (lastSlave
&& lastSlave
!= ptr
))
1455 UpdateFromMaster(&events
[nevents
], lastSlave
, DEVCHANGE_POINTER_EVENT
,
1457 miPointerSetWaitForUpdate(pScreen
, saveWait
);
1460 for (i
= 0; i
< nevents
; i
++)
1461 mieqProcessDeviceEvent(ptr
, &events
[i
], NULL
);
1463 FreeEventList(events
, GetMaximumEventsNum());
1468 XkbFakePointerMotion(DeviceIntPtr dev
, unsigned flags
, int x
, int y
)
1473 /* ignore attached SDs */
1474 if (!IsMaster(dev
) && !IsFloating(dev
))
1477 if (flags
& XkbSA_MoveAbsoluteX
|| flags
& XkbSA_MoveAbsoluteY
)
1478 gpe_flags
= POINTER_ABSOLUTE
;
1480 gpe_flags
= POINTER_RELATIVE
;
1482 valuator_mask_set_range(&mask
, 0, 2, (int[]) {
1485 InjectPointerKeyEvents(dev
, MotionNotify
, 0, gpe_flags
, &mask
);
1489 XkbFakeDeviceButton(DeviceIntPtr dev
, Bool press
, int button
)
1494 /* If dev is a slave device, and the SD is attached, do nothing. If we'd
1495 * post through the attached master pointer we'd get duplicate events.
1497 * if dev is a master keyboard, post through the XTEST device
1499 * if dev is a floating slave, post through the device itself.
1502 if (IsMaster(dev
)) {
1503 DeviceIntPtr mpointer
= GetMaster(dev
, MASTER_POINTER
);
1505 ptr
= GetXTestDevice(mpointer
);
1507 else if (IsFloating(dev
))
1512 down
= button_is_down(ptr
, button
, BUTTON_PROCESSED
);
1516 InjectPointerKeyEvents(dev
, press
? ButtonPress
: ButtonRelease
,