123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793 |
- /************************************************************
- 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 "exglobals.h"
- #include <X11/extensions/XIproto.h>
- #include "inputstr.h"
- #include "eventstr.h"
- #include "inpututils.h"
- #include <xkbsrv.h>
- #if !defined(WIN32)
- #include <sys/time.h>
- #endif
- int XkbDfltRepeatDelay = 660;
- int XkbDfltRepeatInterval = 40;
- #define DFLT_TIMEOUT_CTRLS (XkbAX_KRGMask|XkbStickyKeysMask|XkbMouseKeysMask)
- #define DFLT_TIMEOUT_OPTS (XkbAX_IndicatorFBMask)
- unsigned short XkbDfltAccessXTimeout = 120;
- unsigned int XkbDfltAccessXTimeoutMask = DFLT_TIMEOUT_CTRLS;
- static unsigned int XkbDfltAccessXTimeoutValues = 0;
- static unsigned int XkbDfltAccessXTimeoutOptionsMask = DFLT_TIMEOUT_OPTS;
- static unsigned int XkbDfltAccessXTimeoutOptionsValues = 0;
- unsigned int XkbDfltAccessXFeedback = XkbAccessXFeedbackMask;
- unsigned short XkbDfltAccessXOptions =
- XkbAX_AllOptionsMask & ~(XkbAX_IndicatorFBMask | XkbAX_SKReleaseFBMask |
- XkbAX_SKRejectFBMask);
- void
- AccessXComputeCurveFactor(XkbSrvInfoPtr xkbi, XkbControlsPtr ctrls)
- {
- xkbi->mouseKeysCurve = 1.0 + (((double) ctrls->mk_curve) * 0.001);
- xkbi->mouseKeysCurveFactor = (((double) ctrls->mk_max_speed) /
- pow((double) ctrls->mk_time_to_max,
- xkbi->mouseKeysCurve));
- return;
- }
- void
- AccessXInit(DeviceIntPtr keybd)
- {
- XkbSrvInfoPtr xkbi = keybd->key->xkbInfo;
- XkbControlsPtr ctrls = xkbi->desc->ctrls;
- xkbi->shiftKeyCount = 0;
- xkbi->mouseKeysCounter = 0;
- xkbi->inactiveKey = 0;
- xkbi->slowKey = 0;
- xkbi->repeatKey = 0;
- xkbi->krgTimerActive = _OFF_TIMER;
- xkbi->beepType = _BEEP_NONE;
- xkbi->beepCount = 0;
- xkbi->mouseKeyTimer = NULL;
- xkbi->slowKeysTimer = NULL;
- xkbi->bounceKeysTimer = NULL;
- xkbi->repeatKeyTimer = NULL;
- xkbi->krgTimer = NULL;
- xkbi->beepTimer = NULL;
- ctrls->repeat_delay = XkbDfltRepeatDelay;
- ctrls->repeat_interval = XkbDfltRepeatInterval;
- ctrls->debounce_delay = 300;
- ctrls->slow_keys_delay = 300;
- ctrls->mk_delay = 160;
- ctrls->mk_interval = 40;
- ctrls->mk_time_to_max = 30;
- ctrls->mk_max_speed = 30;
- ctrls->mk_curve = 500;
- ctrls->mk_dflt_btn = 1;
- ctrls->ax_timeout = XkbDfltAccessXTimeout;
- ctrls->axt_ctrls_mask = XkbDfltAccessXTimeoutMask;
- ctrls->axt_ctrls_values = XkbDfltAccessXTimeoutValues;
- ctrls->axt_opts_mask = XkbDfltAccessXTimeoutOptionsMask;
- ctrls->axt_opts_values = XkbDfltAccessXTimeoutOptionsValues;
- if (XkbDfltAccessXTimeout)
- ctrls->enabled_ctrls |= XkbAccessXTimeoutMask;
- else
- ctrls->enabled_ctrls &= ~XkbAccessXTimeoutMask;
- ctrls->enabled_ctrls |= XkbDfltAccessXFeedback;
- ctrls->ax_options = XkbDfltAccessXOptions;
- AccessXComputeCurveFactor(xkbi, ctrls);
- return;
- }
- /************************************************************************/
- /* */
- /* AccessXKeyboardEvent */
- /* */
- /* Generate a synthetic keyboard event. */
- /* */
- /************************************************************************/
- static void
- AccessXKeyboardEvent(DeviceIntPtr keybd, int type, BYTE keyCode, Bool isRepeat)
- {
- DeviceEvent event;
- init_device_event(&event, keybd, GetTimeInMillis());
- event.type = type;
- event.detail.key = keyCode;
- event.key_repeat = isRepeat;
- if (xkbDebugFlags & 0x8) {
- DebugF("[xkb] AXKE: Key %d %s\n", keyCode,
- (event.type == ET_KeyPress ? "down" : "up"));
- }
- XkbProcessKeyboardEvent(&event, keybd);
- return;
- } /* AccessXKeyboardEvent */
- /************************************************************************/
- /* */
- /* AccessXKRGTurnOn */
- /* */
- /* Turn the keyboard response group on. */
- /* */
- /************************************************************************/
- static void
- AccessXKRGTurnOn(DeviceIntPtr dev, CARD16 KRGControl, xkbControlsNotify * pCN)
- {
- XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
- XkbControlsPtr ctrls = xkbi->desc->ctrls;
- XkbControlsRec old;
- XkbEventCauseRec cause;
- XkbSrvLedInfoPtr sli;
- old = *ctrls;
- ctrls->enabled_ctrls |= (KRGControl & XkbAX_KRGMask);
- if (XkbComputeControlsNotify(dev, &old, ctrls, pCN, FALSE))
- XkbSendControlsNotify(dev, pCN);
- cause.kc = pCN->keycode;
- cause.event = pCN->eventType;
- cause.mjr = pCN->requestMajor;
- cause.mnr = pCN->requestMinor;
- sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0);
- XkbUpdateIndicators(dev, sli->usesControls, TRUE, NULL, &cause);
- if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask))
- XkbDDXAccessXBeep(dev, _BEEP_FEATURE_ON, KRGControl);
- return;
- } /* AccessXKRGTurnOn */
- /************************************************************************/
- /* */
- /* AccessXKRGTurnOff */
- /* */
- /* Turn the keyboard response group off. */
- /* */
- /************************************************************************/
- static void
- AccessXKRGTurnOff(DeviceIntPtr dev, xkbControlsNotify * pCN)
- {
- XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
- XkbControlsPtr ctrls = xkbi->desc->ctrls;
- XkbControlsRec old;
- XkbEventCauseRec cause;
- XkbSrvLedInfoPtr sli;
- old = *ctrls;
- ctrls->enabled_ctrls &= ~XkbAX_KRGMask;
- if (XkbComputeControlsNotify(dev, &old, ctrls, pCN, FALSE))
- XkbSendControlsNotify(dev, pCN);
- cause.kc = pCN->keycode;
- cause.event = pCN->eventType;
- cause.mjr = pCN->requestMajor;
- cause.mnr = pCN->requestMinor;
- sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0);
- XkbUpdateIndicators(dev, sli->usesControls, TRUE, NULL, &cause);
- if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask)) {
- unsigned changes = old.enabled_ctrls ^ ctrls->enabled_ctrls;
- XkbDDXAccessXBeep(dev, _BEEP_FEATURE_OFF, changes);
- }
- return;
- } /* AccessXKRGTurnOff */
- /************************************************************************/
- /* */
- /* AccessXStickyKeysTurnOn */
- /* */
- /* Turn StickyKeys on. */
- /* */
- /************************************************************************/
- static void
- AccessXStickyKeysTurnOn(DeviceIntPtr dev, xkbControlsNotify * pCN)
- {
- XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
- XkbControlsPtr ctrls = xkbi->desc->ctrls;
- XkbControlsRec old;
- XkbEventCauseRec cause;
- XkbSrvLedInfoPtr sli;
- old = *ctrls;
- ctrls->enabled_ctrls |= XkbStickyKeysMask;
- xkbi->shiftKeyCount = 0;
- if (XkbComputeControlsNotify(dev, &old, ctrls, pCN, FALSE))
- XkbSendControlsNotify(dev, pCN);
- cause.kc = pCN->keycode;
- cause.event = pCN->eventType;
- cause.mjr = pCN->requestMajor;
- cause.mnr = pCN->requestMinor;
- sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0);
- XkbUpdateIndicators(dev, sli->usesControls, TRUE, NULL, &cause);
- if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask)) {
- XkbDDXAccessXBeep(dev, _BEEP_FEATURE_ON, XkbStickyKeysMask);
- }
- return;
- } /* AccessXStickyKeysTurnOn */
- /************************************************************************/
- /* */
- /* AccessXStickyKeysTurnOff */
- /* */
- /* Turn StickyKeys off. */
- /* */
- /************************************************************************/
- static void
- AccessXStickyKeysTurnOff(DeviceIntPtr dev, xkbControlsNotify * pCN)
- {
- XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
- XkbControlsPtr ctrls = xkbi->desc->ctrls;
- XkbControlsRec old;
- XkbEventCauseRec cause;
- XkbSrvLedInfoPtr sli;
- old = *ctrls;
- ctrls->enabled_ctrls &= ~XkbStickyKeysMask;
- xkbi->shiftKeyCount = 0;
- if (XkbComputeControlsNotify(dev, &old, ctrls, pCN, FALSE))
- XkbSendControlsNotify(dev, pCN);
- cause.kc = pCN->keycode;
- cause.event = pCN->eventType;
- cause.mjr = pCN->requestMajor;
- cause.mnr = pCN->requestMinor;
- sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0);
- XkbUpdateIndicators(dev, sli->usesControls, TRUE, NULL, &cause);
- if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask)) {
- XkbDDXAccessXBeep(dev, _BEEP_FEATURE_OFF, XkbStickyKeysMask);
- }
- #ifndef NO_CLEAR_LATCHES_FOR_STICKY_KEYS_OFF
- XkbClearAllLatchesAndLocks(dev, xkbi, FALSE, &cause);
- #endif
- return;
- } /* AccessXStickyKeysTurnOff */
- static CARD32
- AccessXKRGExpire(OsTimerPtr timer, CARD32 now, void *arg)
- {
- xkbControlsNotify cn;
- DeviceIntPtr dev = arg;
- XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
- if (xkbi->krgTimerActive == _KRG_WARN_TIMER) {
- XkbDDXAccessXBeep(dev, _BEEP_SLOW_WARN, XkbStickyKeysMask);
- xkbi->krgTimerActive = _KRG_TIMER;
- return 4000;
- }
- xkbi->krgTimerActive = _OFF_TIMER;
- cn.keycode = xkbi->slowKeyEnableKey;
- cn.eventType = KeyPress;
- cn.requestMajor = 0;
- cn.requestMinor = 0;
- if (xkbi->desc->ctrls->enabled_ctrls & XkbSlowKeysMask) {
- AccessXKRGTurnOff(dev, &cn);
- LogMessage(X_INFO, "XKB SlowKeys are disabled.\n");
- }
- else {
- AccessXKRGTurnOn(dev, XkbSlowKeysMask, &cn);
- LogMessage(X_INFO, "XKB SlowKeys are now enabled. Hold shift to disable.\n");
- }
- xkbi->slowKeyEnableKey = 0;
- return 0;
- }
- static CARD32
- AccessXRepeatKeyExpire(OsTimerPtr timer, CARD32 now, void *arg)
- {
- DeviceIntPtr dev = (DeviceIntPtr) arg;
- XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
- if (xkbi->repeatKey == 0)
- return 0;
- AccessXKeyboardEvent(dev, ET_KeyPress, xkbi->repeatKey, TRUE);
- return xkbi->desc->ctrls->repeat_interval;
- }
- void
- AccessXCancelRepeatKey(XkbSrvInfoPtr xkbi, KeyCode key)
- {
- if (xkbi->repeatKey == key)
- xkbi->repeatKey = 0;
- return;
- }
- static CARD32
- AccessXSlowKeyExpire(OsTimerPtr timer, CARD32 now, void *arg)
- {
- DeviceIntPtr keybd;
- XkbSrvInfoPtr xkbi;
- XkbDescPtr xkb;
- XkbControlsPtr ctrls;
- keybd = (DeviceIntPtr) arg;
- xkbi = keybd->key->xkbInfo;
- xkb = xkbi->desc;
- ctrls = xkb->ctrls;
- if (xkbi->slowKey != 0) {
- xkbAccessXNotify ev;
- KeySym *sym = XkbKeySymsPtr(xkb, xkbi->slowKey);
- ev.detail = XkbAXN_SKAccept;
- ev.keycode = xkbi->slowKey;
- ev.slowKeysDelay = ctrls->slow_keys_delay;
- ev.debounceDelay = ctrls->debounce_delay;
- XkbSendAccessXNotify(keybd, &ev);
- if (XkbAX_NeedFeedback(ctrls, XkbAX_SKAcceptFBMask))
- XkbDDXAccessXBeep(keybd, _BEEP_SLOW_ACCEPT, XkbSlowKeysMask);
- AccessXKeyboardEvent(keybd, ET_KeyPress, xkbi->slowKey, FALSE);
- /* check for magic sequences */
- if ((ctrls->enabled_ctrls & XkbAccessXKeysMask) &&
- ((sym[0] == XK_Shift_R) || (sym[0] == XK_Shift_L)))
- xkbi->shiftKeyCount++;
- /* Start repeating if necessary. Stop autorepeating if the user
- * presses a non-modifier key that doesn't autorepeat.
- */
- if (keybd->kbdfeed->ctrl.autoRepeat &&
- ((xkbi->slowKey != xkbi->mouseKey) || (!xkbi->mouseKeysAccel)) &&
- (ctrls->enabled_ctrls & XkbRepeatKeysMask)) {
- if (BitIsOn(keybd->kbdfeed->ctrl.autoRepeats, xkbi->slowKey)) {
- xkbi->repeatKey = xkbi->slowKey;
- xkbi->repeatKeyTimer = TimerSet(xkbi->repeatKeyTimer,
- 0, ctrls->repeat_delay,
- AccessXRepeatKeyExpire,
- (void *) keybd);
- }
- }
- }
- return 0;
- }
- static CARD32
- AccessXBounceKeyExpire(OsTimerPtr timer, CARD32 now, void *arg)
- {
- XkbSrvInfoPtr xkbi = ((DeviceIntPtr) arg)->key->xkbInfo;
- xkbi->inactiveKey = 0;
- return 0;
- }
- static CARD32
- AccessXTimeoutExpire(OsTimerPtr timer, CARD32 now, void *arg)
- {
- DeviceIntPtr dev = (DeviceIntPtr) arg;
- XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
- XkbControlsPtr ctrls = xkbi->desc->ctrls;
- XkbControlsRec old;
- xkbControlsNotify cn;
- XkbEventCauseRec cause;
- XkbSrvLedInfoPtr sli;
- if (xkbi->lastPtrEventTime) {
- unsigned timeToWait = (ctrls->ax_timeout * 1000);
- unsigned timeElapsed = (now - xkbi->lastPtrEventTime);
- if (timeToWait > timeElapsed)
- return timeToWait - timeElapsed;
- }
- old = *ctrls;
- xkbi->shiftKeyCount = 0;
- ctrls->enabled_ctrls &= ~ctrls->axt_ctrls_mask;
- ctrls->enabled_ctrls |= (ctrls->axt_ctrls_values & ctrls->axt_ctrls_mask);
- if (ctrls->axt_opts_mask) {
- ctrls->ax_options &= ~ctrls->axt_opts_mask;
- ctrls->ax_options |= (ctrls->axt_opts_values & ctrls->axt_opts_mask);
- }
- if (XkbComputeControlsNotify(dev, &old, ctrls, &cn, FALSE)) {
- cn.keycode = 0;
- cn.eventType = 0;
- cn.requestMajor = 0;
- cn.requestMinor = 0;
- XkbSendControlsNotify(dev, &cn);
- }
- XkbSetCauseUnknown(&cause);
- sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0);
- XkbUpdateIndicators(dev, sli->usesControls, TRUE, NULL, &cause);
- if (ctrls->ax_options != old.ax_options) {
- unsigned set, cleared, bell;
- set = ctrls->ax_options & (~old.ax_options);
- cleared = (~ctrls->ax_options) & old.ax_options;
- if (set && cleared)
- bell = _BEEP_FEATURE_CHANGE;
- else if (set)
- bell = _BEEP_FEATURE_ON;
- else
- bell = _BEEP_FEATURE_OFF;
- XkbDDXAccessXBeep(dev, bell, XkbAccessXTimeoutMask);
- }
- xkbi->krgTimerActive = _OFF_TIMER;
- return 0;
- }
- /************************************************************************/
- /* */
- /* AccessXFilterPressEvent */
- /* */
- /* Filter events before they get any further if SlowKeys is turned on. */
- /* In addition, this routine handles the ever so popular magic key */
- /* acts for turning various accessibility features on/off. */
- /* */
- /* Returns TRUE if this routine has discarded the event. */
- /* Returns FALSE if the event needs further processing. */
- /* */
- /************************************************************************/
- Bool
- AccessXFilterPressEvent(DeviceEvent *event, DeviceIntPtr keybd)
- {
- XkbSrvInfoPtr xkbi = keybd->key->xkbInfo;
- XkbControlsPtr ctrls = xkbi->desc->ctrls;
- Bool ignoreKeyEvent = FALSE;
- KeyCode key = event->detail.key;
- KeySym *sym = XkbKeySymsPtr(xkbi->desc, key);
- if (ctrls->enabled_ctrls & XkbAccessXKeysMask) {
- /* check for magic sequences */
- if ((sym[0] == XK_Shift_R) || (sym[0] == XK_Shift_L)) {
- xkbi->slowKeyEnableKey = key;
- if (XkbAX_NeedFeedback(ctrls, XkbAX_SlowWarnFBMask)) {
- xkbi->krgTimerActive = _KRG_WARN_TIMER;
- xkbi->krgTimer = TimerSet(xkbi->krgTimer, 0, 4000,
- AccessXKRGExpire, (void *) keybd);
- }
- else {
- xkbi->krgTimerActive = _KRG_TIMER;
- xkbi->krgTimer = TimerSet(xkbi->krgTimer, 0, 8000,
- AccessXKRGExpire, (void *) keybd);
- }
- if (!(ctrls->enabled_ctrls & XkbSlowKeysMask)) {
- CARD32 now = GetTimeInMillis();
- if ((now - xkbi->lastShiftEventTime) > 15000)
- xkbi->shiftKeyCount = 1;
- else
- xkbi->shiftKeyCount++;
- xkbi->lastShiftEventTime = now;
- }
- }
- else {
- if (xkbi->krgTimerActive) {
- xkbi->krgTimer = TimerSet(xkbi->krgTimer, 0, 0, NULL, NULL);
- xkbi->krgTimerActive = _OFF_TIMER;
- }
- }
- }
- /* Don't transmit the KeyPress if SlowKeys is turned on;
- * The wakeup handler will synthesize one for us if the user
- * has held the key long enough.
- */
- if (ctrls->enabled_ctrls & XkbSlowKeysMask) {
- xkbAccessXNotify ev;
- /* If key was already pressed, ignore subsequent press events
- * from the server's autorepeat
- */
- if (xkbi->slowKey == key)
- return TRUE;
- ev.detail = XkbAXN_SKPress;
- ev.keycode = key;
- ev.slowKeysDelay = ctrls->slow_keys_delay;
- ev.debounceDelay = ctrls->debounce_delay;
- XkbSendAccessXNotify(keybd, &ev);
- if (XkbAX_NeedFeedback(ctrls, XkbAX_SKPressFBMask))
- XkbDDXAccessXBeep(keybd, _BEEP_SLOW_PRESS, XkbSlowKeysMask);
- xkbi->slowKey = key;
- xkbi->slowKeysTimer = TimerSet(xkbi->slowKeysTimer,
- 0, ctrls->slow_keys_delay,
- AccessXSlowKeyExpire, (void *) keybd);
- ignoreKeyEvent = TRUE;
- }
- /* Don't transmit the KeyPress if BounceKeys is turned on
- * and the user pressed the same key within a given time period
- * from the last release.
- */
- else if ((ctrls->enabled_ctrls & XkbBounceKeysMask) &&
- (key == xkbi->inactiveKey)) {
- if (XkbAX_NeedFeedback(ctrls, XkbAX_BKRejectFBMask))
- XkbDDXAccessXBeep(keybd, _BEEP_BOUNCE_REJECT, XkbBounceKeysMask);
- ignoreKeyEvent = TRUE;
- }
- /* Start repeating if necessary. Stop autorepeating if the user
- * presses a non-modifier key that doesn't autorepeat.
- */
- if (XkbDDXUsesSoftRepeat(keybd)) {
- if ((keybd->kbdfeed->ctrl.autoRepeat) &&
- ((ctrls->enabled_ctrls & (XkbSlowKeysMask | XkbRepeatKeysMask)) ==
- XkbRepeatKeysMask)) {
- if (BitIsOn(keybd->kbdfeed->ctrl.autoRepeats, key)) {
- if (xkbDebugFlags & 0x10)
- DebugF("Starting software autorepeat...\n");
- if (xkbi->repeatKey == key)
- ignoreKeyEvent = TRUE;
- else {
- xkbi->repeatKey = key;
- xkbi->repeatKeyTimer = TimerSet(xkbi->repeatKeyTimer,
- 0, ctrls->repeat_delay,
- AccessXRepeatKeyExpire,
- (void *) keybd);
- }
- }
- }
- }
- /* Check for two keys being pressed at the same time. This section
- * essentially says the following:
- *
- * If StickyKeys is on, and a modifier is currently being held down,
- * and one of the following is true: the current key is not a modifier
- * or the currentKey is a modifier, but not the only modifier being
- * held down, turn StickyKeys off if the TwoKeys off ctrl is set.
- */
- if ((ctrls->enabled_ctrls & XkbStickyKeysMask) &&
- (xkbi->state.base_mods != 0) &&
- (XkbAX_NeedOption(ctrls, XkbAX_TwoKeysMask))) {
- xkbControlsNotify cn;
- cn.keycode = key;
- cn.eventType = KeyPress;
- cn.requestMajor = 0;
- cn.requestMinor = 0;
- AccessXStickyKeysTurnOff(keybd, &cn);
- }
- if (!ignoreKeyEvent)
- XkbProcessKeyboardEvent(event, keybd);
- return ignoreKeyEvent;
- } /* AccessXFilterPressEvent */
- /************************************************************************/
- /* */
- /* AccessXFilterReleaseEvent */
- /* */
- /* Filter events before they get any further if SlowKeys is turned on. */
- /* In addition, this routine handles the ever so popular magic key */
- /* acts for turning various accessibility features on/off. */
- /* */
- /* Returns TRUE if this routine has discarded the event. */
- /* Returns FALSE if the event needs further processing. */
- /* */
- /************************************************************************/
- Bool
- AccessXFilterReleaseEvent(DeviceEvent *event, DeviceIntPtr keybd)
- {
- XkbSrvInfoPtr xkbi = keybd->key->xkbInfo;
- XkbControlsPtr ctrls = xkbi->desc->ctrls;
- KeyCode key = event->detail.key;
- Bool ignoreKeyEvent = FALSE;
- /* Don't transmit the KeyRelease if BounceKeys is on and
- * this is the release of a key that was ignored due to
- * BounceKeys.
- */
- if (ctrls->enabled_ctrls & XkbBounceKeysMask) {
- if ((key != xkbi->mouseKey) && (!BitIsOn(keybd->key->down, key)))
- ignoreKeyEvent = TRUE;
- xkbi->inactiveKey = key;
- xkbi->bounceKeysTimer = TimerSet(xkbi->bounceKeysTimer, 0,
- ctrls->debounce_delay,
- AccessXBounceKeyExpire,
- (void *) keybd);
- }
- /* Don't transmit the KeyRelease if SlowKeys is turned on and
- * the user didn't hold the key long enough. We know we passed
- * the key if the down bit was set by CoreProcessKeyboadEvent.
- */
- if (ctrls->enabled_ctrls & XkbSlowKeysMask) {
- xkbAccessXNotify ev;
- unsigned beep_type;
- ev.keycode = key;
- ev.slowKeysDelay = ctrls->slow_keys_delay;
- ev.debounceDelay = ctrls->debounce_delay;
- if (BitIsOn(keybd->key->down, key) || (xkbi->mouseKey == key)) {
- ev.detail = XkbAXN_SKRelease;
- beep_type = _BEEP_SLOW_RELEASE;
- }
- else {
- ev.detail = XkbAXN_SKReject;
- beep_type = _BEEP_SLOW_REJECT;
- ignoreKeyEvent = TRUE;
- }
- XkbSendAccessXNotify(keybd, &ev);
- if (XkbAX_NeedFeedback(ctrls, XkbAX_SKRejectFBMask)) {
- XkbDDXAccessXBeep(keybd, beep_type, XkbSlowKeysMask);
- }
- if (xkbi->slowKey == key)
- xkbi->slowKey = 0;
- }
- /* Stop Repeating if the user releases the key that is currently
- * repeating.
- */
- if (xkbi->repeatKey == key) {
- xkbi->repeatKey = 0;
- }
- if ((ctrls->enabled_ctrls & XkbAccessXTimeoutMask) &&
- (ctrls->ax_timeout > 0)) {
- xkbi->lastPtrEventTime = 0;
- xkbi->krgTimer = TimerSet(xkbi->krgTimer, 0,
- ctrls->ax_timeout * 1000,
- AccessXTimeoutExpire, (void *) keybd);
- xkbi->krgTimerActive = _ALL_TIMEOUT_TIMER;
- }
- else if (xkbi->krgTimerActive != _OFF_TIMER) {
- xkbi->krgTimer = TimerSet(xkbi->krgTimer, 0, 0, NULL, NULL);
- xkbi->krgTimerActive = _OFF_TIMER;
- }
- /* Keep track of how many times the Shift key has been pressed.
- * If it has been pressed and released 5 times in a row, toggle
- * the state of StickyKeys.
- */
- if ((!ignoreKeyEvent) && (xkbi->shiftKeyCount)) {
- KeySym *pSym = XkbKeySymsPtr(xkbi->desc, key);
- if ((pSym[0] != XK_Shift_L) && (pSym[0] != XK_Shift_R)) {
- xkbi->shiftKeyCount = 0;
- }
- else if (xkbi->shiftKeyCount >= 5) {
- xkbControlsNotify cn;
- cn.keycode = key;
- cn.eventType = KeyPress;
- cn.requestMajor = 0;
- cn.requestMinor = 0;
- if (ctrls->enabled_ctrls & XkbStickyKeysMask)
- AccessXStickyKeysTurnOff(keybd, &cn);
- else
- AccessXStickyKeysTurnOn(keybd, &cn);
- xkbi->shiftKeyCount = 0;
- }
- }
- if (!ignoreKeyEvent)
- XkbProcessKeyboardEvent(event, keybd);
- return ignoreKeyEvent;
- } /* AccessXFilterReleaseEvent */
- /************************************************************************/
- /* */
- /* ProcessPointerEvent */
- /* */
- /* This routine merely sets the shiftKeyCount and clears the keyboard */
- /* response group timer (if necessary) on a mouse event. This is so */
- /* multiple shifts with just the mouse and shift-drags with the mouse */
- /* don't accidentally turn on StickyKeys or the Keyboard Response Group.*/
- /* */
- /************************************************************************/
- extern int xkbDevicePrivateIndex;
- void
- ProcessPointerEvent(InternalEvent *ev, DeviceIntPtr mouse)
- {
- DeviceIntPtr dev;
- XkbSrvInfoPtr xkbi = NULL;
- unsigned changed = 0;
- ProcessInputProc backupproc;
- xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(mouse);
- DeviceEvent *event = &ev->device_event;
- dev = IsFloating(mouse) ? mouse : GetMaster(mouse, MASTER_KEYBOARD);
- if (dev && dev->key) {
- xkbi = dev->key->xkbInfo;
- xkbi->shiftKeyCount = 0;
- xkbi->lastPtrEventTime = event->time;
- }
- if (event->type == ET_ButtonPress) {
- changed |= XkbPointerButtonMask;
- }
- else if (event->type == ET_ButtonRelease) {
- if (IsMaster(dev)) {
- DeviceIntPtr source;
- int rc;
- rc = dixLookupDevice(&source, event->sourceid, serverClient,
- DixWriteAccess);
- if (rc != Success)
- ErrorF("[xkb] bad sourceid '%d' on button release event.\n",
- event->sourceid);
- else if (!IsXTestDevice(source, GetMaster(dev, MASTER_POINTER))) {
- DeviceIntPtr xtest_device;
- xtest_device = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
- if (button_is_down(xtest_device, ev->device_event.detail.button, BUTTON_PROCESSED))
- XkbFakeDeviceButton(dev, FALSE, event->detail.key);
- }
- }
- if (xkbi)
- xkbi->lockedPtrButtons &= ~(1 << (event->detail.key & 0x7));
- changed |= XkbPointerButtonMask;
- }
- UNWRAP_PROCESS_INPUT_PROC(mouse, xkbPrivPtr, backupproc);
- mouse->public.processInputProc(ev, mouse);
- COND_WRAP_PROCESS_INPUT_PROC(mouse, xkbPrivPtr, backupproc, xkbUnwrapProc);
- if (!xkbi)
- return;
- xkbi->state.ptr_buttons = (mouse->button) ? mouse->button->state : 0;
- /* clear any latched modifiers */
- if (xkbi->state.latched_mods && (event->type == ET_ButtonRelease)) {
- unsigned changed_leds;
- XkbStateRec oldState;
- XkbSrvLedInfoPtr sli;
- sli = XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, 0);
- oldState = xkbi->state;
- XkbLatchModifiers(dev, 0xFF, 0x00);
- XkbComputeDerivedState(xkbi);
- changed |= XkbStateChangedFlags(&oldState, &xkbi->state);
- if (changed & sli->usedComponents) {
- changed_leds = XkbIndicatorsToUpdate(dev, changed, FALSE);
- if (changed_leds) {
- XkbEventCauseRec cause;
- XkbSetCauseKey(&cause, (event->detail.key & 0x7), event->type);
- XkbUpdateIndicators(dev, changed_leds, TRUE, NULL, &cause);
- }
- }
- }
- if (((xkbi->flags & _XkbStateNotifyInProgress) == 0) && (changed != 0)) {
- xkbStateNotify sn;
- sn.keycode = event->detail.key;
- sn.eventType = event->type;
- sn.requestMajor = sn.requestMinor = 0;
- sn.changed = changed;
- XkbSendStateNotify(dev, &sn);
- }
- } /* ProcessPointerEvent */
|