xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

xkbActions.c (54662B)


      1 /************************************************************
      2 Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
      3 
      4 Permission to use, copy, modify, and distribute this
      5 software and its documentation for any purpose and without
      6 fee is hereby granted, provided that the above copyright
      7 notice appear in all copies and that both that copyright
      8 notice and this permission notice appear in supporting
      9 documentation, and that the name of Silicon Graphics not be
     10 used in advertising or publicity pertaining to distribution
     11 of the software without specific prior written permission.
     12 Silicon Graphics makes no representation about the suitability
     13 of this software for any purpose. It is provided "as is"
     14 without any express or implied warranty.
     15 
     16 SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
     17 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
     18 AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
     19 GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
     20 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     21 DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
     22 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
     23 THE USE OR PERFORMANCE OF THIS SOFTWARE.
     24 
     25 ********************************************************/
     26 
     27 #ifdef HAVE_DIX_CONFIG_H
     28 #include <dix-config.h>
     29 #endif
     30 
     31 #include <stdio.h>
     32 #include <math.h>
     33 #include <X11/X.h>
     34 #include <X11/Xproto.h>
     35 #include <X11/keysym.h>
     36 #include "misc.h"
     37 #include "inputstr.h"
     38 #include "exevents.h"
     39 #include "eventstr.h"
     40 #include <xkbsrv.h>
     41 #include "xkb.h"
     42 #include <ctype.h>
     43 #include "mi.h"
     44 #include "mipointer.h"
     45 #include "inpututils.h"
     46 #include "dixgrabs.h"
     47 #define EXTENSION_EVENT_BASE 64
     48 
     49 DevPrivateKeyRec xkbDevicePrivateKeyRec;
     50 
     51 static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags, int x,
     52                                  int y);
     53 
     54 void
     55 xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, void *data)
     56 {
     57     xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
     58     ProcessInputProc backupproc;
     59 
     60     if (xkbPrivPtr->unwrapProc)
     61         xkbPrivPtr->unwrapProc = NULL;
     62 
     63     UNWRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, backupproc);
     64     proc(device, data);
     65     COND_WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, backupproc, xkbUnwrapProc);
     66 }
     67 
     68 Bool
     69 XkbInitPrivates(void)
     70 {
     71     return dixRegisterPrivateKey(&xkbDevicePrivateKeyRec, PRIVATE_DEVICE,
     72                                  sizeof(xkbDeviceInfoRec));
     73 }
     74 
     75 void
     76 XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
     77 {
     78     xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
     79 
     80     WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc);
     81 }
     82 
     83 /***====================================================================***/
     84 
     85 static XkbAction
     86 _FixUpAction(XkbDescPtr xkb, XkbAction *act)
     87 {
     88     static XkbAction fake;
     89 
     90     if (XkbIsPtrAction(act) &&
     91         (!(xkb->ctrls->enabled_ctrls & XkbMouseKeysMask))) {
     92         fake.type = XkbSA_NoAction;
     93         return fake;
     94     }
     95     if (xkb->ctrls->enabled_ctrls & XkbStickyKeysMask) {
     96         if (act->any.type == XkbSA_SetMods) {
     97             fake.mods.type = XkbSA_LatchMods;
     98             fake.mods.mask = act->mods.mask;
     99             if (XkbAX_NeedOption(xkb->ctrls, XkbAX_LatchToLockMask))
    100                 fake.mods.flags = XkbSA_ClearLocks | XkbSA_LatchToLock;
    101             else
    102                 fake.mods.flags = XkbSA_ClearLocks;
    103             return fake;
    104         }
    105         if (act->any.type == XkbSA_SetGroup) {
    106             fake.group.type = XkbSA_LatchGroup;
    107             if (XkbAX_NeedOption(xkb->ctrls, XkbAX_LatchToLockMask))
    108                 fake.group.flags = XkbSA_ClearLocks | XkbSA_LatchToLock;
    109             else
    110                 fake.group.flags = XkbSA_ClearLocks;
    111             XkbSASetGroup(&fake.group, XkbSAGroup(&act->group));
    112             return fake;
    113         }
    114     }
    115     return *act;
    116 }
    117 
    118 static XkbAction
    119 XkbGetKeyAction(XkbSrvInfoPtr xkbi, XkbStatePtr xkbState, CARD8 key)
    120 {
    121     int effectiveGroup;
    122     int col;
    123     XkbDescPtr xkb;
    124     XkbKeyTypePtr type;
    125     XkbAction *pActs;
    126     static XkbAction fake;
    127 
    128     xkb = xkbi->desc;
    129     if (!XkbKeyHasActions(xkb, key) || !XkbKeycodeInRange(xkb, key)) {
    130         fake.type = XkbSA_NoAction;
    131         return fake;
    132     }
    133     pActs = XkbKeyActionsPtr(xkb, key);
    134     col = 0;
    135 
    136     effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key);
    137     if (effectiveGroup != XkbGroup1Index)
    138         col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key));
    139 
    140     type = XkbKeyKeyType(xkb, key, effectiveGroup);
    141     if (type->map != NULL) {
    142         register unsigned i, mods;
    143         register XkbKTMapEntryPtr entry;
    144 
    145         mods = xkbState->mods & type->mods.mask;
    146         for (entry = type->map, i = 0; i < type->map_count; i++, entry++) {
    147             if ((entry->active) && (entry->mods.mask == mods)) {
    148                 col += entry->level;
    149                 break;
    150             }
    151         }
    152     }
    153     if (pActs[col].any.type == XkbSA_NoAction)
    154         return pActs[col];
    155     fake = _FixUpAction(xkb, &pActs[col]);
    156     return fake;
    157 }
    158 
    159 static XkbAction
    160 XkbGetButtonAction(DeviceIntPtr kbd, DeviceIntPtr dev, int button)
    161 {
    162     XkbAction fake;
    163 
    164     if ((dev->button) && (dev->button->xkb_acts)) {
    165         if (dev->button->xkb_acts[button - 1].any.type != XkbSA_NoAction) {
    166             fake = _FixUpAction(kbd->key->xkbInfo->desc,
    167                                 &dev->button->xkb_acts[button - 1]);
    168             return fake;
    169         }
    170     }
    171     fake.any.type = XkbSA_NoAction;
    172     return fake;
    173 }
    174 
    175 /***====================================================================***/
    176 
    177 #define	SYNTHETIC_KEYCODE	1
    178 #define	BTN_ACT_FLAG		0x100
    179 
    180 static int
    181 _XkbFilterSetState(XkbSrvInfoPtr xkbi,
    182                    XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
    183 {
    184     if (filter->keycode == 0) { /* initial press */
    185         AccessXCancelRepeatKey(xkbi, keycode);
    186         filter->keycode = keycode;
    187         filter->active = 1;
    188         filter->filterOthers = ((pAction->mods.mask & XkbSA_ClearLocks) != 0);
    189         filter->priv = 0;
    190         filter->filter = _XkbFilterSetState;
    191         if (pAction->type == XkbSA_SetMods) {
    192             filter->upAction = *pAction;
    193             xkbi->setMods = pAction->mods.mask;
    194         }
    195         else {
    196             xkbi->groupChange = XkbSAGroup(&pAction->group);
    197             if (pAction->group.flags & XkbSA_GroupAbsolute)
    198                 xkbi->groupChange -= xkbi->state.base_group;
    199             filter->upAction = *pAction;
    200             XkbSASetGroup(&filter->upAction.group, xkbi->groupChange);
    201         }
    202     }
    203     else if (filter->keycode == keycode) {
    204         if (filter->upAction.type == XkbSA_SetMods) {
    205             xkbi->clearMods = filter->upAction.mods.mask;
    206             if (filter->upAction.mods.flags & XkbSA_ClearLocks) {
    207                 xkbi->state.locked_mods &= ~filter->upAction.mods.mask;
    208             }
    209         }
    210         else {
    211             if (filter->upAction.group.flags & XkbSA_ClearLocks) {
    212                 xkbi->state.locked_group = 0;
    213             }
    214             xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
    215         }
    216         filter->active = 0;
    217     }
    218     else {
    219         filter->upAction.mods.flags &= ~XkbSA_ClearLocks;
    220         filter->filterOthers = 0;
    221     }
    222     return 1;
    223 }
    224 
    225 #define	LATCH_KEY_DOWN	1
    226 #define	LATCH_PENDING	2
    227 
    228 static int
    229 _XkbFilterLatchState(XkbSrvInfoPtr xkbi,
    230                      XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
    231 {
    232 
    233     if (filter->keycode == 0) { /* initial press */
    234         AccessXCancelRepeatKey(xkbi,keycode);
    235         filter->keycode = keycode;
    236         filter->active = 1;
    237         filter->filterOthers = 1;
    238         filter->priv = LATCH_KEY_DOWN;
    239         filter->filter = _XkbFilterLatchState;
    240         if (pAction->type == XkbSA_LatchMods) {
    241             filter->upAction = *pAction;
    242             xkbi->setMods = pAction->mods.mask;
    243         }
    244         else {
    245             xkbi->groupChange = XkbSAGroup(&pAction->group);
    246             if (pAction->group.flags & XkbSA_GroupAbsolute)
    247                 xkbi->groupChange -= xkbi->state.base_group;
    248             filter->upAction = *pAction;
    249             XkbSASetGroup(&filter->upAction.group, xkbi->groupChange);
    250         }
    251     }
    252     else if (pAction && (filter->priv == LATCH_PENDING)) {
    253         if (((1 << pAction->type) & XkbSA_BreakLatch) != 0) {
    254             filter->active = 0;
    255             /* If one latch is broken, all latches are broken, so it's no use
    256                to find out which particular latch this filter tracks. */
    257             xkbi->state.latched_mods = 0;
    258             xkbi->state.latched_group = 0;
    259         }
    260     }
    261     else if (filter->keycode == keycode && filter->priv != LATCH_PENDING){
    262         /* The test above for LATCH_PENDING skips subsequent releases of the
    263            key after it has been released first time and the latch became
    264            pending. */
    265         XkbControlsPtr ctrls = xkbi->desc->ctrls;
    266         int needBeep = ((ctrls->enabled_ctrls & XkbStickyKeysMask) &&
    267                         XkbAX_NeedFeedback(ctrls, XkbAX_StickyKeysFBMask));
    268 
    269         if (filter->upAction.type == XkbSA_LatchMods) {
    270             unsigned char mask = filter->upAction.mods.mask;
    271             unsigned char common;
    272 
    273             xkbi->clearMods = mask;
    274 
    275             /* ClearLocks */
    276             common = mask & xkbi->state.locked_mods;
    277             if ((filter->upAction.mods.flags & XkbSA_ClearLocks) && common) {
    278                 mask &= ~common;
    279                 xkbi->state.locked_mods &= ~common;
    280                 if (needBeep)
    281                     XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_UNLOCK,
    282                                       XkbStickyKeysMask);
    283             }
    284             /* LatchToLock */
    285             common = mask & xkbi->state.latched_mods;
    286             if ((filter->upAction.mods.flags & XkbSA_LatchToLock) && common) {
    287                 unsigned char newlocked;
    288 
    289                 mask &= ~common;
    290                 newlocked = common & ~xkbi->state.locked_mods;
    291                 if(newlocked){
    292                     xkbi->state.locked_mods |= newlocked;
    293                     if (needBeep)
    294                         XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK,
    295                                           XkbStickyKeysMask);
    296 
    297                 }
    298                 xkbi->state.latched_mods &= ~common;
    299             }
    300             /* Latch remaining modifiers, if any. */
    301             if (mask) {
    302                 xkbi->state.latched_mods |= mask;
    303                 filter->priv = LATCH_PENDING;
    304                 if (needBeep)
    305                     XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LATCH,
    306                                       XkbStickyKeysMask);
    307             }
    308         }
    309         else {
    310             xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
    311             /* ClearLocks */
    312             if ((filter->upAction.group.flags & XkbSA_ClearLocks) &&
    313                 (xkbi->state.locked_group)) {
    314                 xkbi->state.locked_group = 0;
    315                 if (needBeep)
    316                     XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_UNLOCK,
    317                                       XkbStickyKeysMask);
    318             }
    319             /* LatchToLock */
    320             else if ((filter->upAction.group.flags & XkbSA_LatchToLock)
    321                      && (xkbi->state.latched_group)) {
    322                 xkbi->state.locked_group  += XkbSAGroup(&filter->upAction.group);
    323                 xkbi->state.latched_group -= XkbSAGroup(&filter->upAction.group);
    324                 if(XkbSAGroup(&filter->upAction.group) && needBeep)
    325                     XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK,
    326                                       XkbStickyKeysMask);
    327             }
    328             /* Latch group */
    329             else if(XkbSAGroup(&filter->upAction.group)){
    330                 xkbi->state.latched_group += XkbSAGroup(&filter->upAction.group);
    331                 filter->priv = LATCH_PENDING;
    332                 if (needBeep)
    333                     XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LATCH,
    334                                       XkbStickyKeysMask);
    335             }
    336         }
    337 
    338         if (filter->priv != LATCH_PENDING)
    339             filter->active = 0;
    340     }
    341     else if (pAction && (filter->priv == LATCH_KEY_DOWN)) {
    342         /* Latch was broken before it became pending: degrade to a
    343            SetMods/SetGroup. */
    344         if (filter->upAction.type == XkbSA_LatchMods)
    345             filter->upAction.type = XkbSA_SetMods;
    346         else
    347             filter->upAction.type = XkbSA_SetGroup;
    348         filter->filter = _XkbFilterSetState;
    349         filter->priv = 0;
    350         return filter->filter(xkbi, filter, keycode, pAction);
    351     }
    352     return 1;
    353 }
    354 
    355 static int
    356 _XkbFilterLockState(XkbSrvInfoPtr xkbi,
    357                     XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
    358 {
    359     if (filter->keycode == 0) /* initial press */
    360         AccessXCancelRepeatKey(xkbi, keycode);
    361 
    362     if (pAction && (pAction->type == XkbSA_LockGroup)) {
    363         if (pAction->group.flags & XkbSA_GroupAbsolute)
    364             xkbi->state.locked_group = XkbSAGroup(&pAction->group);
    365         else
    366             xkbi->state.locked_group += XkbSAGroup(&pAction->group);
    367         return 1;
    368     }
    369     if (filter->keycode == 0) { /* initial press */
    370         filter->keycode = keycode;
    371         filter->active = 1;
    372         filter->filterOthers = 0;
    373         filter->priv = xkbi->state.locked_mods & pAction->mods.mask;
    374         filter->filter = _XkbFilterLockState;
    375         filter->upAction = *pAction;
    376         if (!(filter->upAction.mods.flags & XkbSA_LockNoLock))
    377             xkbi->state.locked_mods |= pAction->mods.mask;
    378         xkbi->setMods = pAction->mods.mask;
    379     }
    380     else if (filter->keycode == keycode) {
    381         filter->active = 0;
    382         xkbi->clearMods = filter->upAction.mods.mask;
    383         if (!(filter->upAction.mods.flags & XkbSA_LockNoUnlock))
    384             xkbi->state.locked_mods &= ~filter->priv;
    385     }
    386     return 1;
    387 }
    388 
    389 #define	ISO_KEY_DOWN		0
    390 #define	NO_ISO_LOCK		1
    391 
    392 static int
    393 _XkbFilterISOLock(XkbSrvInfoPtr xkbi,
    394                   XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
    395 {
    396 
    397     if (filter->keycode == 0) { /* initial press */
    398         CARD8 flags = pAction->iso.flags;
    399 
    400         filter->keycode = keycode;
    401         filter->active = 1;
    402         filter->filterOthers = 1;
    403         filter->priv = ISO_KEY_DOWN;
    404         filter->upAction = *pAction;
    405         filter->filter = _XkbFilterISOLock;
    406         if (flags & XkbSA_ISODfltIsGroup) {
    407             xkbi->groupChange = XkbSAGroup(&pAction->iso);
    408             xkbi->setMods = 0;
    409         }
    410         else {
    411             xkbi->setMods = pAction->iso.mask;
    412             xkbi->groupChange = 0;
    413         }
    414         if ((!(flags & XkbSA_ISONoAffectMods)) && (xkbi->state.base_mods)) {
    415             filter->priv = NO_ISO_LOCK;
    416             xkbi->state.locked_mods ^= xkbi->state.base_mods;
    417         }
    418         if ((!(flags & XkbSA_ISONoAffectGroup)) && (xkbi->state.base_group)) {
    419 /* 6/22/93 (ef) -- lock groups if group key is down first */
    420         }
    421         if (!(flags & XkbSA_ISONoAffectPtr)) {
    422 /* 6/22/93 (ef) -- lock mouse buttons if they're down */
    423         }
    424     }
    425     else if (filter->keycode == keycode) {
    426         CARD8 flags = filter->upAction.iso.flags;
    427 
    428         if (flags & XkbSA_ISODfltIsGroup) {
    429             xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso);
    430             xkbi->clearMods = 0;
    431             if (filter->priv == ISO_KEY_DOWN)
    432                 xkbi->state.locked_group += XkbSAGroup(&filter->upAction.iso);
    433         }
    434         else {
    435             xkbi->clearMods = filter->upAction.iso.mask;
    436             xkbi->groupChange = 0;
    437             if (filter->priv == ISO_KEY_DOWN)
    438                 xkbi->state.locked_mods ^= filter->upAction.iso.mask;
    439         }
    440         filter->active = 0;
    441     }
    442     else if (pAction) {
    443         CARD8 flags = filter->upAction.iso.flags;
    444 
    445         switch (pAction->type) {
    446         case XkbSA_SetMods:
    447         case XkbSA_LatchMods:
    448             if (!(flags & XkbSA_ISONoAffectMods)) {
    449                 pAction->type = XkbSA_LockMods;
    450                 filter->priv = NO_ISO_LOCK;
    451             }
    452             break;
    453         case XkbSA_SetGroup:
    454         case XkbSA_LatchGroup:
    455             if (!(flags & XkbSA_ISONoAffectGroup)) {
    456                 pAction->type = XkbSA_LockGroup;
    457                 filter->priv = NO_ISO_LOCK;
    458             }
    459             break;
    460         case XkbSA_PtrBtn:
    461             if (!(flags & XkbSA_ISONoAffectPtr)) {
    462                 pAction->type = XkbSA_LockPtrBtn;
    463                 filter->priv = NO_ISO_LOCK;
    464             }
    465             break;
    466         case XkbSA_SetControls:
    467             if (!(flags & XkbSA_ISONoAffectCtrls)) {
    468                 pAction->type = XkbSA_LockControls;
    469                 filter->priv = NO_ISO_LOCK;
    470             }
    471             break;
    472         }
    473     }
    474     return 1;
    475 }
    476 
    477 static CARD32
    478 _XkbPtrAccelExpire(OsTimerPtr timer, CARD32 now, void *arg)
    479 {
    480     XkbSrvInfoPtr xkbi = (XkbSrvInfoPtr) arg;
    481     XkbControlsPtr ctrls = xkbi->desc->ctrls;
    482     int dx, dy;
    483 
    484     if (xkbi->mouseKey == 0)
    485         return 0;
    486 
    487     if (xkbi->mouseKeysAccel) {
    488         if ((xkbi->mouseKeysCounter) < ctrls->mk_time_to_max) {
    489             double step;
    490 
    491             xkbi->mouseKeysCounter++;
    492             step = xkbi->mouseKeysCurveFactor *
    493                 pow((double) xkbi->mouseKeysCounter, xkbi->mouseKeysCurve);
    494             if (xkbi->mouseKeysDX < 0)
    495                 dx = floor(((double) xkbi->mouseKeysDX) * step);
    496             else
    497                 dx = ceil(((double) xkbi->mouseKeysDX) * step);
    498             if (xkbi->mouseKeysDY < 0)
    499                 dy = floor(((double) xkbi->mouseKeysDY) * step);
    500             else
    501                 dy = ceil(((double) xkbi->mouseKeysDY) * step);
    502         }
    503         else {
    504             dx = xkbi->mouseKeysDX * ctrls->mk_max_speed;
    505             dy = xkbi->mouseKeysDY * ctrls->mk_max_speed;
    506         }
    507         if (xkbi->mouseKeysFlags & XkbSA_MoveAbsoluteX)
    508             dx = xkbi->mouseKeysDX;
    509         if (xkbi->mouseKeysFlags & XkbSA_MoveAbsoluteY)
    510             dy = xkbi->mouseKeysDY;
    511     }
    512     else {
    513         dx = xkbi->mouseKeysDX;
    514         dy = xkbi->mouseKeysDY;
    515     }
    516     XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags, dx, dy);
    517     return xkbi->desc->ctrls->mk_interval;
    518 }
    519 
    520 static int
    521 _XkbFilterPointerMove(XkbSrvInfoPtr xkbi,
    522                       XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
    523 {
    524     int x, y;
    525     Bool accel;
    526 
    527     if (filter->keycode == 0) { /* initial press */
    528         filter->keycode = keycode;
    529         filter->active = 1;
    530         filter->filterOthers = 0;
    531         filter->priv = 0;
    532         filter->filter = _XkbFilterPointerMove;
    533         filter->upAction = *pAction;
    534         xkbi->mouseKeysCounter = 0;
    535         xkbi->mouseKey = keycode;
    536         accel = ((pAction->ptr.flags & XkbSA_NoAcceleration) == 0);
    537         x = XkbPtrActionX(&pAction->ptr);
    538         y = XkbPtrActionY(&pAction->ptr);
    539         XkbFakePointerMotion(xkbi->device, pAction->ptr.flags, x, y);
    540         AccessXCancelRepeatKey(xkbi, keycode);
    541         xkbi->mouseKeysAccel = accel &&
    542             (xkbi->desc->ctrls->enabled_ctrls & XkbMouseKeysAccelMask);
    543         xkbi->mouseKeysFlags = pAction->ptr.flags;
    544         xkbi->mouseKeysDX = XkbPtrActionX(&pAction->ptr);
    545         xkbi->mouseKeysDY = XkbPtrActionY(&pAction->ptr);
    546         xkbi->mouseKeyTimer = TimerSet(xkbi->mouseKeyTimer, 0,
    547                                        xkbi->desc->ctrls->mk_delay,
    548                                        _XkbPtrAccelExpire, (void *) xkbi);
    549     }
    550     else if (filter->keycode == keycode) {
    551         filter->active = 0;
    552         if (xkbi->mouseKey == keycode) {
    553             xkbi->mouseKey = 0;
    554             xkbi->mouseKeyTimer = TimerSet(xkbi->mouseKeyTimer, 0, 0,
    555                                            NULL, NULL);
    556         }
    557     }
    558     return 0;
    559 }
    560 
    561 static int
    562 _XkbFilterPointerBtn(XkbSrvInfoPtr xkbi,
    563                      XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
    564 {
    565     if (filter->keycode == 0) { /* initial press */
    566         int button = pAction->btn.button;
    567 
    568         if (button == XkbSA_UseDfltButton)
    569             button = xkbi->desc->ctrls->mk_dflt_btn;
    570 
    571         filter->keycode = keycode;
    572         filter->active = 1;
    573         filter->filterOthers = 0;
    574         filter->priv = 0;
    575         filter->filter = _XkbFilterPointerBtn;
    576         filter->upAction = *pAction;
    577         filter->upAction.btn.button = button;
    578         switch (pAction->type) {
    579         case XkbSA_LockPtrBtn:
    580             if (((xkbi->lockedPtrButtons & (1 << button)) == 0) &&
    581                 ((pAction->btn.flags & XkbSA_LockNoLock) == 0)) {
    582                 xkbi->lockedPtrButtons |= (1 << button);
    583                 AccessXCancelRepeatKey(xkbi, keycode);
    584                 XkbFakeDeviceButton(xkbi->device, 1, button);
    585                 filter->upAction.type = XkbSA_NoAction;
    586             }
    587             break;
    588         case XkbSA_PtrBtn:
    589         {
    590             register int i, nClicks;
    591 
    592             AccessXCancelRepeatKey(xkbi, keycode);
    593             if (pAction->btn.count > 0) {
    594                 nClicks = pAction->btn.count;
    595                 for (i = 0; i < nClicks; i++) {
    596                     XkbFakeDeviceButton(xkbi->device, 1, button);
    597                     XkbFakeDeviceButton(xkbi->device, 0, button);
    598                 }
    599                 filter->upAction.type = XkbSA_NoAction;
    600             }
    601             else
    602                 XkbFakeDeviceButton(xkbi->device, 1, button);
    603         }
    604             break;
    605         case XkbSA_SetPtrDflt:
    606         {
    607             XkbControlsPtr ctrls = xkbi->desc->ctrls;
    608             XkbControlsRec old;
    609             xkbControlsNotify cn;
    610 
    611             old = *ctrls;
    612             AccessXCancelRepeatKey(xkbi, keycode);
    613             switch (pAction->dflt.affect) {
    614             case XkbSA_AffectDfltBtn:
    615                 if (pAction->dflt.flags & XkbSA_DfltBtnAbsolute)
    616                     ctrls->mk_dflt_btn = XkbSAPtrDfltValue(&pAction->dflt);
    617                 else {
    618                     ctrls->mk_dflt_btn += XkbSAPtrDfltValue(&pAction->dflt);
    619                     if (ctrls->mk_dflt_btn > 5)
    620                         ctrls->mk_dflt_btn = 5;
    621                     else if (ctrls->mk_dflt_btn < 1)
    622                         ctrls->mk_dflt_btn = 1;
    623                 }
    624                 break;
    625             default:
    626                 ErrorF
    627                     ("Attempt to change unknown pointer default (%d) ignored\n",
    628                      pAction->dflt.affect);
    629                 break;
    630             }
    631             if (XkbComputeControlsNotify(xkbi->device,
    632                                          &old, xkbi->desc->ctrls, &cn, FALSE)) {
    633                 cn.keycode = keycode;
    634                 /* XXX: what about DeviceKeyPress? */
    635                 cn.eventType = KeyPress;
    636                 cn.requestMajor = 0;
    637                 cn.requestMinor = 0;
    638                 XkbSendControlsNotify(xkbi->device, &cn);
    639             }
    640         }
    641             break;
    642         }
    643         return 0;
    644     }
    645     else if (filter->keycode == keycode) {
    646         int button = filter->upAction.btn.button;
    647 
    648         switch (filter->upAction.type) {
    649         case XkbSA_LockPtrBtn:
    650             if (((filter->upAction.btn.flags & XkbSA_LockNoUnlock) != 0) ||
    651                 ((xkbi->lockedPtrButtons & (1 << button)) == 0)) {
    652                 break;
    653             }
    654             xkbi->lockedPtrButtons &= ~(1 << button);
    655 
    656             if (IsMaster(xkbi->device)) {
    657                 XkbMergeLockedPtrBtns(xkbi->device);
    658                 /* One SD still has lock set, don't post event */
    659                 if ((xkbi->lockedPtrButtons & (1 << button)) != 0)
    660                     break;
    661             }
    662 
    663             /* fallthrough */
    664         case XkbSA_PtrBtn:
    665             XkbFakeDeviceButton(xkbi->device, 0, button);
    666             break;
    667         }
    668         filter->active = 0;
    669         return 0;
    670     }
    671     return 1;
    672 }
    673 
    674 static int
    675 _XkbFilterControls(XkbSrvInfoPtr xkbi,
    676                    XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
    677 {
    678     XkbControlsRec old;
    679     XkbControlsPtr ctrls;
    680     DeviceIntPtr kbd;
    681     unsigned int change;
    682     XkbEventCauseRec cause;
    683 
    684     kbd = xkbi->device;
    685     ctrls = xkbi->desc->ctrls;
    686     old = *ctrls;
    687     if (filter->keycode == 0) { /* initial press */
    688         AccessXCancelRepeatKey(xkbi, keycode);
    689         filter->keycode = keycode;
    690         filter->active = 1;
    691         filter->filterOthers = 0;
    692         change = XkbActionCtrls(&pAction->ctrls);
    693         filter->priv = change;
    694         filter->filter = _XkbFilterControls;
    695         filter->upAction = *pAction;
    696 
    697         if (pAction->type == XkbSA_LockControls) {
    698             filter->priv = (ctrls->enabled_ctrls & change);
    699             change &= ~ctrls->enabled_ctrls;
    700         }
    701 
    702         if (change) {
    703             xkbControlsNotify cn;
    704             XkbSrvLedInfoPtr sli;
    705 
    706             ctrls->enabled_ctrls |= change;
    707             if (XkbComputeControlsNotify(kbd, &old, ctrls, &cn, FALSE)) {
    708                 cn.keycode = keycode;
    709                 /* XXX: what about DeviceKeyPress? */
    710                 cn.eventType = KeyPress;
    711                 cn.requestMajor = 0;
    712                 cn.requestMinor = 0;
    713                 XkbSendControlsNotify(kbd, &cn);
    714             }
    715 
    716             XkbSetCauseKey(&cause, keycode, KeyPress);
    717 
    718             /* If sticky keys were disabled, clear all locks and latches */
    719             if ((old.enabled_ctrls & XkbStickyKeysMask) &&
    720                 (!(ctrls->enabled_ctrls & XkbStickyKeysMask))) {
    721                 XkbClearAllLatchesAndLocks(kbd, xkbi, FALSE, &cause);
    722             }
    723             sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass, XkbDfltXIId, 0);
    724             XkbUpdateIndicators(kbd, sli->usesControls, TRUE, NULL, &cause);
    725             if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask))
    726                 XkbDDXAccessXBeep(kbd, _BEEP_FEATURE_ON, change);
    727         }
    728     }
    729     else if (filter->keycode == keycode) {
    730         change = filter->priv;
    731         if (change) {
    732             xkbControlsNotify cn;
    733             XkbSrvLedInfoPtr sli;
    734 
    735             ctrls->enabled_ctrls &= ~change;
    736             if (XkbComputeControlsNotify(kbd, &old, ctrls, &cn, FALSE)) {
    737                 cn.keycode = keycode;
    738                 cn.eventType = KeyRelease;
    739                 cn.requestMajor = 0;
    740                 cn.requestMinor = 0;
    741                 XkbSendControlsNotify(kbd, &cn);
    742             }
    743 
    744             XkbSetCauseKey(&cause, keycode, KeyRelease);
    745             /* If sticky keys were disabled, clear all locks and latches */
    746             if ((old.enabled_ctrls & XkbStickyKeysMask) &&
    747                 (!(ctrls->enabled_ctrls & XkbStickyKeysMask))) {
    748                 XkbClearAllLatchesAndLocks(kbd, xkbi, FALSE, &cause);
    749             }
    750             sli = XkbFindSrvLedInfo(kbd, XkbDfltXIClass, XkbDfltXIId, 0);
    751             XkbUpdateIndicators(kbd, sli->usesControls, TRUE, NULL, &cause);
    752             if (XkbAX_NeedFeedback(ctrls, XkbAX_FeatureFBMask))
    753                 XkbDDXAccessXBeep(kbd, _BEEP_FEATURE_OFF, change);
    754         }
    755         filter->keycode = 0;
    756         filter->active = 0;
    757     }
    758     return 1;
    759 }
    760 
    761 static int
    762 _XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
    763                         XkbFilterPtr filter,
    764                         unsigned keycode, XkbAction *pAction)
    765 {
    766     XkbMessageAction *pMsg;
    767     DeviceIntPtr kbd;
    768 
    769     if ((filter->keycode != 0) && (filter->keycode != keycode))
    770 	return 1;
    771 
    772     /* This can happen if the key repeats, and the state (modifiers or group)
    773        changes meanwhile. */
    774     if ((filter->keycode == keycode) && pAction &&
    775 	(pAction->type != XkbSA_ActionMessage))
    776 	return 1;
    777 
    778     kbd = xkbi->device;
    779     if (filter->keycode == 0) { /* initial press */
    780         pMsg = &pAction->msg;
    781         if ((pMsg->flags & XkbSA_MessageOnRelease) ||
    782             ((pMsg->flags & XkbSA_MessageGenKeyEvent) == 0)) {
    783             filter->keycode = keycode;
    784             filter->active = 1;
    785             filter->filterOthers = 0;
    786             filter->priv = 0;
    787             filter->filter = _XkbFilterActionMessage;
    788             filter->upAction = *pAction;
    789         }
    790         if (pMsg->flags & XkbSA_MessageOnPress) {
    791             xkbActionMessage msg;
    792 
    793             msg.keycode = keycode;
    794             msg.press = 1;
    795             msg.keyEventFollows =
    796                 ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
    797             memcpy((char *) msg.message, (char *) pMsg->message,
    798                    XkbActionMessageLength);
    799             XkbSendActionMessage(kbd, &msg);
    800         }
    801         return ((pAction->msg.flags & XkbSA_MessageGenKeyEvent) != 0);
    802     }
    803     else if (filter->keycode == keycode) {
    804         pMsg = &filter->upAction.msg;
    805 	if (pAction == NULL) {
    806 	    if (pMsg->flags & XkbSA_MessageOnRelease) {
    807 		xkbActionMessage msg;
    808 
    809 		msg.keycode = keycode;
    810 		msg.press = 0;
    811 		msg.keyEventFollows =
    812 		    ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
    813 		memcpy((char *) msg.message, (char *) pMsg->message,
    814 		       XkbActionMessageLength);
    815 		XkbSendActionMessage(kbd, &msg);
    816 	    }
    817 	    filter->keycode = 0;
    818 	    filter->active = 0;
    819 	    return ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
    820 	} else if (memcmp(pMsg, pAction, 8) == 0) {
    821 	    /* Repeat: If we send the same message, avoid multiple messages
    822 	       on release from piling up. */
    823 	    filter->keycode = 0;
    824 	    filter->active = 0;
    825         }
    826     }
    827     return 1;
    828 }
    829 
    830 static int
    831 _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
    832                       XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
    833 {
    834     DeviceEvent ev;
    835     int x, y;
    836     XkbStateRec old, old_prev;
    837     unsigned mods, mask;
    838     xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
    839     ProcessInputProc backupproc;
    840 
    841     if ((filter->keycode != 0) && (filter->keycode != keycode))
    842         return 1;
    843 
    844     /* This can happen if the key repeats, and the state (modifiers or group)
    845        changes meanwhile. */
    846     if ((filter->keycode == keycode) && pAction &&
    847 	(pAction->type != XkbSA_RedirectKey))
    848 	return 1;
    849 
    850     /* never actually used uninitialised, but gcc isn't smart enough
    851      * to work that out. */
    852     memset(&old, 0, sizeof(old));
    853     memset(&old_prev, 0, sizeof(old_prev));
    854     memset(&ev, 0, sizeof(ev));
    855 
    856     GetSpritePosition(xkbi->device, &x, &y);
    857     ev.header = ET_Internal;
    858     ev.length = sizeof(DeviceEvent);
    859     ev.time = GetTimeInMillis();
    860     ev.root_x = x;
    861     ev.root_y = y;
    862     /* redirect actions do not work across devices, therefore the following is
    863      * correct: */
    864     ev.deviceid = xkbi->device->id;
    865     /* filter->priv must be set up by the caller for the initial press. */
    866     ev.sourceid = filter->priv;
    867 
    868     if (filter->keycode == 0) { /* initial press */
    869         if ((pAction->redirect.new_key < xkbi->desc->min_key_code) ||
    870             (pAction->redirect.new_key > xkbi->desc->max_key_code)) {
    871             return 1;
    872         }
    873         filter->keycode = keycode;
    874         filter->active = 1;
    875         filter->filterOthers = 0;
    876         filter->filter = _XkbFilterRedirectKey;
    877         filter->upAction = *pAction;
    878 
    879         ev.type = ET_KeyPress;
    880         ev.detail.key = pAction->redirect.new_key;
    881 
    882         mask = XkbSARedirectVModsMask(&pAction->redirect);
    883         mods = XkbSARedirectVMods(&pAction->redirect);
    884         if (mask)
    885             XkbVirtualModsToReal(xkbi->desc, mask, &mask);
    886         if (mods)
    887             XkbVirtualModsToReal(xkbi->desc, mods, &mods);
    888         mask |= pAction->redirect.mods_mask;
    889         mods |= pAction->redirect.mods;
    890 
    891         if (mask || mods) {
    892             old = xkbi->state;
    893             old_prev = xkbi->prev_state;
    894             xkbi->state.base_mods &= ~mask;
    895             xkbi->state.base_mods |= (mods & mask);
    896             xkbi->state.latched_mods &= ~mask;
    897             xkbi->state.latched_mods |= (mods & mask);
    898             xkbi->state.locked_mods &= ~mask;
    899             xkbi->state.locked_mods |= (mods & mask);
    900             XkbComputeDerivedState(xkbi);
    901             xkbi->prev_state = xkbi->state;
    902         }
    903 
    904         UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
    905         xkbi->device->public.processInputProc((InternalEvent *) &ev,
    906                                               xkbi->device);
    907         COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
    908                                      xkbUnwrapProc);
    909 
    910         if (mask || mods) {
    911             xkbi->state = old;
    912             xkbi->prev_state = old_prev;
    913         }
    914 	return 0;
    915     }
    916     else {
    917 	/* If it is a key release, or we redirect to another key, release the
    918 	   previous new_key.  Otherwise, repeat. */
    919 	ev.detail.key = filter->upAction.redirect.new_key;
    920 	if (pAction == NULL ||  ev.detail.key != pAction->redirect.new_key) {
    921 	    ev.type = ET_KeyRelease;
    922 	    filter->active = 0;
    923 	}
    924 	else {
    925 	    ev.type = ET_KeyPress;
    926 	    ev.key_repeat = TRUE;
    927 	}
    928 
    929 	mask = XkbSARedirectVModsMask(&filter->upAction.redirect);
    930 	mods = XkbSARedirectVMods(&filter->upAction.redirect);
    931 	if (mask)
    932 	    XkbVirtualModsToReal(xkbi->desc, mask, &mask);
    933 	if (mods)
    934 	    XkbVirtualModsToReal(xkbi->desc, mods, &mods);
    935 	mask |= filter->upAction.redirect.mods_mask;
    936 	mods |= filter->upAction.redirect.mods;
    937 
    938 	if (mask || mods) {
    939 	    old = xkbi->state;
    940 	    old_prev = xkbi->prev_state;
    941 	    xkbi->state.base_mods &= ~mask;
    942 	    xkbi->state.base_mods |= (mods & mask);
    943 	    xkbi->state.latched_mods &= ~mask;
    944 	    xkbi->state.latched_mods |= (mods & mask);
    945 	    xkbi->state.locked_mods &= ~mask;
    946 	    xkbi->state.locked_mods |= (mods & mask);
    947 	    XkbComputeDerivedState(xkbi);
    948 	    xkbi->prev_state = xkbi->state;
    949 	}
    950 
    951 	UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
    952 	xkbi->device->public.processInputProc((InternalEvent *) &ev,
    953 					      xkbi->device);
    954 	COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
    955 				     xkbUnwrapProc);
    956 
    957 	if (mask || mods) {
    958 	    xkbi->state = old;
    959 	    xkbi->prev_state = old_prev;
    960 	}
    961 
    962 	/* We return 1 in case we have sent a release event because the new_key
    963 	   has changed.  Then, subsequently, we will call this function again
    964 	   with the same pAction, which will create the press for the new
    965 	   new_key. */
    966 	return (pAction && ev.detail.key != pAction->redirect.new_key);
    967     }
    968 }
    969 
    970 static int
    971 _XkbFilterSwitchScreen(XkbSrvInfoPtr xkbi,
    972                        XkbFilterPtr filter,
    973                        unsigned keycode, XkbAction *pAction)
    974 {
    975     DeviceIntPtr dev = xkbi->device;
    976 
    977     if (dev == inputInfo.keyboard)
    978         return 0;
    979 
    980     if (filter->keycode == 0) { /* initial press */
    981         filter->keycode = keycode;
    982         filter->active = 1;
    983         filter->filterOthers = 0;
    984         filter->filter = _XkbFilterSwitchScreen;
    985         AccessXCancelRepeatKey(xkbi, keycode);
    986         XkbDDXSwitchScreen(dev, keycode, pAction);
    987         return 0;
    988     }
    989     else if (filter->keycode == keycode) {
    990         filter->active = 0;
    991         return 0;
    992     }
    993     return 1;
    994 }
    995 
    996 static int
    997 XkbHandlePrivate(DeviceIntPtr dev, KeyCode keycode, XkbAction *pAction)
    998 {
    999     XkbAnyAction *xkb_act = &(pAction->any);
   1000 
   1001     if (xkb_act->type == XkbSA_XFree86Private) {
   1002         char msgbuf[XkbAnyActionDataSize + 1];
   1003 
   1004         memcpy(msgbuf, xkb_act->data, XkbAnyActionDataSize);
   1005         msgbuf[XkbAnyActionDataSize] = '\0';
   1006 
   1007         if (strcasecmp(msgbuf, "prgrbs") == 0) {
   1008             DeviceIntPtr tmp;
   1009 
   1010             LogMessage(X_INFO, "Printing all currently active device grabs:\n");
   1011             for (tmp = inputInfo.devices; tmp; tmp = tmp->next)
   1012                 if (tmp->deviceGrab.grab)
   1013                     PrintDeviceGrabInfo(tmp);
   1014             LogMessage(X_INFO, "End list of active device grabs\n");
   1015 
   1016             PrintPassiveGrabs();
   1017         }
   1018         else if (strcasecmp(msgbuf, "ungrab") == 0) {
   1019             LogMessage(X_INFO, "Ungrabbing devices\n");
   1020             UngrabAllDevices(FALSE);
   1021         }
   1022         else if (strcasecmp(msgbuf, "clsgrb") == 0) {
   1023             LogMessage(X_INFO, "Clear grabs\n");
   1024             UngrabAllDevices(TRUE);
   1025         }
   1026         else if (strcasecmp(msgbuf, "prwins") == 0) {
   1027             LogMessage(X_INFO, "Printing window tree\n");
   1028             PrintWindowTree();
   1029         }
   1030     }
   1031 
   1032     return XkbDDXPrivate(dev, keycode, pAction);
   1033 }
   1034 
   1035 static int
   1036 _XkbFilterXF86Private(XkbSrvInfoPtr xkbi,
   1037                       XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
   1038 {
   1039     DeviceIntPtr dev = xkbi->device;
   1040 
   1041     if (dev == inputInfo.keyboard)
   1042         return 0;
   1043 
   1044     if (filter->keycode == 0) { /* initial press */
   1045         filter->keycode = keycode;
   1046         filter->active = 1;
   1047         filter->filterOthers = 0;
   1048         filter->filter = _XkbFilterXF86Private;
   1049         XkbHandlePrivate(dev, keycode, pAction);
   1050         return 0;
   1051     }
   1052     else if (filter->keycode == keycode) {
   1053         filter->active = 0;
   1054         return 0;
   1055     }
   1056     return 1;
   1057 }
   1058 
   1059 static int
   1060 _XkbFilterDeviceBtn(XkbSrvInfoPtr xkbi,
   1061                     XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
   1062 {
   1063     if (xkbi->device == inputInfo.keyboard)
   1064         return 0;
   1065 
   1066     if (filter->keycode == 0) { /* initial press */
   1067         DeviceIntPtr dev;
   1068         int button;
   1069 
   1070         _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient,
   1071                                DixUnknownAccess, &button);
   1072         if (!dev || !dev->public.on)
   1073             return 1;
   1074 
   1075         button = pAction->devbtn.button;
   1076         if ((button < 1) || (button > dev->button->numButtons))
   1077             return 1;
   1078 
   1079         filter->keycode = keycode;
   1080         filter->active = 1;
   1081         filter->filterOthers = 0;
   1082         filter->priv = 0;
   1083         filter->filter = _XkbFilterDeviceBtn;
   1084         filter->upAction = *pAction;
   1085         switch (pAction->type) {
   1086         case XkbSA_LockDeviceBtn:
   1087             if ((pAction->devbtn.flags & XkbSA_LockNoLock) ||
   1088                 BitIsOn(dev->button->down, button))
   1089                 return 0;
   1090             XkbFakeDeviceButton(dev, TRUE, button);
   1091             filter->upAction.type = XkbSA_NoAction;
   1092             break;
   1093         case XkbSA_DeviceBtn:
   1094             if (pAction->devbtn.count > 0) {
   1095                 int nClicks, i;
   1096 
   1097                 nClicks = pAction->btn.count;
   1098                 for (i = 0; i < nClicks; i++) {
   1099                     XkbFakeDeviceButton(dev, TRUE, button);
   1100                     XkbFakeDeviceButton(dev, FALSE, button);
   1101                 }
   1102                 filter->upAction.type = XkbSA_NoAction;
   1103             }
   1104             else
   1105                 XkbFakeDeviceButton(dev, TRUE, button);
   1106             break;
   1107         }
   1108     }
   1109     else if (filter->keycode == keycode) {
   1110         DeviceIntPtr dev;
   1111         int button;
   1112 
   1113         filter->active = 0;
   1114         _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device,
   1115                                serverClient, DixUnknownAccess, &button);
   1116         if (!dev || !dev->public.on)
   1117             return 1;
   1118 
   1119         button = filter->upAction.btn.button;
   1120         switch (filter->upAction.type) {
   1121         case XkbSA_LockDeviceBtn:
   1122             if ((filter->upAction.devbtn.flags & XkbSA_LockNoUnlock) ||
   1123                 !BitIsOn(dev->button->down, button))
   1124                 return 0;
   1125             XkbFakeDeviceButton(dev, FALSE, button);
   1126             break;
   1127         case XkbSA_DeviceBtn:
   1128             XkbFakeDeviceButton(dev, FALSE, button);
   1129             break;
   1130         }
   1131         filter->active = 0;
   1132     }
   1133     return 0;
   1134 }
   1135 
   1136 static XkbFilterPtr
   1137 _XkbNextFreeFilter(XkbSrvInfoPtr xkbi)
   1138 {
   1139     register int i;
   1140 
   1141     if (xkbi->szFilters == 0) {
   1142         xkbi->szFilters = 4;
   1143         xkbi->filters = calloc(xkbi->szFilters, sizeof(XkbFilterRec));
   1144         /* 6/21/93 (ef) -- XXX! deal with allocation failure */
   1145     }
   1146     for (i = 0; i < xkbi->szFilters; i++) {
   1147         if (!xkbi->filters[i].active) {
   1148             xkbi->filters[i].keycode = 0;
   1149             return &xkbi->filters[i];
   1150         }
   1151     }
   1152     xkbi->szFilters *= 2;
   1153     xkbi->filters = reallocarray(xkbi->filters,
   1154                                  xkbi->szFilters, sizeof(XkbFilterRec));
   1155     /* 6/21/93 (ef) -- XXX! deal with allocation failure */
   1156     memset(&xkbi->filters[xkbi->szFilters / 2], 0,
   1157            (xkbi->szFilters / 2) * sizeof(XkbFilterRec));
   1158     return &xkbi->filters[xkbi->szFilters / 2];
   1159 }
   1160 
   1161 static int
   1162 _XkbApplyFilters(XkbSrvInfoPtr xkbi, unsigned kc, XkbAction *pAction)
   1163 {
   1164     register int i, send;
   1165 
   1166     send = 1;
   1167     for (i = 0; i < xkbi->szFilters; i++) {
   1168         if ((xkbi->filters[i].active) && (xkbi->filters[i].filter))
   1169             send =
   1170                 ((*xkbi->filters[i].filter) (xkbi, &xkbi->filters[i], kc,
   1171                                              pAction)
   1172                  && send);
   1173     }
   1174     return send;
   1175 }
   1176 
   1177 static int
   1178 _XkbEnsureStateChange(XkbSrvInfoPtr xkbi)
   1179 {
   1180     Bool genStateNotify = FALSE;
   1181 
   1182     /* The state may change, so if we're not in the middle of sending a state
   1183      * notify, prepare for it */
   1184     if ((xkbi->flags & _XkbStateNotifyInProgress) == 0) {
   1185         xkbi->prev_state = xkbi->state;
   1186         xkbi->flags |= _XkbStateNotifyInProgress;
   1187         genStateNotify = TRUE;
   1188     }
   1189 
   1190     return genStateNotify;
   1191 }
   1192 
   1193 static void
   1194 _XkbApplyState(DeviceIntPtr dev, Bool genStateNotify, int evtype, int key)
   1195 {
   1196     XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
   1197     int changed;
   1198 
   1199     XkbComputeDerivedState(xkbi);
   1200 
   1201     changed = XkbStateChangedFlags(&xkbi->prev_state, &xkbi->state);
   1202     if (genStateNotify) {
   1203         if (changed) {
   1204             xkbStateNotify sn;
   1205 
   1206             sn.keycode = key;
   1207             sn.eventType = evtype;
   1208             sn.requestMajor = sn.requestMinor = 0;
   1209             sn.changed = changed;
   1210             XkbSendStateNotify(dev, &sn);
   1211         }
   1212         xkbi->flags &= ~_XkbStateNotifyInProgress;
   1213     }
   1214 
   1215     changed = XkbIndicatorsToUpdate(dev, changed, FALSE);
   1216     if (changed) {
   1217         XkbEventCauseRec cause;
   1218         XkbSetCauseKey(&cause, key, evtype);
   1219         XkbUpdateIndicators(dev, changed, FALSE, NULL, &cause);
   1220     }
   1221 }
   1222 
   1223 void
   1224 XkbPushLockedStateToSlaves(DeviceIntPtr master, int evtype, int key)
   1225 {
   1226     DeviceIntPtr dev;
   1227     Bool genStateNotify;
   1228 
   1229     nt_list_for_each_entry(dev, inputInfo.devices, next) {
   1230         if (!dev->key || GetMaster(dev, MASTER_KEYBOARD) != master)
   1231             continue;
   1232 
   1233         genStateNotify = _XkbEnsureStateChange(dev->key->xkbInfo);
   1234 
   1235         dev->key->xkbInfo->state.locked_mods =
   1236             master->key->xkbInfo->state.locked_mods;
   1237 
   1238         _XkbApplyState(dev, genStateNotify, evtype, key);
   1239     }
   1240 }
   1241 
   1242 static void
   1243 XkbActionGetFilter(DeviceIntPtr dev, DeviceEvent *event, KeyCode key,
   1244                    XkbAction *act, int *sendEvent)
   1245 {
   1246     XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
   1247     XkbFilterPtr filter;
   1248 
   1249     /* For focus events, we only want to run actions which update our state to
   1250      * (hopefully vaguely kinda) match that of the host server, rather than
   1251      * actually execute anything. For example, if we enter our VT with
   1252      * Ctrl+Alt+Backspace held down, we don't want to terminate our server
   1253      * immediately, but we _do_ want Ctrl+Alt to be latched down, so if
   1254      * Backspace is released and then pressed again, the server will terminate.
   1255      *
   1256      * This is pretty flaky, and we should in fact inherit the complete state
   1257      * from the host server. There are some state combinations that we cannot
   1258      * express by running the state machine over every key, e.g. if AltGr+Shift
   1259      * generates a different state to Shift+AltGr. */
   1260     if (event->source_type == EVENT_SOURCE_FOCUS) {
   1261         switch (act->type) {
   1262         case XkbSA_SetMods:
   1263         case XkbSA_SetGroup:
   1264         case XkbSA_LatchMods:
   1265         case XkbSA_LatchGroup:
   1266         case XkbSA_LockMods:
   1267         case XkbSA_LockGroup:
   1268             break;
   1269         default:
   1270             *sendEvent = 1;
   1271             return;
   1272         }
   1273     }
   1274 
   1275     switch (act->type) {
   1276     case XkbSA_SetMods:
   1277     case XkbSA_SetGroup:
   1278         filter = _XkbNextFreeFilter(xkbi);
   1279         *sendEvent = _XkbFilterSetState(xkbi, filter, key, act);
   1280         break;
   1281     case XkbSA_LatchMods:
   1282     case XkbSA_LatchGroup:
   1283         filter = _XkbNextFreeFilter(xkbi);
   1284         *sendEvent = _XkbFilterLatchState(xkbi, filter, key, act);
   1285         break;
   1286     case XkbSA_LockMods:
   1287     case XkbSA_LockGroup:
   1288         filter = _XkbNextFreeFilter(xkbi);
   1289         *sendEvent = _XkbFilterLockState(xkbi, filter, key, act);
   1290         break;
   1291     case XkbSA_ISOLock:
   1292         filter = _XkbNextFreeFilter(xkbi);
   1293         *sendEvent = _XkbFilterISOLock(xkbi, filter, key, act);
   1294         break;
   1295     case XkbSA_MovePtr:
   1296         filter = _XkbNextFreeFilter(xkbi);
   1297         *sendEvent = _XkbFilterPointerMove(xkbi, filter, key, act);
   1298         break;
   1299     case XkbSA_PtrBtn:
   1300     case XkbSA_LockPtrBtn:
   1301     case XkbSA_SetPtrDflt:
   1302         filter = _XkbNextFreeFilter(xkbi);
   1303         *sendEvent = _XkbFilterPointerBtn(xkbi, filter, key, act);
   1304         break;
   1305     case XkbSA_Terminate:
   1306         *sendEvent = XkbDDXTerminateServer(dev, key, act);
   1307         break;
   1308     case XkbSA_SwitchScreen:
   1309         filter = _XkbNextFreeFilter(xkbi);
   1310         *sendEvent = _XkbFilterSwitchScreen(xkbi, filter, key, act);
   1311         break;
   1312     case XkbSA_SetControls:
   1313     case XkbSA_LockControls:
   1314         filter = _XkbNextFreeFilter(xkbi);
   1315         *sendEvent = _XkbFilterControls(xkbi, filter, key, act);
   1316         break;
   1317     case XkbSA_ActionMessage:
   1318         filter = _XkbNextFreeFilter(xkbi);
   1319         *sendEvent = _XkbFilterActionMessage(xkbi, filter, key, act);
   1320         break;
   1321     case XkbSA_RedirectKey:
   1322         filter = _XkbNextFreeFilter(xkbi);
   1323         /* redirect actions must create a new DeviceEvent.  The
   1324          * source device id for this event cannot be obtained from
   1325          * xkbi, so we pass it here explicitly. The field deviceid
   1326          * equals to xkbi->device->id. */
   1327         filter->priv = event->sourceid;
   1328         *sendEvent = _XkbFilterRedirectKey(xkbi, filter, key, act);
   1329         break;
   1330     case XkbSA_DeviceBtn:
   1331     case XkbSA_LockDeviceBtn:
   1332         filter = _XkbNextFreeFilter(xkbi);
   1333         *sendEvent = _XkbFilterDeviceBtn(xkbi, filter, key, act);
   1334         break;
   1335     case XkbSA_XFree86Private:
   1336         filter = _XkbNextFreeFilter(xkbi);
   1337         *sendEvent = _XkbFilterXF86Private(xkbi, filter, key, act);
   1338         break;
   1339     }
   1340 }
   1341 
   1342 void
   1343 XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
   1344 {
   1345     int key, bit, i;
   1346     XkbSrvInfoPtr xkbi;
   1347     KeyClassPtr keyc;
   1348     int sendEvent;
   1349     Bool genStateNotify;
   1350     XkbAction act;
   1351     Bool keyEvent;
   1352     Bool pressEvent;
   1353     ProcessInputProc backupproc;
   1354 
   1355     xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
   1356 
   1357     keyc = kbd->key;
   1358     xkbi = keyc->xkbInfo;
   1359     key = event->detail.key;
   1360 
   1361     genStateNotify = _XkbEnsureStateChange(xkbi);
   1362 
   1363     xkbi->clearMods = xkbi->setMods = 0;
   1364     xkbi->groupChange = 0;
   1365 
   1366     sendEvent = 1;
   1367     keyEvent = ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease));
   1368     pressEvent = ((event->type == ET_KeyPress) ||
   1369                   (event->type == ET_ButtonPress));
   1370 
   1371     if (pressEvent) {
   1372         if (keyEvent)
   1373             act = XkbGetKeyAction(xkbi, &xkbi->state, key);
   1374         else {
   1375             act = XkbGetButtonAction(kbd, dev, key);
   1376             key |= BTN_ACT_FLAG;
   1377         }
   1378 
   1379         sendEvent = _XkbApplyFilters(xkbi, key, &act);
   1380         if (sendEvent)
   1381             XkbActionGetFilter(dev, event, key, &act, &sendEvent);
   1382     }
   1383     else {
   1384         if (!keyEvent)
   1385             key |= BTN_ACT_FLAG;
   1386         sendEvent = _XkbApplyFilters(xkbi, key, NULL);
   1387     }
   1388 
   1389     if (xkbi->groupChange != 0)
   1390         xkbi->state.base_group += xkbi->groupChange;
   1391     if (xkbi->setMods) {
   1392         for (i = 0, bit = 1; xkbi->setMods; i++, bit <<= 1) {
   1393             if (xkbi->setMods & bit) {
   1394                 keyc->modifierKeyCount[i]++;
   1395                 xkbi->state.base_mods |= bit;
   1396                 xkbi->setMods &= ~bit;
   1397             }
   1398         }
   1399     }
   1400     if (xkbi->clearMods) {
   1401         for (i = 0, bit = 1; xkbi->clearMods; i++, bit <<= 1) {
   1402             if (xkbi->clearMods & bit) {
   1403                 keyc->modifierKeyCount[i]--;
   1404                 if (keyc->modifierKeyCount[i] <= 0) {
   1405                     xkbi->state.base_mods &= ~bit;
   1406                     keyc->modifierKeyCount[i] = 0;
   1407                 }
   1408                 xkbi->clearMods &= ~bit;
   1409             }
   1410         }
   1411     }
   1412 
   1413     if (sendEvent) {
   1414         DeviceIntPtr tmpdev;
   1415 
   1416         if (keyEvent)
   1417             tmpdev = dev;
   1418         else
   1419             tmpdev = GetMaster(dev, POINTER_OR_FLOAT);
   1420 
   1421         UNWRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr, backupproc);
   1422         dev->public.processInputProc((InternalEvent *) event, tmpdev);
   1423         COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
   1424                                      backupproc, xkbUnwrapProc);
   1425     }
   1426     else if (keyEvent) {
   1427         FixKeyState(event, dev);
   1428     }
   1429 
   1430     _XkbApplyState(dev, genStateNotify, event->type, key);
   1431     XkbPushLockedStateToSlaves(dev, event->type, key);
   1432 }
   1433 
   1434 int
   1435 XkbLatchModifiers(DeviceIntPtr pXDev, CARD8 mask, CARD8 latches)
   1436 {
   1437     XkbSrvInfoPtr xkbi;
   1438     XkbFilterPtr filter;
   1439     XkbAction act;
   1440     unsigned clear;
   1441 
   1442     if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
   1443         xkbi = pXDev->key->xkbInfo;
   1444         clear = (mask & (~latches));
   1445         xkbi->state.latched_mods &= ~clear;
   1446         /* Clear any pending latch to locks.
   1447          */
   1448         act.type = XkbSA_NoAction;
   1449         _XkbApplyFilters(xkbi, SYNTHETIC_KEYCODE, &act);
   1450         act.type = XkbSA_LatchMods;
   1451         act.mods.flags = 0;
   1452         act.mods.mask = mask & latches;
   1453         filter = _XkbNextFreeFilter(xkbi);
   1454         _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, &act);
   1455         _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE,
   1456                              (XkbAction *) NULL);
   1457         return Success;
   1458     }
   1459     return BadValue;
   1460 }
   1461 
   1462 int
   1463 XkbLatchGroup(DeviceIntPtr pXDev, int group)
   1464 {
   1465     XkbSrvInfoPtr xkbi;
   1466     XkbFilterPtr filter;
   1467     XkbAction act;
   1468 
   1469     if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
   1470         xkbi = pXDev->key->xkbInfo;
   1471         act.type = XkbSA_LatchGroup;
   1472         act.group.flags = 0;
   1473         XkbSASetGroup(&act.group, group);
   1474         filter = _XkbNextFreeFilter(xkbi);
   1475         _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE, &act);
   1476         _XkbFilterLatchState(xkbi, filter, SYNTHETIC_KEYCODE,
   1477                              (XkbAction *) NULL);
   1478         return Success;
   1479     }
   1480     return BadValue;
   1481 }
   1482 
   1483 /***====================================================================***/
   1484 
   1485 void
   1486 XkbClearAllLatchesAndLocks(DeviceIntPtr dev,
   1487                            XkbSrvInfoPtr xkbi,
   1488                            Bool genEv, XkbEventCausePtr cause)
   1489 {
   1490     XkbStateRec os;
   1491     xkbStateNotify sn;
   1492 
   1493     sn.changed = 0;
   1494     os = xkbi->state;
   1495     if (os.latched_mods) {      /* clear all latches */
   1496         XkbLatchModifiers(dev, ~0, 0);
   1497         sn.changed |= XkbModifierLatchMask;
   1498     }
   1499     if (os.latched_group) {
   1500         XkbLatchGroup(dev, 0);
   1501         sn.changed |= XkbGroupLatchMask;
   1502     }
   1503     if (os.locked_mods) {
   1504         xkbi->state.locked_mods = 0;
   1505         sn.changed |= XkbModifierLockMask;
   1506     }
   1507     if (os.locked_group) {
   1508         xkbi->state.locked_group = 0;
   1509         sn.changed |= XkbGroupLockMask;
   1510     }
   1511     if (genEv && sn.changed) {
   1512         CARD32 changed;
   1513 
   1514         XkbComputeDerivedState(xkbi);
   1515         sn.keycode = cause->kc;
   1516         sn.eventType = cause->event;
   1517         sn.requestMajor = cause->mjr;
   1518         sn.requestMinor = cause->mnr;
   1519         sn.changed = XkbStateChangedFlags(&os, &xkbi->state);
   1520         XkbSendStateNotify(dev, &sn);
   1521         changed = XkbIndicatorsToUpdate(dev, sn.changed, FALSE);
   1522         if (changed) {
   1523             XkbUpdateIndicators(dev, changed, TRUE, NULL, cause);
   1524         }
   1525     }
   1526     return;
   1527 }
   1528 
   1529 /*
   1530  * The event is injected into the event processing, not the EQ. Thus,
   1531  * ensure that we restore the master after the event sequence to the
   1532  * original set of classes. Otherwise, the master remains on the XTEST
   1533  * classes and drops events that don't fit into the XTEST layout (e.g.
   1534  * events with more than 2 valuators).
   1535  *
   1536  * FIXME: EQ injection in the processing stage is not designed for, so this
   1537  * is a rather awkward hack. The event list returned by GetPointerEvents()
   1538  * and friends is always prefixed with a DCE if the last _posted_ device was
   1539  * different. For normal events, this sequence then resets the master during
   1540  * the processing stage. Since we inject the PointerKey events in the
   1541  * processing stage though, we need to manually reset to restore the
   1542  * previous order, because the events already in the EQ must be sent for the
   1543  * right device.
   1544  * So we post-fix the event list we get from GPE with a DCE back to the
   1545  * previous slave device.
   1546  *
   1547  * First one on drinking island wins!
   1548  */
   1549 static void
   1550 InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags,
   1551                        ValuatorMask *mask)
   1552 {
   1553     ScreenPtr pScreen;
   1554     InternalEvent *events;
   1555     int nevents, i;
   1556     DeviceIntPtr ptr, mpointer, lastSlave = NULL;
   1557     Bool saveWait;
   1558 
   1559     if (IsMaster(dev)) {
   1560         mpointer = GetMaster(dev, MASTER_POINTER);
   1561         lastSlave = mpointer->lastSlave;
   1562         ptr = GetXTestDevice(mpointer);
   1563     }
   1564     else if (IsFloating(dev))
   1565         ptr = dev;
   1566     else
   1567         return;
   1568 
   1569     events = InitEventList(GetMaximumEventsNum() + 1);
   1570     input_lock();
   1571     pScreen = miPointerGetScreen(ptr);
   1572     saveWait = miPointerSetWaitForUpdate(pScreen, FALSE);
   1573     nevents = GetPointerEvents(events, ptr, type, button, flags, mask);
   1574     if (IsMaster(dev) && (lastSlave && lastSlave != ptr))
   1575         UpdateFromMaster(&events[nevents], lastSlave, DEVCHANGE_POINTER_EVENT,
   1576                          &nevents);
   1577     miPointerSetWaitForUpdate(pScreen, saveWait);
   1578 
   1579     for (i = 0; i < nevents; i++)
   1580         mieqProcessDeviceEvent(ptr, &events[i], NULL);
   1581     input_unlock();
   1582 
   1583     FreeEventList(events, GetMaximumEventsNum());
   1584 }
   1585 
   1586 static void
   1587 XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags, int x, int y)
   1588 {
   1589     ValuatorMask mask;
   1590     int gpe_flags = 0;
   1591 
   1592     /* ignore attached SDs */
   1593     if (!IsMaster(dev) && !IsFloating(dev))
   1594         return;
   1595 
   1596     if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
   1597         gpe_flags = POINTER_ABSOLUTE;
   1598     else
   1599         gpe_flags = POINTER_RELATIVE;
   1600 
   1601     valuator_mask_set_range(&mask, 0, 2, (int[]) {
   1602                             x, y});
   1603 
   1604     InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, &mask);
   1605 }
   1606 
   1607 void
   1608 XkbFakeDeviceButton(DeviceIntPtr dev, Bool press, int button)
   1609 {
   1610     DeviceIntPtr ptr;
   1611     int down;
   1612 
   1613     /* If dev is a slave device, and the SD is attached, do nothing. If we'd
   1614      * post through the attached master pointer we'd get duplicate events.
   1615      *
   1616      * if dev is a master keyboard, post through the XTEST device
   1617      *
   1618      * if dev is a floating slave, post through the device itself.
   1619      */
   1620 
   1621     if (IsMaster(dev)) {
   1622         DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER);
   1623 
   1624         ptr = GetXTestDevice(mpointer);
   1625     }
   1626     else if (IsFloating(dev))
   1627         ptr = dev;
   1628     else
   1629         return;
   1630 
   1631     down = button_is_down(ptr, button, BUTTON_PROCESSED);
   1632     if (press == down)
   1633         return;
   1634 
   1635     InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease,
   1636                            button, 0, NULL);
   1637 }