123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557 |
- /************************************************************
- Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
- Permission to use, copy, modify, and distribute this
- software and its documentation for any purpose and without
- fee is hereby granted, provided that the above copyright
- notice appear in all copies and that both that copyright
- notice and this permission notice appear in supporting
- documentation, and that the name of Silicon Graphics not be
- used in advertising or publicity pertaining to distribution
- of the software without specific prior written permission.
- Silicon Graphics makes no representation about the suitability
- of this software for any purpose. It is provided "as is"
- without any express or implied warranty.
- SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
- THE USE OR PERFORMANCE OF THIS SOFTWARE.
- ********************************************************/
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #include <stdio.h>
- #include <math.h>
- #include <X11/X.h>
- #include <X11/Xproto.h>
- #include <X11/keysym.h>
- #include "misc.h"
- #include "inputstr.h"
- #include "exevents.h"
- #include "eventstr.h"
- #include <xkbsrv.h>
- #include "xkb.h"
- #include <ctype.h>
- #include "mi.h"
- #include "mipointer.h"
- #include "inpututils.h"
- #define EXTENSION_EVENT_BASE 64
- DevPrivateKeyRec xkbDevicePrivateKeyRec;
- static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags, int x,
- int y);
- void
- xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, void *data)
- {
- xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
- ProcessInputProc backupproc;
- if (xkbPrivPtr->unwrapProc)
- xkbPrivPtr->unwrapProc = NULL;
- UNWRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, backupproc);
- proc(device, data);
- COND_WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, backupproc, xkbUnwrapProc);
- }
- Bool
- XkbInitPrivates(void)
- {
- return dixRegisterPrivateKey(&xkbDevicePrivateKeyRec, PRIVATE_DEVICE,
- sizeof(xkbDeviceInfoRec));
- }
- void
- XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
- {
- xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
- WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc);
- }
- /***====================================================================***/
- static XkbAction
- _FixUpAction(XkbDescPtr xkb, XkbAction *act)
- {
- static XkbAction fake;
- if (XkbIsPtrAction(act) &&
- (!(xkb->ctrls->enabled_ctrls & XkbMouseKeysMask))) {
- fake.type = XkbSA_NoAction;
- return fake;
- }
- if (xkb->ctrls->enabled_ctrls & XkbStickyKeysMask) {
- if (act->any.type == XkbSA_SetMods) {
- fake.mods.type = XkbSA_LatchMods;
- fake.mods.mask = act->mods.mask;
- if (XkbAX_NeedOption(xkb->ctrls, XkbAX_LatchToLockMask))
- fake.mods.flags = XkbSA_ClearLocks | XkbSA_LatchToLock;
- else
- fake.mods.flags = XkbSA_ClearLocks;
- return fake;
- }
- if (act->any.type == XkbSA_SetGroup) {
- fake.group.type = XkbSA_LatchGroup;
- if (XkbAX_NeedOption(xkb->ctrls, XkbAX_LatchToLockMask))
- fake.group.flags = XkbSA_ClearLocks | XkbSA_LatchToLock;
- else
- fake.group.flags = XkbSA_ClearLocks;
- XkbSASetGroup(&fake.group, XkbSAGroup(&act->group));
- return fake;
- }
- }
- return *act;
- }
- static XkbAction
- XkbGetKeyAction(XkbSrvInfoPtr xkbi, XkbStatePtr xkbState, CARD8 key)
- {
- int effectiveGroup;
- int col;
- XkbDescPtr xkb;
- XkbKeyTypePtr type;
- XkbAction *pActs;
- static XkbAction fake;
- xkb = xkbi->desc;
- if (!XkbKeyHasActions(xkb, key) || !XkbKeycodeInRange(xkb, key)) {
- fake.type = XkbSA_NoAction;
- return fake;
- }
- pActs = XkbKeyActionsPtr(xkb, key);
- col = 0;
- effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key);
- if (effectiveGroup != XkbGroup1Index)
- col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key));
- type = XkbKeyKeyType(xkb, key, effectiveGroup);
- if (type->map != NULL) {
- register unsigned i, mods;
- register XkbKTMapEntryPtr entry;
- mods = xkbState->mods & type->mods.mask;
- for (entry = type->map, i = 0; i < type->map_count; i++, entry++) {
- if ((entry->active) && (entry->mods.mask == mods)) {
- col += entry->level;
- break;
- }
- }
- }
- if (pActs[col].any.type == XkbSA_NoAction)
- return pActs[col];
- fake = _FixUpAction(xkb, &pActs[col]);
- return fake;
- }
- static XkbAction
- XkbGetButtonAction(DeviceIntPtr kbd, DeviceIntPtr dev, int button)
- {
- XkbAction fake;
- if ((dev->button) && (dev->button->xkb_acts)) {
- if (dev->button->xkb_acts[button - 1].any.type != XkbSA_NoAction) {
- fake = _FixUpAction(kbd->key->xkbInfo->desc,
- &dev->button->xkb_acts[button - 1]);
- return fake;
- }
- }
- fake.any.type = XkbSA_NoAction;
- return fake;
- }
- /***====================================================================***/
- #define SYNTHETIC_KEYCODE 1
- #define BTN_ACT_FLAG 0x100
- static int
- _XkbFilterSetState(XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
- {
- if (filter->keycode == 0) { /* initial press */
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = ((pAction->mods.mask & XkbSA_ClearLocks) != 0);
- filter->priv = 0;
- filter->filter = _XkbFilterSetState;
- if (pAction->type == XkbSA_SetMods) {
- filter->upAction = *pAction;
- xkbi->setMods = pAction->mods.mask;
- }
- else {
- xkbi->groupChange = XkbSAGroup(&pAction->group);
- if (pAction->group.flags & XkbSA_GroupAbsolute)
- xkbi->groupChange -= xkbi->state.base_group;
- filter->upAction = *pAction;
- XkbSASetGroup(&filter->upAction.group, xkbi->groupChange);
- }
- }
- else if (filter->keycode == keycode) {
- if (filter->upAction.type == XkbSA_SetMods) {
- xkbi->clearMods = filter->upAction.mods.mask;
- if (filter->upAction.mods.flags & XkbSA_ClearLocks) {
- xkbi->state.locked_mods &= ~filter->upAction.mods.mask;
- }
- }
- else {
- if (filter->upAction.group.flags & XkbSA_ClearLocks) {
- xkbi->state.locked_group = 0;
- }
- xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
- }
- filter->active = 0;
- }
- else {
- filter->upAction.mods.flags &= ~XkbSA_ClearLocks;
- filter->filterOthers = 0;
- }
- return 1;
- }
- #define LATCH_KEY_DOWN 1
- #define LATCH_PENDING 2
- static int
- _XkbFilterLatchState(XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
- {
- if (filter->keycode == 0) { /* initial press */
- AccessXCancelRepeatKey(xkbi,keycode);
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 1;
- filter->priv = LATCH_KEY_DOWN;
- filter->filter = _XkbFilterLatchState;
- if (pAction->type == XkbSA_LatchMods) {
- filter->upAction = *pAction;
- xkbi->setMods = pAction->mods.mask;
- }
- else {
- xkbi->groupChange = XkbSAGroup(&pAction->group);
- if (pAction->group.flags & XkbSA_GroupAbsolute)
- xkbi->groupChange -= xkbi->state.base_group;
- filter->upAction = *pAction;
- XkbSASetGroup(&filter->upAction.group, xkbi->groupChange);
- }
- }
- else if (pAction && (filter->priv == LATCH_PENDING)) {
- if (((1 << pAction->type) & XkbSA_BreakLatch) != 0) {
- filter->active = 0;
- /* If one latch is broken, all latches are broken, so it's no use
- to find out which particular latch this filter tracks. */
- xkbi->state.latched_mods = 0;
- xkbi->state.latched_group = 0;
- }
- }
- else if (filter->keycode == keycode && filter->priv != LATCH_PENDING){
- /* The test above for LATCH_PENDING skips subsequent releases of the
- key after it has been released first time and the latch became
- pending. */
- XkbControlsPtr ctrls = xkbi->desc->ctrls;
- int needBeep = ((ctrls->enabled_ctrls & XkbStickyKeysMask) &&
- XkbAX_NeedFeedback(ctrls, XkbAX_StickyKeysFBMask));
- if (filter->upAction.type == XkbSA_LatchMods) {
- unsigned char mask = filter->upAction.mods.mask;
- unsigned char common;
- xkbi->clearMods = mask;
- /* ClearLocks */
- common = mask & xkbi->state.locked_mods;
- if ((filter->upAction.mods.flags & XkbSA_ClearLocks) && common) {
- mask &= ~common;
- xkbi->state.locked_mods &= ~common;
- if (needBeep)
- XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_UNLOCK,
- XkbStickyKeysMask);
- }
- /* LatchToLock */
- common = mask & xkbi->state.latched_mods;
- if ((filter->upAction.mods.flags & XkbSA_LatchToLock) && common) {
- unsigned char newlocked;
- mask &= ~common;
- newlocked = common & ~xkbi->state.locked_mods;
- if(newlocked){
- xkbi->state.locked_mods |= newlocked;
- if (needBeep)
- XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK,
- XkbStickyKeysMask);
- }
- xkbi->state.latched_mods &= ~common;
- }
- /* Latch remaining modifiers, if any. */
- if (mask) {
- xkbi->state.latched_mods |= mask;
- filter->priv = LATCH_PENDING;
- if (needBeep)
- XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LATCH,
- XkbStickyKeysMask);
- }
- }
- else {
- xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
- /* ClearLocks */
- if ((filter->upAction.group.flags & XkbSA_ClearLocks) &&
- (xkbi->state.locked_group)) {
- xkbi->state.locked_group = 0;
- if (needBeep)
- XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_UNLOCK,
- XkbStickyKeysMask);
- }
- /* LatchToLock */
- else if ((filter->upAction.group.flags & XkbSA_LatchToLock)
- && (xkbi->state.latched_group)) {
- xkbi->state.locked_group += XkbSAGroup(&filter->upAction.group);
- xkbi->state.latched_group -= XkbSAGroup(&filter->upAction.group);
- if(XkbSAGroup(&filter->upAction.group) && needBeep)
- XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK,
- XkbStickyKeysMask);
- }
- /* Latch group */
- else if(XkbSAGroup(&filter->upAction.group)){
- xkbi->state.latched_group += XkbSAGroup(&filter->upAction.group);
- filter->priv = LATCH_PENDING;
- if (needBeep)
- XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LATCH,
- XkbStickyKeysMask);
- }
- }
- if (filter->priv != LATCH_PENDING)
- filter->active = 0;
- }
- else if (pAction && (filter->priv == LATCH_KEY_DOWN)) {
- /* Latch was broken before it became pending: degrade to a
- SetMods/SetGroup. */
- if (filter->upAction.type == XkbSA_LatchMods)
- filter->upAction.type = XkbSA_SetMods;
- else
- filter->upAction.type = XkbSA_SetGroup;
- filter->filter = _XkbFilterSetState;
- filter->priv = 0;
- return filter->filter(xkbi, filter, keycode, pAction);
- }
- return 1;
- }
- static int
- _XkbFilterLockState(XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
- {
- if (pAction && (pAction->type == XkbSA_LockGroup)) {
- if (pAction->group.flags & XkbSA_GroupAbsolute)
- xkbi->state.locked_group = XkbSAGroup(&pAction->group);
- else
- xkbi->state.locked_group += XkbSAGroup(&pAction->group);
- return 1;
- }
- if (filter->keycode == 0) { /* initial press */
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- filter->priv = xkbi->state.locked_mods & pAction->mods.mask;
- filter->filter = _XkbFilterLockState;
- filter->upAction = *pAction;
- if (!(filter->upAction.mods.flags & XkbSA_LockNoLock))
- xkbi->state.locked_mods |= pAction->mods.mask;
- xkbi->setMods = pAction->mods.mask;
- }
- else if (filter->keycode == keycode) {
- filter->active = 0;
- xkbi->clearMods = filter->upAction.mods.mask;
- if (!(filter->upAction.mods.flags & XkbSA_LockNoUnlock))
- xkbi->state.locked_mods &= ~filter->priv;
- }
- return 1;
- }
- #define ISO_KEY_DOWN 0
- #define NO_ISO_LOCK 1
- static int
- _XkbFilterISOLock(XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
- {
- if (filter->keycode == 0) { /* initial press */
- CARD8 flags = pAction->iso.flags;
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 1;
- filter->priv = ISO_KEY_DOWN;
- filter->upAction = *pAction;
- filter->filter = _XkbFilterISOLock;
- if (flags & XkbSA_ISODfltIsGroup) {
- xkbi->groupChange = XkbSAGroup(&pAction->iso);
- xkbi->setMods = 0;
- }
- else {
- xkbi->setMods = pAction->iso.mask;
- xkbi->groupChange = 0;
- }
- if ((!(flags & XkbSA_ISONoAffectMods)) && (xkbi->state.base_mods)) {
- filter->priv = NO_ISO_LOCK;
- xkbi->state.locked_mods ^= xkbi->state.base_mods;
- }
- if ((!(flags & XkbSA_ISONoAffectGroup)) && (xkbi->state.base_group)) {
- /* 6/22/93 (ef) -- lock groups if group key is down first */
- }
- if (!(flags & XkbSA_ISONoAffectPtr)) {
- /* 6/22/93 (ef) -- lock mouse buttons if they're down */
- }
- }
- else if (filter->keycode == keycode) {
- CARD8 flags = filter->upAction.iso.flags;
- if (flags & XkbSA_ISODfltIsGroup) {
- xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso);
- xkbi->clearMods = 0;
- if (filter->priv == ISO_KEY_DOWN)
- xkbi->state.locked_group += XkbSAGroup(&filter->upAction.iso);
- }
- else {
- xkbi->clearMods = filter->upAction.iso.mask;
- xkbi->groupChange = 0;
- if (filter->priv == ISO_KEY_DOWN)
- xkbi->state.locked_mods ^= filter->upAction.iso.mask;
- }
- filter->active = 0;
- }
- else if (pAction) {
- CARD8 flags = filter->upAction.iso.flags;
- switch (pAction->type) {
- case XkbSA_SetMods:
- case XkbSA_LatchMods:
- if (!(flags & XkbSA_ISONoAffectMods)) {
- pAction->type = XkbSA_LockMods;
- filter->priv = NO_ISO_LOCK;
- }
- break;
- case XkbSA_SetGroup:
- case XkbSA_LatchGroup:
- if (!(flags & XkbSA_ISONoAffectGroup)) {
- pAction->type = XkbSA_LockGroup;
- filter->priv = NO_ISO_LOCK;
- }
- break;
- case XkbSA_PtrBtn:
- if (!(flags & XkbSA_ISONoAffectPtr)) {
- pAction->type = XkbSA_LockPtrBtn;
- filter->priv = NO_ISO_LOCK;
- }
- break;
- case XkbSA_SetControls:
- if (!(flags & XkbSA_ISONoAffectCtrls)) {
- pAction->type = XkbSA_LockControls;
- filter->priv = NO_ISO_LOCK;
- }
- break;
- }
- }
- return 1;
- }
- static CARD32
- _XkbPtrAccelExpire(OsTimerPtr timer, CARD32 now, void *arg)
- {
- XkbSrvInfoPtr xkbi = (XkbSrvInfoPtr) arg;
- XkbControlsPtr ctrls = xkbi->desc->ctrls;
- int dx, dy;
- if (xkbi->mouseKey == 0)
- return 0;
- if (xkbi->mouseKeysAccel) {
- if ((xkbi->mouseKeysCounter) < ctrls->mk_time_to_max) {
- double step;
- xkbi->mouseKeysCounter++;
- step = xkbi->mouseKeysCurveFactor *
- pow((double) xkbi->mouseKeysCounter, xkbi->mouseKeysCurve);
- if (xkbi->mouseKeysDX < 0)
- dx = floor(((double) xkbi->mouseKeysDX) * step);
- else
- dx = ceil(((double) xkbi->mouseKeysDX) * step);
- if (xkbi->mouseKeysDY < 0)
- dy = floor(((double) xkbi->mouseKeysDY) * step);
- else
- dy = ceil(((double) xkbi->mouseKeysDY) * step);
- }
- else {
- dx = xkbi->mouseKeysDX * ctrls->mk_max_speed;
- dy = xkbi->mouseKeysDY * ctrls->mk_max_speed;
- }
- if (xkbi->mouseKeysFlags & XkbSA_MoveAbsoluteX)
- dx = xkbi->mouseKeysDX;
- if (xkbi->mouseKeysFlags & XkbSA_MoveAbsoluteY)
- dy = xkbi->mouseKeysDY;
- }
- else {
- dx = xkbi->mouseKeysDX;
- dy = xkbi->mouseKeysDY;
- }
- XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags, dx, dy);
- return xkbi->desc->ctrls->mk_interval;
- }
- static int
- _XkbFilterPointerMove(XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
- {
- int x, y;
- Bool accel;
- if (filter->keycode == 0) { /* initial press */
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- filter->priv = 0;
- filter->filter = _XkbFilterPointerMove;
- filter->upAction = *pAction;
- xkbi->mouseKeysCounter = 0;
- xkbi->mouseKey = keycode;
- accel = ((pAction->ptr.flags & XkbSA_NoAcceleration) == 0);
- x = XkbPtrActionX(&pAction->ptr);
- y = XkbPtrActionY(&pAction->ptr);
- XkbFakePointerMotion(xkbi->device, pAction->ptr.flags, x, y);
- AccessXCancelRepeatKey(xkbi, keycode);
- xkbi->mouseKeysAccel = accel &&
- (xkbi->desc->ctrls->enabled_ctrls & XkbMouseKeysAccelMask);
- xkbi->mouseKeysFlags = pAction->ptr.flags;
- xkbi->mouseKeysDX = XkbPtrActionX(&pAction->ptr);
- xkbi->mouseKeysDY = XkbPtrActionY(&pAction->ptr);
- xkbi->mouseKeyTimer = TimerSet(xkbi->mouseKeyTimer, 0,
- xkbi->desc->ctrls->mk_delay,
- _XkbPtrAccelExpire, (void *) xkbi);
- }
- else if (filter->keycode == keycode) {
- filter->active = 0;
- if (xkbi->mouseKey == keycode) {
- xkbi->mouseKey = 0;
- xkbi->mouseKeyTimer = TimerSet(xkbi->mouseKeyTimer, 0, 0,
- NULL, NULL);
- }
- }
- return 0;
- }
- static int
- _XkbFilterPointerBtn(XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
- {
- if (filter->keycode == 0) { /* initial press */
- int button = pAction->btn.button;
- if (button == XkbSA_UseDfltButton)
- button = xkbi->desc->ctrls->mk_dflt_btn;
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- filter->priv = 0;
- filter->filter = _XkbFilterPointerBtn;
- filter->upAction = *pAction;
- filter->upAction.btn.button = button;
- switch (pAction->type) {
- case XkbSA_LockPtrBtn:
- if (((xkbi->lockedPtrButtons & (1 << button)) == 0) &&
- ((pAction->btn.flags & XkbSA_LockNoLock) == 0)) {
- xkbi->lockedPtrButtons |= (1 << button);
- AccessXCancelRepeatKey(xkbi, keycode);
- XkbFakeDeviceButton(xkbi->device, 1, button);
- filter->upAction.type = XkbSA_NoAction;
- }
- break;
- case XkbSA_PtrBtn:
- {
- register int i, nClicks;
- AccessXCancelRepeatKey(xkbi, keycode);
- if (pAction->btn.count > 0) {
- nClicks = pAction->btn.count;
- for (i = 0; i < nClicks; i++) {
- XkbFakeDeviceButton(xkbi->device, 1, button);
- XkbFakeDeviceButton(xkbi->device, 0, button);
- }
- filter->upAction.type = XkbSA_NoAction;
- }
- else
- XkbFakeDeviceButton(xkbi->device, 1, button);
- }
- break;
- case XkbSA_SetPtrDflt:
- {
- XkbControlsPtr ctrls = xkbi->desc->ctrls;
- XkbControlsRec old;
- xkbControlsNotify cn;
- old = *ctrls;
- AccessXCancelRepeatKey(xkbi, keycode);
- switch (pAction->dflt.affect) {
- case XkbSA_AffectDfltBtn:
- if (pAction->dflt.flags & XkbSA_DfltBtnAbsolute)
- ctrls->mk_dflt_btn = XkbSAPtrDfltValue(&pAction->dflt);
- else {
- ctrls->mk_dflt_btn += XkbSAPtrDfltValue(&pAction->dflt);
- if (ctrls->mk_dflt_btn > 5)
- ctrls->mk_dflt_btn = 5;
- else if (ctrls->mk_dflt_btn < 1)
- ctrls->mk_dflt_btn = 1;
- }
- break;
- default:
- ErrorF
- ("Attempt to change unknown pointer default (%d) ignored\n",
- pAction->dflt.affect);
- break;
- }
- if (XkbComputeControlsNotify(xkbi->device,
- &old, xkbi->desc->ctrls, &cn, FALSE)) {
- cn.keycode = keycode;
- /* XXX: what about DeviceKeyPress? */
- cn.eventType = KeyPress;
- cn.requestMajor = 0;
- cn.requestMinor = 0;
- XkbSendControlsNotify(xkbi->device, &cn);
- }
- }
- break;
- }
- }
- else if (filter->keycode == keycode) {
- int button = filter->upAction.btn.button;
- switch (filter->upAction.type) {
- case XkbSA_LockPtrBtn:
- if (((filter->upAction.btn.flags & XkbSA_LockNoUnlock) != 0) ||
- ((xkbi->lockedPtrButtons & (1 << button)) == 0)) {
- break;
- }
- xkbi->lockedPtrButtons &= ~(1 << button);
- if (IsMaster(xkbi->device)) {
- XkbMergeLockedPtrBtns(xkbi->device);
- /* One SD still has lock set, don't post event */
- if ((xkbi->lockedPtrButtons & (1 << button)) != 0)
- break;
- }
- /* fallthrough */
- case XkbSA_PtrBtn:
- XkbFakeDeviceButton(xkbi->device, 0, button);
- break;
- }
- filter->active = 0;
- }
- return 0;
- }
- static int
- _XkbFilterControls(XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
- {
- XkbControlsRec old;
- XkbControlsPtr ctrls;
- DeviceIntPtr kbd;
- unsigned int change;
- XkbEventCauseRec cause;
- kbd = xkbi->device;
- ctrls = xkbi->desc->ctrls;
- old = *ctrls;
- if (filter->keycode == 0) { /* initial press */
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- change = XkbActionCtrls(&pAction->ctrls);
- filter->priv = change;
- filter->filter = _XkbFilterControls;
- filter->upAction = *pAction;
- if (pAction->type == XkbSA_LockControls) {
- filter->priv = (ctrls->enabled_ctrls & change);
- change &= ~ctrls->enabled_ctrls;
- }
- if (change) {
- xkbControlsNotify cn;
- XkbSrvLedInfoPtr sli;
- ctrls->enabled_ctrls |= change;
- if (XkbComputeControlsNotify(kbd, &old, ctrls, &cn, FALSE)) {
- cn.keycode = keycode;
- /* XXX: what about DeviceKeyPress? */
- cn.eventType = KeyPress;
- cn.requestMajor = 0;
- cn.requestMinor = 0;
- XkbSendControlsNotify(kbd, &cn);
- }
- XkbSetCauseKey(&cause, keycode, KeyPress);
- /* If sticky keys were disabled, clear all locks and latches */
- if ((old.enabled_ctrls & XkbStickyKeysMask) &&
- (!(ctrls->enabled_ctrls & XkbStickyKeysMask))) {
- XkbClearAllLatchesAndLocks(kbd, xkbi, FALSE, &cause);
- }
- sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass, XkbDfltXIId, 0);
- XkbUpdateIndicators(kbd, sli->usesControls, TRUE, NULL, &cause);
- if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask))
- XkbDDXAccessXBeep(kbd, _BEEP_FEATURE_ON, change);
- }
- }
- else if (filter->keycode == keycode) {
- change = filter->priv;
- if (change) {
- xkbControlsNotify cn;
- XkbSrvLedInfoPtr sli;
- ctrls->enabled_ctrls &= ~change;
- if (XkbComputeControlsNotify(kbd, &old, ctrls, &cn, FALSE)) {
- cn.keycode = keycode;
- cn.eventType = KeyRelease;
- cn.requestMajor = 0;
- cn.requestMinor = 0;
- XkbSendControlsNotify(kbd, &cn);
- }
- XkbSetCauseKey(&cause, keycode, KeyRelease);
- /* If sticky keys were disabled, clear all locks and latches */
- if ((old.enabled_ctrls & XkbStickyKeysMask) &&
- (!(ctrls->enabled_ctrls & XkbStickyKeysMask))) {
- XkbClearAllLatchesAndLocks(kbd, xkbi, FALSE, &cause);
- }
- sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass, XkbDfltXIId, 0);
- XkbUpdateIndicators(kbd, sli->usesControls, TRUE, NULL, &cause);
- if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask))
- XkbDDXAccessXBeep(kbd, _BEEP_FEATURE_OFF, change);
- }
- filter->keycode = 0;
- filter->active = 0;
- }
- return 1;
- }
- static int
- _XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter,
- unsigned keycode, XkbAction *pAction)
- {
- XkbMessageAction *pMsg;
- DeviceIntPtr kbd;
- if ((filter->keycode != 0) && (filter->keycode != keycode))
- return 1;
- /* This can happen if the key repeats, and the state (modifiers or group)
- changes meanwhile. */
- if ((filter->keycode == keycode) && pAction &&
- (pAction->type != XkbSA_ActionMessage))
- return 1;
- kbd = xkbi->device;
- if (filter->keycode == 0) { /* initial press */
- pMsg = &pAction->msg;
- if ((pMsg->flags & XkbSA_MessageOnRelease) ||
- ((pMsg->flags & XkbSA_MessageGenKeyEvent) == 0)) {
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- filter->priv = 0;
- filter->filter = _XkbFilterActionMessage;
- filter->upAction = *pAction;
- }
- if (pMsg->flags & XkbSA_MessageOnPress) {
- xkbActionMessage msg;
- msg.keycode = keycode;
- msg.press = 1;
- msg.keyEventFollows =
- ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
- memcpy((char *) msg.message, (char *) pMsg->message,
- XkbActionMessageLength);
- XkbSendActionMessage(kbd, &msg);
- }
- return ((pAction->msg.flags & XkbSA_MessageGenKeyEvent) != 0);
- }
- else if (filter->keycode == keycode) {
- pMsg = &filter->upAction.msg;
- if (pAction == NULL) {
- if (pMsg->flags & XkbSA_MessageOnRelease) {
- xkbActionMessage msg;
- msg.keycode = keycode;
- msg.press = 0;
- msg.keyEventFollows =
- ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
- memcpy((char *) msg.message, (char *) pMsg->message,
- XkbActionMessageLength);
- XkbSendActionMessage(kbd, &msg);
- }
- filter->keycode = 0;
- filter->active = 0;
- return ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
- } else if (memcmp(pMsg, pAction, 8) == 0) {
- /* Repeat: If we send the same message, avoid multiple messages
- on release from piling up. */
- filter->keycode = 0;
- filter->active = 0;
- }
- }
- return 1;
- }
- static int
- _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
- {
- DeviceEvent ev;
- int x, y;
- XkbStateRec old, old_prev;
- unsigned mods, mask;
- xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
- ProcessInputProc backupproc;
- if ((filter->keycode != 0) && (filter->keycode != keycode))
- return 1;
- /* This can happen if the key repeats, and the state (modifiers or group)
- changes meanwhile. */
- if ((filter->keycode == keycode) && pAction &&
- (pAction->type != XkbSA_RedirectKey))
- return 1;
- /* never actually used uninitialised, but gcc isn't smart enough
- * to work that out. */
- memset(&old, 0, sizeof(old));
- memset(&old_prev, 0, sizeof(old_prev));
- memset(&ev, 0, sizeof(ev));
- GetSpritePosition(xkbi->device, &x, &y);
- ev.header = ET_Internal;
- ev.length = sizeof(DeviceEvent);
- ev.time = GetTimeInMillis();
- ev.root_x = x;
- ev.root_y = y;
- /* redirect actions do not work across devices, therefore the following is
- * correct: */
- ev.deviceid = xkbi->device->id;
- /* filter->priv must be set up by the caller for the initial press. */
- ev.sourceid = filter->priv;
- if (filter->keycode == 0) { /* initial press */
- if ((pAction->redirect.new_key < xkbi->desc->min_key_code) ||
- (pAction->redirect.new_key > xkbi->desc->max_key_code)) {
- return 1;
- }
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- filter->filter = _XkbFilterRedirectKey;
- filter->upAction = *pAction;
- ev.type = ET_KeyPress;
- ev.detail.key = pAction->redirect.new_key;
- mask = XkbSARedirectVModsMask(&pAction->redirect);
- mods = XkbSARedirectVMods(&pAction->redirect);
- if (mask)
- XkbVirtualModsToReal(xkbi->desc, mask, &mask);
- if (mods)
- XkbVirtualModsToReal(xkbi->desc, mods, &mods);
- mask |= pAction->redirect.mods_mask;
- mods |= pAction->redirect.mods;
- if (mask || mods) {
- old = xkbi->state;
- old_prev = xkbi->prev_state;
- xkbi->state.base_mods &= ~mask;
- xkbi->state.base_mods |= (mods & mask);
- xkbi->state.latched_mods &= ~mask;
- xkbi->state.latched_mods |= (mods & mask);
- xkbi->state.locked_mods &= ~mask;
- xkbi->state.locked_mods |= (mods & mask);
- XkbComputeDerivedState(xkbi);
- xkbi->prev_state = xkbi->state;
- }
- UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
- xkbi->device->public.processInputProc((InternalEvent *) &ev,
- xkbi->device);
- COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
- xkbUnwrapProc);
- if (mask || mods) {
- xkbi->state = old;
- xkbi->prev_state = old_prev;
- }
- return 0;
- }
- else {
- /* If it is a key release, or we redirect to another key, release the
- previous new_key. Otherwise, repeat. */
- ev.detail.key = filter->upAction.redirect.new_key;
- if (pAction == NULL || ev.detail.key != pAction->redirect.new_key) {
- ev.type = ET_KeyRelease;
- filter->active = 0;
- }
- else {
- ev.type = ET_KeyPress;
- ev.key_repeat = TRUE;
- }
- mask = XkbSARedirectVModsMask(&filter->upAction.redirect);
- mods = XkbSARedirectVMods(&filter->upAction.redirect);
- if (mask)
- XkbVirtualModsToReal(xkbi->desc, mask, &mask);
- if (mods)
- XkbVirtualModsToReal(xkbi->desc, mods, &mods);
- mask |= filter->upAction.redirect.mods_mask;
- mods |= filter->upAction.redirect.mods;
- if (mask || mods) {
- old = xkbi->state;
- old_prev = xkbi->prev_state;
- xkbi->state.base_mods &= ~mask;
- xkbi->state.base_mods |= (mods & mask);
- xkbi->state.latched_mods &= ~mask;
- xkbi->state.latched_mods |= (mods & mask);
- xkbi->state.locked_mods &= ~mask;
- xkbi->state.locked_mods |= (mods & mask);
- XkbComputeDerivedState(xkbi);
- xkbi->prev_state = xkbi->state;
- }
- UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
- xkbi->device->public.processInputProc((InternalEvent *) &ev,
- xkbi->device);
- COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
- xkbUnwrapProc);
- if (mask || mods) {
- xkbi->state = old;
- xkbi->prev_state = old_prev;
- }
- /* We return 1 in case we have sent a release event because the new_key
- has changed. Then, subsequently, we will call this function again
- with the same pAction, which will create the press for the new
- new_key. */
- return (pAction && ev.detail.key != pAction->redirect.new_key);
- }
- }
- static int
- _XkbFilterSwitchScreen(XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter,
- unsigned keycode, XkbAction *pAction)
- {
- DeviceIntPtr dev = xkbi->device;
- if (dev == inputInfo.keyboard)
- return 0;
- if (filter->keycode == 0) { /* initial press */
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- filter->filter = _XkbFilterSwitchScreen;
- AccessXCancelRepeatKey(xkbi, keycode);
- XkbDDXSwitchScreen(dev, keycode, pAction);
- return 0;
- }
- else if (filter->keycode == keycode) {
- filter->active = 0;
- return 0;
- }
- return 1;
- }
- static int
- _XkbFilterXF86Private(XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
- {
- DeviceIntPtr dev = xkbi->device;
- if (dev == inputInfo.keyboard)
- return 0;
- if (filter->keycode == 0) { /* initial press */
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- filter->filter = _XkbFilterXF86Private;
- XkbDDXPrivate(dev, keycode, pAction);
- return 0;
- }
- else if (filter->keycode == keycode) {
- filter->active = 0;
- return 0;
- }
- return 1;
- }
- static int
- _XkbFilterDeviceBtn(XkbSrvInfoPtr xkbi,
- XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
- {
- if (xkbi->device == inputInfo.keyboard)
- return 0;
- if (filter->keycode == 0) { /* initial press */
- DeviceIntPtr dev;
- int button;
- _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient,
- DixUnknownAccess, &button);
- if (!dev || !dev->public.on)
- return 1;
- button = pAction->devbtn.button;
- if ((button < 1) || (button > dev->button->numButtons))
- return 1;
- filter->keycode = keycode;
- filter->active = 1;
- filter->filterOthers = 0;
- filter->priv = 0;
- filter->filter = _XkbFilterDeviceBtn;
- filter->upAction = *pAction;
- switch (pAction->type) {
- case XkbSA_LockDeviceBtn:
- if ((pAction->devbtn.flags & XkbSA_LockNoLock) ||
- BitIsOn(dev->button->down, button))
- return 0;
- XkbFakeDeviceButton(dev, TRUE, button);
- filter->upAction.type = XkbSA_NoAction;
- break;
- case XkbSA_DeviceBtn:
- if (pAction->devbtn.count > 0) {
- int nClicks, i;
- nClicks = pAction->btn.count;
- for (i = 0; i < nClicks; i++) {
- XkbFakeDeviceButton(dev, TRUE, button);
- XkbFakeDeviceButton(dev, FALSE, button);
- }
- filter->upAction.type = XkbSA_NoAction;
- }
- else
- XkbFakeDeviceButton(dev, TRUE, button);
- break;
- }
- }
- else if (filter->keycode == keycode) {
- DeviceIntPtr dev;
- int button;
- filter->active = 0;
- _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device,
- serverClient, DixUnknownAccess, &button);
- if (!dev || !dev->public.on)
- return 1;
- button = filter->upAction.btn.button;
- switch (filter->upAction.type) {
- case XkbSA_LockDeviceBtn:
- if ((filter->upAction.devbtn.flags & XkbSA_LockNoUnlock) ||
- !BitIsOn(dev->button->down, button))
- return 0;
- XkbFakeDeviceButton(dev, FALSE, button);
- break;
- case XkbSA_DeviceBtn:
- XkbFakeDeviceButton(dev, FALSE, button);
- break;
- }
- filter->active = 0;
- }
- return 0;
- }
- static XkbFilterPtr
- _XkbNextFreeFilter(XkbSrvInfoPtr xkbi)
- {
- register int i;
- if (xkbi->szFilters == 0) {
- xkbi->szFilters = 4;
- xkbi->filters = calloc(xkbi->szFilters, sizeof(XkbFilterRec));
- /* 6/21/93 (ef) -- XXX! deal with allocation failure */
- }
- for (i = 0; i < xkbi->szFilters; i++) {
- if (!xkbi->filters[i].active) {
- xkbi->filters[i].keycode = 0;
- return &xkbi->filters[i];
- }
- }
- xkbi->szFilters *= 2;
- xkbi->filters = realloc(xkbi->filters,
- xkbi->szFilters * sizeof(XkbFilterRec));
- /* 6/21/93 (ef) -- XXX! deal with allocation failure */
- memset(&xkbi->filters[xkbi->szFilters / 2], 0,
- (xkbi->szFilters / 2) * sizeof(XkbFilterRec));
- return &xkbi->filters[xkbi->szFilters / 2];
- }
- static int
- _XkbApplyFilters(XkbSrvInfoPtr xkbi, unsigned kc, XkbAction *pAction)
- {
- register int i, send;
- send = 1;
- for (i = 0; i < xkbi->szFilters; i++) {
- if ((xkbi->filters[i].active) && (xkbi->filters[i].filter))
- send =
- ((*xkbi->filters[i].filter) (xkbi, &xkbi->filters[i], kc,
- pAction)
- && send);
- }
- return send;
- }
- static int
- _XkbEnsureStateChange(XkbSrvInfoPtr xkbi)
- {
- Bool genStateNotify = FALSE;
- /* The state may change, so if we're not in the middle of sending a state
- * notify, prepare for it */
- if ((xkbi->flags & _XkbStateNotifyInProgress) == 0) {
- xkbi->prev_state = xkbi->state;
- xkbi->flags |= _XkbStateNotifyInProgress;
- genStateNotify = TRUE;
- }
- return genStateNotify;
- }
- static void
- _XkbApplyState(DeviceIntPtr dev, Bool genStateNotify, int evtype, int key)
- {
- XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
- int changed;
- XkbComputeDerivedState(xkbi);
- changed = XkbStateChangedFlags(&xkbi->prev_state, &xkbi->state);
- if (genStateNotify) {
- if (changed) {
- xkbStateNotify sn;
- sn.keycode = key;
- sn.eventType = evtype;
- sn.requestMajor = sn.requestMinor = 0;
- sn.changed = changed;
- XkbSendStateNotify(dev, &sn);
- }
- xkbi->flags &= ~_XkbStateNotifyInProgress;
- }
- changed = XkbIndicatorsToUpdate(dev, changed, FALSE);
- if (changed) {
- XkbEventCauseRec cause;
- XkbSetCauseKey(&cause, key, evtype);
- XkbUpdateIndicators(dev, changed, FALSE, NULL, &cause);
- }
- }
- void
- XkbPushLockedStateToSlaves(DeviceIntPtr master, int evtype, int key)
- {
- DeviceIntPtr dev;
- Bool genStateNotify;
- nt_list_for_each_entry(dev, inputInfo.devices, next) {
- if (!dev->key || GetMaster(dev, MASTER_KEYBOARD) != master)
- continue;
- genStateNotify = _XkbEnsureStateChange(dev->key->xkbInfo);
- dev->key->xkbInfo->state.locked_mods =
- master->key->xkbInfo->state.locked_mods;
- _XkbApplyState(dev, genStateNotify, evtype, key);
- }
- }
- void
- XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
- {
- int key, bit, i;
- XkbSrvInfoPtr xkbi;
- KeyClassPtr keyc;
- int sendEvent;
- Bool genStateNotify;
- XkbAction act;
- XkbFilterPtr filter;
- Bool keyEvent;
- Bool pressEvent;
- ProcessInputProc backupproc;
- xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
- keyc = kbd->key;
- xkbi = keyc->xkbInfo;
- key = event->detail.key;
- genStateNotify = _XkbEnsureStateChange(xkbi);
- xkbi->clearMods = xkbi->setMods = 0;
- xkbi->groupChange = 0;
- sendEvent = 1;
- keyEvent = ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease));
- pressEvent = ((event->type == ET_KeyPress) ||
- (event->type == ET_ButtonPress));
- if (pressEvent) {
- if (keyEvent)
- act = XkbGetKeyAction(xkbi, &xkbi->state, key);
- else {
- act = XkbGetButtonAction(kbd, dev, key);
- key |= BTN_ACT_FLAG;
- }
- sendEvent = _XkbApplyFilters(xkbi, key, &act);
- if (sendEvent) {
- switch (act.type) {
- case XkbSA_SetMods:
- case XkbSA_SetGroup:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent = _XkbFilterSetState(xkbi, filter, key, &act);
- break;
- case XkbSA_LatchMods:
- case XkbSA_LatchGroup:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent = _XkbFilterLatchState(xkbi, filter, key, &act);
- break;
- case XkbSA_LockMods:
- case XkbSA_LockGroup:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent = _XkbFilterLockState(xkbi, filter, key, &act);
- break;
- case XkbSA_ISOLock:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent = _XkbFilterISOLock(xkbi, filter, key, &act);
- break;
- case XkbSA_MovePtr:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent = _XkbFilterPointerMove(xkbi, filter, key, &act);
- break;
- case XkbSA_PtrBtn:
- case XkbSA_LockPtrBtn:
- case XkbSA_SetPtrDflt:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent = _XkbFilterPointerBtn(xkbi, filter, key, &act);
- break;
- case XkbSA_Terminate:
- sendEvent = XkbDDXTerminateServer(dev, key, &act);
- break;
- case XkbSA_SwitchScreen:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent = _XkbFilterSwitchScreen(xkbi, filter, key, &act);
- break;
- case XkbSA_SetControls:
- case XkbSA_LockControls:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent = _XkbFilterControls(xkbi, filter, key, &act);
- break;
- case XkbSA_ActionMessage:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent = _XkbFilterActionMessage(xkbi, filter, key, &act);
- break;
- case XkbSA_RedirectKey:
- filter = _XkbNextFreeFilter(xkbi);
- /* redirect actions must create a new DeviceEvent. The
- * source device id for this event cannot be obtained from
- * xkbi, so we pass it here explicitly. The field deviceid
- * equals to xkbi->device->id. */
- filter->priv = event->sourceid;
- sendEvent = _XkbFilterRedirectKey(xkbi, filter, key, &act);
- break;
- case XkbSA_DeviceBtn:
- case XkbSA_LockDeviceBtn:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent = _XkbFilterDeviceBtn(xkbi, filter, key, &act);
- break;
- case XkbSA_XFree86Private:
- filter = _XkbNextFreeFilter(xkbi);
- sendEvent = _XkbFilterXF86Private(xkbi, filter, key, &act);
- break;
- }
- }
- }
- else {
- if (!keyEvent)
- key |= BTN_ACT_FLAG;
- sendEvent = _XkbApplyFilters(xkbi, key, NULL);
- }
- if (xkbi->groupChange != 0)
- xkbi->state.base_group += xkbi->groupChange;
- if (xkbi->setMods) {
- for (i = 0, bit = 1; xkbi->setMods; i++, bit <<= 1) {
- if (xkbi->setMods & bit) {
- keyc->modifierKeyCount[i]++;
- xkbi->state.base_mods |= bit;
- xkbi->setMods &= ~bit;
- }
- }
- }
- if (xkbi->clearMods) {
- for (i = 0, bit = 1; xkbi->clearMods; i++, bit <<= 1) {
- if (xkbi->clearMods & bit) {
- keyc->modifierKeyCount[i]--;
- if (keyc->modifierKeyCount[i] <= 0) {
- xkbi->state.base_mods &= ~bit;
- keyc->modifierKeyCount[i] = 0;
- }
- xkbi->clearMods &= ~bit;
- }
- }
- }
- if (sendEvent) {
- DeviceIntPtr tmpdev;
- if (keyEvent)
- tmpdev = dev;
- else
- tmpdev = GetMaster(dev, POINTER_OR_FLOAT);
- UNWRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr, backupproc);
- dev->public.processInputProc((InternalEvent *) event, tmpdev);
- COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
- backupproc, xkbUnwrapProc);
- }
- else if (keyEvent) {
- FixKeyState(event, dev);
- }
- _XkbApplyState(dev, genStateNotify, event->type, key);
- XkbPushLockedStateToSlaves(dev, event->type, key);
- }
- int
- XkbLatchModifiers(DeviceIntPtr pXDev, CARD8 mask, CARD8 latches)
- {
- XkbSrvInfoPtr xkbi;
- XkbFilterPtr filter;
- XkbAction act;
- unsigned clear;
- if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
- xkbi = pXDev->key->xkbInfo;
- clear = (mask & (~latches));
- xkbi->state.latched_mods &= ~clear;
- /* Clear any pending latch to locks.
- */
- act.type = XkbSA_NoAction;
- _XkbApplyFilters(xkbi, SYNTHETIC_KEYCODE, &act);
- act.type = XkbSA_LatchMods;
- act.mods.flags = 0;
- act.mods.mask = mask & latches;
- filter = _XkbNextFreeFilter(xkbi);
- _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, &act);
- _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE,
- (XkbAction *) NULL);
- return Success;
- }
- return BadValue;
- }
- int
- XkbLatchGroup(DeviceIntPtr pXDev, int group)
- {
- XkbSrvInfoPtr xkbi;
- XkbFilterPtr filter;
- XkbAction act;
- if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
- xkbi = pXDev->key->xkbInfo;
- act.type = XkbSA_LatchGroup;
- act.group.flags = 0;
- XkbSASetGroup(&act.group, group);
- filter = _XkbNextFreeFilter(xkbi);
- _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, &act);
- _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE,
- (XkbAction *) NULL);
- return Success;
- }
- return BadValue;
- }
- /***====================================================================***/
- void
- XkbClearAllLatchesAndLocks(DeviceIntPtr dev,
- XkbSrvInfoPtr xkbi,
- Bool genEv, XkbEventCausePtr cause)
- {
- XkbStateRec os;
- xkbStateNotify sn;
- sn.changed = 0;
- os = xkbi->state;
- if (os.latched_mods) { /* clear all latches */
- XkbLatchModifiers(dev, ~0, 0);
- sn.changed |= XkbModifierLatchMask;
- }
- if (os.latched_group) {
- XkbLatchGroup(dev, 0);
- sn.changed |= XkbGroupLatchMask;
- }
- if (os.locked_mods) {
- xkbi->state.locked_mods = 0;
- sn.changed |= XkbModifierLockMask;
- }
- if (os.locked_group) {
- xkbi->state.locked_group = 0;
- sn.changed |= XkbGroupLockMask;
- }
- if (genEv && sn.changed) {
- CARD32 changed;
- XkbComputeDerivedState(xkbi);
- sn.keycode = cause->kc;
- sn.eventType = cause->event;
- sn.requestMajor = cause->mjr;
- sn.requestMinor = cause->mnr;
- sn.changed = XkbStateChangedFlags(&os, &xkbi->state);
- XkbSendStateNotify(dev, &sn);
- changed = XkbIndicatorsToUpdate(dev, sn.changed, FALSE);
- if (changed) {
- XkbUpdateIndicators(dev, changed, TRUE, NULL, cause);
- }
- }
- return;
- }
- /*
- * The event is injected into the event processing, not the EQ. Thus,
- * ensure that we restore the master after the event sequence to the
- * original set of classes. Otherwise, the master remains on the XTEST
- * classes and drops events that don't fit into the XTEST layout (e.g.
- * events with more than 2 valuators).
- *
- * FIXME: EQ injection in the processing stage is not designed for, so this
- * is a rather awkward hack. The event list returned by GetPointerEvents()
- * and friends is always prefixed with a DCE if the last _posted_ device was
- * different. For normal events, this sequence then resets the master during
- * the processing stage. Since we inject the PointerKey events in the
- * processing stage though, we need to manually reset to restore the
- * previous order, because the events already in the EQ must be sent for the
- * right device.
- * So we post-fix the event list we get from GPE with a DCE back to the
- * previous slave device.
- *
- * First one on drinking island wins!
- */
- static void
- InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags,
- ValuatorMask *mask)
- {
- ScreenPtr pScreen;
- InternalEvent *events;
- int nevents, i;
- DeviceIntPtr ptr, mpointer, lastSlave = NULL;
- Bool saveWait;
- if (IsMaster(dev)) {
- mpointer = GetMaster(dev, MASTER_POINTER);
- lastSlave = mpointer->lastSlave;
- ptr = GetXTestDevice(mpointer);
- }
- else if (IsFloating(dev))
- ptr = dev;
- else
- return;
- events = InitEventList(GetMaximumEventsNum() + 1);
- OsBlockSignals();
- pScreen = miPointerGetScreen(ptr);
- saveWait = miPointerSetWaitForUpdate(pScreen, FALSE);
- nevents = GetPointerEvents(events, ptr, type, button, flags, mask);
- if (IsMaster(dev) && (lastSlave && lastSlave != ptr))
- UpdateFromMaster(&events[nevents], lastSlave, DEVCHANGE_POINTER_EVENT,
- &nevents);
- miPointerSetWaitForUpdate(pScreen, saveWait);
- OsReleaseSignals();
- for (i = 0; i < nevents; i++)
- mieqProcessDeviceEvent(ptr, &events[i], NULL);
- FreeEventList(events, GetMaximumEventsNum());
- }
- static void
- XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags, int x, int y)
- {
- ValuatorMask mask;
- int gpe_flags = 0;
- /* ignore attached SDs */
- if (!IsMaster(dev) && !IsFloating(dev))
- return;
- if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
- gpe_flags = POINTER_ABSOLUTE;
- else
- gpe_flags = POINTER_RELATIVE;
- valuator_mask_set_range(&mask, 0, 2, (int[]) {
- x, y});
- InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, &mask);
- }
- void
- XkbFakeDeviceButton(DeviceIntPtr dev, Bool press, int button)
- {
- DeviceIntPtr ptr;
- int down;
- /* If dev is a slave device, and the SD is attached, do nothing. If we'd
- * post through the attached master pointer we'd get duplicate events.
- *
- * if dev is a master keyboard, post through the XTEST device
- *
- * if dev is a floating slave, post through the device itself.
- */
- if (IsMaster(dev)) {
- DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER);
- ptr = GetXTestDevice(mpointer);
- }
- else if (IsFloating(dev))
- ptr = dev;
- else
- return;
- down = button_is_down(ptr, button, BUTTON_PROCESSED);
- if (press == down)
- return;
- InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease,
- button, 0, NULL);
- }
|