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, void *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, void *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, (void *) 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 _XkbEnsureStateChange(XkbSrvInfoPtr xkbi)
1133 Bool genStateNotify = FALSE;
1135 /* The state may change, so if we're not in the middle of sending a state
1136 * notify, prepare for it */
1137 if ((xkbi->flags & _XkbStateNotifyInProgress) == 0) {
1138 xkbi->prev_state = xkbi->state;
1139 xkbi->flags |= _XkbStateNotifyInProgress;
1140 genStateNotify = TRUE;
1143 return genStateNotify;
1147 _XkbApplyState(DeviceIntPtr dev, Bool genStateNotify, int evtype, int key)
1149 XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
1152 XkbComputeDerivedState(xkbi);
1154 changed = XkbStateChangedFlags(&xkbi->prev_state, &xkbi->state);
1155 if (genStateNotify) {
1160 sn.eventType = evtype;
1161 sn.requestMajor = sn.requestMinor = 0;
1162 sn.changed = changed;
1163 XkbSendStateNotify(dev, &sn);
1165 xkbi->flags &= ~_XkbStateNotifyInProgress;
1168 changed = XkbIndicatorsToUpdate(dev, changed, FALSE);
1170 XkbEventCauseRec cause;
1171 XkbSetCauseKey(&cause, key, evtype);
1172 XkbUpdateIndicators(dev, changed, FALSE, NULL, &cause);
1177 XkbPushLockedStateToSlaves(DeviceIntPtr master, int evtype, int key)
1180 Bool genStateNotify;
1182 nt_list_for_each_entry(dev, inputInfo.devices, next) {
1183 if (!dev->key || GetMaster(dev, MASTER_KEYBOARD) != master)
1186 genStateNotify = _XkbEnsureStateChange(dev->key->xkbInfo);
1188 dev->key->xkbInfo->state.locked_mods =
1189 master->key->xkbInfo->state.locked_mods;
1191 _XkbApplyState(dev, genStateNotify, evtype, key);
1196 XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
1202 Bool genStateNotify;
1204 XkbFilterPtr filter;
1207 ProcessInputProc backupproc;
1209 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
1212 xkbi = keyc->xkbInfo;
1213 key = event->detail.key;
1215 genStateNotify = _XkbEnsureStateChange(xkbi);
1217 xkbi->clearMods = xkbi->setMods = 0;
1218 xkbi->groupChange = 0;
1221 keyEvent = ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease));
1222 pressEvent = ((event->type == ET_KeyPress) ||
1223 (event->type == ET_ButtonPress));
1227 act = XkbGetKeyAction(xkbi, &xkbi->state, key);
1229 act = XkbGetButtonAction(kbd, dev, key);
1230 key |= BTN_ACT_FLAG;
1232 sendEvent = _XkbApplyFilters(xkbi, key, &act);
1236 case XkbSA_SetGroup:
1237 filter = _XkbNextFreeFilter(xkbi);
1238 sendEvent = _XkbFilterSetState(xkbi, filter, key, &act);
1240 case XkbSA_LatchMods:
1241 case XkbSA_LatchGroup:
1242 filter = _XkbNextFreeFilter(xkbi);
1243 sendEvent = _XkbFilterLatchState(xkbi, filter, key, &act);
1245 case XkbSA_LockMods:
1246 case XkbSA_LockGroup:
1247 filter = _XkbNextFreeFilter(xkbi);
1248 sendEvent = _XkbFilterLockState(xkbi, filter, key, &act);
1251 filter = _XkbNextFreeFilter(xkbi);
1252 sendEvent = _XkbFilterISOLock(xkbi, filter, key, &act);
1255 filter = _XkbNextFreeFilter(xkbi);
1256 sendEvent = _XkbFilterPointerMove(xkbi, filter, key, &act);
1259 case XkbSA_LockPtrBtn:
1260 case XkbSA_SetPtrDflt:
1261 filter = _XkbNextFreeFilter(xkbi);
1262 sendEvent = _XkbFilterPointerBtn(xkbi, filter, key, &act);
1264 case XkbSA_Terminate:
1265 sendEvent = XkbDDXTerminateServer(dev, key, &act);
1267 case XkbSA_SwitchScreen:
1268 filter = _XkbNextFreeFilter(xkbi);
1269 sendEvent = _XkbFilterSwitchScreen(xkbi, filter, key, &act);
1271 case XkbSA_SetControls:
1272 case XkbSA_LockControls:
1273 filter = _XkbNextFreeFilter(xkbi);
1274 sendEvent = _XkbFilterControls(xkbi, filter, key, &act);
1276 case XkbSA_ActionMessage:
1277 filter = _XkbNextFreeFilter(xkbi);
1278 sendEvent = _XkbFilterActionMessage(xkbi, filter, key, &act);
1280 case XkbSA_RedirectKey:
1281 filter = _XkbNextFreeFilter(xkbi);
1282 /* redirect actions must create a new DeviceEvent. The
1283 * source device id for this event cannot be obtained from
1284 * xkbi, so we pass it here explicitly. The field deviceid
1285 * equals to xkbi->device->id. */
1286 filter->priv = event->sourceid;
1287 sendEvent = _XkbFilterRedirectKey(xkbi, filter, key, &act);
1289 case XkbSA_DeviceBtn:
1290 case XkbSA_LockDeviceBtn:
1291 filter = _XkbNextFreeFilter(xkbi);
1292 sendEvent = _XkbFilterDeviceBtn(xkbi, filter, key, &act);
1294 case XkbSA_XFree86Private:
1295 filter = _XkbNextFreeFilter(xkbi);
1296 sendEvent = _XkbFilterXF86Private(xkbi, filter, key, &act);
1303 key |= BTN_ACT_FLAG;
1304 sendEvent = _XkbApplyFilters(xkbi, key, NULL);
1307 if (xkbi->groupChange != 0)
1308 xkbi->state.base_group += xkbi->groupChange;
1309 if (xkbi->setMods) {
1310 for (i = 0, bit = 1; xkbi->setMods; i++, bit <<= 1) {
1311 if (xkbi->setMods & bit) {
1312 keyc->modifierKeyCount[i]++;
1313 xkbi->state.base_mods |= bit;
1314 xkbi->setMods &= ~bit;
1318 if (xkbi->clearMods) {
1319 for (i = 0, bit = 1; xkbi->clearMods; i++, bit <<= 1) {
1320 if (xkbi->clearMods & bit) {
1321 keyc->modifierKeyCount[i]--;
1322 if (keyc->modifierKeyCount[i] <= 0) {
1323 xkbi->state.base_mods &= ~bit;
1324 keyc->modifierKeyCount[i] = 0;
1326 xkbi->clearMods &= ~bit;
1332 DeviceIntPtr tmpdev;
1337 tmpdev = GetMaster(dev, POINTER_OR_FLOAT);
1339 UNWRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr, backupproc);
1340 dev->public.processInputProc((InternalEvent *) event, tmpdev);
1341 COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
1342 backupproc, xkbUnwrapProc);
1344 else if (keyEvent) {
1345 FixKeyState(event, dev);
1348 _XkbApplyState(dev, genStateNotify, event->type, key);
1349 XkbPushLockedStateToSlaves(dev, event->type, key);
1353 XkbLatchModifiers(DeviceIntPtr pXDev, CARD8 mask, CARD8 latches)
1356 XkbFilterPtr filter;
1360 if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
1361 xkbi = pXDev->key->xkbInfo;
1362 clear = (mask & (~latches));
1363 xkbi->state.latched_mods &= ~clear;
1364 /* Clear any pending latch to locks.
1366 act.type = XkbSA_NoAction;
1367 _XkbApplyFilters(xkbi, SYNTHETIC_KEYCODE, &act);
1368 act.type = XkbSA_LatchMods;
1370 act.mods.mask = mask & latches;
1371 filter = _XkbNextFreeFilter(xkbi);
1372 _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, &act);
1373 _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE,
1374 (XkbAction *) NULL);
1381 XkbLatchGroup(DeviceIntPtr pXDev, int group)
1384 XkbFilterPtr filter;
1387 if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
1388 xkbi = pXDev->key->xkbInfo;
1389 act.type = XkbSA_LatchGroup;
1390 act.group.flags = 0;
1391 XkbSASetGroup(&act.group, group);
1392 filter = _XkbNextFreeFilter(xkbi);
1393 _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, &act);
1394 _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE,
1395 (XkbAction *) NULL);
1401 /***====================================================================***/
1404 XkbClearAllLatchesAndLocks(DeviceIntPtr dev,
1406 Bool genEv, XkbEventCausePtr cause)
1413 if (os.latched_mods) { /* clear all latches */
1414 XkbLatchModifiers(dev, ~0, 0);
1415 sn.changed |= XkbModifierLatchMask;
1417 if (os.latched_group) {
1418 XkbLatchGroup(dev, 0);
1419 sn.changed |= XkbGroupLatchMask;
1421 if (os.locked_mods) {
1422 xkbi->state.locked_mods = 0;
1423 sn.changed |= XkbModifierLockMask;
1425 if (os.locked_group) {
1426 xkbi->state.locked_group = 0;
1427 sn.changed |= XkbGroupLockMask;
1429 if (genEv && sn.changed) {
1432 XkbComputeDerivedState(xkbi);
1433 sn.keycode = cause->kc;
1434 sn.eventType = cause->event;
1435 sn.requestMajor = cause->mjr;
1436 sn.requestMinor = cause->mnr;
1437 sn.changed = XkbStateChangedFlags(&os, &xkbi->state);
1438 XkbSendStateNotify(dev, &sn);
1439 changed = XkbIndicatorsToUpdate(dev, sn.changed, FALSE);
1441 XkbUpdateIndicators(dev, changed, TRUE, NULL, cause);
1448 * The event is injected into the event processing, not the EQ. Thus,
1449 * ensure that we restore the master after the event sequence to the
1450 * original set of classes. Otherwise, the master remains on the XTEST
1451 * classes and drops events that don't fit into the XTEST layout (e.g.
1452 * events with more than 2 valuators).
1454 * FIXME: EQ injection in the processing stage is not designed for, so this
1455 * is a rather awkward hack. The event list returned by GetPointerEvents()
1456 * and friends is always prefixed with a DCE if the last _posted_ device was
1457 * different. For normal events, this sequence then resets the master during
1458 * the processing stage. Since we inject the PointerKey events in the
1459 * processing stage though, we need to manually reset to restore the
1460 * previous order, because the events already in the EQ must be sent for the
1462 * So we post-fix the event list we get from GPE with a DCE back to the
1463 * previous slave device.
1465 * First one on drinking island wins!
1468 InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags,
1472 InternalEvent *events;
1474 DeviceIntPtr ptr, mpointer, lastSlave = NULL;
1477 if (IsMaster(dev)) {
1478 mpointer = GetMaster(dev, MASTER_POINTER);
1479 lastSlave = mpointer->lastSlave;
1480 ptr = GetXTestDevice(mpointer);
1482 else if (IsFloating(dev))
1487 events = InitEventList(GetMaximumEventsNum() + 1);
1489 pScreen = miPointerGetScreen(ptr);
1490 saveWait = miPointerSetWaitForUpdate(pScreen, FALSE);
1491 nevents = GetPointerEvents(events, ptr, type, button, flags, mask);
1492 if (IsMaster(dev) && (lastSlave && lastSlave != ptr))
1493 UpdateFromMaster(&events[nevents], lastSlave, DEVCHANGE_POINTER_EVENT,
1495 miPointerSetWaitForUpdate(pScreen, saveWait);
1498 for (i = 0; i < nevents; i++)
1499 mieqProcessDeviceEvent(ptr, &events[i], NULL);
1501 FreeEventList(events, GetMaximumEventsNum());
1506 XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags, int x, int y)
1511 /* ignore attached SDs */
1512 if (!IsMaster(dev) && !IsFloating(dev))
1515 if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
1516 gpe_flags = POINTER_ABSOLUTE;
1518 gpe_flags = POINTER_RELATIVE;
1520 valuator_mask_set_range(&mask, 0, 2, (int[]) {
1523 InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, &mask);
1527 XkbFakeDeviceButton(DeviceIntPtr dev, Bool press, int button)
1532 /* If dev is a slave device, and the SD is attached, do nothing. If we'd
1533 * post through the attached master pointer we'd get duplicate events.
1535 * if dev is a master keyboard, post through the XTEST device
1537 * if dev is a floating slave, post through the device itself.
1540 if (IsMaster(dev)) {
1541 DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER);
1543 ptr = GetXTestDevice(mpointer);
1545 else if (IsFloating(dev))
1550 #ifdef _F_DO_NULL_CHECK_AT_XKBFAKEDEVICEBUTTON_
1553 #endif /* #ifdef _F_DO_NULL_CHECK_AT_XKBFAKEDEVICEBUTTON_ */
1555 down = button_is_down(ptr, button, BUTTON_PROCESSED);
1559 InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease,