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
228 _XkbFilterLatchState(XkbSrvInfoPtr xkbi,
229 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
232 if (filter->keycode == 0) { /* initial press */
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 (filter->upAction.type == XkbSA_LatchMods)
254 xkbi->state.latched_mods &= ~filter->upAction.mods.mask;
256 xkbi->state.latched_group -=
257 XkbSAGroup(&filter->upAction.group);
259 else if ((pAction->type == filter->upAction.type) &&
260 (pAction->mods.flags == filter->upAction.mods.flags) &&
261 (pAction->mods.mask == filter->upAction.mods.mask)) {
262 if (filter->upAction.mods.flags & XkbSA_LatchToLock) {
263 XkbControlsPtr ctrls = xkbi->desc->ctrls;
265 if (filter->upAction.type == XkbSA_LatchMods)
266 pAction->mods.type = XkbSA_LockMods;
268 pAction->group.type = XkbSA_LockGroup;
269 if (XkbAX_NeedFeedback(ctrls, XkbAX_StickyKeysFBMask) &&
270 (ctrls->enabled_ctrls & XkbStickyKeysMask)) {
271 XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK,
276 if (filter->upAction.type == XkbSA_LatchMods)
277 pAction->mods.type = XkbSA_SetMods;
279 pAction->group.type = XkbSA_SetGroup;
281 if (filter->upAction.type == XkbSA_LatchMods)
282 xkbi->state.latched_mods &= ~filter->upAction.mods.mask;
284 xkbi->state.latched_group -=
285 XkbSAGroup(&filter->upAction.group);
289 else if (filter->keycode == keycode) { /* release */
290 XkbControlsPtr ctrls = xkbi->desc->ctrls;
292 int beepType = _BEEP_NONE;
294 needBeep = ((ctrls->enabled_ctrls & XkbStickyKeysMask) &&
295 XkbAX_NeedFeedback(ctrls, XkbAX_StickyKeysFBMask));
296 if (filter->upAction.type == XkbSA_LatchMods) {
297 xkbi->clearMods = filter->upAction.mods.mask;
298 if ((filter->upAction.mods.flags & XkbSA_ClearLocks) &&
299 (xkbi->clearMods & xkbi->state.locked_mods) ==
301 xkbi->state.locked_mods &= ~xkbi->clearMods;
302 filter->priv = NO_LATCH;
303 beepType = _BEEP_STICKY_UNLOCK;
307 xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
308 if ((filter->upAction.group.flags & XkbSA_ClearLocks) &&
309 (xkbi->state.locked_group)) {
310 xkbi->state.locked_group = 0;
311 filter->priv = NO_LATCH;
312 beepType = _BEEP_STICKY_UNLOCK;
315 if (filter->priv == NO_LATCH) {
319 filter->priv = LATCH_PENDING;
320 if (filter->upAction.type == XkbSA_LatchMods) {
321 xkbi->state.latched_mods |= filter->upAction.mods.mask;
322 needBeep = xkbi->state.latched_mods ? needBeep : 0;
323 xkbi->state.latched_mods |= filter->upAction.mods.mask;
326 xkbi->state.latched_group +=
327 XkbSAGroup(&filter->upAction.group);
329 if (needBeep && (beepType == _BEEP_NONE))
330 beepType = _BEEP_STICKY_LATCH;
332 if (needBeep && (beepType != _BEEP_NONE))
333 XkbDDXAccessXBeep(xkbi->device, beepType, XkbStickyKeysMask);
335 else if (filter->priv == LATCH_KEY_DOWN) {
336 filter->priv = NO_LATCH;
337 filter->filterOthers = 0;
343 _XkbFilterLockState(XkbSrvInfoPtr xkbi,
344 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
346 if (pAction && (pAction->type == XkbSA_LockGroup)) {
347 if (pAction->group.flags & XkbSA_GroupAbsolute)
348 xkbi->state.locked_group = XkbSAGroup(&pAction->group);
350 xkbi->state.locked_group += XkbSAGroup(&pAction->group);
353 if (filter->keycode == 0) { /* initial press */
354 filter->keycode = keycode;
356 filter->filterOthers = 0;
357 filter->priv = xkbi->state.locked_mods & pAction->mods.mask;
358 filter->filter = _XkbFilterLockState;
359 filter->upAction = *pAction;
360 if (!(filter->upAction.mods.flags & XkbSA_LockNoLock))
361 xkbi->state.locked_mods |= pAction->mods.mask;
362 xkbi->setMods = pAction->mods.mask;
364 else if (filter->keycode == keycode) {
366 xkbi->clearMods = filter->upAction.mods.mask;
367 if (!(filter->upAction.mods.flags & XkbSA_LockNoUnlock))
368 xkbi->state.locked_mods &= ~filter->priv;
373 #define ISO_KEY_DOWN 0
374 #define NO_ISO_LOCK 1
377 _XkbFilterISOLock(XkbSrvInfoPtr xkbi,
378 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
381 if (filter->keycode == 0) { /* initial press */
382 CARD8 flags = pAction->iso.flags;
384 filter->keycode = keycode;
386 filter->filterOthers = 1;
387 filter->priv = ISO_KEY_DOWN;
388 filter->upAction = *pAction;
389 filter->filter = _XkbFilterISOLock;
390 if (flags & XkbSA_ISODfltIsGroup) {
391 xkbi->groupChange = XkbSAGroup(&pAction->iso);
395 xkbi->setMods = pAction->iso.mask;
396 xkbi->groupChange = 0;
398 if ((!(flags & XkbSA_ISONoAffectMods)) && (xkbi->state.base_mods)) {
399 filter->priv = NO_ISO_LOCK;
400 xkbi->state.locked_mods ^= xkbi->state.base_mods;
402 if ((!(flags & XkbSA_ISONoAffectGroup)) && (xkbi->state.base_group)) {
403 /* 6/22/93 (ef) -- lock groups if group key is down first */
405 if (!(flags & XkbSA_ISONoAffectPtr)) {
406 /* 6/22/93 (ef) -- lock mouse buttons if they're down */
409 else if (filter->keycode == keycode) {
410 CARD8 flags = filter->upAction.iso.flags;
412 if (flags & XkbSA_ISODfltIsGroup) {
413 xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso);
415 if (filter->priv == ISO_KEY_DOWN)
416 xkbi->state.locked_group += XkbSAGroup(&filter->upAction.iso);
419 xkbi->clearMods = filter->upAction.iso.mask;
420 xkbi->groupChange = 0;
421 if (filter->priv == ISO_KEY_DOWN)
422 xkbi->state.locked_mods ^= filter->upAction.iso.mask;
427 CARD8 flags = filter->upAction.iso.flags;
429 switch (pAction->type) {
431 case XkbSA_LatchMods:
432 if (!(flags & XkbSA_ISONoAffectMods)) {
433 pAction->type = XkbSA_LockMods;
434 filter->priv = NO_ISO_LOCK;
438 case XkbSA_LatchGroup:
439 if (!(flags & XkbSA_ISONoAffectGroup)) {
440 pAction->type = XkbSA_LockGroup;
441 filter->priv = NO_ISO_LOCK;
445 if (!(flags & XkbSA_ISONoAffectPtr)) {
446 pAction->type = XkbSA_LockPtrBtn;
447 filter->priv = NO_ISO_LOCK;
450 case XkbSA_SetControls:
451 if (!(flags & XkbSA_ISONoAffectCtrls)) {
452 pAction->type = XkbSA_LockControls;
453 filter->priv = NO_ISO_LOCK;
462 _XkbPtrAccelExpire(OsTimerPtr timer, CARD32 now, pointer arg)
464 XkbSrvInfoPtr xkbi = (XkbSrvInfoPtr) arg;
465 XkbControlsPtr ctrls = xkbi->desc->ctrls;
468 if (xkbi->mouseKey == 0)
471 if (xkbi->mouseKeysAccel) {
472 if ((xkbi->mouseKeysCounter) < ctrls->mk_time_to_max) {
475 xkbi->mouseKeysCounter++;
476 step = xkbi->mouseKeysCurveFactor *
477 pow((double) xkbi->mouseKeysCounter, xkbi->mouseKeysCurve);
478 if (xkbi->mouseKeysDX < 0)
479 dx = floor(((double) xkbi->mouseKeysDX) * step);
481 dx = ceil(((double) xkbi->mouseKeysDX) * step);
482 if (xkbi->mouseKeysDY < 0)
483 dy = floor(((double) xkbi->mouseKeysDY) * step);
485 dy = ceil(((double) xkbi->mouseKeysDY) * step);
488 dx = xkbi->mouseKeysDX * ctrls->mk_max_speed;
489 dy = xkbi->mouseKeysDY * ctrls->mk_max_speed;
491 if (xkbi->mouseKeysFlags & XkbSA_MoveAbsoluteX)
492 dx = xkbi->mouseKeysDX;
493 if (xkbi->mouseKeysFlags & XkbSA_MoveAbsoluteY)
494 dy = xkbi->mouseKeysDY;
497 dx = xkbi->mouseKeysDX;
498 dy = xkbi->mouseKeysDY;
500 XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags, dx, dy);
501 return xkbi->desc->ctrls->mk_interval;
505 _XkbFilterPointerMove(XkbSrvInfoPtr xkbi,
506 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
511 if (filter->keycode == 0) { /* initial press */
512 filter->keycode = keycode;
514 filter->filterOthers = 0;
516 filter->filter = _XkbFilterPointerMove;
517 filter->upAction = *pAction;
518 xkbi->mouseKeysCounter = 0;
519 xkbi->mouseKey = keycode;
520 accel = ((pAction->ptr.flags & XkbSA_NoAcceleration) == 0);
521 x = XkbPtrActionX(&pAction->ptr);
522 y = XkbPtrActionY(&pAction->ptr);
523 XkbFakePointerMotion(xkbi->device, pAction->ptr.flags, x, y);
524 AccessXCancelRepeatKey(xkbi, keycode);
525 xkbi->mouseKeysAccel = accel &&
526 (xkbi->desc->ctrls->enabled_ctrls & XkbMouseKeysAccelMask);
527 xkbi->mouseKeysFlags = pAction->ptr.flags;
528 xkbi->mouseKeysDX = XkbPtrActionX(&pAction->ptr);
529 xkbi->mouseKeysDY = XkbPtrActionY(&pAction->ptr);
530 xkbi->mouseKeyTimer = TimerSet(xkbi->mouseKeyTimer, 0,
531 xkbi->desc->ctrls->mk_delay,
532 _XkbPtrAccelExpire, (pointer) xkbi);
534 else if (filter->keycode == keycode) {
536 if (xkbi->mouseKey == keycode) {
538 xkbi->mouseKeyTimer = TimerSet(xkbi->mouseKeyTimer, 0, 0,
546 _XkbFilterPointerBtn(XkbSrvInfoPtr xkbi,
547 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
549 if (filter->keycode == 0) { /* initial press */
550 int button = pAction->btn.button;
552 if (button == XkbSA_UseDfltButton)
553 button = xkbi->desc->ctrls->mk_dflt_btn;
555 filter->keycode = keycode;
557 filter->filterOthers = 0;
559 filter->filter = _XkbFilterPointerBtn;
560 filter->upAction = *pAction;
561 filter->upAction.btn.button = button;
562 switch (pAction->type) {
563 case XkbSA_LockPtrBtn:
564 if (((xkbi->lockedPtrButtons & (1 << button)) == 0) &&
565 ((pAction->btn.flags & XkbSA_LockNoLock) == 0)) {
566 xkbi->lockedPtrButtons |= (1 << button);
567 AccessXCancelRepeatKey(xkbi, keycode);
568 XkbFakeDeviceButton(xkbi->device, 1, button);
569 filter->upAction.type = XkbSA_NoAction;
574 register int i, nClicks;
576 AccessXCancelRepeatKey(xkbi, keycode);
577 if (pAction->btn.count > 0) {
578 nClicks = pAction->btn.count;
579 for (i = 0; i < nClicks; i++) {
580 XkbFakeDeviceButton(xkbi->device, 1, button);
581 XkbFakeDeviceButton(xkbi->device, 0, button);
583 filter->upAction.type = XkbSA_NoAction;
586 XkbFakeDeviceButton(xkbi->device, 1, button);
589 case XkbSA_SetPtrDflt:
591 XkbControlsPtr ctrls = xkbi->desc->ctrls;
593 xkbControlsNotify cn;
596 AccessXCancelRepeatKey(xkbi, keycode);
597 switch (pAction->dflt.affect) {
598 case XkbSA_AffectDfltBtn:
599 if (pAction->dflt.flags & XkbSA_DfltBtnAbsolute)
600 ctrls->mk_dflt_btn = XkbSAPtrDfltValue(&pAction->dflt);
602 ctrls->mk_dflt_btn += XkbSAPtrDfltValue(&pAction->dflt);
603 if (ctrls->mk_dflt_btn > 5)
604 ctrls->mk_dflt_btn = 5;
605 else if (ctrls->mk_dflt_btn < 1)
606 ctrls->mk_dflt_btn = 1;
611 ("Attempt to change unknown pointer default (%d) ignored\n",
612 pAction->dflt.affect);
615 if (XkbComputeControlsNotify(xkbi->device,
616 &old, xkbi->desc->ctrls, &cn, FALSE)) {
617 cn.keycode = keycode;
618 /* XXX: what about DeviceKeyPress? */
619 cn.eventType = KeyPress;
622 XkbSendControlsNotify(xkbi->device, &cn);
628 else if (filter->keycode == keycode) {
629 int button = filter->upAction.btn.button;
631 switch (filter->upAction.type) {
632 case XkbSA_LockPtrBtn:
633 if (((filter->upAction.btn.flags & XkbSA_LockNoUnlock) != 0) ||
634 ((xkbi->lockedPtrButtons & (1 << button)) == 0)) {
637 xkbi->lockedPtrButtons &= ~(1 << button);
639 if (IsMaster(xkbi->device)) {
640 XkbMergeLockedPtrBtns(xkbi->device);
641 /* One SD still has lock set, don't post event */
642 if ((xkbi->lockedPtrButtons & (1 << button)) != 0)
648 XkbFakeDeviceButton(xkbi->device, 0, button);
657 _XkbFilterControls(XkbSrvInfoPtr xkbi,
658 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
661 XkbControlsPtr ctrls;
664 XkbEventCauseRec cause;
667 ctrls = xkbi->desc->ctrls;
669 if (filter->keycode == 0) { /* initial press */
670 filter->keycode = keycode;
672 filter->filterOthers = 0;
673 change = XkbActionCtrls(&pAction->ctrls);
674 filter->priv = change;
675 filter->filter = _XkbFilterControls;
676 filter->upAction = *pAction;
678 if (pAction->type == XkbSA_LockControls) {
679 filter->priv = (ctrls->enabled_ctrls & change);
680 change &= ~ctrls->enabled_ctrls;
684 xkbControlsNotify cn;
685 XkbSrvLedInfoPtr sli;
687 ctrls->enabled_ctrls |= change;
688 if (XkbComputeControlsNotify(kbd, &old, ctrls, &cn, FALSE)) {
689 cn.keycode = keycode;
690 /* XXX: what about DeviceKeyPress? */
691 cn.eventType = KeyPress;
694 XkbSendControlsNotify(kbd, &cn);
697 XkbSetCauseKey(&cause, keycode, KeyPress);
699 /* If sticky keys were disabled, clear all locks and latches */
700 if ((old.enabled_ctrls & XkbStickyKeysMask) &&
701 (!(ctrls->enabled_ctrls & XkbStickyKeysMask))) {
702 XkbClearAllLatchesAndLocks(kbd, xkbi, FALSE, &cause);
704 sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass, XkbDfltXIId, 0);
705 XkbUpdateIndicators(kbd, sli->usesControls, TRUE, NULL, &cause);
706 if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask))
707 XkbDDXAccessXBeep(kbd, _BEEP_FEATURE_ON, change);
710 else if (filter->keycode == keycode) {
711 change = filter->priv;
713 xkbControlsNotify cn;
714 XkbSrvLedInfoPtr sli;
716 ctrls->enabled_ctrls &= ~change;
717 if (XkbComputeControlsNotify(kbd, &old, ctrls, &cn, FALSE)) {
718 cn.keycode = keycode;
719 cn.eventType = KeyRelease;
722 XkbSendControlsNotify(kbd, &cn);
725 XkbSetCauseKey(&cause, keycode, KeyRelease);
726 /* If sticky keys were disabled, clear all locks and latches */
727 if ((old.enabled_ctrls & XkbStickyKeysMask) &&
728 (!(ctrls->enabled_ctrls & XkbStickyKeysMask))) {
729 XkbClearAllLatchesAndLocks(kbd, xkbi, FALSE, &cause);
731 sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass, XkbDfltXIId, 0);
732 XkbUpdateIndicators(kbd, sli->usesControls, TRUE, NULL, &cause);
733 if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask))
734 XkbDDXAccessXBeep(kbd, _BEEP_FEATURE_OFF, change);
743 _XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
745 unsigned keycode, XkbAction *pAction)
747 XkbMessageAction *pMsg;
751 if (filter->keycode == 0) { /* initial press */
752 pMsg = &pAction->msg;
753 if ((pMsg->flags & XkbSA_MessageOnRelease) ||
754 ((pMsg->flags & XkbSA_MessageGenKeyEvent) == 0)) {
755 filter->keycode = keycode;
757 filter->filterOthers = 0;
759 filter->filter = _XkbFilterActionMessage;
760 filter->upAction = *pAction;
762 if (pMsg->flags & XkbSA_MessageOnPress) {
763 xkbActionMessage msg;
765 msg.keycode = keycode;
767 msg.keyEventFollows =
768 ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
769 memcpy((char *) msg.message, (char *) pMsg->message,
770 XkbActionMessageLength);
771 XkbSendActionMessage(kbd, &msg);
773 return ((pAction->msg.flags & XkbSA_MessageGenKeyEvent) != 0);
775 else if (filter->keycode == keycode) {
776 pMsg = &filter->upAction.msg;
777 if (pMsg->flags & XkbSA_MessageOnRelease) {
778 xkbActionMessage msg;
780 msg.keycode = keycode;
782 msg.keyEventFollows =
783 ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
784 memcpy((char *) msg.message, (char *) pMsg->message,
785 XkbActionMessageLength);
786 XkbSendActionMessage(kbd, &msg);
790 return ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
796 _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
797 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
801 XkbStateRec old, old_prev;
803 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
804 ProcessInputProc backupproc;
806 /* never actually used uninitialised, but gcc isn't smart enough
807 * to work that out. */
808 memset(&old, 0, sizeof(old));
809 memset(&old_prev, 0, sizeof(old_prev));
810 memset(&ev, 0, sizeof(ev));
812 if ((filter->keycode != 0) && (filter->keycode != keycode))
815 GetSpritePosition(xkbi->device, &x, &y);
816 ev.header = ET_Internal;
817 ev.length = sizeof(DeviceEvent);
818 ev.time = GetTimeInMillis();
821 /* redirect actions do not work across devices, therefore the following is
823 ev.deviceid = xkbi->device->id;
824 /* filter->priv must be set up by the caller for the initial press. */
825 ev.sourceid = filter->priv;
827 if (filter->keycode == 0) { /* initial press */
828 if ((pAction->redirect.new_key < xkbi->desc->min_key_code) ||
829 (pAction->redirect.new_key > xkbi->desc->max_key_code)) {
832 filter->keycode = keycode;
834 filter->filterOthers = 0;
835 filter->filter = _XkbFilterRedirectKey;
836 filter->upAction = *pAction;
838 ev.type = ET_KeyPress;
839 ev.detail.key = pAction->redirect.new_key;
841 mask = XkbSARedirectVModsMask(&pAction->redirect);
842 mods = XkbSARedirectVMods(&pAction->redirect);
844 XkbVirtualModsToReal(xkbi->desc, mask, &mask);
846 XkbVirtualModsToReal(xkbi->desc, mods, &mods);
847 mask |= pAction->redirect.mods_mask;
848 mods |= pAction->redirect.mods;
852 old_prev = xkbi->prev_state;
853 xkbi->state.base_mods &= ~mask;
854 xkbi->state.base_mods |= (mods & mask);
855 xkbi->state.latched_mods &= ~mask;
856 xkbi->state.latched_mods |= (mods & mask);
857 xkbi->state.locked_mods &= ~mask;
858 xkbi->state.locked_mods |= (mods & mask);
859 XkbComputeDerivedState(xkbi);
860 xkbi->prev_state = xkbi->state;
863 UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
864 xkbi->device->public.processInputProc((InternalEvent *) &ev,
866 COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
871 xkbi->prev_state = old_prev;
874 else if (filter->keycode == keycode) {
876 ev.type = ET_KeyRelease;
877 ev.detail.key = filter->upAction.redirect.new_key;
879 mask = XkbSARedirectVModsMask(&filter->upAction.redirect);
880 mods = XkbSARedirectVMods(&filter->upAction.redirect);
882 XkbVirtualModsToReal(xkbi->desc, mask, &mask);
884 XkbVirtualModsToReal(xkbi->desc, mods, &mods);
885 mask |= filter->upAction.redirect.mods_mask;
886 mods |= filter->upAction.redirect.mods;
890 old_prev = xkbi->prev_state;
891 xkbi->state.base_mods &= ~mask;
892 xkbi->state.base_mods |= (mods & mask);
893 xkbi->state.latched_mods &= ~mask;
894 xkbi->state.latched_mods |= (mods & mask);
895 xkbi->state.locked_mods &= ~mask;
896 xkbi->state.locked_mods |= (mods & mask);
897 XkbComputeDerivedState(xkbi);
898 xkbi->prev_state = xkbi->state;
901 UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
902 xkbi->device->public.processInputProc((InternalEvent *) &ev,
904 COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
909 xkbi->prev_state = old_prev;
919 _XkbFilterSwitchScreen(XkbSrvInfoPtr xkbi,
921 unsigned keycode, XkbAction *pAction)
923 DeviceIntPtr dev = xkbi->device;
925 if (dev == inputInfo.keyboard)
928 if (filter->keycode == 0) { /* initial press */
929 filter->keycode = keycode;
931 filter->filterOthers = 0;
932 filter->filter = _XkbFilterSwitchScreen;
933 AccessXCancelRepeatKey(xkbi, keycode);
934 XkbDDXSwitchScreen(dev, keycode, pAction);
937 else if (filter->keycode == keycode) {
945 _XkbFilterXF86Private(XkbSrvInfoPtr xkbi,
946 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
948 DeviceIntPtr dev = xkbi->device;
950 if (dev == inputInfo.keyboard)
953 if (filter->keycode == 0) { /* initial press */
954 filter->keycode = keycode;
956 filter->filterOthers = 0;
957 filter->filter = _XkbFilterXF86Private;
958 XkbDDXPrivate(dev, keycode, pAction);
961 else if (filter->keycode == keycode) {
969 _XkbFilterDeviceBtn(XkbSrvInfoPtr xkbi,
970 XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
972 if (xkbi->device == inputInfo.keyboard)
975 if (filter->keycode == 0) { /* initial press */
979 _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient,
980 DixUnknownAccess, &button);
981 if (!dev || !dev->public.on)
984 button = pAction->devbtn.button;
985 if ((button < 1) || (button > dev->button->numButtons))
988 filter->keycode = keycode;
990 filter->filterOthers = 0;
992 filter->filter = _XkbFilterDeviceBtn;
993 filter->upAction = *pAction;
994 switch (pAction->type) {
995 case XkbSA_LockDeviceBtn:
996 if ((pAction->devbtn.flags & XkbSA_LockNoLock) ||
997 BitIsOn(dev->button->down, button))
999 XkbFakeDeviceButton(dev, TRUE, button);
1000 filter->upAction.type = XkbSA_NoAction;
1002 case XkbSA_DeviceBtn:
1003 if (pAction->devbtn.count > 0) {
1006 nClicks = pAction->btn.count;
1007 for (i = 0; i < nClicks; i++) {
1008 XkbFakeDeviceButton(dev, TRUE, button);
1009 XkbFakeDeviceButton(dev, FALSE, button);
1011 filter->upAction.type = XkbSA_NoAction;
1014 XkbFakeDeviceButton(dev, TRUE, button);
1018 else if (filter->keycode == keycode) {
1023 _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device,
1024 serverClient, DixUnknownAccess, &button);
1025 if (!dev || !dev->public.on)
1028 button = filter->upAction.btn.button;
1029 switch (filter->upAction.type) {
1030 case XkbSA_LockDeviceBtn:
1031 if ((filter->upAction.devbtn.flags & XkbSA_LockNoUnlock) ||
1032 !BitIsOn(dev->button->down, button))
1034 XkbFakeDeviceButton(dev, FALSE, button);
1036 case XkbSA_DeviceBtn:
1037 XkbFakeDeviceButton(dev, FALSE, button);
1046 _XkbNextFreeFilter(XkbSrvInfoPtr xkbi)
1050 if (xkbi->szFilters == 0) {
1051 xkbi->szFilters = 4;
1052 xkbi->filters = calloc(xkbi->szFilters, sizeof(XkbFilterRec));
1053 /* 6/21/93 (ef) -- XXX! deal with allocation failure */
1055 for (i = 0; i < xkbi->szFilters; i++) {
1056 if (!xkbi->filters[i].active) {
1057 xkbi->filters[i].keycode = 0;
1058 return &xkbi->filters[i];
1061 xkbi->szFilters *= 2;
1062 xkbi->filters = realloc(xkbi->filters,
1063 xkbi->szFilters * sizeof(XkbFilterRec));
1064 /* 6/21/93 (ef) -- XXX! deal with allocation failure */
1065 memset(&xkbi->filters[xkbi->szFilters / 2], 0,
1066 (xkbi->szFilters / 2) * sizeof(XkbFilterRec));
1067 return &xkbi->filters[xkbi->szFilters / 2];
1071 _XkbApplyFilters(XkbSrvInfoPtr xkbi, unsigned kc, XkbAction *pAction)
1073 register int i, send;
1076 for (i = 0; i < xkbi->szFilters; i++) {
1077 if ((xkbi->filters[i].active) && (xkbi->filters[i].filter))
1079 ((*xkbi->filters[i].filter) (xkbi, &xkbi->filters[i], kc,
1087 XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
1092 int changed, sendEvent;
1093 Bool genStateNotify;
1095 XkbFilterPtr filter;
1098 ProcessInputProc backupproc;
1100 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
1103 xkbi = keyc->xkbInfo;
1104 key = event->detail.key;
1105 /* The state may change, so if we're not in the middle of sending a state
1106 * notify, prepare for it */
1107 if ((xkbi->flags & _XkbStateNotifyInProgress) == 0) {
1108 xkbi->prev_state = xkbi->state;
1109 xkbi->flags |= _XkbStateNotifyInProgress;
1110 genStateNotify = TRUE;
1113 genStateNotify = FALSE;
1115 xkbi->clearMods = xkbi->setMods = 0;
1116 xkbi->groupChange = 0;
1119 keyEvent = ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease));
1120 pressEvent = ((event->type == ET_KeyPress) ||
1121 (event->type == ET_ButtonPress));
1125 act = XkbGetKeyAction(xkbi, &xkbi->state, key);
1127 act = XkbGetButtonAction(kbd, dev, key);
1128 key |= BTN_ACT_FLAG;
1130 sendEvent = _XkbApplyFilters(xkbi, key, &act);
1134 case XkbSA_SetGroup:
1135 filter = _XkbNextFreeFilter(xkbi);
1136 sendEvent = _XkbFilterSetState(xkbi, filter, key, &act);
1138 case XkbSA_LatchMods:
1139 case XkbSA_LatchGroup:
1140 filter = _XkbNextFreeFilter(xkbi);
1141 sendEvent = _XkbFilterLatchState(xkbi, filter, key, &act);
1143 case XkbSA_LockMods:
1144 case XkbSA_LockGroup:
1145 filter = _XkbNextFreeFilter(xkbi);
1146 sendEvent = _XkbFilterLockState(xkbi, filter, key, &act);
1149 filter = _XkbNextFreeFilter(xkbi);
1150 sendEvent = _XkbFilterISOLock(xkbi, filter, key, &act);
1153 filter = _XkbNextFreeFilter(xkbi);
1154 sendEvent = _XkbFilterPointerMove(xkbi, filter, key, &act);
1157 case XkbSA_LockPtrBtn:
1158 case XkbSA_SetPtrDflt:
1159 filter = _XkbNextFreeFilter(xkbi);
1160 sendEvent = _XkbFilterPointerBtn(xkbi, filter, key, &act);
1162 case XkbSA_Terminate:
1163 sendEvent = XkbDDXTerminateServer(dev, key, &act);
1165 case XkbSA_SwitchScreen:
1166 filter = _XkbNextFreeFilter(xkbi);
1167 sendEvent = _XkbFilterSwitchScreen(xkbi, filter, key, &act);
1169 case XkbSA_SetControls:
1170 case XkbSA_LockControls:
1171 filter = _XkbNextFreeFilter(xkbi);
1172 sendEvent = _XkbFilterControls(xkbi, filter, key, &act);
1174 case XkbSA_ActionMessage:
1175 filter = _XkbNextFreeFilter(xkbi);
1176 sendEvent = _XkbFilterActionMessage(xkbi, filter, key, &act);
1178 case XkbSA_RedirectKey:
1179 filter = _XkbNextFreeFilter(xkbi);
1180 /* redirect actions must create a new DeviceEvent. The
1181 * source device id for this event cannot be obtained from
1182 * xkbi, so we pass it here explicitly. The field deviceid
1183 * equals to xkbi->device->id. */
1184 filter->priv = event->sourceid;
1185 sendEvent = _XkbFilterRedirectKey(xkbi, filter, key, &act);
1187 case XkbSA_DeviceBtn:
1188 case XkbSA_LockDeviceBtn:
1189 filter = _XkbNextFreeFilter(xkbi);
1190 sendEvent = _XkbFilterDeviceBtn(xkbi, filter, key, &act);
1192 case XkbSA_XFree86Private:
1193 filter = _XkbNextFreeFilter(xkbi);
1194 sendEvent = _XkbFilterXF86Private(xkbi, filter, key, &act);
1201 key |= BTN_ACT_FLAG;
1202 sendEvent = _XkbApplyFilters(xkbi, key, NULL);
1205 if (xkbi->groupChange != 0)
1206 xkbi->state.base_group += xkbi->groupChange;
1207 if (xkbi->setMods) {
1208 for (i = 0, bit = 1; xkbi->setMods; i++, bit <<= 1) {
1209 if (xkbi->setMods & bit) {
1210 keyc->modifierKeyCount[i]++;
1211 xkbi->state.base_mods |= bit;
1212 xkbi->setMods &= ~bit;
1216 if (xkbi->clearMods) {
1217 for (i = 0, bit = 1; xkbi->clearMods; i++, bit <<= 1) {
1218 if (xkbi->clearMods & bit) {
1219 keyc->modifierKeyCount[i]--;
1220 if (keyc->modifierKeyCount[i] <= 0) {
1221 xkbi->state.base_mods &= ~bit;
1222 keyc->modifierKeyCount[i] = 0;
1224 xkbi->clearMods &= ~bit;
1230 DeviceIntPtr tmpdev;
1235 tmpdev = GetMaster(dev, POINTER_OR_FLOAT);
1237 UNWRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr, backupproc);
1238 dev->public.processInputProc((InternalEvent *) event, tmpdev);
1239 COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
1240 backupproc, xkbUnwrapProc);
1242 else if (keyEvent) {
1243 FixKeyState(event, dev);
1246 XkbComputeDerivedState(xkbi);
1247 changed = XkbStateChangedFlags(&xkbi->prev_state, &xkbi->state);
1248 if (genStateNotify) {
1253 sn.eventType = event->type;
1254 sn.requestMajor = sn.requestMinor = 0;
1255 sn.changed = changed;
1256 XkbSendStateNotify(dev, &sn);
1258 xkbi->flags &= ~_XkbStateNotifyInProgress;
1260 changed = XkbIndicatorsToUpdate(dev, changed, FALSE);
1262 XkbEventCauseRec cause;
1264 XkbSetCauseKey(&cause, key, event->type);
1265 XkbUpdateIndicators(dev, changed, FALSE, NULL, &cause);
1271 XkbLatchModifiers(DeviceIntPtr pXDev, CARD8 mask, CARD8 latches)
1274 XkbFilterPtr filter;
1278 if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
1279 xkbi = pXDev->key->xkbInfo;
1280 clear = (mask & (~latches));
1281 xkbi->state.latched_mods &= ~clear;
1282 /* Clear any pending latch to locks.
1284 act.type = XkbSA_NoAction;
1285 _XkbApplyFilters(xkbi, SYNTHETIC_KEYCODE, &act);
1286 act.type = XkbSA_LatchMods;
1288 act.mods.mask = mask & latches;
1289 filter = _XkbNextFreeFilter(xkbi);
1290 _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, &act);
1291 _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE,
1292 (XkbAction *) NULL);
1299 XkbLatchGroup(DeviceIntPtr pXDev, int group)
1302 XkbFilterPtr filter;
1305 if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
1306 xkbi = pXDev->key->xkbInfo;
1307 act.type = XkbSA_LatchGroup;
1308 act.group.flags = 0;
1309 XkbSASetGroup(&act.group, group);
1310 filter = _XkbNextFreeFilter(xkbi);
1311 _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, &act);
1312 _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE,
1313 (XkbAction *) NULL);
1319 /***====================================================================***/
1322 XkbClearAllLatchesAndLocks(DeviceIntPtr dev,
1324 Bool genEv, XkbEventCausePtr cause)
1331 if (os.latched_mods) { /* clear all latches */
1332 XkbLatchModifiers(dev, ~0, 0);
1333 sn.changed |= XkbModifierLatchMask;
1335 if (os.latched_group) {
1336 XkbLatchGroup(dev, 0);
1337 sn.changed |= XkbGroupLatchMask;
1339 if (os.locked_mods) {
1340 xkbi->state.locked_mods = 0;
1341 sn.changed |= XkbModifierLockMask;
1343 if (os.locked_group) {
1344 xkbi->state.locked_group = 0;
1345 sn.changed |= XkbGroupLockMask;
1347 if (genEv && sn.changed) {
1350 XkbComputeDerivedState(xkbi);
1351 sn.keycode = cause->kc;
1352 sn.eventType = cause->event;
1353 sn.requestMajor = cause->mjr;
1354 sn.requestMinor = cause->mnr;
1355 sn.changed = XkbStateChangedFlags(&os, &xkbi->state);
1356 XkbSendStateNotify(dev, &sn);
1357 changed = XkbIndicatorsToUpdate(dev, sn.changed, FALSE);
1359 XkbUpdateIndicators(dev, changed, TRUE, NULL, cause);
1366 * The event is injected into the event processing, not the EQ. Thus,
1367 * ensure that we restore the master after the event sequence to the
1368 * original set of classes. Otherwise, the master remains on the XTEST
1369 * classes and drops events that don't fit into the XTEST layout (e.g.
1370 * events with more than 2 valuators).
1372 * FIXME: EQ injection in the processing stage is not designed for, so this
1373 * is a rather awkward hack. The event list returned by GetPointerEvents()
1374 * and friends is always prefixed with a DCE if the last _posted_ device was
1375 * different. For normal events, this sequence then resets the master during
1376 * the processing stage. Since we inject the PointerKey events in the
1377 * processing stage though, we need to manually reset to restore the
1378 * previous order, because the events already in the EQ must be sent for the
1380 * So we post-fix the event list we get from GPE with a DCE back to the
1381 * previous slave device.
1383 * First one on drinking island wins!
1386 InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags,
1390 InternalEvent *events;
1392 DeviceIntPtr ptr, mpointer, lastSlave = NULL;
1395 if (IsMaster(dev)) {
1396 mpointer = GetMaster(dev, MASTER_POINTER);
1397 lastSlave = mpointer->lastSlave;
1398 ptr = GetXTestDevice(mpointer);
1400 else if (IsFloating(dev))
1405 events = InitEventList(GetMaximumEventsNum() + 1);
1407 pScreen = miPointerGetScreen(ptr);
1408 saveWait = miPointerSetWaitForUpdate(pScreen, FALSE);
1409 nevents = GetPointerEvents(events, ptr, type, button, flags, mask);
1410 if (IsMaster(dev) && (lastSlave && lastSlave != ptr))
1411 UpdateFromMaster(&events[nevents], lastSlave, DEVCHANGE_POINTER_EVENT,
1413 miPointerSetWaitForUpdate(pScreen, saveWait);
1416 for (i = 0; i < nevents; i++)
1417 mieqProcessDeviceEvent(ptr, &events[i], NULL);
1419 FreeEventList(events, GetMaximumEventsNum());
1424 XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags, int x, int y)
1429 /* ignore attached SDs */
1430 if (!IsMaster(dev) && !IsFloating(dev))
1433 if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
1434 gpe_flags = POINTER_ABSOLUTE;
1436 gpe_flags = POINTER_RELATIVE;
1438 valuator_mask_set_range(&mask, 0, 2, (int[]) {
1441 InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, &mask);
1445 XkbFakeDeviceButton(DeviceIntPtr dev, Bool press, int button)
1450 /* If dev is a slave device, and the SD is attached, do nothing. If we'd
1451 * post through the attached master pointer we'd get duplicate events.
1453 * if dev is a master keyboard, post through the XTEST device
1455 * if dev is a floating slave, post through the device itself.
1458 if (IsMaster(dev)) {
1459 DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER);
1461 ptr = GetXTestDevice(mpointer);
1463 else if (IsFloating(dev))
1468 down = button_is_down(ptr, button, BUTTON_PROCESSED);
1472 InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease,