105b261ecSmrg/************************************************************ 205b261ecSmrgCopyright (c) 1993 by Silicon Graphics Computer Systems, Inc. 305b261ecSmrg 405b261ecSmrgPermission to use, copy, modify, and distribute this 505b261ecSmrgsoftware and its documentation for any purpose and without 605b261ecSmrgfee is hereby granted, provided that the above copyright 705b261ecSmrgnotice appear in all copies and that both that copyright 805b261ecSmrgnotice and this permission notice appear in supporting 935c4bbdfSmrgdocumentation, and that the name of Silicon Graphics not be 1035c4bbdfSmrgused in advertising or publicity pertaining to distribution 1105b261ecSmrgof the software without specific prior written permission. 1235c4bbdfSmrgSilicon Graphics makes no representation about the suitability 1305b261ecSmrgof this software for any purpose. It is provided "as is" 1405b261ecSmrgwithout any express or implied warranty. 1505b261ecSmrg 1635c4bbdfSmrgSILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 1735c4bbdfSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 1805b261ecSmrgAND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 1935c4bbdfSmrgGRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 2035c4bbdfSmrgDAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2135c4bbdfSmrgDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 2205b261ecSmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH 2305b261ecSmrgTHE USE OR PERFORMANCE OF THIS SOFTWARE. 2405b261ecSmrg 2505b261ecSmrg********************************************************/ 2605b261ecSmrg 2705b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2805b261ecSmrg#include <dix-config.h> 2905b261ecSmrg#endif 3005b261ecSmrg 3105b261ecSmrg#include <stdio.h> 3205b261ecSmrg#include <math.h> 3305b261ecSmrg#include <X11/X.h> 3405b261ecSmrg#include <X11/Xproto.h> 3505b261ecSmrg#include <X11/keysym.h> 3605b261ecSmrg#include "misc.h" 3705b261ecSmrg#include "inputstr.h" 3805b261ecSmrg#include "exevents.h" 396747b715Smrg#include "eventstr.h" 4005b261ecSmrg#include <xkbsrv.h> 4105b261ecSmrg#include "xkb.h" 4205b261ecSmrg#include <ctype.h> 436747b715Smrg#include "mi.h" 446747b715Smrg#include "mipointer.h" 459ace9065Smrg#include "inpututils.h" 46ed6184dfSmrg#include "dixgrabs.h" 4705b261ecSmrg#define EXTENSION_EVENT_BASE 64 4805b261ecSmrg 496747b715SmrgDevPrivateKeyRec xkbDevicePrivateKeyRec; 506747b715Smrg 5135c4bbdfSmrgstatic void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags, int x, 5235c4bbdfSmrg int y); 5305b261ecSmrg 5405b261ecSmrgvoid 5535c4bbdfSmrgxkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, void *data) 5605b261ecSmrg{ 5705b261ecSmrg xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device); 5805b261ecSmrg ProcessInputProc backupproc; 5905b261ecSmrg 6035c4bbdfSmrg if (xkbPrivPtr->unwrapProc) 6135c4bbdfSmrg xkbPrivPtr->unwrapProc = NULL; 6235c4bbdfSmrg 6335c4bbdfSmrg UNWRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, backupproc); 6435c4bbdfSmrg proc(device, data); 6535c4bbdfSmrg COND_WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, backupproc, xkbUnwrapProc); 6605b261ecSmrg} 6705b261ecSmrg 686747b715SmrgBool 696747b715SmrgXkbInitPrivates(void) 706747b715Smrg{ 7135c4bbdfSmrg return dixRegisterPrivateKey(&xkbDevicePrivateKeyRec, PRIVATE_DEVICE, 7235c4bbdfSmrg sizeof(xkbDeviceInfoRec)); 736747b715Smrg} 7405b261ecSmrg 7505b261ecSmrgvoid 7605b261ecSmrgXkbSetExtension(DeviceIntPtr device, ProcessInputProc proc) 7705b261ecSmrg{ 789ace9065Smrg xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device); 7935c4bbdfSmrg 8005b261ecSmrg WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc); 8105b261ecSmrg} 8205b261ecSmrg 8305b261ecSmrg/***====================================================================***/ 8405b261ecSmrg 8505b261ecSmrgstatic XkbAction 8635c4bbdfSmrg_FixUpAction(XkbDescPtr xkb, XkbAction *act) 8705b261ecSmrg{ 8835c4bbdfSmrg static XkbAction fake; 8905b261ecSmrg 9035c4bbdfSmrg if (XkbIsPtrAction(act) && 9135c4bbdfSmrg (!(xkb->ctrls->enabled_ctrls & XkbMouseKeysMask))) { 9235c4bbdfSmrg fake.type = XkbSA_NoAction; 9335c4bbdfSmrg return fake; 9405b261ecSmrg } 9535c4bbdfSmrg if (xkb->ctrls->enabled_ctrls & XkbStickyKeysMask) { 9635c4bbdfSmrg if (act->any.type == XkbSA_SetMods) { 9735c4bbdfSmrg fake.mods.type = XkbSA_LatchMods; 9835c4bbdfSmrg fake.mods.mask = act->mods.mask; 9935c4bbdfSmrg if (XkbAX_NeedOption(xkb->ctrls, XkbAX_LatchToLockMask)) 10035c4bbdfSmrg fake.mods.flags = XkbSA_ClearLocks | XkbSA_LatchToLock; 10135c4bbdfSmrg else 10235c4bbdfSmrg fake.mods.flags = XkbSA_ClearLocks; 10335c4bbdfSmrg return fake; 10435c4bbdfSmrg } 10535c4bbdfSmrg if (act->any.type == XkbSA_SetGroup) { 10635c4bbdfSmrg fake.group.type = XkbSA_LatchGroup; 10735c4bbdfSmrg if (XkbAX_NeedOption(xkb->ctrls, XkbAX_LatchToLockMask)) 10835c4bbdfSmrg fake.group.flags = XkbSA_ClearLocks | XkbSA_LatchToLock; 10935c4bbdfSmrg else 11035c4bbdfSmrg fake.group.flags = XkbSA_ClearLocks; 11135c4bbdfSmrg XkbSASetGroup(&fake.group, XkbSAGroup(&act->group)); 11235c4bbdfSmrg return fake; 11335c4bbdfSmrg } 11405b261ecSmrg } 11505b261ecSmrg return *act; 11605b261ecSmrg} 11705b261ecSmrg 11805b261ecSmrgstatic XkbAction 11935c4bbdfSmrgXkbGetKeyAction(XkbSrvInfoPtr xkbi, XkbStatePtr xkbState, CARD8 key) 12005b261ecSmrg{ 12135c4bbdfSmrg int effectiveGroup; 12235c4bbdfSmrg int col; 12335c4bbdfSmrg XkbDescPtr xkb; 12435c4bbdfSmrg XkbKeyTypePtr type; 12535c4bbdfSmrg XkbAction *pActs; 12635c4bbdfSmrg static XkbAction fake; 12735c4bbdfSmrg 12835c4bbdfSmrg xkb = xkbi->desc; 12935c4bbdfSmrg if (!XkbKeyHasActions(xkb, key) || !XkbKeycodeInRange(xkb, key)) { 13035c4bbdfSmrg fake.type = XkbSA_NoAction; 13135c4bbdfSmrg return fake; 13205b261ecSmrg } 13335c4bbdfSmrg pActs = XkbKeyActionsPtr(xkb, key); 13435c4bbdfSmrg col = 0; 1356747b715Smrg 1366747b715Smrg effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key); 1376747b715Smrg if (effectiveGroup != XkbGroup1Index) 1386747b715Smrg col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key)); 1396747b715Smrg 14035c4bbdfSmrg type = XkbKeyKeyType(xkb, key, effectiveGroup); 14135c4bbdfSmrg if (type->map != NULL) { 14235c4bbdfSmrg register unsigned i, mods; 14335c4bbdfSmrg register XkbKTMapEntryPtr entry; 14435c4bbdfSmrg 14535c4bbdfSmrg mods = xkbState->mods & type->mods.mask; 14635c4bbdfSmrg for (entry = type->map, i = 0; i < type->map_count; i++, entry++) { 14735c4bbdfSmrg if ((entry->active) && (entry->mods.mask == mods)) { 14835c4bbdfSmrg col += entry->level; 14935c4bbdfSmrg break; 15035c4bbdfSmrg } 15135c4bbdfSmrg } 15205b261ecSmrg } 15335c4bbdfSmrg if (pActs[col].any.type == XkbSA_NoAction) 15435c4bbdfSmrg return pActs[col]; 15535c4bbdfSmrg fake = _FixUpAction(xkb, &pActs[col]); 15605b261ecSmrg return fake; 15705b261ecSmrg} 15805b261ecSmrg 15905b261ecSmrgstatic XkbAction 16035c4bbdfSmrgXkbGetButtonAction(DeviceIntPtr kbd, DeviceIntPtr dev, int button) 16105b261ecSmrg{ 16235c4bbdfSmrg XkbAction fake; 16335c4bbdfSmrg 16435c4bbdfSmrg if ((dev->button) && (dev->button->xkb_acts)) { 16535c4bbdfSmrg if (dev->button->xkb_acts[button - 1].any.type != XkbSA_NoAction) { 16635c4bbdfSmrg fake = _FixUpAction(kbd->key->xkbInfo->desc, 16735c4bbdfSmrg &dev->button->xkb_acts[button - 1]); 16835c4bbdfSmrg return fake; 16935c4bbdfSmrg } 17035c4bbdfSmrg } 17135c4bbdfSmrg fake.any.type = XkbSA_NoAction; 17235c4bbdfSmrg return fake; 17305b261ecSmrg} 17405b261ecSmrg 17505b261ecSmrg/***====================================================================***/ 17605b261ecSmrg 17705b261ecSmrg#define SYNTHETIC_KEYCODE 1 17805b261ecSmrg#define BTN_ACT_FLAG 0x100 17905b261ecSmrg 18005b261ecSmrgstatic int 18135c4bbdfSmrg_XkbFilterSetState(XkbSrvInfoPtr xkbi, 18235c4bbdfSmrg XkbFilterPtr filter, unsigned keycode, XkbAction *pAction) 18305b261ecSmrg{ 18435c4bbdfSmrg if (filter->keycode == 0) { /* initial press */ 18535c4bbdfSmrg AccessXCancelRepeatKey(xkbi, keycode); 18635c4bbdfSmrg filter->keycode = keycode; 18735c4bbdfSmrg filter->active = 1; 18835c4bbdfSmrg filter->filterOthers = ((pAction->mods.mask & XkbSA_ClearLocks) != 0); 18935c4bbdfSmrg filter->priv = 0; 19035c4bbdfSmrg filter->filter = _XkbFilterSetState; 19135c4bbdfSmrg if (pAction->type == XkbSA_SetMods) { 19235c4bbdfSmrg filter->upAction = *pAction; 19335c4bbdfSmrg xkbi->setMods = pAction->mods.mask; 19435c4bbdfSmrg } 19535c4bbdfSmrg else { 19635c4bbdfSmrg xkbi->groupChange = XkbSAGroup(&pAction->group); 19735c4bbdfSmrg if (pAction->group.flags & XkbSA_GroupAbsolute) 19835c4bbdfSmrg xkbi->groupChange -= xkbi->state.base_group; 19935c4bbdfSmrg filter->upAction = *pAction; 20035c4bbdfSmrg XkbSASetGroup(&filter->upAction.group, xkbi->groupChange); 20135c4bbdfSmrg } 20205b261ecSmrg } 20335c4bbdfSmrg else if (filter->keycode == keycode) { 20435c4bbdfSmrg if (filter->upAction.type == XkbSA_SetMods) { 20535c4bbdfSmrg xkbi->clearMods = filter->upAction.mods.mask; 20635c4bbdfSmrg if (filter->upAction.mods.flags & XkbSA_ClearLocks) { 20735c4bbdfSmrg xkbi->state.locked_mods &= ~filter->upAction.mods.mask; 20835c4bbdfSmrg } 20935c4bbdfSmrg } 21035c4bbdfSmrg else { 21135c4bbdfSmrg if (filter->upAction.group.flags & XkbSA_ClearLocks) { 21235c4bbdfSmrg xkbi->state.locked_group = 0; 21335c4bbdfSmrg } 21435c4bbdfSmrg xkbi->groupChange = -XkbSAGroup(&filter->upAction.group); 21535c4bbdfSmrg } 21635c4bbdfSmrg filter->active = 0; 21705b261ecSmrg } 21805b261ecSmrg else { 21935c4bbdfSmrg filter->upAction.mods.flags &= ~XkbSA_ClearLocks; 22035c4bbdfSmrg filter->filterOthers = 0; 22105b261ecSmrg } 22205b261ecSmrg return 1; 22305b261ecSmrg} 22405b261ecSmrg 22505b261ecSmrg#define LATCH_KEY_DOWN 1 22605b261ecSmrg#define LATCH_PENDING 2 22705b261ecSmrg 22805b261ecSmrgstatic int 22935c4bbdfSmrg_XkbFilterLatchState(XkbSrvInfoPtr xkbi, 23035c4bbdfSmrg XkbFilterPtr filter, unsigned keycode, XkbAction *pAction) 23105b261ecSmrg{ 23205b261ecSmrg 23335c4bbdfSmrg if (filter->keycode == 0) { /* initial press */ 23435c4bbdfSmrg AccessXCancelRepeatKey(xkbi,keycode); 23535c4bbdfSmrg filter->keycode = keycode; 23635c4bbdfSmrg filter->active = 1; 23735c4bbdfSmrg filter->filterOthers = 1; 23835c4bbdfSmrg filter->priv = LATCH_KEY_DOWN; 23935c4bbdfSmrg filter->filter = _XkbFilterLatchState; 24035c4bbdfSmrg if (pAction->type == XkbSA_LatchMods) { 24135c4bbdfSmrg filter->upAction = *pAction; 24235c4bbdfSmrg xkbi->setMods = pAction->mods.mask; 24335c4bbdfSmrg } 24435c4bbdfSmrg else { 24535c4bbdfSmrg xkbi->groupChange = XkbSAGroup(&pAction->group); 24635c4bbdfSmrg if (pAction->group.flags & XkbSA_GroupAbsolute) 24735c4bbdfSmrg xkbi->groupChange -= xkbi->state.base_group; 24835c4bbdfSmrg filter->upAction = *pAction; 24935c4bbdfSmrg XkbSASetGroup(&filter->upAction.group, xkbi->groupChange); 25035c4bbdfSmrg } 25105b261ecSmrg } 25235c4bbdfSmrg else if (pAction && (filter->priv == LATCH_PENDING)) { 25335c4bbdfSmrg if (((1 << pAction->type) & XkbSA_BreakLatch) != 0) { 25435c4bbdfSmrg filter->active = 0; 25535c4bbdfSmrg /* If one latch is broken, all latches are broken, so it's no use 25635c4bbdfSmrg to find out which particular latch this filter tracks. */ 25735c4bbdfSmrg xkbi->state.latched_mods = 0; 25835c4bbdfSmrg xkbi->state.latched_group = 0; 25935c4bbdfSmrg } 26005b261ecSmrg } 26135c4bbdfSmrg else if (filter->keycode == keycode && filter->priv != LATCH_PENDING){ 26235c4bbdfSmrg /* The test above for LATCH_PENDING skips subsequent releases of the 26335c4bbdfSmrg key after it has been released first time and the latch became 26435c4bbdfSmrg pending. */ 26535c4bbdfSmrg XkbControlsPtr ctrls = xkbi->desc->ctrls; 26635c4bbdfSmrg int needBeep = ((ctrls->enabled_ctrls & XkbStickyKeysMask) && 26735c4bbdfSmrg XkbAX_NeedFeedback(ctrls, XkbAX_StickyKeysFBMask)); 26835c4bbdfSmrg 26935c4bbdfSmrg if (filter->upAction.type == XkbSA_LatchMods) { 27035c4bbdfSmrg unsigned char mask = filter->upAction.mods.mask; 27135c4bbdfSmrg unsigned char common; 27235c4bbdfSmrg 27335c4bbdfSmrg xkbi->clearMods = mask; 27435c4bbdfSmrg 27535c4bbdfSmrg /* ClearLocks */ 27635c4bbdfSmrg common = mask & xkbi->state.locked_mods; 27735c4bbdfSmrg if ((filter->upAction.mods.flags & XkbSA_ClearLocks) && common) { 27835c4bbdfSmrg mask &= ~common; 27935c4bbdfSmrg xkbi->state.locked_mods &= ~common; 28035c4bbdfSmrg if (needBeep) 28135c4bbdfSmrg XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_UNLOCK, 28235c4bbdfSmrg XkbStickyKeysMask); 28335c4bbdfSmrg } 28435c4bbdfSmrg /* LatchToLock */ 28535c4bbdfSmrg common = mask & xkbi->state.latched_mods; 28635c4bbdfSmrg if ((filter->upAction.mods.flags & XkbSA_LatchToLock) && common) { 28735c4bbdfSmrg unsigned char newlocked; 28835c4bbdfSmrg 28935c4bbdfSmrg mask &= ~common; 29035c4bbdfSmrg newlocked = common & ~xkbi->state.locked_mods; 29135c4bbdfSmrg if(newlocked){ 29235c4bbdfSmrg xkbi->state.locked_mods |= newlocked; 29335c4bbdfSmrg if (needBeep) 29435c4bbdfSmrg XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK, 29535c4bbdfSmrg XkbStickyKeysMask); 29635c4bbdfSmrg 29735c4bbdfSmrg } 29835c4bbdfSmrg xkbi->state.latched_mods &= ~common; 29935c4bbdfSmrg } 30035c4bbdfSmrg /* Latch remaining modifiers, if any. */ 30135c4bbdfSmrg if (mask) { 30235c4bbdfSmrg xkbi->state.latched_mods |= mask; 30335c4bbdfSmrg filter->priv = LATCH_PENDING; 30435c4bbdfSmrg if (needBeep) 30535c4bbdfSmrg XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LATCH, 30635c4bbdfSmrg XkbStickyKeysMask); 30735c4bbdfSmrg } 30835c4bbdfSmrg } 30935c4bbdfSmrg else { 31035c4bbdfSmrg xkbi->groupChange = -XkbSAGroup(&filter->upAction.group); 31135c4bbdfSmrg /* ClearLocks */ 31235c4bbdfSmrg if ((filter->upAction.group.flags & XkbSA_ClearLocks) && 31335c4bbdfSmrg (xkbi->state.locked_group)) { 31435c4bbdfSmrg xkbi->state.locked_group = 0; 31535c4bbdfSmrg if (needBeep) 31635c4bbdfSmrg XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_UNLOCK, 31735c4bbdfSmrg XkbStickyKeysMask); 31835c4bbdfSmrg } 31935c4bbdfSmrg /* LatchToLock */ 32035c4bbdfSmrg else if ((filter->upAction.group.flags & XkbSA_LatchToLock) 32135c4bbdfSmrg && (xkbi->state.latched_group)) { 32235c4bbdfSmrg xkbi->state.locked_group += XkbSAGroup(&filter->upAction.group); 32335c4bbdfSmrg xkbi->state.latched_group -= XkbSAGroup(&filter->upAction.group); 32435c4bbdfSmrg if(XkbSAGroup(&filter->upAction.group) && needBeep) 32535c4bbdfSmrg XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK, 32635c4bbdfSmrg XkbStickyKeysMask); 32735c4bbdfSmrg } 32835c4bbdfSmrg /* Latch group */ 32935c4bbdfSmrg else if(XkbSAGroup(&filter->upAction.group)){ 33035c4bbdfSmrg xkbi->state.latched_group += XkbSAGroup(&filter->upAction.group); 33135c4bbdfSmrg filter->priv = LATCH_PENDING; 33235c4bbdfSmrg if (needBeep) 33335c4bbdfSmrg XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LATCH, 33435c4bbdfSmrg XkbStickyKeysMask); 33535c4bbdfSmrg } 33635c4bbdfSmrg } 33735c4bbdfSmrg 33835c4bbdfSmrg if (filter->priv != LATCH_PENDING) 33935c4bbdfSmrg filter->active = 0; 34005b261ecSmrg } 34135c4bbdfSmrg else if (pAction && (filter->priv == LATCH_KEY_DOWN)) { 34235c4bbdfSmrg /* Latch was broken before it became pending: degrade to a 34335c4bbdfSmrg SetMods/SetGroup. */ 34435c4bbdfSmrg if (filter->upAction.type == XkbSA_LatchMods) 34535c4bbdfSmrg filter->upAction.type = XkbSA_SetMods; 34635c4bbdfSmrg else 34735c4bbdfSmrg filter->upAction.type = XkbSA_SetGroup; 34835c4bbdfSmrg filter->filter = _XkbFilterSetState; 34935c4bbdfSmrg filter->priv = 0; 35035c4bbdfSmrg return filter->filter(xkbi, filter, keycode, pAction); 35105b261ecSmrg } 35205b261ecSmrg return 1; 35305b261ecSmrg} 35405b261ecSmrg 35505b261ecSmrgstatic int 35635c4bbdfSmrg_XkbFilterLockState(XkbSrvInfoPtr xkbi, 35735c4bbdfSmrg XkbFilterPtr filter, unsigned keycode, XkbAction *pAction) 35805b261ecSmrg{ 35935c4bbdfSmrg if (filter->keycode == 0) /* initial press */ 36035c4bbdfSmrg AccessXCancelRepeatKey(xkbi, keycode); 36135c4bbdfSmrg 36235c4bbdfSmrg if (pAction && (pAction->type == XkbSA_LockGroup)) { 36335c4bbdfSmrg if (pAction->group.flags & XkbSA_GroupAbsolute) 36435c4bbdfSmrg xkbi->state.locked_group = XkbSAGroup(&pAction->group); 36535c4bbdfSmrg else 36635c4bbdfSmrg xkbi->state.locked_group += XkbSAGroup(&pAction->group); 36735c4bbdfSmrg return 1; 36805b261ecSmrg } 36935c4bbdfSmrg if (filter->keycode == 0) { /* initial press */ 37035c4bbdfSmrg filter->keycode = keycode; 37135c4bbdfSmrg filter->active = 1; 37235c4bbdfSmrg filter->filterOthers = 0; 37335c4bbdfSmrg filter->priv = xkbi->state.locked_mods & pAction->mods.mask; 37435c4bbdfSmrg filter->filter = _XkbFilterLockState; 37535c4bbdfSmrg filter->upAction = *pAction; 37635c4bbdfSmrg if (!(filter->upAction.mods.flags & XkbSA_LockNoLock)) 37735c4bbdfSmrg xkbi->state.locked_mods |= pAction->mods.mask; 37835c4bbdfSmrg xkbi->setMods = pAction->mods.mask; 37905b261ecSmrg } 38035c4bbdfSmrg else if (filter->keycode == keycode) { 38135c4bbdfSmrg filter->active = 0; 38235c4bbdfSmrg xkbi->clearMods = filter->upAction.mods.mask; 38335c4bbdfSmrg if (!(filter->upAction.mods.flags & XkbSA_LockNoUnlock)) 38435c4bbdfSmrg xkbi->state.locked_mods &= ~filter->priv; 38505b261ecSmrg } 38605b261ecSmrg return 1; 38705b261ecSmrg} 38805b261ecSmrg 38905b261ecSmrg#define ISO_KEY_DOWN 0 39005b261ecSmrg#define NO_ISO_LOCK 1 39105b261ecSmrg 39205b261ecSmrgstatic int 39335c4bbdfSmrg_XkbFilterISOLock(XkbSrvInfoPtr xkbi, 39435c4bbdfSmrg XkbFilterPtr filter, unsigned keycode, XkbAction *pAction) 39505b261ecSmrg{ 39605b261ecSmrg 39735c4bbdfSmrg if (filter->keycode == 0) { /* initial press */ 39835c4bbdfSmrg CARD8 flags = pAction->iso.flags; 39935c4bbdfSmrg 40035c4bbdfSmrg filter->keycode = keycode; 40135c4bbdfSmrg filter->active = 1; 40235c4bbdfSmrg filter->filterOthers = 1; 40335c4bbdfSmrg filter->priv = ISO_KEY_DOWN; 40435c4bbdfSmrg filter->upAction = *pAction; 40535c4bbdfSmrg filter->filter = _XkbFilterISOLock; 40635c4bbdfSmrg if (flags & XkbSA_ISODfltIsGroup) { 40735c4bbdfSmrg xkbi->groupChange = XkbSAGroup(&pAction->iso); 40835c4bbdfSmrg xkbi->setMods = 0; 40935c4bbdfSmrg } 41035c4bbdfSmrg else { 41135c4bbdfSmrg xkbi->setMods = pAction->iso.mask; 41235c4bbdfSmrg xkbi->groupChange = 0; 41335c4bbdfSmrg } 41435c4bbdfSmrg if ((!(flags & XkbSA_ISONoAffectMods)) && (xkbi->state.base_mods)) { 41535c4bbdfSmrg filter->priv = NO_ISO_LOCK; 41635c4bbdfSmrg xkbi->state.locked_mods ^= xkbi->state.base_mods; 41735c4bbdfSmrg } 41835c4bbdfSmrg if ((!(flags & XkbSA_ISONoAffectGroup)) && (xkbi->state.base_group)) { 41905b261ecSmrg/* 6/22/93 (ef) -- lock groups if group key is down first */ 42035c4bbdfSmrg } 42135c4bbdfSmrg if (!(flags & XkbSA_ISONoAffectPtr)) { 42205b261ecSmrg/* 6/22/93 (ef) -- lock mouse buttons if they're down */ 42335c4bbdfSmrg } 42405b261ecSmrg } 42535c4bbdfSmrg else if (filter->keycode == keycode) { 42635c4bbdfSmrg CARD8 flags = filter->upAction.iso.flags; 42735c4bbdfSmrg 42835c4bbdfSmrg if (flags & XkbSA_ISODfltIsGroup) { 42935c4bbdfSmrg xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso); 43035c4bbdfSmrg xkbi->clearMods = 0; 43135c4bbdfSmrg if (filter->priv == ISO_KEY_DOWN) 43235c4bbdfSmrg xkbi->state.locked_group += XkbSAGroup(&filter->upAction.iso); 43335c4bbdfSmrg } 43435c4bbdfSmrg else { 43535c4bbdfSmrg xkbi->clearMods = filter->upAction.iso.mask; 43635c4bbdfSmrg xkbi->groupChange = 0; 43735c4bbdfSmrg if (filter->priv == ISO_KEY_DOWN) 43835c4bbdfSmrg xkbi->state.locked_mods ^= filter->upAction.iso.mask; 43935c4bbdfSmrg } 44035c4bbdfSmrg filter->active = 0; 44105b261ecSmrg } 44205b261ecSmrg else if (pAction) { 44335c4bbdfSmrg CARD8 flags = filter->upAction.iso.flags; 44435c4bbdfSmrg 44535c4bbdfSmrg switch (pAction->type) { 44635c4bbdfSmrg case XkbSA_SetMods: 44735c4bbdfSmrg case XkbSA_LatchMods: 44835c4bbdfSmrg if (!(flags & XkbSA_ISONoAffectMods)) { 44935c4bbdfSmrg pAction->type = XkbSA_LockMods; 45035c4bbdfSmrg filter->priv = NO_ISO_LOCK; 45135c4bbdfSmrg } 45235c4bbdfSmrg break; 45335c4bbdfSmrg case XkbSA_SetGroup: 45435c4bbdfSmrg case XkbSA_LatchGroup: 45535c4bbdfSmrg if (!(flags & XkbSA_ISONoAffectGroup)) { 45635c4bbdfSmrg pAction->type = XkbSA_LockGroup; 45735c4bbdfSmrg filter->priv = NO_ISO_LOCK; 45835c4bbdfSmrg } 45935c4bbdfSmrg break; 46035c4bbdfSmrg case XkbSA_PtrBtn: 46135c4bbdfSmrg if (!(flags & XkbSA_ISONoAffectPtr)) { 46235c4bbdfSmrg pAction->type = XkbSA_LockPtrBtn; 46335c4bbdfSmrg filter->priv = NO_ISO_LOCK; 46435c4bbdfSmrg } 46535c4bbdfSmrg break; 46635c4bbdfSmrg case XkbSA_SetControls: 46735c4bbdfSmrg if (!(flags & XkbSA_ISONoAffectCtrls)) { 46835c4bbdfSmrg pAction->type = XkbSA_LockControls; 46935c4bbdfSmrg filter->priv = NO_ISO_LOCK; 47035c4bbdfSmrg } 47135c4bbdfSmrg break; 47235c4bbdfSmrg } 47305b261ecSmrg } 47405b261ecSmrg return 1; 47505b261ecSmrg} 47605b261ecSmrg 47705b261ecSmrgstatic CARD32 47835c4bbdfSmrg_XkbPtrAccelExpire(OsTimerPtr timer, CARD32 now, void *arg) 47905b261ecSmrg{ 48035c4bbdfSmrg XkbSrvInfoPtr xkbi = (XkbSrvInfoPtr) arg; 48135c4bbdfSmrg XkbControlsPtr ctrls = xkbi->desc->ctrls; 48235c4bbdfSmrg int dx, dy; 48305b261ecSmrg 48435c4bbdfSmrg if (xkbi->mouseKey == 0) 48535c4bbdfSmrg return 0; 48605b261ecSmrg 48705b261ecSmrg if (xkbi->mouseKeysAccel) { 48835c4bbdfSmrg if ((xkbi->mouseKeysCounter) < ctrls->mk_time_to_max) { 48935c4bbdfSmrg double step; 49035c4bbdfSmrg 49135c4bbdfSmrg xkbi->mouseKeysCounter++; 49235c4bbdfSmrg step = xkbi->mouseKeysCurveFactor * 49335c4bbdfSmrg pow((double) xkbi->mouseKeysCounter, xkbi->mouseKeysCurve); 49435c4bbdfSmrg if (xkbi->mouseKeysDX < 0) 49535c4bbdfSmrg dx = floor(((double) xkbi->mouseKeysDX) * step); 49635c4bbdfSmrg else 49735c4bbdfSmrg dx = ceil(((double) xkbi->mouseKeysDX) * step); 49835c4bbdfSmrg if (xkbi->mouseKeysDY < 0) 49935c4bbdfSmrg dy = floor(((double) xkbi->mouseKeysDY) * step); 50035c4bbdfSmrg else 50135c4bbdfSmrg dy = ceil(((double) xkbi->mouseKeysDY) * step); 50235c4bbdfSmrg } 50335c4bbdfSmrg else { 50435c4bbdfSmrg dx = xkbi->mouseKeysDX * ctrls->mk_max_speed; 50535c4bbdfSmrg dy = xkbi->mouseKeysDY * ctrls->mk_max_speed; 50635c4bbdfSmrg } 50735c4bbdfSmrg if (xkbi->mouseKeysFlags & XkbSA_MoveAbsoluteX) 50835c4bbdfSmrg dx = xkbi->mouseKeysDX; 50935c4bbdfSmrg if (xkbi->mouseKeysFlags & XkbSA_MoveAbsoluteY) 51035c4bbdfSmrg dy = xkbi->mouseKeysDY; 51105b261ecSmrg } 51205b261ecSmrg else { 51335c4bbdfSmrg dx = xkbi->mouseKeysDX; 51435c4bbdfSmrg dy = xkbi->mouseKeysDY; 51505b261ecSmrg } 51635c4bbdfSmrg XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags, dx, dy); 51705b261ecSmrg return xkbi->desc->ctrls->mk_interval; 51805b261ecSmrg} 51905b261ecSmrg 52005b261ecSmrgstatic int 52135c4bbdfSmrg_XkbFilterPointerMove(XkbSrvInfoPtr xkbi, 52235c4bbdfSmrg XkbFilterPtr filter, unsigned keycode, XkbAction *pAction) 52305b261ecSmrg{ 52435c4bbdfSmrg int x, y; 52535c4bbdfSmrg Bool accel; 52635c4bbdfSmrg 52735c4bbdfSmrg if (filter->keycode == 0) { /* initial press */ 52835c4bbdfSmrg filter->keycode = keycode; 52935c4bbdfSmrg filter->active = 1; 53035c4bbdfSmrg filter->filterOthers = 0; 53135c4bbdfSmrg filter->priv = 0; 53235c4bbdfSmrg filter->filter = _XkbFilterPointerMove; 53335c4bbdfSmrg filter->upAction = *pAction; 53435c4bbdfSmrg xkbi->mouseKeysCounter = 0; 53535c4bbdfSmrg xkbi->mouseKey = keycode; 53635c4bbdfSmrg accel = ((pAction->ptr.flags & XkbSA_NoAcceleration) == 0); 53735c4bbdfSmrg x = XkbPtrActionX(&pAction->ptr); 53835c4bbdfSmrg y = XkbPtrActionY(&pAction->ptr); 53935c4bbdfSmrg XkbFakePointerMotion(xkbi->device, pAction->ptr.flags, x, y); 54035c4bbdfSmrg AccessXCancelRepeatKey(xkbi, keycode); 54135c4bbdfSmrg xkbi->mouseKeysAccel = accel && 54235c4bbdfSmrg (xkbi->desc->ctrls->enabled_ctrls & XkbMouseKeysAccelMask); 54335c4bbdfSmrg xkbi->mouseKeysFlags = pAction->ptr.flags; 54435c4bbdfSmrg xkbi->mouseKeysDX = XkbPtrActionX(&pAction->ptr); 54535c4bbdfSmrg xkbi->mouseKeysDY = XkbPtrActionY(&pAction->ptr); 54635c4bbdfSmrg xkbi->mouseKeyTimer = TimerSet(xkbi->mouseKeyTimer, 0, 54735c4bbdfSmrg xkbi->desc->ctrls->mk_delay, 54835c4bbdfSmrg _XkbPtrAccelExpire, (void *) xkbi); 54905b261ecSmrg } 55035c4bbdfSmrg else if (filter->keycode == keycode) { 55135c4bbdfSmrg filter->active = 0; 55235c4bbdfSmrg if (xkbi->mouseKey == keycode) { 55335c4bbdfSmrg xkbi->mouseKey = 0; 55435c4bbdfSmrg xkbi->mouseKeyTimer = TimerSet(xkbi->mouseKeyTimer, 0, 0, 55535c4bbdfSmrg NULL, NULL); 55635c4bbdfSmrg } 55705b261ecSmrg } 55805b261ecSmrg return 0; 55905b261ecSmrg} 56005b261ecSmrg 56105b261ecSmrgstatic int 56235c4bbdfSmrg_XkbFilterPointerBtn(XkbSrvInfoPtr xkbi, 56335c4bbdfSmrg XkbFilterPtr filter, unsigned keycode, XkbAction *pAction) 56405b261ecSmrg{ 56535c4bbdfSmrg if (filter->keycode == 0) { /* initial press */ 56635c4bbdfSmrg int button = pAction->btn.button; 56735c4bbdfSmrg 56835c4bbdfSmrg if (button == XkbSA_UseDfltButton) 56935c4bbdfSmrg button = xkbi->desc->ctrls->mk_dflt_btn; 57035c4bbdfSmrg 57135c4bbdfSmrg filter->keycode = keycode; 57235c4bbdfSmrg filter->active = 1; 57335c4bbdfSmrg filter->filterOthers = 0; 57435c4bbdfSmrg filter->priv = 0; 57535c4bbdfSmrg filter->filter = _XkbFilterPointerBtn; 57635c4bbdfSmrg filter->upAction = *pAction; 57735c4bbdfSmrg filter->upAction.btn.button = button; 57835c4bbdfSmrg switch (pAction->type) { 57935c4bbdfSmrg case XkbSA_LockPtrBtn: 58035c4bbdfSmrg if (((xkbi->lockedPtrButtons & (1 << button)) == 0) && 58135c4bbdfSmrg ((pAction->btn.flags & XkbSA_LockNoLock) == 0)) { 58235c4bbdfSmrg xkbi->lockedPtrButtons |= (1 << button); 58335c4bbdfSmrg AccessXCancelRepeatKey(xkbi, keycode); 58435c4bbdfSmrg XkbFakeDeviceButton(xkbi->device, 1, button); 58535c4bbdfSmrg filter->upAction.type = XkbSA_NoAction; 58635c4bbdfSmrg } 58735c4bbdfSmrg break; 58835c4bbdfSmrg case XkbSA_PtrBtn: 58935c4bbdfSmrg { 59035c4bbdfSmrg register int i, nClicks; 59135c4bbdfSmrg 59235c4bbdfSmrg AccessXCancelRepeatKey(xkbi, keycode); 59335c4bbdfSmrg if (pAction->btn.count > 0) { 59435c4bbdfSmrg nClicks = pAction->btn.count; 59535c4bbdfSmrg for (i = 0; i < nClicks; i++) { 59635c4bbdfSmrg XkbFakeDeviceButton(xkbi->device, 1, button); 59735c4bbdfSmrg XkbFakeDeviceButton(xkbi->device, 0, button); 59835c4bbdfSmrg } 59935c4bbdfSmrg filter->upAction.type = XkbSA_NoAction; 60035c4bbdfSmrg } 60135c4bbdfSmrg else 60235c4bbdfSmrg XkbFakeDeviceButton(xkbi->device, 1, button); 60335c4bbdfSmrg } 60435c4bbdfSmrg break; 60535c4bbdfSmrg case XkbSA_SetPtrDflt: 60635c4bbdfSmrg { 60735c4bbdfSmrg XkbControlsPtr ctrls = xkbi->desc->ctrls; 60835c4bbdfSmrg XkbControlsRec old; 60935c4bbdfSmrg xkbControlsNotify cn; 61035c4bbdfSmrg 61135c4bbdfSmrg old = *ctrls; 61235c4bbdfSmrg AccessXCancelRepeatKey(xkbi, keycode); 61335c4bbdfSmrg switch (pAction->dflt.affect) { 61435c4bbdfSmrg case XkbSA_AffectDfltBtn: 61535c4bbdfSmrg if (pAction->dflt.flags & XkbSA_DfltBtnAbsolute) 61635c4bbdfSmrg ctrls->mk_dflt_btn = XkbSAPtrDfltValue(&pAction->dflt); 61735c4bbdfSmrg else { 61835c4bbdfSmrg ctrls->mk_dflt_btn += XkbSAPtrDfltValue(&pAction->dflt); 61935c4bbdfSmrg if (ctrls->mk_dflt_btn > 5) 62035c4bbdfSmrg ctrls->mk_dflt_btn = 5; 62135c4bbdfSmrg else if (ctrls->mk_dflt_btn < 1) 62235c4bbdfSmrg ctrls->mk_dflt_btn = 1; 62335c4bbdfSmrg } 62435c4bbdfSmrg break; 62535c4bbdfSmrg default: 62635c4bbdfSmrg ErrorF 62735c4bbdfSmrg ("Attempt to change unknown pointer default (%d) ignored\n", 62835c4bbdfSmrg pAction->dflt.affect); 62935c4bbdfSmrg break; 63035c4bbdfSmrg } 63135c4bbdfSmrg if (XkbComputeControlsNotify(xkbi->device, 63235c4bbdfSmrg &old, xkbi->desc->ctrls, &cn, FALSE)) { 63335c4bbdfSmrg cn.keycode = keycode; 63435c4bbdfSmrg /* XXX: what about DeviceKeyPress? */ 63535c4bbdfSmrg cn.eventType = KeyPress; 63635c4bbdfSmrg cn.requestMajor = 0; 63735c4bbdfSmrg cn.requestMinor = 0; 63835c4bbdfSmrg XkbSendControlsNotify(xkbi->device, &cn); 63935c4bbdfSmrg } 64035c4bbdfSmrg } 64135c4bbdfSmrg break; 64235c4bbdfSmrg } 64335c4bbdfSmrg return 0; 64405b261ecSmrg } 64535c4bbdfSmrg else if (filter->keycode == keycode) { 64635c4bbdfSmrg int button = filter->upAction.btn.button; 64735c4bbdfSmrg 64835c4bbdfSmrg switch (filter->upAction.type) { 64935c4bbdfSmrg case XkbSA_LockPtrBtn: 65035c4bbdfSmrg if (((filter->upAction.btn.flags & XkbSA_LockNoUnlock) != 0) || 65135c4bbdfSmrg ((xkbi->lockedPtrButtons & (1 << button)) == 0)) { 65235c4bbdfSmrg break; 65335c4bbdfSmrg } 65435c4bbdfSmrg xkbi->lockedPtrButtons &= ~(1 << button); 65535c4bbdfSmrg 65635c4bbdfSmrg if (IsMaster(xkbi->device)) { 65735c4bbdfSmrg XkbMergeLockedPtrBtns(xkbi->device); 65835c4bbdfSmrg /* One SD still has lock set, don't post event */ 65935c4bbdfSmrg if ((xkbi->lockedPtrButtons & (1 << button)) != 0) 66035c4bbdfSmrg break; 66135c4bbdfSmrg } 66235c4bbdfSmrg 66335c4bbdfSmrg /* fallthrough */ 66435c4bbdfSmrg case XkbSA_PtrBtn: 66535c4bbdfSmrg XkbFakeDeviceButton(xkbi->device, 0, button); 66635c4bbdfSmrg break; 66735c4bbdfSmrg } 66835c4bbdfSmrg filter->active = 0; 66935c4bbdfSmrg return 0; 67005b261ecSmrg } 67135c4bbdfSmrg return 1; 67205b261ecSmrg} 67305b261ecSmrg 67405b261ecSmrgstatic int 67535c4bbdfSmrg_XkbFilterControls(XkbSrvInfoPtr xkbi, 67635c4bbdfSmrg XkbFilterPtr filter, unsigned keycode, XkbAction *pAction) 67705b261ecSmrg{ 67835c4bbdfSmrg XkbControlsRec old; 67935c4bbdfSmrg XkbControlsPtr ctrls; 68035c4bbdfSmrg DeviceIntPtr kbd; 68135c4bbdfSmrg unsigned int change; 68235c4bbdfSmrg XkbEventCauseRec cause; 68335c4bbdfSmrg 68435c4bbdfSmrg kbd = xkbi->device; 68535c4bbdfSmrg ctrls = xkbi->desc->ctrls; 68635c4bbdfSmrg old = *ctrls; 68735c4bbdfSmrg if (filter->keycode == 0) { /* initial press */ 68835c4bbdfSmrg AccessXCancelRepeatKey(xkbi, keycode); 68935c4bbdfSmrg filter->keycode = keycode; 69035c4bbdfSmrg filter->active = 1; 69135c4bbdfSmrg filter->filterOthers = 0; 69235c4bbdfSmrg change = XkbActionCtrls(&pAction->ctrls); 69335c4bbdfSmrg filter->priv = change; 69435c4bbdfSmrg filter->filter = _XkbFilterControls; 69535c4bbdfSmrg filter->upAction = *pAction; 69635c4bbdfSmrg 69735c4bbdfSmrg if (pAction->type == XkbSA_LockControls) { 69835c4bbdfSmrg filter->priv = (ctrls->enabled_ctrls & change); 69935c4bbdfSmrg change &= ~ctrls->enabled_ctrls; 70035c4bbdfSmrg } 70135c4bbdfSmrg 70235c4bbdfSmrg if (change) { 70335c4bbdfSmrg xkbControlsNotify cn; 70435c4bbdfSmrg XkbSrvLedInfoPtr sli; 70535c4bbdfSmrg 70635c4bbdfSmrg ctrls->enabled_ctrls |= change; 70735c4bbdfSmrg if (XkbComputeControlsNotify(kbd, &old, ctrls, &cn, FALSE)) { 70835c4bbdfSmrg cn.keycode = keycode; 70905b261ecSmrg /* XXX: what about DeviceKeyPress? */ 71035c4bbdfSmrg cn.eventType = KeyPress; 71135c4bbdfSmrg cn.requestMajor = 0; 71235c4bbdfSmrg cn.requestMinor = 0; 71335c4bbdfSmrg XkbSendControlsNotify(kbd, &cn); 71435c4bbdfSmrg } 71535c4bbdfSmrg 71635c4bbdfSmrg XkbSetCauseKey(&cause, keycode, KeyPress); 71735c4bbdfSmrg 71835c4bbdfSmrg /* If sticky keys were disabled, clear all locks and latches */ 71935c4bbdfSmrg if ((old.enabled_ctrls & XkbStickyKeysMask) && 72035c4bbdfSmrg (!(ctrls->enabled_ctrls & XkbStickyKeysMask))) { 72135c4bbdfSmrg XkbClearAllLatchesAndLocks(kbd, xkbi, FALSE, &cause); 72235c4bbdfSmrg } 72335c4bbdfSmrg sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass, XkbDfltXIId, 0); 72435c4bbdfSmrg XkbUpdateIndicators(kbd, sli->usesControls, TRUE, NULL, &cause); 72535c4bbdfSmrg if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask)) 72635c4bbdfSmrg XkbDDXAccessXBeep(kbd, _BEEP_FEATURE_ON, change); 72735c4bbdfSmrg } 72805b261ecSmrg } 72935c4bbdfSmrg else if (filter->keycode == keycode) { 73035c4bbdfSmrg change = filter->priv; 73135c4bbdfSmrg if (change) { 73235c4bbdfSmrg xkbControlsNotify cn; 73335c4bbdfSmrg XkbSrvLedInfoPtr sli; 73435c4bbdfSmrg 73535c4bbdfSmrg ctrls->enabled_ctrls &= ~change; 73635c4bbdfSmrg if (XkbComputeControlsNotify(kbd, &old, ctrls, &cn, FALSE)) { 73735c4bbdfSmrg cn.keycode = keycode; 73835c4bbdfSmrg cn.eventType = KeyRelease; 73935c4bbdfSmrg cn.requestMajor = 0; 74035c4bbdfSmrg cn.requestMinor = 0; 74135c4bbdfSmrg XkbSendControlsNotify(kbd, &cn); 74235c4bbdfSmrg } 74335c4bbdfSmrg 74435c4bbdfSmrg XkbSetCauseKey(&cause, keycode, KeyRelease); 74535c4bbdfSmrg /* If sticky keys were disabled, clear all locks and latches */ 74635c4bbdfSmrg if ((old.enabled_ctrls & XkbStickyKeysMask) && 74735c4bbdfSmrg (!(ctrls->enabled_ctrls & XkbStickyKeysMask))) { 74835c4bbdfSmrg XkbClearAllLatchesAndLocks(kbd, xkbi, FALSE, &cause); 74935c4bbdfSmrg } 75035c4bbdfSmrg sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass, XkbDfltXIId, 0); 75135c4bbdfSmrg XkbUpdateIndicators(kbd, sli->usesControls, TRUE, NULL, &cause); 75235c4bbdfSmrg if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask)) 75335c4bbdfSmrg XkbDDXAccessXBeep(kbd, _BEEP_FEATURE_OFF, change); 75435c4bbdfSmrg } 75535c4bbdfSmrg filter->keycode = 0; 75635c4bbdfSmrg filter->active = 0; 75705b261ecSmrg } 75805b261ecSmrg return 1; 75905b261ecSmrg} 76005b261ecSmrg 76105b261ecSmrgstatic int 76235c4bbdfSmrg_XkbFilterActionMessage(XkbSrvInfoPtr xkbi, 76335c4bbdfSmrg XkbFilterPtr filter, 76435c4bbdfSmrg unsigned keycode, XkbAction *pAction) 76505b261ecSmrg{ 76635c4bbdfSmrg XkbMessageAction *pMsg; 76735c4bbdfSmrg DeviceIntPtr kbd; 76835c4bbdfSmrg 76935c4bbdfSmrg if ((filter->keycode != 0) && (filter->keycode != keycode)) 77035c4bbdfSmrg return 1; 77135c4bbdfSmrg 77235c4bbdfSmrg /* This can happen if the key repeats, and the state (modifiers or group) 77335c4bbdfSmrg changes meanwhile. */ 77435c4bbdfSmrg if ((filter->keycode == keycode) && pAction && 77535c4bbdfSmrg (pAction->type != XkbSA_ActionMessage)) 77635c4bbdfSmrg return 1; 77735c4bbdfSmrg 77835c4bbdfSmrg kbd = xkbi->device; 77935c4bbdfSmrg if (filter->keycode == 0) { /* initial press */ 78035c4bbdfSmrg pMsg = &pAction->msg; 78135c4bbdfSmrg if ((pMsg->flags & XkbSA_MessageOnRelease) || 78235c4bbdfSmrg ((pMsg->flags & XkbSA_MessageGenKeyEvent) == 0)) { 78335c4bbdfSmrg filter->keycode = keycode; 78435c4bbdfSmrg filter->active = 1; 78535c4bbdfSmrg filter->filterOthers = 0; 78635c4bbdfSmrg filter->priv = 0; 78735c4bbdfSmrg filter->filter = _XkbFilterActionMessage; 78835c4bbdfSmrg filter->upAction = *pAction; 78935c4bbdfSmrg } 79035c4bbdfSmrg if (pMsg->flags & XkbSA_MessageOnPress) { 79135c4bbdfSmrg xkbActionMessage msg; 79235c4bbdfSmrg 79335c4bbdfSmrg msg.keycode = keycode; 79435c4bbdfSmrg msg.press = 1; 79535c4bbdfSmrg msg.keyEventFollows = 79635c4bbdfSmrg ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0); 79735c4bbdfSmrg memcpy((char *) msg.message, (char *) pMsg->message, 79835c4bbdfSmrg XkbActionMessageLength); 79935c4bbdfSmrg XkbSendActionMessage(kbd, &msg); 80035c4bbdfSmrg } 80135c4bbdfSmrg return ((pAction->msg.flags & XkbSA_MessageGenKeyEvent) != 0); 80205b261ecSmrg } 80335c4bbdfSmrg else if (filter->keycode == keycode) { 80435c4bbdfSmrg pMsg = &filter->upAction.msg; 80535c4bbdfSmrg if (pAction == NULL) { 80635c4bbdfSmrg if (pMsg->flags & XkbSA_MessageOnRelease) { 80735c4bbdfSmrg xkbActionMessage msg; 80835c4bbdfSmrg 80935c4bbdfSmrg msg.keycode = keycode; 81035c4bbdfSmrg msg.press = 0; 81135c4bbdfSmrg msg.keyEventFollows = 81235c4bbdfSmrg ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0); 81335c4bbdfSmrg memcpy((char *) msg.message, (char *) pMsg->message, 81435c4bbdfSmrg XkbActionMessageLength); 81535c4bbdfSmrg XkbSendActionMessage(kbd, &msg); 81635c4bbdfSmrg } 81735c4bbdfSmrg filter->keycode = 0; 81835c4bbdfSmrg filter->active = 0; 81935c4bbdfSmrg return ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0); 82035c4bbdfSmrg } else if (memcmp(pMsg, pAction, 8) == 0) { 82135c4bbdfSmrg /* Repeat: If we send the same message, avoid multiple messages 82235c4bbdfSmrg on release from piling up. */ 82335c4bbdfSmrg filter->keycode = 0; 82435c4bbdfSmrg filter->active = 0; 82535c4bbdfSmrg } 82605b261ecSmrg } 82735c4bbdfSmrg return 1; 82805b261ecSmrg} 82905b261ecSmrg 83005b261ecSmrgstatic int 83135c4bbdfSmrg_XkbFilterRedirectKey(XkbSrvInfoPtr xkbi, 83235c4bbdfSmrg XkbFilterPtr filter, unsigned keycode, XkbAction *pAction) 83305b261ecSmrg{ 83435c4bbdfSmrg DeviceEvent ev; 83535c4bbdfSmrg int x, y; 83635c4bbdfSmrg XkbStateRec old, old_prev; 83735c4bbdfSmrg unsigned mods, mask; 83835c4bbdfSmrg xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device); 83935c4bbdfSmrg ProcessInputProc backupproc; 84035c4bbdfSmrg 84135c4bbdfSmrg if ((filter->keycode != 0) && (filter->keycode != keycode)) 84235c4bbdfSmrg return 1; 84335c4bbdfSmrg 84435c4bbdfSmrg /* This can happen if the key repeats, and the state (modifiers or group) 84535c4bbdfSmrg changes meanwhile. */ 84635c4bbdfSmrg if ((filter->keycode == keycode) && pAction && 84735c4bbdfSmrg (pAction->type != XkbSA_RedirectKey)) 84835c4bbdfSmrg return 1; 84905b261ecSmrg 85005b261ecSmrg /* never actually used uninitialised, but gcc isn't smart enough 85105b261ecSmrg * to work that out. */ 85205b261ecSmrg memset(&old, 0, sizeof(old)); 85335c4bbdfSmrg memset(&old_prev, 0, sizeof(old_prev)); 8546747b715Smrg memset(&ev, 0, sizeof(ev)); 85505b261ecSmrg 85635c4bbdfSmrg GetSpritePosition(xkbi->device, &x, &y); 8576747b715Smrg ev.header = ET_Internal; 8586747b715Smrg ev.length = sizeof(DeviceEvent); 8596747b715Smrg ev.time = GetTimeInMillis(); 8606747b715Smrg ev.root_x = x; 8616747b715Smrg ev.root_y = y; 86235c4bbdfSmrg /* redirect actions do not work across devices, therefore the following is 86335c4bbdfSmrg * correct: */ 86435c4bbdfSmrg ev.deviceid = xkbi->device->id; 86535c4bbdfSmrg /* filter->priv must be set up by the caller for the initial press. */ 86635c4bbdfSmrg ev.sourceid = filter->priv; 86735c4bbdfSmrg 86835c4bbdfSmrg if (filter->keycode == 0) { /* initial press */ 86935c4bbdfSmrg if ((pAction->redirect.new_key < xkbi->desc->min_key_code) || 87035c4bbdfSmrg (pAction->redirect.new_key > xkbi->desc->max_key_code)) { 87135c4bbdfSmrg return 1; 87235c4bbdfSmrg } 87335c4bbdfSmrg filter->keycode = keycode; 87435c4bbdfSmrg filter->active = 1; 87535c4bbdfSmrg filter->filterOthers = 0; 87635c4bbdfSmrg filter->filter = _XkbFilterRedirectKey; 87735c4bbdfSmrg filter->upAction = *pAction; 87805b261ecSmrg 8796747b715Smrg ev.type = ET_KeyPress; 8806747b715Smrg ev.detail.key = pAction->redirect.new_key; 88105b261ecSmrg 88235c4bbdfSmrg mask = XkbSARedirectVModsMask(&pAction->redirect); 88335c4bbdfSmrg mods = XkbSARedirectVMods(&pAction->redirect); 88435c4bbdfSmrg if (mask) 88535c4bbdfSmrg XkbVirtualModsToReal(xkbi->desc, mask, &mask); 88635c4bbdfSmrg if (mods) 88735c4bbdfSmrg XkbVirtualModsToReal(xkbi->desc, mods, &mods); 88835c4bbdfSmrg mask |= pAction->redirect.mods_mask; 88935c4bbdfSmrg mods |= pAction->redirect.mods; 89035c4bbdfSmrg 89135c4bbdfSmrg if (mask || mods) { 89235c4bbdfSmrg old = xkbi->state; 89335c4bbdfSmrg old_prev = xkbi->prev_state; 89435c4bbdfSmrg xkbi->state.base_mods &= ~mask; 89535c4bbdfSmrg xkbi->state.base_mods |= (mods & mask); 89635c4bbdfSmrg xkbi->state.latched_mods &= ~mask; 89735c4bbdfSmrg xkbi->state.latched_mods |= (mods & mask); 89835c4bbdfSmrg xkbi->state.locked_mods &= ~mask; 89935c4bbdfSmrg xkbi->state.locked_mods |= (mods & mask); 90035c4bbdfSmrg XkbComputeDerivedState(xkbi); 90135c4bbdfSmrg xkbi->prev_state = xkbi->state; 90235c4bbdfSmrg } 90335c4bbdfSmrg 90435c4bbdfSmrg UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc); 90535c4bbdfSmrg xkbi->device->public.processInputProc((InternalEvent *) &ev, 90635c4bbdfSmrg xkbi->device); 90735c4bbdfSmrg COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc, 90835c4bbdfSmrg xkbUnwrapProc); 90935c4bbdfSmrg 91035c4bbdfSmrg if (mask || mods) { 91135c4bbdfSmrg xkbi->state = old; 91235c4bbdfSmrg xkbi->prev_state = old_prev; 91335c4bbdfSmrg } 91435c4bbdfSmrg return 0; 91535c4bbdfSmrg } 91635c4bbdfSmrg else { 91735c4bbdfSmrg /* If it is a key release, or we redirect to another key, release the 91835c4bbdfSmrg previous new_key. Otherwise, repeat. */ 91935c4bbdfSmrg ev.detail.key = filter->upAction.redirect.new_key; 92035c4bbdfSmrg if (pAction == NULL || ev.detail.key != pAction->redirect.new_key) { 92135c4bbdfSmrg ev.type = ET_KeyRelease; 92235c4bbdfSmrg filter->active = 0; 92335c4bbdfSmrg } 92435c4bbdfSmrg else { 92535c4bbdfSmrg ev.type = ET_KeyPress; 92635c4bbdfSmrg ev.key_repeat = TRUE; 92705b261ecSmrg } 92805b261ecSmrg 92935c4bbdfSmrg mask = XkbSARedirectVModsMask(&filter->upAction.redirect); 93035c4bbdfSmrg mods = XkbSARedirectVMods(&filter->upAction.redirect); 93135c4bbdfSmrg if (mask) 93235c4bbdfSmrg XkbVirtualModsToReal(xkbi->desc, mask, &mask); 93335c4bbdfSmrg if (mods) 93435c4bbdfSmrg XkbVirtualModsToReal(xkbi->desc, mods, &mods); 93535c4bbdfSmrg mask |= filter->upAction.redirect.mods_mask; 93635c4bbdfSmrg mods |= filter->upAction.redirect.mods; 93735c4bbdfSmrg 93835c4bbdfSmrg if (mask || mods) { 93935c4bbdfSmrg old = xkbi->state; 94035c4bbdfSmrg old_prev = xkbi->prev_state; 94135c4bbdfSmrg xkbi->state.base_mods &= ~mask; 94235c4bbdfSmrg xkbi->state.base_mods |= (mods & mask); 94335c4bbdfSmrg xkbi->state.latched_mods &= ~mask; 94435c4bbdfSmrg xkbi->state.latched_mods |= (mods & mask); 94535c4bbdfSmrg xkbi->state.locked_mods &= ~mask; 94635c4bbdfSmrg xkbi->state.locked_mods |= (mods & mask); 94705b261ecSmrg XkbComputeDerivedState(xkbi); 94835c4bbdfSmrg xkbi->prev_state = xkbi->state; 94905b261ecSmrg } 95005b261ecSmrg 95135c4bbdfSmrg UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc); 95235c4bbdfSmrg xkbi->device->public.processInputProc((InternalEvent *) &ev, 95335c4bbdfSmrg xkbi->device); 95435c4bbdfSmrg COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc, 95535c4bbdfSmrg xkbUnwrapProc); 95605b261ecSmrg 95735c4bbdfSmrg if (mask || mods) { 95835c4bbdfSmrg xkbi->state = old; 95935c4bbdfSmrg xkbi->prev_state = old_prev; 96035c4bbdfSmrg } 96105b261ecSmrg 96235c4bbdfSmrg /* We return 1 in case we have sent a release event because the new_key 96335c4bbdfSmrg has changed. Then, subsequently, we will call this function again 96435c4bbdfSmrg with the same pAction, which will create the press for the new 96535c4bbdfSmrg new_key. */ 96635c4bbdfSmrg return (pAction && ev.detail.key != pAction->redirect.new_key); 96705b261ecSmrg } 96805b261ecSmrg} 96905b261ecSmrg 97005b261ecSmrgstatic int 97135c4bbdfSmrg_XkbFilterSwitchScreen(XkbSrvInfoPtr xkbi, 97235c4bbdfSmrg XkbFilterPtr filter, 97335c4bbdfSmrg unsigned keycode, XkbAction *pAction) 97405b261ecSmrg{ 97505b261ecSmrg DeviceIntPtr dev = xkbi->device; 97635c4bbdfSmrg 97705b261ecSmrg if (dev == inputInfo.keyboard) 97805b261ecSmrg return 0; 97905b261ecSmrg 98035c4bbdfSmrg if (filter->keycode == 0) { /* initial press */ 98135c4bbdfSmrg filter->keycode = keycode; 98235c4bbdfSmrg filter->active = 1; 98335c4bbdfSmrg filter->filterOthers = 0; 98435c4bbdfSmrg filter->filter = _XkbFilterSwitchScreen; 98535c4bbdfSmrg AccessXCancelRepeatKey(xkbi, keycode); 98635c4bbdfSmrg XkbDDXSwitchScreen(dev, keycode, pAction); 98735c4bbdfSmrg return 0; 98805b261ecSmrg } 98935c4bbdfSmrg else if (filter->keycode == keycode) { 99035c4bbdfSmrg filter->active = 0; 99135c4bbdfSmrg return 0; 99205b261ecSmrg } 99305b261ecSmrg return 1; 99405b261ecSmrg} 99505b261ecSmrg 996ed6184dfSmrgstatic int 997ed6184dfSmrgXkbHandlePrivate(DeviceIntPtr dev, KeyCode keycode, XkbAction *pAction) 998ed6184dfSmrg{ 999ed6184dfSmrg XkbAnyAction *xkb_act = &(pAction->any); 1000ed6184dfSmrg 1001ed6184dfSmrg if (xkb_act->type == XkbSA_XFree86Private) { 1002ed6184dfSmrg char msgbuf[XkbAnyActionDataSize + 1]; 1003ed6184dfSmrg 1004ed6184dfSmrg memcpy(msgbuf, xkb_act->data, XkbAnyActionDataSize); 1005ed6184dfSmrg msgbuf[XkbAnyActionDataSize] = '\0'; 1006ed6184dfSmrg 1007ed6184dfSmrg if (strcasecmp(msgbuf, "prgrbs") == 0) { 1008ed6184dfSmrg DeviceIntPtr tmp; 1009ed6184dfSmrg 1010ed6184dfSmrg LogMessage(X_INFO, "Printing all currently active device grabs:\n"); 1011ed6184dfSmrg for (tmp = inputInfo.devices; tmp; tmp = tmp->next) 1012ed6184dfSmrg if (tmp->deviceGrab.grab) 1013ed6184dfSmrg PrintDeviceGrabInfo(tmp); 1014ed6184dfSmrg LogMessage(X_INFO, "End list of active device grabs\n"); 1015ed6184dfSmrg 1016ed6184dfSmrg PrintPassiveGrabs(); 1017ed6184dfSmrg } 1018ed6184dfSmrg else if (strcasecmp(msgbuf, "ungrab") == 0) { 1019ed6184dfSmrg LogMessage(X_INFO, "Ungrabbing devices\n"); 1020ed6184dfSmrg UngrabAllDevices(FALSE); 1021ed6184dfSmrg } 1022ed6184dfSmrg else if (strcasecmp(msgbuf, "clsgrb") == 0) { 1023ed6184dfSmrg LogMessage(X_INFO, "Clear grabs\n"); 1024ed6184dfSmrg UngrabAllDevices(TRUE); 1025ed6184dfSmrg } 1026ed6184dfSmrg else if (strcasecmp(msgbuf, "prwins") == 0) { 1027ed6184dfSmrg LogMessage(X_INFO, "Printing window tree\n"); 1028ed6184dfSmrg PrintWindowTree(); 1029ed6184dfSmrg } 1030ed6184dfSmrg } 1031ed6184dfSmrg 1032ed6184dfSmrg return XkbDDXPrivate(dev, keycode, pAction); 1033ed6184dfSmrg} 1034ed6184dfSmrg 103505b261ecSmrgstatic int 103635c4bbdfSmrg_XkbFilterXF86Private(XkbSrvInfoPtr xkbi, 103735c4bbdfSmrg XkbFilterPtr filter, unsigned keycode, XkbAction *pAction) 103805b261ecSmrg{ 103905b261ecSmrg DeviceIntPtr dev = xkbi->device; 104035c4bbdfSmrg 104105b261ecSmrg if (dev == inputInfo.keyboard) 104205b261ecSmrg return 0; 104305b261ecSmrg 104435c4bbdfSmrg if (filter->keycode == 0) { /* initial press */ 104535c4bbdfSmrg filter->keycode = keycode; 104635c4bbdfSmrg filter->active = 1; 104735c4bbdfSmrg filter->filterOthers = 0; 104835c4bbdfSmrg filter->filter = _XkbFilterXF86Private; 1049ed6184dfSmrg XkbHandlePrivate(dev, keycode, pAction); 105035c4bbdfSmrg return 0; 105105b261ecSmrg } 105235c4bbdfSmrg else if (filter->keycode == keycode) { 105335c4bbdfSmrg filter->active = 0; 105435c4bbdfSmrg return 0; 105505b261ecSmrg } 105605b261ecSmrg return 1; 105705b261ecSmrg} 105805b261ecSmrg 105905b261ecSmrgstatic int 106035c4bbdfSmrg_XkbFilterDeviceBtn(XkbSrvInfoPtr xkbi, 106135c4bbdfSmrg XkbFilterPtr filter, unsigned keycode, XkbAction *pAction) 106205b261ecSmrg{ 10634642e01fSmrg if (xkbi->device == inputInfo.keyboard) 106405b261ecSmrg return 0; 106505b261ecSmrg 106635c4bbdfSmrg if (filter->keycode == 0) { /* initial press */ 106735c4bbdfSmrg DeviceIntPtr dev; 106835c4bbdfSmrg int button; 106935c4bbdfSmrg 107035c4bbdfSmrg _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient, 107135c4bbdfSmrg DixUnknownAccess, &button); 107235c4bbdfSmrg if (!dev || !dev->public.on) 107335c4bbdfSmrg return 1; 107435c4bbdfSmrg 107535c4bbdfSmrg button = pAction->devbtn.button; 107635c4bbdfSmrg if ((button < 1) || (button > dev->button->numButtons)) 107735c4bbdfSmrg return 1; 107835c4bbdfSmrg 107935c4bbdfSmrg filter->keycode = keycode; 108035c4bbdfSmrg filter->active = 1; 108135c4bbdfSmrg filter->filterOthers = 0; 108235c4bbdfSmrg filter->priv = 0; 108335c4bbdfSmrg filter->filter = _XkbFilterDeviceBtn; 108435c4bbdfSmrg filter->upAction = *pAction; 108535c4bbdfSmrg switch (pAction->type) { 108635c4bbdfSmrg case XkbSA_LockDeviceBtn: 108735c4bbdfSmrg if ((pAction->devbtn.flags & XkbSA_LockNoLock) || 108835c4bbdfSmrg BitIsOn(dev->button->down, button)) 108935c4bbdfSmrg return 0; 109035c4bbdfSmrg XkbFakeDeviceButton(dev, TRUE, button); 109135c4bbdfSmrg filter->upAction.type = XkbSA_NoAction; 109235c4bbdfSmrg break; 109335c4bbdfSmrg case XkbSA_DeviceBtn: 109435c4bbdfSmrg if (pAction->devbtn.count > 0) { 109535c4bbdfSmrg int nClicks, i; 109635c4bbdfSmrg 109735c4bbdfSmrg nClicks = pAction->btn.count; 109835c4bbdfSmrg for (i = 0; i < nClicks; i++) { 109935c4bbdfSmrg XkbFakeDeviceButton(dev, TRUE, button); 110035c4bbdfSmrg XkbFakeDeviceButton(dev, FALSE, button); 110135c4bbdfSmrg } 110235c4bbdfSmrg filter->upAction.type = XkbSA_NoAction; 110335c4bbdfSmrg } 110435c4bbdfSmrg else 110535c4bbdfSmrg XkbFakeDeviceButton(dev, TRUE, button); 110635c4bbdfSmrg break; 110735c4bbdfSmrg } 110805b261ecSmrg } 110935c4bbdfSmrg else if (filter->keycode == keycode) { 111035c4bbdfSmrg DeviceIntPtr dev; 111135c4bbdfSmrg int button; 111235c4bbdfSmrg 111335c4bbdfSmrg filter->active = 0; 111435c4bbdfSmrg _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device, 111535c4bbdfSmrg serverClient, DixUnknownAccess, &button); 111635c4bbdfSmrg if (!dev || !dev->public.on) 111735c4bbdfSmrg return 1; 111835c4bbdfSmrg 111935c4bbdfSmrg button = filter->upAction.btn.button; 112035c4bbdfSmrg switch (filter->upAction.type) { 112135c4bbdfSmrg case XkbSA_LockDeviceBtn: 112235c4bbdfSmrg if ((filter->upAction.devbtn.flags & XkbSA_LockNoUnlock) || 112335c4bbdfSmrg !BitIsOn(dev->button->down, button)) 112435c4bbdfSmrg return 0; 112535c4bbdfSmrg XkbFakeDeviceButton(dev, FALSE, button); 112635c4bbdfSmrg break; 112735c4bbdfSmrg case XkbSA_DeviceBtn: 112835c4bbdfSmrg XkbFakeDeviceButton(dev, FALSE, button); 112935c4bbdfSmrg break; 113035c4bbdfSmrg } 113135c4bbdfSmrg filter->active = 0; 113205b261ecSmrg } 113305b261ecSmrg return 0; 113405b261ecSmrg} 113505b261ecSmrg 113605b261ecSmrgstatic XkbFilterPtr 113735c4bbdfSmrg_XkbNextFreeFilter(XkbSrvInfoPtr xkbi) 113805b261ecSmrg{ 113935c4bbdfSmrg register int i; 114005b261ecSmrg 114135c4bbdfSmrg if (xkbi->szFilters == 0) { 114235c4bbdfSmrg xkbi->szFilters = 4; 114335c4bbdfSmrg xkbi->filters = calloc(xkbi->szFilters, sizeof(XkbFilterRec)); 114435c4bbdfSmrg /* 6/21/93 (ef) -- XXX! deal with allocation failure */ 114505b261ecSmrg } 114635c4bbdfSmrg for (i = 0; i < xkbi->szFilters; i++) { 114735c4bbdfSmrg if (!xkbi->filters[i].active) { 114835c4bbdfSmrg xkbi->filters[i].keycode = 0; 114935c4bbdfSmrg return &xkbi->filters[i]; 115035c4bbdfSmrg } 115105b261ecSmrg } 115235c4bbdfSmrg xkbi->szFilters *= 2; 115335c4bbdfSmrg xkbi->filters = reallocarray(xkbi->filters, 115435c4bbdfSmrg xkbi->szFilters, sizeof(XkbFilterRec)); 115505b261ecSmrg /* 6/21/93 (ef) -- XXX! deal with allocation failure */ 115635c4bbdfSmrg memset(&xkbi->filters[xkbi->szFilters / 2], 0, 115735c4bbdfSmrg (xkbi->szFilters / 2) * sizeof(XkbFilterRec)); 115835c4bbdfSmrg return &xkbi->filters[xkbi->szFilters / 2]; 115905b261ecSmrg} 116005b261ecSmrg 116105b261ecSmrgstatic int 116235c4bbdfSmrg_XkbApplyFilters(XkbSrvInfoPtr xkbi, unsigned kc, XkbAction *pAction) 116305b261ecSmrg{ 116435c4bbdfSmrg register int i, send; 116535c4bbdfSmrg 116635c4bbdfSmrg send = 1; 116735c4bbdfSmrg for (i = 0; i < xkbi->szFilters; i++) { 116835c4bbdfSmrg if ((xkbi->filters[i].active) && (xkbi->filters[i].filter)) 116935c4bbdfSmrg send = 117035c4bbdfSmrg ((*xkbi->filters[i].filter) (xkbi, &xkbi->filters[i], kc, 117135c4bbdfSmrg pAction) 117235c4bbdfSmrg && send); 117305b261ecSmrg } 117405b261ecSmrg return send; 117505b261ecSmrg} 117605b261ecSmrg 117735c4bbdfSmrgstatic int 117835c4bbdfSmrg_XkbEnsureStateChange(XkbSrvInfoPtr xkbi) 117905b261ecSmrg{ 118035c4bbdfSmrg Bool genStateNotify = FALSE; 118135c4bbdfSmrg 118205b261ecSmrg /* The state may change, so if we're not in the middle of sending a state 118305b261ecSmrg * notify, prepare for it */ 118435c4bbdfSmrg if ((xkbi->flags & _XkbStateNotifyInProgress) == 0) { 118535c4bbdfSmrg xkbi->prev_state = xkbi->state; 118635c4bbdfSmrg xkbi->flags |= _XkbStateNotifyInProgress; 118735c4bbdfSmrg genStateNotify = TRUE; 118805b261ecSmrg } 118935c4bbdfSmrg 119035c4bbdfSmrg return genStateNotify; 119135c4bbdfSmrg} 119235c4bbdfSmrg 119335c4bbdfSmrgstatic void 119435c4bbdfSmrg_XkbApplyState(DeviceIntPtr dev, Bool genStateNotify, int evtype, int key) 119535c4bbdfSmrg{ 119635c4bbdfSmrg XkbSrvInfoPtr xkbi = dev->key->xkbInfo; 119735c4bbdfSmrg int changed; 119835c4bbdfSmrg 119935c4bbdfSmrg XkbComputeDerivedState(xkbi); 120035c4bbdfSmrg 120135c4bbdfSmrg changed = XkbStateChangedFlags(&xkbi->prev_state, &xkbi->state); 120235c4bbdfSmrg if (genStateNotify) { 120335c4bbdfSmrg if (changed) { 120435c4bbdfSmrg xkbStateNotify sn; 120535c4bbdfSmrg 120635c4bbdfSmrg sn.keycode = key; 120735c4bbdfSmrg sn.eventType = evtype; 120835c4bbdfSmrg sn.requestMajor = sn.requestMinor = 0; 120935c4bbdfSmrg sn.changed = changed; 121035c4bbdfSmrg XkbSendStateNotify(dev, &sn); 121135c4bbdfSmrg } 121235c4bbdfSmrg xkbi->flags &= ~_XkbStateNotifyInProgress; 121335c4bbdfSmrg } 121435c4bbdfSmrg 121535c4bbdfSmrg changed = XkbIndicatorsToUpdate(dev, changed, FALSE); 121635c4bbdfSmrg if (changed) { 121735c4bbdfSmrg XkbEventCauseRec cause; 121835c4bbdfSmrg XkbSetCauseKey(&cause, key, evtype); 121935c4bbdfSmrg XkbUpdateIndicators(dev, changed, FALSE, NULL, &cause); 122035c4bbdfSmrg } 122135c4bbdfSmrg} 122235c4bbdfSmrg 122335c4bbdfSmrgvoid 122435c4bbdfSmrgXkbPushLockedStateToSlaves(DeviceIntPtr master, int evtype, int key) 122535c4bbdfSmrg{ 122635c4bbdfSmrg DeviceIntPtr dev; 122735c4bbdfSmrg Bool genStateNotify; 122835c4bbdfSmrg 122935c4bbdfSmrg nt_list_for_each_entry(dev, inputInfo.devices, next) { 123035c4bbdfSmrg if (!dev->key || GetMaster(dev, MASTER_KEYBOARD) != master) 123135c4bbdfSmrg continue; 123235c4bbdfSmrg 123335c4bbdfSmrg genStateNotify = _XkbEnsureStateChange(dev->key->xkbInfo); 123435c4bbdfSmrg 123535c4bbdfSmrg dev->key->xkbInfo->state.locked_mods = 123635c4bbdfSmrg master->key->xkbInfo->state.locked_mods; 123735c4bbdfSmrg 123835c4bbdfSmrg _XkbApplyState(dev, genStateNotify, evtype, key); 123935c4bbdfSmrg } 124035c4bbdfSmrg} 124135c4bbdfSmrg 12421b5d61b8Smrgstatic void 12431b5d61b8SmrgXkbActionGetFilter(DeviceIntPtr dev, DeviceEvent *event, KeyCode key, 12441b5d61b8Smrg XkbAction *act, int *sendEvent) 12451b5d61b8Smrg{ 12461b5d61b8Smrg XkbSrvInfoPtr xkbi = dev->key->xkbInfo; 12471b5d61b8Smrg XkbFilterPtr filter; 12481b5d61b8Smrg 12491b5d61b8Smrg /* For focus events, we only want to run actions which update our state to 12501b5d61b8Smrg * (hopefully vaguely kinda) match that of the host server, rather than 12511b5d61b8Smrg * actually execute anything. For example, if we enter our VT with 12521b5d61b8Smrg * Ctrl+Alt+Backspace held down, we don't want to terminate our server 12531b5d61b8Smrg * immediately, but we _do_ want Ctrl+Alt to be latched down, so if 12541b5d61b8Smrg * Backspace is released and then pressed again, the server will terminate. 12551b5d61b8Smrg * 12561b5d61b8Smrg * This is pretty flaky, and we should in fact inherit the complete state 12571b5d61b8Smrg * from the host server. There are some state combinations that we cannot 12581b5d61b8Smrg * express by running the state machine over every key, e.g. if AltGr+Shift 12591b5d61b8Smrg * generates a different state to Shift+AltGr. */ 12601b5d61b8Smrg if (event->source_type == EVENT_SOURCE_FOCUS) { 12611b5d61b8Smrg switch (act->type) { 12621b5d61b8Smrg case XkbSA_SetMods: 12631b5d61b8Smrg case XkbSA_SetGroup: 12641b5d61b8Smrg case XkbSA_LatchMods: 12651b5d61b8Smrg case XkbSA_LatchGroup: 12661b5d61b8Smrg case XkbSA_LockMods: 12671b5d61b8Smrg case XkbSA_LockGroup: 12681b5d61b8Smrg break; 12691b5d61b8Smrg default: 12701b5d61b8Smrg *sendEvent = 1; 12711b5d61b8Smrg return; 12721b5d61b8Smrg } 12731b5d61b8Smrg } 12741b5d61b8Smrg 12751b5d61b8Smrg switch (act->type) { 12761b5d61b8Smrg case XkbSA_SetMods: 12771b5d61b8Smrg case XkbSA_SetGroup: 12781b5d61b8Smrg filter = _XkbNextFreeFilter(xkbi); 12791b5d61b8Smrg *sendEvent = _XkbFilterSetState(xkbi, filter, key, act); 12801b5d61b8Smrg break; 12811b5d61b8Smrg case XkbSA_LatchMods: 12821b5d61b8Smrg case XkbSA_LatchGroup: 12831b5d61b8Smrg filter = _XkbNextFreeFilter(xkbi); 12841b5d61b8Smrg *sendEvent = _XkbFilterLatchState(xkbi, filter, key, act); 12851b5d61b8Smrg break; 12861b5d61b8Smrg case XkbSA_LockMods: 12871b5d61b8Smrg case XkbSA_LockGroup: 12881b5d61b8Smrg filter = _XkbNextFreeFilter(xkbi); 12891b5d61b8Smrg *sendEvent = _XkbFilterLockState(xkbi, filter, key, act); 12901b5d61b8Smrg break; 12911b5d61b8Smrg case XkbSA_ISOLock: 12921b5d61b8Smrg filter = _XkbNextFreeFilter(xkbi); 12931b5d61b8Smrg *sendEvent = _XkbFilterISOLock(xkbi, filter, key, act); 12941b5d61b8Smrg break; 12951b5d61b8Smrg case XkbSA_MovePtr: 12961b5d61b8Smrg filter = _XkbNextFreeFilter(xkbi); 12971b5d61b8Smrg *sendEvent = _XkbFilterPointerMove(xkbi, filter, key, act); 12981b5d61b8Smrg break; 12991b5d61b8Smrg case XkbSA_PtrBtn: 13001b5d61b8Smrg case XkbSA_LockPtrBtn: 13011b5d61b8Smrg case XkbSA_SetPtrDflt: 13021b5d61b8Smrg filter = _XkbNextFreeFilter(xkbi); 13031b5d61b8Smrg *sendEvent = _XkbFilterPointerBtn(xkbi, filter, key, act); 13041b5d61b8Smrg break; 13051b5d61b8Smrg case XkbSA_Terminate: 13061b5d61b8Smrg *sendEvent = XkbDDXTerminateServer(dev, key, act); 13071b5d61b8Smrg break; 13081b5d61b8Smrg case XkbSA_SwitchScreen: 13091b5d61b8Smrg filter = _XkbNextFreeFilter(xkbi); 13101b5d61b8Smrg *sendEvent = _XkbFilterSwitchScreen(xkbi, filter, key, act); 13111b5d61b8Smrg break; 13121b5d61b8Smrg case XkbSA_SetControls: 13131b5d61b8Smrg case XkbSA_LockControls: 13141b5d61b8Smrg filter = _XkbNextFreeFilter(xkbi); 13151b5d61b8Smrg *sendEvent = _XkbFilterControls(xkbi, filter, key, act); 13161b5d61b8Smrg break; 13171b5d61b8Smrg case XkbSA_ActionMessage: 13181b5d61b8Smrg filter = _XkbNextFreeFilter(xkbi); 13191b5d61b8Smrg *sendEvent = _XkbFilterActionMessage(xkbi, filter, key, act); 13201b5d61b8Smrg break; 13211b5d61b8Smrg case XkbSA_RedirectKey: 13221b5d61b8Smrg filter = _XkbNextFreeFilter(xkbi); 13231b5d61b8Smrg /* redirect actions must create a new DeviceEvent. The 13241b5d61b8Smrg * source device id for this event cannot be obtained from 13251b5d61b8Smrg * xkbi, so we pass it here explicitly. The field deviceid 13261b5d61b8Smrg * equals to xkbi->device->id. */ 13271b5d61b8Smrg filter->priv = event->sourceid; 13281b5d61b8Smrg *sendEvent = _XkbFilterRedirectKey(xkbi, filter, key, act); 13291b5d61b8Smrg break; 13301b5d61b8Smrg case XkbSA_DeviceBtn: 13311b5d61b8Smrg case XkbSA_LockDeviceBtn: 13321b5d61b8Smrg filter = _XkbNextFreeFilter(xkbi); 13331b5d61b8Smrg *sendEvent = _XkbFilterDeviceBtn(xkbi, filter, key, act); 13341b5d61b8Smrg break; 13351b5d61b8Smrg case XkbSA_XFree86Private: 13361b5d61b8Smrg filter = _XkbNextFreeFilter(xkbi); 13371b5d61b8Smrg *sendEvent = _XkbFilterXF86Private(xkbi, filter, key, act); 13381b5d61b8Smrg break; 13391b5d61b8Smrg } 13401b5d61b8Smrg} 13411b5d61b8Smrg 134235c4bbdfSmrgvoid 134335c4bbdfSmrgXkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event) 134435c4bbdfSmrg{ 134535c4bbdfSmrg int key, bit, i; 134635c4bbdfSmrg XkbSrvInfoPtr xkbi; 134735c4bbdfSmrg KeyClassPtr keyc; 134835c4bbdfSmrg int sendEvent; 134935c4bbdfSmrg Bool genStateNotify; 135035c4bbdfSmrg XkbAction act; 135135c4bbdfSmrg Bool keyEvent; 135235c4bbdfSmrg Bool pressEvent; 135335c4bbdfSmrg ProcessInputProc backupproc; 135435c4bbdfSmrg 135535c4bbdfSmrg xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev); 135635c4bbdfSmrg 135735c4bbdfSmrg keyc = kbd->key; 135835c4bbdfSmrg xkbi = keyc->xkbInfo; 135935c4bbdfSmrg key = event->detail.key; 136035c4bbdfSmrg 136135c4bbdfSmrg genStateNotify = _XkbEnsureStateChange(xkbi); 136205b261ecSmrg 136305b261ecSmrg xkbi->clearMods = xkbi->setMods = 0; 136405b261ecSmrg xkbi->groupChange = 0; 136505b261ecSmrg 136605b261ecSmrg sendEvent = 1; 136735c4bbdfSmrg keyEvent = ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease)); 136835c4bbdfSmrg pressEvent = ((event->type == ET_KeyPress) || 136935c4bbdfSmrg (event->type == ET_ButtonPress)); 137005b261ecSmrg 137105b261ecSmrg if (pressEvent) { 137235c4bbdfSmrg if (keyEvent) 137335c4bbdfSmrg act = XkbGetKeyAction(xkbi, &xkbi->state, key); 137435c4bbdfSmrg else { 137535c4bbdfSmrg act = XkbGetButtonAction(kbd, dev, key); 137635c4bbdfSmrg key |= BTN_ACT_FLAG; 137735c4bbdfSmrg } 13781b5d61b8Smrg 137935c4bbdfSmrg sendEvent = _XkbApplyFilters(xkbi, key, &act); 13801b5d61b8Smrg if (sendEvent) 13811b5d61b8Smrg XkbActionGetFilter(dev, event, key, &act, &sendEvent); 138205b261ecSmrg } 138305b261ecSmrg else { 138435c4bbdfSmrg if (!keyEvent) 138535c4bbdfSmrg key |= BTN_ACT_FLAG; 138635c4bbdfSmrg sendEvent = _XkbApplyFilters(xkbi, key, NULL); 138705b261ecSmrg } 138805b261ecSmrg 138935c4bbdfSmrg if (xkbi->groupChange != 0) 139035c4bbdfSmrg xkbi->state.base_group += xkbi->groupChange; 139105b261ecSmrg if (xkbi->setMods) { 139235c4bbdfSmrg for (i = 0, bit = 1; xkbi->setMods; i++, bit <<= 1) { 139335c4bbdfSmrg if (xkbi->setMods & bit) { 139435c4bbdfSmrg keyc->modifierKeyCount[i]++; 139535c4bbdfSmrg xkbi->state.base_mods |= bit; 139635c4bbdfSmrg xkbi->setMods &= ~bit; 139735c4bbdfSmrg } 139835c4bbdfSmrg } 139905b261ecSmrg } 140005b261ecSmrg if (xkbi->clearMods) { 140135c4bbdfSmrg for (i = 0, bit = 1; xkbi->clearMods; i++, bit <<= 1) { 140235c4bbdfSmrg if (xkbi->clearMods & bit) { 140335c4bbdfSmrg keyc->modifierKeyCount[i]--; 140435c4bbdfSmrg if (keyc->modifierKeyCount[i] <= 0) { 140535c4bbdfSmrg xkbi->state.base_mods &= ~bit; 140635c4bbdfSmrg keyc->modifierKeyCount[i] = 0; 140735c4bbdfSmrg } 140835c4bbdfSmrg xkbi->clearMods &= ~bit; 140935c4bbdfSmrg } 141035c4bbdfSmrg } 141105b261ecSmrg } 141205b261ecSmrg 141305b261ecSmrg if (sendEvent) { 14144642e01fSmrg DeviceIntPtr tmpdev; 141535c4bbdfSmrg 141635c4bbdfSmrg if (keyEvent) 14174642e01fSmrg tmpdev = dev; 14186747b715Smrg else 141935c4bbdfSmrg tmpdev = GetMaster(dev, POINTER_OR_FLOAT); 142005b261ecSmrg 142135c4bbdfSmrg UNWRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr, backupproc); 142235c4bbdfSmrg dev->public.processInputProc((InternalEvent *) event, tmpdev); 14234642e01fSmrg COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr, 142435c4bbdfSmrg backupproc, xkbUnwrapProc); 142505b261ecSmrg } 142605b261ecSmrg else if (keyEvent) { 142735c4bbdfSmrg FixKeyState(event, dev); 142805b261ecSmrg } 142905b261ecSmrg 143035c4bbdfSmrg _XkbApplyState(dev, genStateNotify, event->type, key); 143135c4bbdfSmrg XkbPushLockedStateToSlaves(dev, event->type, key); 143205b261ecSmrg} 143305b261ecSmrg 143405b261ecSmrgint 143535c4bbdfSmrgXkbLatchModifiers(DeviceIntPtr pXDev, CARD8 mask, CARD8 latches) 143605b261ecSmrg{ 143735c4bbdfSmrg XkbSrvInfoPtr xkbi; 143835c4bbdfSmrg XkbFilterPtr filter; 143935c4bbdfSmrg XkbAction act; 144035c4bbdfSmrg unsigned clear; 144135c4bbdfSmrg 144235c4bbdfSmrg if (pXDev && pXDev->key && pXDev->key->xkbInfo) { 144335c4bbdfSmrg xkbi = pXDev->key->xkbInfo; 144435c4bbdfSmrg clear = (mask & (~latches)); 144535c4bbdfSmrg xkbi->state.latched_mods &= ~clear; 144635c4bbdfSmrg /* Clear any pending latch to locks. 144735c4bbdfSmrg */ 144835c4bbdfSmrg act.type = XkbSA_NoAction; 144935c4bbdfSmrg _XkbApplyFilters(xkbi, SYNTHETIC_KEYCODE, &act); 145035c4bbdfSmrg act.type = XkbSA_LatchMods; 145135c4bbdfSmrg act.mods.flags = 0; 145235c4bbdfSmrg act.mods.mask = mask & latches; 145335c4bbdfSmrg filter = _XkbNextFreeFilter(xkbi); 145435c4bbdfSmrg _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, &act); 145535c4bbdfSmrg _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, 145635c4bbdfSmrg (XkbAction *) NULL); 145735c4bbdfSmrg return Success; 145805b261ecSmrg } 145905b261ecSmrg return BadValue; 146005b261ecSmrg} 146105b261ecSmrg 146205b261ecSmrgint 146335c4bbdfSmrgXkbLatchGroup(DeviceIntPtr pXDev, int group) 146405b261ecSmrg{ 146535c4bbdfSmrg XkbSrvInfoPtr xkbi; 146635c4bbdfSmrg XkbFilterPtr filter; 146735c4bbdfSmrg XkbAction act; 146835c4bbdfSmrg 146935c4bbdfSmrg if (pXDev && pXDev->key && pXDev->key->xkbInfo) { 147035c4bbdfSmrg xkbi = pXDev->key->xkbInfo; 147135c4bbdfSmrg act.type = XkbSA_LatchGroup; 147235c4bbdfSmrg act.group.flags = 0; 147335c4bbdfSmrg XkbSASetGroup(&act.group, group); 147435c4bbdfSmrg filter = _XkbNextFreeFilter(xkbi); 147535c4bbdfSmrg _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, &act); 147635c4bbdfSmrg _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, 147735c4bbdfSmrg (XkbAction *) NULL); 147835c4bbdfSmrg return Success; 147905b261ecSmrg } 148005b261ecSmrg return BadValue; 148105b261ecSmrg} 148205b261ecSmrg 148305b261ecSmrg/***====================================================================***/ 148405b261ecSmrg 148505b261ecSmrgvoid 148635c4bbdfSmrgXkbClearAllLatchesAndLocks(DeviceIntPtr dev, 148735c4bbdfSmrg XkbSrvInfoPtr xkbi, 148835c4bbdfSmrg Bool genEv, XkbEventCausePtr cause) 148905b261ecSmrg{ 149035c4bbdfSmrg XkbStateRec os; 149135c4bbdfSmrg xkbStateNotify sn; 149235c4bbdfSmrg 149335c4bbdfSmrg sn.changed = 0; 149435c4bbdfSmrg os = xkbi->state; 149535c4bbdfSmrg if (os.latched_mods) { /* clear all latches */ 149635c4bbdfSmrg XkbLatchModifiers(dev, ~0, 0); 149735c4bbdfSmrg sn.changed |= XkbModifierLatchMask; 149805b261ecSmrg } 149905b261ecSmrg if (os.latched_group) { 150035c4bbdfSmrg XkbLatchGroup(dev, 0); 150135c4bbdfSmrg sn.changed |= XkbGroupLatchMask; 150205b261ecSmrg } 150305b261ecSmrg if (os.locked_mods) { 150435c4bbdfSmrg xkbi->state.locked_mods = 0; 150535c4bbdfSmrg sn.changed |= XkbModifierLockMask; 150605b261ecSmrg } 150705b261ecSmrg if (os.locked_group) { 150835c4bbdfSmrg xkbi->state.locked_group = 0; 150935c4bbdfSmrg sn.changed |= XkbGroupLockMask; 151005b261ecSmrg } 151135c4bbdfSmrg if (genEv && sn.changed) { 151235c4bbdfSmrg CARD32 changed; 151335c4bbdfSmrg 151435c4bbdfSmrg XkbComputeDerivedState(xkbi); 151535c4bbdfSmrg sn.keycode = cause->kc; 151635c4bbdfSmrg sn.eventType = cause->event; 151735c4bbdfSmrg sn.requestMajor = cause->mjr; 151835c4bbdfSmrg sn.requestMinor = cause->mnr; 151935c4bbdfSmrg sn.changed = XkbStateChangedFlags(&os, &xkbi->state); 152035c4bbdfSmrg XkbSendStateNotify(dev, &sn); 152135c4bbdfSmrg changed = XkbIndicatorsToUpdate(dev, sn.changed, FALSE); 152235c4bbdfSmrg if (changed) { 152335c4bbdfSmrg XkbUpdateIndicators(dev, changed, TRUE, NULL, cause); 152435c4bbdfSmrg } 152505b261ecSmrg } 152605b261ecSmrg return; 152705b261ecSmrg} 152805b261ecSmrg 15296747b715Smrg/* 15306747b715Smrg * The event is injected into the event processing, not the EQ. Thus, 15316747b715Smrg * ensure that we restore the master after the event sequence to the 15326747b715Smrg * original set of classes. Otherwise, the master remains on the XTEST 15336747b715Smrg * classes and drops events that don't fit into the XTEST layout (e.g. 15346747b715Smrg * events with more than 2 valuators). 15356747b715Smrg * 15366747b715Smrg * FIXME: EQ injection in the processing stage is not designed for, so this 15376747b715Smrg * is a rather awkward hack. The event list returned by GetPointerEvents() 15386747b715Smrg * and friends is always prefixed with a DCE if the last _posted_ device was 15396747b715Smrg * different. For normal events, this sequence then resets the master during 15406747b715Smrg * the processing stage. Since we inject the PointerKey events in the 15416747b715Smrg * processing stage though, we need to manually reset to restore the 15426747b715Smrg * previous order, because the events already in the EQ must be sent for the 15436747b715Smrg * right device. 15446747b715Smrg * So we post-fix the event list we get from GPE with a DCE back to the 15456747b715Smrg * previous slave device. 15466747b715Smrg * 15476747b715Smrg * First one on drinking island wins! 15486747b715Smrg */ 15496747b715Smrgstatic void 155035c4bbdfSmrgInjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, 155135c4bbdfSmrg ValuatorMask *mask) 15526747b715Smrg{ 155335c4bbdfSmrg ScreenPtr pScreen; 155435c4bbdfSmrg InternalEvent *events; 155535c4bbdfSmrg int nevents, i; 155635c4bbdfSmrg DeviceIntPtr ptr, mpointer, lastSlave = NULL; 155735c4bbdfSmrg Bool saveWait; 15586747b715Smrg 15596747b715Smrg if (IsMaster(dev)) { 15606747b715Smrg mpointer = GetMaster(dev, MASTER_POINTER); 156135c4bbdfSmrg lastSlave = mpointer->lastSlave; 15626747b715Smrg ptr = GetXTestDevice(mpointer); 156335c4bbdfSmrg } 156435c4bbdfSmrg else if (IsFloating(dev)) 15656747b715Smrg ptr = dev; 15666747b715Smrg else 15676747b715Smrg return; 15686747b715Smrg 15696747b715Smrg events = InitEventList(GetMaximumEventsNum() + 1); 15701b5d61b8Smrg input_lock(); 15716747b715Smrg pScreen = miPointerGetScreen(ptr); 15726747b715Smrg saveWait = miPointerSetWaitForUpdate(pScreen, FALSE); 15739ace9065Smrg nevents = GetPointerEvents(events, ptr, type, button, flags, mask); 15746747b715Smrg if (IsMaster(dev) && (lastSlave && lastSlave != ptr)) 157535c4bbdfSmrg UpdateFromMaster(&events[nevents], lastSlave, DEVCHANGE_POINTER_EVENT, 157635c4bbdfSmrg &nevents); 15776747b715Smrg miPointerSetWaitForUpdate(pScreen, saveWait); 15786747b715Smrg 15796747b715Smrg for (i = 0; i < nevents; i++) 158035c4bbdfSmrg mieqProcessDeviceEvent(ptr, &events[i], NULL); 15811b5d61b8Smrg input_unlock(); 15826747b715Smrg 15836747b715Smrg FreeEventList(events, GetMaximumEventsNum()); 15846747b715Smrg} 15856747b715Smrg 15866747b715Smrgstatic void 158735c4bbdfSmrgXkbFakePointerMotion(DeviceIntPtr dev, unsigned flags, int x, int y) 15886747b715Smrg{ 158935c4bbdfSmrg ValuatorMask mask; 159035c4bbdfSmrg int gpe_flags = 0; 15916747b715Smrg 15926747b715Smrg /* ignore attached SDs */ 159335c4bbdfSmrg if (!IsMaster(dev) && !IsFloating(dev)) 15946747b715Smrg return; 15956747b715Smrg 15966747b715Smrg if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY) 15976747b715Smrg gpe_flags = POINTER_ABSOLUTE; 15986747b715Smrg else 15996747b715Smrg gpe_flags = POINTER_RELATIVE; 16006747b715Smrg 160135c4bbdfSmrg valuator_mask_set_range(&mask, 0, 2, (int[]) { 160235c4bbdfSmrg x, y}); 16039ace9065Smrg 16049ace9065Smrg InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, &mask); 16056747b715Smrg} 16066747b715Smrg 16076747b715Smrgvoid 160835c4bbdfSmrgXkbFakeDeviceButton(DeviceIntPtr dev, Bool press, int button) 16096747b715Smrg{ 161035c4bbdfSmrg DeviceIntPtr ptr; 161135c4bbdfSmrg int down; 16126747b715Smrg 16136747b715Smrg /* If dev is a slave device, and the SD is attached, do nothing. If we'd 16146747b715Smrg * post through the attached master pointer we'd get duplicate events. 16156747b715Smrg * 16166747b715Smrg * if dev is a master keyboard, post through the XTEST device 16176747b715Smrg * 16186747b715Smrg * if dev is a floating slave, post through the device itself. 16196747b715Smrg */ 16206747b715Smrg 16216747b715Smrg if (IsMaster(dev)) { 16226747b715Smrg DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER); 162335c4bbdfSmrg 16246747b715Smrg ptr = GetXTestDevice(mpointer); 162535c4bbdfSmrg } 162635c4bbdfSmrg else if (IsFloating(dev)) 16276747b715Smrg ptr = dev; 16286747b715Smrg else 16296747b715Smrg return; 16306747b715Smrg 16316747b715Smrg down = button_is_down(ptr, button, BUTTON_PROCESSED); 16326747b715Smrg if (press == down) 16336747b715Smrg return; 16346747b715Smrg 16356747b715Smrg InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease, 16369ace9065Smrg button, 0, NULL); 16376747b715Smrg} 1638