Home | History | Annotate | Line # | Download | only in Xi
      1 /************************************************************
      2 
      3 Copyright 1989, 1998  The Open Group
      4 
      5 Permission to use, copy, modify, distribute, and sell this software and its
      6 documentation for any purpose is hereby granted without fee, provided that
      7 the above copyright notice appear in all copies and that both that
      8 copyright notice and this permission notice appear in supporting
      9 documentation.
     10 
     11 The above copyright notice and this permission notice shall be included in
     12 all copies or substantial portions of the Software.
     13 
     14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     20 
     21 Except as contained in this notice, the name of The Open Group shall not be
     22 used in advertising or otherwise to promote the sale, use or other dealings
     23 in this Software without prior written authorization from The Open Group.
     24 
     25 Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
     26 
     27 			All Rights Reserved
     28 
     29 Permission to use, copy, modify, and distribute this software and its
     30 documentation for any purpose and without fee is hereby granted,
     31 provided that the above copyright notice appear in all copies and that
     32 both that copyright notice and this permission notice appear in
     33 supporting documentation, and that the name of Hewlett-Packard not be
     34 used in advertising or publicity pertaining to distribution of the
     35 software without specific, written prior permission.
     36 
     37 HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
     38 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
     39 HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
     40 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
     41 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
     42 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
     43 SOFTWARE.
     44 
     45 ********************************************************/
     46 
     47 /*
     48  * Copyright  2010 Collabora Ltd.
     49  * Copyright  2011 Red Hat, Inc.
     50  *
     51  * Permission is hereby granted, free of charge, to any person obtaining a
     52  * copy of this software and associated documentation files (the "Software"),
     53  * to deal in the Software without restriction, including without limitation
     54  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     55  * and/or sell copies of the Software, and to permit persons to whom the
     56  * Software is furnished to do so, subject to the following conditions:
     57  *
     58  * The above copyright notice and this permission notice (including the next
     59  * paragraph) shall be included in all copies or substantial portions of the
     60  * Software.
     61  *
     62  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     63  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     64  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     65  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     66  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     67  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     68  * DEALINGS IN THE SOFTWARE.
     69  *
     70  * Author: Daniel Stone <daniel (at) fooishbar.org>
     71  */
     72 
     73 /********************************************************************
     74  *
     75  *  Routines to register and initialize extension input devices.
     76  *  This also contains ProcessOtherEvent, the routine called from DDX
     77  *  to route extension events.
     78  *
     79  */
     80 
     81 #ifdef HAVE_DIX_CONFIG_H
     82 #include <dix-config.h>
     83 #endif
     84 
     85 #include "inputstr.h"
     86 #include <X11/X.h>
     87 #include <X11/Xproto.h>
     88 #include <X11/extensions/XI.h>
     89 #include <X11/extensions/XIproto.h>
     90 #include <X11/extensions/XI2proto.h>
     91 #include <X11/extensions/geproto.h>
     92 #include "windowstr.h"
     93 #include "miscstruct.h"
     94 #include "region.h"
     95 #include "exevents.h"
     96 #include "extnsionst.h"
     97 #include "exglobals.h"
     98 #include "eventstr.h"
     99 #include "dixevents.h"          /* DeliverFocusedEvent */
    100 #include "dixgrabs.h"           /* CreateGrab() */
    101 #include "scrnintstr.h"
    102 #include "listdev.h"            /* for CopySwapXXXClass */
    103 #include "xace.h"
    104 #include "xiquerydevice.h"      /* For List*Info */
    105 #include "eventconvert.h"
    106 #include "eventstr.h"
    107 #include "inpututils.h"
    108 #include "mi.h"
    109 
    110 #include <X11/extensions/XKBproto.h>
    111 #include "xkbsrv.h"
    112 
    113 #define WID(w) ((w) ? ((w)->drawable.id) : 0)
    114 #define AllModifiersMask ( \
    115 	ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
    116 	Mod3Mask | Mod4Mask | Mod5Mask )
    117 #define AllButtonsMask ( \
    118 	Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
    119 
    120 Bool ShouldFreeInputMasks(WindowPtr /* pWin */ ,
    121                           Bool  /* ignoreSelectedEvents */
    122     );
    123 static Bool MakeInputMasks(WindowPtr    /* pWin */
    124     );
    125 
    126 /*
    127  * Only let the given client know of core events which will affect its
    128  * interpretation of input events, if the client's ClientPointer (or the
    129  * paired keyboard) is the current device.
    130  */
    131 int
    132 XIShouldNotify(ClientPtr client, DeviceIntPtr dev)
    133 {
    134     DeviceIntPtr current_ptr = PickPointer(client);
    135     DeviceIntPtr current_kbd = GetMaster(current_ptr, KEYBOARD_OR_FLOAT);
    136 
    137     if (dev == current_kbd || dev == current_ptr)
    138         return 1;
    139 
    140     return 0;
    141 }
    142 
    143 Bool
    144 IsPointerEvent(InternalEvent *event)
    145 {
    146     switch (event->any.type) {
    147     case ET_ButtonPress:
    148     case ET_ButtonRelease:
    149     case ET_Motion:
    150         /* XXX: enter/leave ?? */
    151         return TRUE;
    152     default:
    153         break;
    154     }
    155     return FALSE;
    156 }
    157 
    158 Bool
    159 IsTouchEvent(InternalEvent *event)
    160 {
    161     switch (event->any.type) {
    162     case ET_TouchBegin:
    163     case ET_TouchUpdate:
    164     case ET_TouchEnd:
    165         return TRUE;
    166     default:
    167         break;
    168     }
    169     return FALSE;
    170 }
    171 
    172 Bool
    173 IsGestureEvent(InternalEvent *event)
    174 {
    175     switch (event->any.type) {
    176     case ET_GesturePinchBegin:
    177     case ET_GesturePinchUpdate:
    178     case ET_GesturePinchEnd:
    179     case ET_GestureSwipeBegin:
    180     case ET_GestureSwipeUpdate:
    181     case ET_GestureSwipeEnd:
    182         return TRUE;
    183     default:
    184         break;
    185     }
    186     return FALSE;
    187 }
    188 
    189 Bool
    190 IsGestureBeginEvent(InternalEvent *event)
    191 {
    192     switch (event->any.type) {
    193     case ET_GesturePinchBegin:
    194     case ET_GestureSwipeBegin:
    195         return TRUE;
    196     default:
    197         break;
    198     }
    199     return FALSE;
    200 }
    201 
    202 Bool
    203 IsGestureEndEvent(InternalEvent *event)
    204 {
    205     switch (event->any.type) {
    206     case ET_GesturePinchEnd:
    207     case ET_GestureSwipeEnd:
    208         return TRUE;
    209     default:
    210         break;
    211     }
    212     return FALSE;
    213 }
    214 
    215 /**
    216  * @return the device matching the deviceid of the device set in the event, or
    217  * NULL if the event is not an XInput event.
    218  */
    219 DeviceIntPtr
    220 XIGetDevice(xEvent *xE)
    221 {
    222     DeviceIntPtr pDev = NULL;
    223 
    224     if (xE->u.u.type == DeviceButtonPress ||
    225         xE->u.u.type == DeviceButtonRelease ||
    226         xE->u.u.type == DeviceMotionNotify ||
    227         xE->u.u.type == ProximityIn ||
    228         xE->u.u.type == ProximityOut || xE->u.u.type == DevicePropertyNotify) {
    229         int rc;
    230         int id;
    231 
    232         id = ((deviceKeyButtonPointer *) xE)->deviceid & ~MORE_EVENTS;
    233 
    234         rc = dixLookupDevice(&pDev, id, serverClient, DixUnknownAccess);
    235         if (rc != Success)
    236             ErrorF("[dix] XIGetDevice failed on XACE restrictions (%d)\n", rc);
    237     }
    238     return pDev;
    239 }
    240 
    241 /**
    242  * Copy the device->key into master->key and send a mapping notify to the
    243  * clients if appropriate.
    244  * master->key needs to be allocated by the caller.
    245  *
    246  * Device is the slave device. If it is attached to a master device, we may
    247  * need to send a mapping notify to the client because it causes the MD
    248  * to change state.
    249  *
    250  * Mapping notify needs to be sent in the following cases:
    251  *      - different slave device on same master
    252  *      - different master
    253  *
    254  * XXX: They way how the code is we also send a map notify if the slave device
    255  * stays the same, but the master changes. This isn't really necessary though.
    256  *
    257  * XXX: this gives you funny behaviour with the ClientPointer. When a
    258  * MappingNotify is sent to the client, the client usually responds with a
    259  * GetKeyboardMapping. This will retrieve the ClientPointer's keyboard
    260  * mapping, regardless of which keyboard sent the last mapping notify request.
    261  * So depending on the CP setting, your keyboard may change layout in each
    262  * app...
    263  *
    264  * This code is basically the old SwitchCoreKeyboard.
    265  */
    266 
    267 void
    268 CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
    269 {
    270     KeyClassPtr mk = master->key;
    271 
    272     if (device == master)
    273         return;
    274 
    275     mk->sourceid = device->id;
    276 
    277     if (!XkbDeviceApplyKeymap(master, device->key->xkbInfo->desc))
    278         FatalError("Couldn't pivot keymap from device to core!\n");
    279 }
    280 
    281 /**
    282  * Copies the feedback classes from device "from" into device "to". Classes
    283  * are duplicated (not just flipping the pointers). All feedback classes are
    284  * linked lists, the full list is duplicated.
    285  */
    286 static void
    287 DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
    288 {
    289     ClassesPtr classes;
    290 
    291     if (from->intfeed) {
    292         IntegerFeedbackPtr *i, it;
    293 
    294         if (!to->intfeed) {
    295             classes = to->unused_classes;
    296             to->intfeed = classes->intfeed;
    297             classes->intfeed = NULL;
    298         }
    299 
    300         i = &to->intfeed;
    301         for (it = from->intfeed; it; it = it->next) {
    302             if (!(*i)) {
    303                 *i = calloc(1, sizeof(IntegerFeedbackClassRec));
    304                 if (!(*i)) {
    305                     ErrorF("[Xi] Cannot alloc memory for class copy.");
    306                     return;
    307                 }
    308             }
    309             (*i)->CtrlProc = it->CtrlProc;
    310             (*i)->ctrl = it->ctrl;
    311 
    312             i = &(*i)->next;
    313         }
    314     }
    315     else if (to->intfeed && !from->intfeed) {
    316         classes = to->unused_classes;
    317         classes->intfeed = to->intfeed;
    318         to->intfeed = NULL;
    319     }
    320 
    321     if (from->stringfeed) {
    322         StringFeedbackPtr *s, it;
    323 
    324         if (!to->stringfeed) {
    325             classes = to->unused_classes;
    326             to->stringfeed = classes->stringfeed;
    327             classes->stringfeed = NULL;
    328         }
    329 
    330         s = &to->stringfeed;
    331         for (it = from->stringfeed; it; it = it->next) {
    332             if (!(*s)) {
    333                 *s = calloc(1, sizeof(StringFeedbackClassRec));
    334                 if (!(*s)) {
    335                     ErrorF("[Xi] Cannot alloc memory for class copy.");
    336                     return;
    337                 }
    338             }
    339             (*s)->CtrlProc = it->CtrlProc;
    340             (*s)->ctrl = it->ctrl;
    341 
    342             s = &(*s)->next;
    343         }
    344     }
    345     else if (to->stringfeed && !from->stringfeed) {
    346         classes = to->unused_classes;
    347         classes->stringfeed = to->stringfeed;
    348         to->stringfeed = NULL;
    349     }
    350 
    351     if (from->bell) {
    352         BellFeedbackPtr *b, it;
    353 
    354         if (!to->bell) {
    355             classes = to->unused_classes;
    356             to->bell = classes->bell;
    357             classes->bell = NULL;
    358         }
    359 
    360         b = &to->bell;
    361         for (it = from->bell; it; it = it->next) {
    362             if (!(*b)) {
    363                 *b = calloc(1, sizeof(BellFeedbackClassRec));
    364                 if (!(*b)) {
    365                     ErrorF("[Xi] Cannot alloc memory for class copy.");
    366                     return;
    367                 }
    368             }
    369             (*b)->BellProc = it->BellProc;
    370             (*b)->CtrlProc = it->CtrlProc;
    371             (*b)->ctrl = it->ctrl;
    372 
    373             b = &(*b)->next;
    374         }
    375     }
    376     else if (to->bell && !from->bell) {
    377         classes = to->unused_classes;
    378         classes->bell = to->bell;
    379         to->bell = NULL;
    380     }
    381 
    382     if (from->leds) {
    383         LedFeedbackPtr *l, it;
    384 
    385         if (!to->leds) {
    386             classes = to->unused_classes;
    387             to->leds = classes->leds;
    388             classes->leds = NULL;
    389         }
    390 
    391         l = &to->leds;
    392         for (it = from->leds; it; it = it->next) {
    393             if (!(*l)) {
    394                 *l = calloc(1, sizeof(LedFeedbackClassRec));
    395                 if (!(*l)) {
    396                     ErrorF("[Xi] Cannot alloc memory for class copy.");
    397                     return;
    398                 }
    399             }
    400             (*l)->CtrlProc = it->CtrlProc;
    401             (*l)->ctrl = it->ctrl;
    402             if ((*l)->xkb_sli)
    403                 XkbFreeSrvLedInfo((*l)->xkb_sli);
    404             (*l)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, NULL, *l);
    405 
    406             l = &(*l)->next;
    407         }
    408     }
    409     else if (to->leds && !from->leds) {
    410         classes = to->unused_classes;
    411         classes->leds = to->leds;
    412         to->leds = NULL;
    413     }
    414 }
    415 
    416 static void
    417 DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to)
    418 {
    419     ClassesPtr classes;
    420 
    421     /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the
    422      * kbdfeed to be set up properly, so let's do the feedback classes first.
    423      */
    424     if (from->kbdfeed) {
    425         KbdFeedbackPtr *k, it;
    426 
    427         if (!to->kbdfeed) {
    428             classes = to->unused_classes;
    429 
    430             to->kbdfeed = classes->kbdfeed;
    431             if (!to->kbdfeed)
    432                 InitKeyboardDeviceStruct(to, NULL, NULL, NULL);
    433             classes->kbdfeed = NULL;
    434         }
    435 
    436         k = &to->kbdfeed;
    437         for (it = from->kbdfeed; it; it = it->next) {
    438             if (!(*k)) {
    439                 *k = calloc(1, sizeof(KbdFeedbackClassRec));
    440                 if (!*k) {
    441                     ErrorF("[Xi] Cannot alloc memory for class copy.");
    442                     return;
    443                 }
    444             }
    445             (*k)->BellProc = it->BellProc;
    446             (*k)->CtrlProc = it->CtrlProc;
    447             (*k)->ctrl = it->ctrl;
    448             if ((*k)->xkb_sli)
    449                 XkbFreeSrvLedInfo((*k)->xkb_sli);
    450             (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL);
    451 
    452             k = &(*k)->next;
    453         }
    454     }
    455     else if (to->kbdfeed && !from->kbdfeed) {
    456         classes = to->unused_classes;
    457         classes->kbdfeed = to->kbdfeed;
    458         to->kbdfeed = NULL;
    459     }
    460 
    461     if (from->key) {
    462         if (!to->key) {
    463             classes = to->unused_classes;
    464             to->key = classes->key;
    465             if (!to->key)
    466                 InitKeyboardDeviceStruct(to, NULL, NULL, NULL);
    467             else
    468                 classes->key = NULL;
    469         }
    470 
    471         CopyKeyClass(from, to);
    472     }
    473     else if (to->key && !from->key) {
    474         classes = to->unused_classes;
    475         classes->key = to->key;
    476         to->key = NULL;
    477     }
    478 
    479     /* If a SrvLedInfoPtr's flags are XkbSLI_IsDefault, the names and maps
    480      * pointer point into the xkbInfo->desc struct.  XkbCopySrvLedInfo
    481      * didn't update the pointers so we need to do it manually here.
    482      */
    483     if (to->kbdfeed) {
    484         KbdFeedbackPtr k;
    485 
    486         for (k = to->kbdfeed; k; k = k->next) {
    487             if (!k->xkb_sli)
    488                 continue;
    489             if (k->xkb_sli->flags & XkbSLI_IsDefault) {
    490                 k->xkb_sli->names = to->key->xkbInfo->desc->names->indicators;
    491                 k->xkb_sli->maps = to->key->xkbInfo->desc->indicators->maps;
    492             }
    493         }
    494     }
    495 
    496     /* We can't just copy over the focus class. When an app sets the focus,
    497      * it'll do so on the master device. Copying the SDs focus means losing
    498      * the focus.
    499      * So we only copy the focus class if the device didn't have one,
    500      * otherwise we leave it as it is.
    501      */
    502     if (from->focus) {
    503         if (!to->focus) {
    504             WindowPtr *oldTrace;
    505 
    506             classes = to->unused_classes;
    507             to->focus = classes->focus;
    508             if (!to->focus) {
    509                 to->focus = calloc(1, sizeof(FocusClassRec));
    510                 if (!to->focus)
    511                     FatalError("[Xi] no memory for class shift.\n");
    512             }
    513             else
    514                 classes->focus = NULL;
    515 
    516             oldTrace = to->focus->trace;
    517             memcpy(to->focus, from->focus, sizeof(FocusClassRec));
    518             to->focus->trace = reallocarray(oldTrace,
    519                                             to->focus->traceSize,
    520                                             sizeof(WindowPtr));
    521             if (!to->focus->trace && to->focus->traceSize)
    522                 FatalError("[Xi] no memory for trace.\n");
    523             memcpy(to->focus->trace, from->focus->trace,
    524                    from->focus->traceSize * sizeof(WindowPtr));
    525             to->focus->sourceid = from->id;
    526         }
    527     }
    528     else if (to->focus) {
    529         classes = to->unused_classes;
    530         classes->focus = to->focus;
    531         to->focus = NULL;
    532     }
    533 
    534 }
    535 
    536 /* FIXME: this should really be shared with the InitValuatorAxisClassRec and
    537  * similar */
    538 static void
    539 DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
    540 {
    541     ClassesPtr classes;
    542 
    543     /* Feedback classes must be copied first */
    544     if (from->ptrfeed) {
    545         PtrFeedbackPtr *p, it;
    546 
    547         if (!to->ptrfeed) {
    548             classes = to->unused_classes;
    549             to->ptrfeed = classes->ptrfeed;
    550             classes->ptrfeed = NULL;
    551         }
    552 
    553         p = &to->ptrfeed;
    554         for (it = from->ptrfeed; it; it = it->next) {
    555             if (!(*p)) {
    556                 *p = calloc(1, sizeof(PtrFeedbackClassRec));
    557                 if (!*p) {
    558                     ErrorF("[Xi] Cannot alloc memory for class copy.");
    559                     return;
    560                 }
    561             }
    562             (*p)->CtrlProc = it->CtrlProc;
    563             (*p)->ctrl = it->ctrl;
    564 
    565             p = &(*p)->next;
    566         }
    567     }
    568     else if (to->ptrfeed && !from->ptrfeed) {
    569         classes = to->unused_classes;
    570         classes->ptrfeed = to->ptrfeed;
    571         to->ptrfeed = NULL;
    572     }
    573 
    574     if (from->valuator) {
    575         ValuatorClassPtr v;
    576 
    577         if (!to->valuator) {
    578             classes = to->unused_classes;
    579             to->valuator = classes->valuator;
    580             if (to->valuator)
    581                 classes->valuator = NULL;
    582         }
    583 
    584         v = AllocValuatorClass(to->valuator, from->valuator->numAxes);
    585 
    586         if (!v)
    587             FatalError("[Xi] no memory for class shift.\n");
    588 
    589         to->valuator = v;
    590         memcpy(v->axes, from->valuator->axes, v->numAxes * sizeof(AxisInfo));
    591 
    592         v->sourceid = from->id;
    593     }
    594     else if (to->valuator && !from->valuator) {
    595         classes = to->unused_classes;
    596         classes->valuator = to->valuator;
    597         to->valuator = NULL;
    598     }
    599 
    600     if (from->button) {
    601         if (!to->button) {
    602             classes = to->unused_classes;
    603             to->button = classes->button;
    604             if (!to->button) {
    605                 to->button = calloc(1, sizeof(ButtonClassRec));
    606                 if (!to->button)
    607                     FatalError("[Xi] no memory for class shift.\n");
    608                 to->button->numButtons = from->button->numButtons;
    609             }
    610             else
    611                 classes->button = NULL;
    612         }
    613 
    614         if (from->button->xkb_acts) {
    615             size_t maxbuttons = max(to->button->numButtons, from->button->numButtons);
    616             to->button->xkb_acts = xnfreallocarray(to->button->xkb_acts,
    617                                                    maxbuttons,
    618                                                    sizeof(XkbAction));
    619             memset(to->button->xkb_acts, 0, maxbuttons * sizeof(XkbAction));
    620             memcpy(to->button->xkb_acts, from->button->xkb_acts,
    621                    from->button->numButtons * sizeof(XkbAction));
    622         }
    623         else {
    624             free(to->button->xkb_acts);
    625             to->button->xkb_acts = NULL;
    626         }
    627 
    628         memcpy(to->button->labels, from->button->labels,
    629                from->button->numButtons * sizeof(Atom));
    630         to->button->sourceid = from->id;
    631     }
    632     else if (to->button && !from->button) {
    633         classes = to->unused_classes;
    634         classes->button = to->button;
    635         to->button = NULL;
    636     }
    637 
    638     if (from->proximity) {
    639         if (!to->proximity) {
    640             classes = to->unused_classes;
    641             to->proximity = classes->proximity;
    642             if (!to->proximity) {
    643                 to->proximity = calloc(1, sizeof(ProximityClassRec));
    644                 if (!to->proximity)
    645                     FatalError("[Xi] no memory for class shift.\n");
    646             }
    647             else
    648                 classes->proximity = NULL;
    649         }
    650         memcpy(to->proximity, from->proximity, sizeof(ProximityClassRec));
    651         to->proximity->sourceid = from->id;
    652     }
    653     else if (to->proximity) {
    654         classes = to->unused_classes;
    655         classes->proximity = to->proximity;
    656         to->proximity = NULL;
    657     }
    658 
    659     if (from->touch) {
    660         TouchClassPtr t, f;
    661 
    662         if (!to->touch) {
    663             classes = to->unused_classes;
    664             to->touch = classes->touch;
    665             if (!to->touch) {
    666                 int i;
    667 
    668                 to->touch = calloc(1, sizeof(TouchClassRec));
    669                 if (!to->touch)
    670                     FatalError("[Xi] no memory for class shift.\n");
    671                 to->touch->num_touches = from->touch->num_touches;
    672                 to->touch->touches = calloc(to->touch->num_touches,
    673                                             sizeof(TouchPointInfoRec));
    674                 for (i = 0; i < to->touch->num_touches; i++)
    675                     TouchInitTouchPoint(to->touch, to->valuator, i);
    676                 if (!to->touch)
    677                     FatalError("[Xi] no memory for class shift.\n");
    678             }
    679             else
    680                 classes->touch = NULL;
    681         }
    682 
    683         t = to->touch;
    684         f = from->touch;
    685         t->sourceid = f->sourceid;
    686         t->max_touches = f->max_touches;
    687         t->mode = f->mode;
    688         t->buttonsDown = f->buttonsDown;
    689         t->state = f->state;
    690         t->motionMask = f->motionMask;
    691         /* to->touches and to->num_touches are separate on the master,
    692          * don't copy */
    693     }
    694     /* Don't remove touch class if from->touch is non-existent. The to device
    695      * may have an active touch grab, so we need to keep the touch class record
    696      * around. */
    697 
    698     if (from->gesture) {
    699         if (!to->gesture) {
    700             classes = to->unused_classes;
    701             to->gesture = classes->gesture;
    702             if (!to->gesture) {
    703                 if (!InitGestureClassDeviceStruct(to, from->gesture->max_touches))
    704                     FatalError("[Xi] no memory for class shift.\n");
    705             }
    706             else
    707                 classes->gesture = NULL;
    708         }
    709 
    710         to->gesture->sourceid = from->gesture->sourceid;
    711         /* to->gesture->gesture is separate on the master,  don't copy */
    712     }
    713     /* Don't remove gesture class if from->gesture is non-existent. The to device
    714      * may have an active gesture grab, so we need to keep the gesture class record
    715      * around. */
    716 }
    717 
    718 /**
    719  * Copies the CONTENT of the classes of device from into the classes in device
    720  * to. From and to are identical after finishing.
    721  *
    722  * If to does not have classes from currently has, the classes are stored in
    723  * to's devPrivates system. Later, we recover it again from there if needed.
    724  * Saves a few memory allocations.
    725  */
    726 void
    727 DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to,
    728                       DeviceChangedEvent *dce)
    729 {
    730     input_lock();
    731 
    732     /* generic feedback classes, not tied to pointer and/or keyboard */
    733     DeepCopyFeedbackClasses(from, to);
    734 
    735     if ((dce->flags & DEVCHANGE_KEYBOARD_EVENT))
    736         DeepCopyKeyboardClasses(from, to);
    737     if ((dce->flags & DEVCHANGE_POINTER_EVENT))
    738         DeepCopyPointerClasses(from, to);
    739 
    740     input_unlock();
    741 }
    742 
    743 /**
    744  * Send an XI2 DeviceChangedEvent to all interested clients.
    745  */
    746 void
    747 XISendDeviceChangedEvent(DeviceIntPtr device, DeviceChangedEvent *dce)
    748 {
    749     xXIDeviceChangedEvent *dcce;
    750     int rc;
    751 
    752     rc = EventToXI2((InternalEvent *) dce, (xEvent **) &dcce);
    753     if (rc != Success) {
    754         ErrorF("[Xi] event conversion from DCE failed with code %d\n", rc);
    755         return;
    756     }
    757 
    758     /* we don't actually swap if there's a NullClient, swapping is done
    759      * later when event is delivered. */
    760     SendEventToAllWindows(device, XI_DeviceChangedMask, (xEvent *) dcce, 1);
    761     free(dcce);
    762 }
    763 
    764 static void
    765 ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce)
    766 {
    767     DeviceIntPtr slave;
    768     int rc;
    769 
    770     /* For now, we don't have devices that change physically. */
    771     if (!IsMaster(device))
    772         return;
    773 
    774     rc = dixLookupDevice(&slave, dce->sourceid, serverClient, DixReadAccess);
    775 
    776     if (rc != Success)
    777         return;                 /* Device has disappeared */
    778 
    779     if (IsMaster(slave))
    780         return;
    781 
    782     if (IsFloating(slave))
    783         return;                 /* set floating since the event */
    784 
    785     if (GetMaster(slave, MASTER_ATTACHED)->id != dce->masterid)
    786         return;                 /* not our slave anymore, don't care */
    787 
    788     /* FIXME: we probably need to send a DCE for the new slave now */
    789 
    790     device->public.devicePrivate = slave->public.devicePrivate;
    791 
    792     /* FIXME: the classes may have changed since we generated the event. */
    793     DeepCopyDeviceClasses(slave, device, dce);
    794     dce->deviceid = device->id;
    795     XISendDeviceChangedEvent(device, dce);
    796 }
    797 
    798 /**
    799  * Add state and motionMask to the filter for this event. The protocol
    800  * supports some extra masks for motion when a button is down:
    801  * ButtonXMotionMask and the DeviceButtonMotionMask to trigger only when at
    802  * least one button (or that specific button is down). These masks need to
    803  * be added to the filters for core/XI motion events.
    804  *
    805  * @param device The device to update the mask for
    806  * @param state The current button state mask
    807  * @param motion_mask The motion mask (DeviceButtonMotionMask or 0)
    808  */
    809 static void
    810 UpdateDeviceMotionMask(DeviceIntPtr device, unsigned short state,
    811                        Mask motion_mask)
    812 {
    813     Mask mask;
    814 
    815     mask = PointerMotionMask | state | motion_mask;
    816     SetMaskForEvent(device->id, mask, DeviceMotionNotify);
    817     SetMaskForEvent(device->id, mask, MotionNotify);
    818 }
    819 
    820 static void
    821 IncreaseButtonCount(DeviceIntPtr dev, int key, CARD8 *buttons_down,
    822                     Mask *motion_mask, unsigned short *state)
    823 {
    824     if (dev->valuator)
    825         dev->valuator->motionHintWindow = NullWindow;
    826 
    827     (*buttons_down)++;
    828     *motion_mask = DeviceButtonMotionMask;
    829     if (dev->button->map[key] <= 5)
    830         *state |= (Button1Mask >> 1) << dev->button->map[key];
    831 }
    832 
    833 static void
    834 DecreaseButtonCount(DeviceIntPtr dev, int key, CARD8 *buttons_down,
    835                     Mask *motion_mask, unsigned short *state)
    836 {
    837     if (dev->valuator)
    838         dev->valuator->motionHintWindow = NullWindow;
    839 
    840     if (*buttons_down >= 1 && !--(*buttons_down))
    841         *motion_mask = 0;
    842     if (dev->button->map[key] <= 5)
    843         *state &= ~((Button1Mask >> 1) << dev->button->map[key]);
    844 }
    845 
    846 /**
    847  * Update the device state according to the data in the event.
    848  *
    849  * return values are
    850  *   DEFAULT ... process as normal
    851  *   DONT_PROCESS ... return immediately from caller
    852  */
    853 #define DEFAULT 0
    854 #define DONT_PROCESS 1
    855 int
    856 UpdateDeviceState(DeviceIntPtr device, DeviceEvent *event)
    857 {
    858     int i;
    859     int key = 0, last_valuator;
    860 
    861     KeyClassPtr k = NULL;
    862     ButtonClassPtr b = NULL;
    863     ValuatorClassPtr v = NULL;
    864     TouchClassPtr t = NULL;
    865 
    866     /* This event is always the first we get, before the actual events with
    867      * the data. However, the way how the DDX is set up, "device" will
    868      * actually be the slave device that caused the event.
    869      */
    870     switch (event->type) {
    871     case ET_DeviceChanged:
    872         ChangeMasterDeviceClasses(device, (DeviceChangedEvent *) event);
    873         return DONT_PROCESS;    /* event has been sent already */
    874     case ET_Motion:
    875     case ET_ButtonPress:
    876     case ET_ButtonRelease:
    877     case ET_KeyPress:
    878     case ET_KeyRelease:
    879     case ET_ProximityIn:
    880     case ET_ProximityOut:
    881     case ET_TouchBegin:
    882     case ET_TouchUpdate:
    883     case ET_TouchEnd:
    884         break;
    885     default:
    886         /* other events don't update the device */
    887         return DEFAULT;
    888     }
    889 
    890     k = device->key;
    891     v = device->valuator;
    892     b = device->button;
    893     t = device->touch;
    894 
    895     key = event->detail.key;
    896 
    897     /* Update device axis */
    898     /* Check valuators first */
    899     last_valuator = -1;
    900     for (i = 0; i < MAX_VALUATORS; i++) {
    901         if (BitIsOn(&event->valuators.mask, i)) {
    902             if (!v) {
    903                 ErrorF("[Xi] Valuators reported for non-valuator device '%s'. "
    904                        "Ignoring event.\n", device->name);
    905                 return DONT_PROCESS;
    906             }
    907             else if (v->numAxes < i) {
    908                 ErrorF("[Xi] Too many valuators reported for device '%s'. "
    909                        "Ignoring event.\n", device->name);
    910                 return DONT_PROCESS;
    911             }
    912             last_valuator = i;
    913         }
    914     }
    915 
    916     for (i = 0; i <= last_valuator && i < v->numAxes; i++) {
    917         /* XXX: Relative/Absolute mode */
    918         if (BitIsOn(&event->valuators.mask, i))
    919             v->axisVal[i] = event->valuators.data[i];
    920     }
    921 
    922     if (event->type == ET_KeyPress) {
    923         if (!k)
    924             return DONT_PROCESS;
    925 
    926         /* don't allow ddx to generate multiple downs, but repeats are okay */
    927         if (key_is_down(device, key, KEY_PROCESSED) && !event->key_repeat)
    928             return DONT_PROCESS;
    929 
    930         if (device->valuator)
    931             device->valuator->motionHintWindow = NullWindow;
    932         set_key_down(device, key, KEY_PROCESSED);
    933     }
    934     else if (event->type == ET_KeyRelease) {
    935         if (!k)
    936             return DONT_PROCESS;
    937 
    938         if (!key_is_down(device, key, KEY_PROCESSED))   /* guard against duplicates */
    939             return DONT_PROCESS;
    940         if (device->valuator)
    941             device->valuator->motionHintWindow = NullWindow;
    942         set_key_up(device, key, KEY_PROCESSED);
    943     }
    944     else if (event->type == ET_ButtonPress) {
    945         if (!b)
    946             return DONT_PROCESS;
    947 
    948         if (button_is_down(device, key, BUTTON_PROCESSED))
    949             return DONT_PROCESS;
    950 
    951         set_button_down(device, key, BUTTON_PROCESSED);
    952 
    953         if (!b->map[key])
    954             return DONT_PROCESS;
    955 
    956         IncreaseButtonCount(device, key, &b->buttonsDown, &b->motionMask,
    957                             &b->state);
    958         UpdateDeviceMotionMask(device, b->state, b->motionMask);
    959     }
    960     else if (event->type == ET_ButtonRelease) {
    961         if (!b)
    962             return DONT_PROCESS;
    963 
    964         if (!button_is_down(device, key, BUTTON_PROCESSED))
    965             return DONT_PROCESS;
    966         if (IsMaster(device)) {
    967             DeviceIntPtr sd;
    968 
    969             /*
    970              * Leave the button down if any slave has the
    971              * button still down. Note that this depends on the
    972              * event being delivered through the slave first
    973              */
    974             for (sd = inputInfo.devices; sd; sd = sd->next) {
    975                 if (IsMaster(sd) || GetMaster(sd, MASTER_POINTER) != device)
    976                     continue;
    977                 if (!sd->button)
    978                     continue;
    979                 for (i = 1; i <= sd->button->numButtons; i++)
    980                     if (sd->button->map[i] == key &&
    981                         button_is_down(sd, i, BUTTON_PROCESSED))
    982                         return DONT_PROCESS;
    983             }
    984         }
    985         set_button_up(device, key, BUTTON_PROCESSED);
    986         if (!b->map[key])
    987             return DONT_PROCESS;
    988 
    989         DecreaseButtonCount(device, key, &b->buttonsDown, &b->motionMask,
    990                             &b->state);
    991         UpdateDeviceMotionMask(device, b->state, b->motionMask);
    992     }
    993     else if (event->type == ET_ProximityIn)
    994         device->proximity->in_proximity = TRUE;
    995     else if (event->type == ET_ProximityOut)
    996         device->proximity->in_proximity = FALSE;
    997     else if (event->type == ET_TouchBegin) {
    998         BUG_RETURN_VAL(!b || !v, DONT_PROCESS);
    999         BUG_RETURN_VAL(!t, DONT_PROCESS);
   1000 
   1001         if (!b->map[key])
   1002             return DONT_PROCESS;
   1003 
   1004         if (!(event->flags & TOUCH_POINTER_EMULATED) ||
   1005             (event->flags & TOUCH_REPLAYING))
   1006             return DONT_PROCESS;
   1007 
   1008         IncreaseButtonCount(device, key, &t->buttonsDown, &t->motionMask,
   1009                             &t->state);
   1010         UpdateDeviceMotionMask(device, t->state, DeviceButtonMotionMask);
   1011     }
   1012     else if (event->type == ET_TouchEnd) {
   1013         BUG_RETURN_VAL(!b || !v, DONT_PROCESS);
   1014         BUG_RETURN_VAL(!t, DONT_PROCESS);
   1015 
   1016         if (t->buttonsDown <= 0 || !b->map[key])
   1017             return DONT_PROCESS;
   1018 
   1019         if (!(event->flags & TOUCH_POINTER_EMULATED))
   1020             return DONT_PROCESS;
   1021 
   1022         DecreaseButtonCount(device, key, &t->buttonsDown, &t->motionMask,
   1023                             &t->state);
   1024         UpdateDeviceMotionMask(device, t->state, DeviceButtonMotionMask);
   1025     }
   1026 
   1027     return DEFAULT;
   1028 }
   1029 
   1030 /**
   1031  * A client that does not have the TouchOwnership mask set may not receive a
   1032  * TouchBegin event if there is at least one grab active.
   1033  *
   1034  * @return TRUE if the client selected for ownership events on the given
   1035  * window for this device, FALSE otherwise
   1036  */
   1037 static inline Bool
   1038 TouchClientWantsOwnershipEvents(ClientPtr client, DeviceIntPtr dev,
   1039                                 WindowPtr win)
   1040 {
   1041     InputClients *iclient;
   1042 
   1043     nt_list_for_each_entry(iclient, wOtherInputMasks(win)->inputClients, next) {
   1044         if (rClient(iclient) != client)
   1045             continue;
   1046 
   1047         return xi2mask_isset(iclient->xi2mask, dev, XI_TouchOwnership);
   1048     }
   1049 
   1050     return FALSE;
   1051 }
   1052 
   1053 static void
   1054 TouchSendOwnershipEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, int reason,
   1055                         XID resource)
   1056 {
   1057     int nev, i;
   1058     InternalEvent *tel = InitEventList(GetMaximumEventsNum());
   1059 
   1060     nev = GetTouchOwnershipEvents(tel, dev, ti, reason, resource, 0);
   1061     for (i = 0; i < nev; i++)
   1062         mieqProcessDeviceEvent(dev, tel + i, NULL);
   1063 
   1064     FreeEventList(tel, GetMaximumEventsNum());
   1065 }
   1066 
   1067 /**
   1068  * Attempts to deliver a touch event to the given client.
   1069  */
   1070 static Bool
   1071 DeliverOneTouchEvent(ClientPtr client, DeviceIntPtr dev, TouchPointInfoPtr ti,
   1072                      GrabPtr grab, WindowPtr win, InternalEvent *ev)
   1073 {
   1074     int err;
   1075     xEvent *xi2;
   1076     Mask filter;
   1077     Window child = DeepestSpriteWin(&ti->sprite)->drawable.id;
   1078 
   1079     /* FIXME: owner event handling */
   1080 
   1081     /* If the client does not have the ownership mask set and is not
   1082      * the current owner of the touch, only pretend we delivered */
   1083     if (!grab && ti->num_grabs != 0 &&
   1084         !TouchClientWantsOwnershipEvents(client, dev, win))
   1085         return TRUE;
   1086 
   1087     /* If we fail here, we're going to leave a client hanging. */
   1088     err = EventToXI2(ev, &xi2);
   1089     if (err != Success)
   1090         FatalError("[Xi] %s: XI2 conversion failed in %s"
   1091                    " (%d)\n", dev->name, __func__, err);
   1092 
   1093     FixUpEventFromWindow(&ti->sprite, xi2, win, child, FALSE);
   1094     filter = GetEventFilter(dev, xi2);
   1095     if (XaceHook(XACE_RECEIVE_ACCESS, client, win, xi2, 1) != Success)
   1096         return FALSE;
   1097     err = TryClientEvents(client, dev, xi2, 1, filter, filter, NullGrab);
   1098     free(xi2);
   1099 
   1100     /* Returning the value from TryClientEvents isn't useful, since all our
   1101      * resource-gone cleanups will update the delivery list anyway. */
   1102     return TRUE;
   1103 }
   1104 
   1105 static void
   1106 ActivateEarlyAccept(DeviceIntPtr dev, TouchPointInfoPtr ti)
   1107 {
   1108     ClientPtr client;
   1109     XID error;
   1110     GrabPtr grab = ti->listeners[0].grab;
   1111 
   1112     BUG_RETURN(ti->listeners[0].type != TOUCH_LISTENER_GRAB &&
   1113                ti->listeners[0].type != TOUCH_LISTENER_POINTER_GRAB);
   1114     BUG_RETURN(!grab);
   1115 
   1116     client = rClient(grab);
   1117 
   1118     if (TouchAcceptReject(client, dev, XIAcceptTouch, ti->client_id,
   1119                           ti->listeners[0].window->drawable.id, &error) != Success)
   1120         ErrorF("[Xi] Failed to accept touch grab after early acceptance.\n");
   1121 }
   1122 
   1123 /**
   1124  * Find the oldest touch that still has a pointer emulation client.
   1125  *
   1126  * Pointer emulation can only be performed for the oldest touch. Otherwise, the
   1127  * order of events seen by the client will be wrong. This function helps us find
   1128  * the next touch to be emulated.
   1129  *
   1130  * @param dev The device to find touches for.
   1131  */
   1132 static TouchPointInfoPtr
   1133 FindOldestPointerEmulatedTouch(DeviceIntPtr dev)
   1134 {
   1135     TouchPointInfoPtr oldest = NULL;
   1136     int i;
   1137 
   1138     for (i = 0; i < dev->touch->num_touches; i++) {
   1139         TouchPointInfoPtr ti = dev->touch->touches + i;
   1140         int j;
   1141 
   1142         if (!ti->active || !ti->emulate_pointer)
   1143             continue;
   1144 
   1145         for (j = 0; j < ti->num_listeners; j++) {
   1146             if (ti->listeners[j].type == TOUCH_LISTENER_POINTER_GRAB ||
   1147                 ti->listeners[j].type == TOUCH_LISTENER_POINTER_REGULAR)
   1148                 break;
   1149         }
   1150         if (j == ti->num_listeners)
   1151             continue;
   1152 
   1153         if (!oldest) {
   1154             oldest = ti;
   1155             continue;
   1156         }
   1157 
   1158         if (oldest->client_id - ti->client_id < UINT_MAX / 2)
   1159             oldest = ti;
   1160     }
   1161 
   1162     return oldest;
   1163 }
   1164 
   1165 /**
   1166  * If the current owner has rejected the event, deliver the
   1167  * TouchOwnership/TouchBegin to the next item in the sprite stack.
   1168  */
   1169 static void
   1170 TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
   1171                      TouchOwnershipEvent *ev)
   1172 {
   1173     TouchListener *listener = &ti->listeners[0]; /* new owner */
   1174     int accepted_early = listener->state == TOUCH_LISTENER_EARLY_ACCEPT;
   1175 
   1176     /* Deliver the ownership */
   1177     if (listener->state == TOUCH_LISTENER_AWAITING_OWNER || accepted_early)
   1178         DeliverTouchEvents(dev, ti, (InternalEvent *) ev,
   1179                            listener->listener);
   1180     else if (listener->state == TOUCH_LISTENER_AWAITING_BEGIN) {
   1181         /* We can't punt to a pointer listener unless all older pointer
   1182          * emulated touches have been seen already. */
   1183         if ((listener->type == TOUCH_LISTENER_POINTER_GRAB ||
   1184              listener->type == TOUCH_LISTENER_POINTER_REGULAR) &&
   1185             ti != FindOldestPointerEmulatedTouch(dev))
   1186             return;
   1187 
   1188         TouchEventHistoryReplay(ti, dev, listener->listener);
   1189     }
   1190 
   1191     /* New owner has Begin/Update but not end. If touch is pending_finish,
   1192      * emulate the TouchEnd now */
   1193     if (ti->pending_finish) {
   1194         TouchEmitTouchEnd(dev, ti, 0, 0);
   1195 
   1196         /* If the last owner is not a touch grab, finalise the touch, we
   1197            won't get more correspondence on this.
   1198          */
   1199         if (ti->num_listeners == 1 &&
   1200             (ti->num_grabs == 0 ||
   1201              listener->grab->grabtype != XI2 ||
   1202              !xi2mask_isset(listener->grab->xi2mask, dev, XI_TouchBegin))) {
   1203             TouchEndTouch(dev, ti);
   1204             return;
   1205         }
   1206     }
   1207 
   1208     if (accepted_early)
   1209         ActivateEarlyAccept(dev, ti);
   1210 }
   1211 
   1212 /**
   1213  * Check the oldest touch to see if it needs to be replayed to its pointer
   1214  * owner.
   1215  *
   1216  * Touch event propagation is paused if it hits a pointer listener while an
   1217  * older touch with a pointer listener is waiting on accept or reject. This
   1218  * function will restart propagation of a paused touch if needed.
   1219  *
   1220  * @param dev The device to check touches for.
   1221  */
   1222 static void
   1223 CheckOldestTouch(DeviceIntPtr dev)
   1224 {
   1225     TouchPointInfoPtr oldest = FindOldestPointerEmulatedTouch(dev);
   1226 
   1227     if (oldest && oldest->listeners[0].state == TOUCH_LISTENER_AWAITING_BEGIN)
   1228         TouchPuntToNextOwner(dev, oldest, NULL);
   1229 }
   1230 
   1231 /**
   1232  * Process a touch rejection.
   1233  *
   1234  * @param sourcedev The source device of the touch sequence.
   1235  * @param ti The touchpoint info record.
   1236  * @param resource The resource of the client rejecting the touch.
   1237  * @param ev TouchOwnership event to send. Set to NULL if no event should be
   1238  *        sent.
   1239  */
   1240 void
   1241 TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource,
   1242               TouchOwnershipEvent *ev)
   1243 {
   1244     Bool was_owner = (resource == ti->listeners[0].listener);
   1245     int i;
   1246 
   1247     /* Send a TouchEnd event to the resource being removed, but only if they
   1248      * haven't received one yet already */
   1249     for (i = 0; i < ti->num_listeners; i++) {
   1250         if (ti->listeners[i].listener == resource) {
   1251             if (ti->listeners[i].state != TOUCH_LISTENER_HAS_END)
   1252                 TouchEmitTouchEnd(sourcedev, ti, TOUCH_REJECT, resource);
   1253             break;
   1254         }
   1255     }
   1256 
   1257     /* Remove the resource from the listener list, updating
   1258      * ti->num_listeners, as well as ti->num_grabs if it was a grab. */
   1259     TouchRemoveListener(ti, resource);
   1260 
   1261     /* If the current owner was removed and there are further listeners, deliver
   1262      * the TouchOwnership or TouchBegin event to the new owner. */
   1263     if (ev && ti->num_listeners > 0 && was_owner)
   1264         TouchPuntToNextOwner(sourcedev, ti, ev);
   1265     else if (ti->num_listeners == 0)
   1266         TouchEndTouch(sourcedev, ti);
   1267 
   1268     CheckOldestTouch(sourcedev);
   1269 }
   1270 
   1271 /**
   1272  * Processes a TouchOwnership event, indicating a grab has accepted the touch
   1273  * it currently owns, or a grab or selection has been removed.  Will generate
   1274  * and send TouchEnd events to all clients removed from the delivery list, as
   1275  * well as possibly sending the new TouchOwnership event.  May end the
   1276  * touchpoint if it is pending finish.
   1277  */
   1278 static void
   1279 ProcessTouchOwnershipEvent(TouchOwnershipEvent *ev,
   1280                            DeviceIntPtr dev)
   1281 {
   1282     TouchPointInfoPtr ti = TouchFindByClientID(dev, ev->touchid);
   1283 
   1284     if (!ti) {
   1285         DebugF("[Xi] %s: Failed to get event %d for touchpoint %d\n",
   1286                dev->name, ev->type, ev->touchid);
   1287         return;
   1288     }
   1289 
   1290     if (ev->reason == XIRejectTouch)
   1291         TouchRejected(dev, ti, ev->resource, ev);
   1292     else if (ev->reason == XIAcceptTouch) {
   1293         int i;
   1294 
   1295 
   1296         /* For pointer-emulated listeners that ungrabbed the active grab,
   1297          * the state was forced to TOUCH_LISTENER_HAS_END. Still go
   1298          * through the motions of ending the touch if the listener has
   1299          * already seen the end. This ensures that the touch record is ended in
   1300          * the server.
   1301          */
   1302         if (ti->listeners[0].state == TOUCH_LISTENER_HAS_END)
   1303             TouchEmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[0].listener);
   1304 
   1305         /* The touch owner has accepted the touch.  Send TouchEnd events to
   1306          * everyone else, and truncate the list of listeners. */
   1307         for (i = 1; i < ti->num_listeners; i++)
   1308             TouchEmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[i].listener);
   1309 
   1310         while (ti->num_listeners > 1)
   1311             TouchRemoveListener(ti, ti->listeners[1].listener);
   1312         /* Owner accepted after receiving end */
   1313         if (ti->listeners[0].state == TOUCH_LISTENER_HAS_END)
   1314             TouchEndTouch(dev, ti);
   1315         else
   1316             ti->listeners[0].state = TOUCH_LISTENER_HAS_ACCEPTED;
   1317     }
   1318     else {  /* this is the very first ownership event for a grab */
   1319         DeliverTouchEvents(dev, ti, (InternalEvent *) ev, ev->resource);
   1320     }
   1321 }
   1322 
   1323 /**
   1324  * Copy the event's valuator information into the touchpoint, we may need
   1325  * this for emulated TouchEnd events.
   1326  */
   1327 static void
   1328 TouchCopyValuatorData(DeviceEvent *ev, TouchPointInfoPtr ti)
   1329 {
   1330     int i;
   1331 
   1332     for (i = 0; i < ARRAY_SIZE(ev->valuators.data); i++)
   1333         if (BitIsOn(ev->valuators.mask, i))
   1334             valuator_mask_set_double(ti->valuators, i, ev->valuators.data[i]);
   1335 }
   1336 
   1337 /**
   1338  * Given a touch event and a potential listener, retrieve info needed for
   1339  * processing the event.
   1340  *
   1341  * @param dev The device generating the touch event.
   1342  * @param ti The touch point info record for the touch event.
   1343  * @param ev The touch event to process.
   1344  * @param listener The touch event listener that may receive the touch event.
   1345  * @param[out] client The client that should receive the touch event.
   1346  * @param[out] win The window to deliver the event on.
   1347  * @param[out] grab The grab to deliver the event through, if any.
   1348  * @param[out] mask The XI 2.x event mask of the grab or selection, if any.
   1349  * @return TRUE if an event should be delivered to the listener, FALSE
   1350  *         otherwise.
   1351  */
   1352 static Bool
   1353 RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti,
   1354                           InternalEvent *ev, TouchListener * listener,
   1355                           ClientPtr *client, WindowPtr *win, GrabPtr *grab,
   1356                           XI2Mask **mask)
   1357 {
   1358     int rc;
   1359     InputClients *iclients = NULL;
   1360     *mask = NULL;
   1361 
   1362     if (listener->type == TOUCH_LISTENER_GRAB ||
   1363         listener->type == TOUCH_LISTENER_POINTER_GRAB) {
   1364         *grab = listener->grab;
   1365 
   1366         BUG_RETURN_VAL(!*grab, FALSE);
   1367 
   1368         *client = rClient(*grab);
   1369         *win = (*grab)->window;
   1370         *mask = (*grab)->xi2mask;
   1371     }
   1372     else {
   1373         rc = dixLookupResourceByType((void **) win, listener->listener,
   1374                                      listener->resource_type,
   1375                                      serverClient, DixSendAccess);
   1376         if (rc != Success)
   1377             return FALSE;
   1378 
   1379         if (listener->level == XI2) {
   1380             int evtype;
   1381 
   1382             if (ti->emulate_pointer &&
   1383                 listener->type == TOUCH_LISTENER_POINTER_REGULAR)
   1384                 evtype = GetXI2Type(TouchGetPointerEventType(ev));
   1385             else
   1386                 evtype = GetXI2Type(ev->any.type);
   1387 
   1388             BUG_RETURN_VAL(!wOtherInputMasks(*win), FALSE);
   1389             nt_list_for_each_entry(iclients,
   1390                                    wOtherInputMasks(*win)->inputClients, next)
   1391                 if (xi2mask_isset(iclients->xi2mask, dev, evtype))
   1392                 break;
   1393 
   1394             BUG_RETURN_VAL(!iclients, FALSE);
   1395 
   1396             *mask = iclients->xi2mask;
   1397             *client = rClient(iclients);
   1398         }
   1399         else if (listener->level == XI) {
   1400             int xi_type = GetXIType(TouchGetPointerEventType(ev));
   1401             Mask xi_filter = event_get_filter_from_type(dev, xi_type);
   1402 
   1403             BUG_RETURN_VAL(!wOtherInputMasks(*win), FALSE);
   1404             nt_list_for_each_entry(iclients,
   1405                                    wOtherInputMasks(*win)->inputClients, next)
   1406                 if (iclients->mask[dev->id] & xi_filter)
   1407                 break;
   1408             BUG_RETURN_VAL(!iclients, FALSE);
   1409 
   1410             *client = rClient(iclients);
   1411         }
   1412         else {
   1413             int coretype = GetCoreType(TouchGetPointerEventType(ev));
   1414             Mask core_filter = event_get_filter_from_type(dev, coretype);
   1415             OtherClients *oclients;
   1416 
   1417             /* all others */
   1418             nt_list_for_each_entry(oclients,
   1419                                    (OtherClients *) wOtherClients(*win), next)
   1420                 if (oclients->mask & core_filter)
   1421                     break;
   1422 
   1423             /* if owner selected, oclients is NULL */
   1424             *client = oclients ? rClient(oclients) : wClient(*win);
   1425         }
   1426 
   1427         *grab = NULL;
   1428     }
   1429 
   1430     return TRUE;
   1431 }
   1432 
   1433 static int
   1434 DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
   1435                           InternalEvent *ev, TouchListener * listener,
   1436                           ClientPtr client, WindowPtr win, GrabPtr grab,
   1437                           XI2Mask *xi2mask)
   1438 {
   1439     InternalEvent motion, button;
   1440     InternalEvent *ptrev = &motion;
   1441     int nevents;
   1442     DeviceIntPtr kbd;
   1443 
   1444     /* There may be a pointer grab on the device */
   1445     if (!grab) {
   1446         grab = dev->deviceGrab.grab;
   1447         if (grab) {
   1448             win = grab->window;
   1449             xi2mask = grab->xi2mask;
   1450             client = rClient(grab);
   1451         }
   1452     }
   1453 
   1454     /* We don't deliver pointer events to non-owners */
   1455     if (!TouchResourceIsOwner(ti, listener->listener))
   1456         return !Success;
   1457 
   1458     if (!ti->emulate_pointer)
   1459         return !Success;
   1460 
   1461     nevents = TouchConvertToPointerEvent(ev, &motion, &button);
   1462     BUG_RETURN_VAL(nevents == 0, BadValue);
   1463 
   1464     /* Note that here we deliver only part of the events that are generated by the touch event:
   1465      *
   1466      * TouchBegin results in ButtonPress (motion is handled in DeliverEmulatedMotionEvent)
   1467      * TouchUpdate results in Motion
   1468      * TouchEnd results in ButtonRelease (motion is handled in DeliverEmulatedMotionEvent)
   1469      */
   1470     if (nevents > 1)
   1471         ptrev = &button;
   1472 
   1473     kbd = GetMaster(dev, KEYBOARD_OR_FLOAT);
   1474     event_set_state(dev, kbd, &ptrev->device_event);
   1475     ptrev->device_event.corestate = event_get_corestate(dev, kbd);
   1476 
   1477     if (grab) {
   1478         /* this side-steps the usual activation mechanisms, but... */
   1479         if (ev->any.type == ET_TouchBegin && !dev->deviceGrab.grab)
   1480             ActivatePassiveGrab(dev, grab, ptrev, ev);  /* also delivers the event */
   1481         else {
   1482             int deliveries = 0;
   1483 
   1484             /* 'grab' is the passive grab, but if the grab isn't active,
   1485              * don't deliver */
   1486             if (!dev->deviceGrab.grab)
   1487                 return !Success;
   1488 
   1489             if (grab->ownerEvents) {
   1490                 WindowPtr focus = NullWindow;
   1491                 WindowPtr sprite_win = DeepestSpriteWin(dev->spriteInfo->sprite);
   1492 
   1493                 deliveries = DeliverDeviceEvents(sprite_win, ptrev, grab, focus, dev);
   1494             }
   1495 
   1496             if (!deliveries)
   1497                 deliveries = DeliverOneGrabbedEvent(ptrev, dev, grab->grabtype);
   1498 
   1499             /* We must accept the touch sequence once a pointer listener has
   1500              * received one event past ButtonPress. */
   1501             if (deliveries && ev->any.type != ET_TouchBegin &&
   1502                 !(ev->device_event.flags & TOUCH_CLIENT_ID))
   1503                 TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch);
   1504 
   1505             if (ev->any.type == ET_TouchEnd &&
   1506                 ti->num_listeners == 1 &&
   1507                 !dev->button->buttonsDown &&
   1508                 dev->deviceGrab.fromPassiveGrab && GrabIsPointerGrab(grab)) {
   1509                 (*dev->deviceGrab.DeactivateGrab) (dev);
   1510                 CheckOldestTouch(dev);
   1511                 return Success;
   1512             }
   1513         }
   1514     }
   1515     else {
   1516         GrabPtr devgrab = dev->deviceGrab.grab;
   1517         WindowPtr sprite_win = DeepestSpriteWin(dev->spriteInfo->sprite);
   1518 
   1519         DeliverDeviceEvents(sprite_win, ptrev, grab, win, dev);
   1520         /* FIXME: bad hack
   1521          * Implicit passive grab activated in response to this event. Store
   1522          * the event.
   1523          */
   1524         if (!devgrab && dev->deviceGrab.grab && dev->deviceGrab.implicitGrab) {
   1525             TouchListener *l;
   1526             GrabPtr g;
   1527 
   1528             devgrab = dev->deviceGrab.grab;
   1529             g = AllocGrab(devgrab);
   1530             BUG_WARN(!g);
   1531 
   1532             CopyPartialInternalEvent(dev->deviceGrab.sync.event, ev);
   1533 
   1534             /* The listener array has a sequence of grabs and then one event
   1535              * selection. Implicit grab activation occurs through delivering an
   1536              * event selection. Thus, we update the last listener in the array.
   1537              */
   1538             l = &ti->listeners[ti->num_listeners - 1];
   1539             l->listener = g->resource;
   1540             l->grab = g;
   1541             //l->resource_type = RT_NONE;
   1542 
   1543             if (devgrab->grabtype != XI2 || devgrab->type != XI_TouchBegin)
   1544                 l->type = TOUCH_LISTENER_POINTER_GRAB;
   1545             else
   1546                 l->type = TOUCH_LISTENER_GRAB;
   1547         }
   1548 
   1549     }
   1550     if (ev->any.type == ET_TouchBegin)
   1551         listener->state = TOUCH_LISTENER_IS_OWNER;
   1552     else if (ev->any.type == ET_TouchEnd)
   1553         listener->state = TOUCH_LISTENER_HAS_END;
   1554 
   1555     return Success;
   1556 }
   1557 
   1558 static void
   1559 DeliverEmulatedMotionEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
   1560                            InternalEvent *ev)
   1561 {
   1562     DeviceEvent motion;
   1563 
   1564     if (ti->num_listeners) {
   1565         ClientPtr client;
   1566         WindowPtr win;
   1567         GrabPtr grab;
   1568         XI2Mask *mask;
   1569 
   1570         if (ti->listeners[0].type != TOUCH_LISTENER_POINTER_REGULAR &&
   1571             ti->listeners[0].type != TOUCH_LISTENER_POINTER_GRAB)
   1572             return;
   1573 
   1574         motion = ev->device_event;
   1575         motion.type = ET_TouchUpdate;
   1576         motion.detail.button = 0;
   1577 
   1578         if (!RetrieveTouchDeliveryData(dev, ti, (InternalEvent*)&motion,
   1579                                        &ti->listeners[0], &client, &win, &grab,
   1580                                        &mask))
   1581             return;
   1582 
   1583         DeliverTouchEmulatedEvent(dev, ti, (InternalEvent*)&motion, &ti->listeners[0], client,
   1584                                   win, grab, mask);
   1585     }
   1586     else {
   1587         InternalEvent button;
   1588         int converted;
   1589 
   1590         converted = TouchConvertToPointerEvent(ev, (InternalEvent*)&motion, &button);
   1591 
   1592         BUG_WARN(converted == 0);
   1593         if (converted)
   1594             ProcessOtherEvent((InternalEvent*)&motion, dev);
   1595     }
   1596 }
   1597 
   1598 /**
   1599  * Processes and delivers a TouchBegin, TouchUpdate, or a
   1600  * TouchEnd event.
   1601  *
   1602  * Due to having rather different delivery semantics (see the Xi 2.2 protocol
   1603  * spec for more information), this implements its own grab and event-selection
   1604  * delivery logic.
   1605  */
   1606 static void
   1607 ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
   1608 {
   1609     TouchClassPtr t = dev->touch;
   1610     TouchPointInfoPtr ti;
   1611     uint32_t touchid;
   1612     int type = ev->any.type;
   1613     int emulate_pointer = ! !(ev->device_event.flags & TOUCH_POINTER_EMULATED);
   1614     DeviceIntPtr kbd;
   1615 
   1616     if (!t)
   1617         return;
   1618 
   1619     touchid = ev->device_event.touchid;
   1620 
   1621     if (type == ET_TouchBegin && !(ev->device_event.flags & TOUCH_REPLAYING)) {
   1622         ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
   1623                              emulate_pointer);
   1624     }
   1625     else
   1626         ti = TouchFindByClientID(dev, touchid);
   1627 
   1628     /* Active pointer grab */
   1629     if (emulate_pointer && dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab &&
   1630         (dev->deviceGrab.grab->grabtype == CORE ||
   1631          dev->deviceGrab.grab->grabtype == XI ||
   1632          !xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin)))
   1633     {
   1634         /* Active pointer grab on touch point and we get a TouchEnd - claim this
   1635          * touchpoint accepted, otherwise clients waiting for ownership will
   1636          * wait on this touchpoint until this client ungrabs, or the cows come
   1637          * home, whichever is earlier */
   1638         if (ti && type == ET_TouchEnd)
   1639             TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch);
   1640         else if (!ti && type != ET_TouchBegin) {
   1641             /* Under the following circumstances we create a new touch record for an
   1642              * existing touch:
   1643              *
   1644              * - The touch may be pointer emulated
   1645              * - An explicit grab is active on the device
   1646              * - The grab is a pointer grab
   1647              *
   1648              * This allows for an explicit grab to receive pointer events for an already
   1649              * active touch.
   1650              */
   1651             ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
   1652                                  emulate_pointer);
   1653             if (!ti) {
   1654                 DebugF("[Xi] %s: Failed to create new dix record for explicitly "
   1655                        "grabbed touchpoint %d\n",
   1656                        dev->name, touchid);
   1657                 return;
   1658             }
   1659 
   1660             TouchBuildSprite(dev, ti, ev);
   1661             TouchSetupListeners(dev, ti, ev);
   1662         }
   1663     }
   1664 
   1665     if (!ti) {
   1666         DebugF("[Xi] %s: Failed to get event %d for touchpoint %d\n",
   1667                dev->name, type, touchid);
   1668         goto out;
   1669     }
   1670 
   1671     /* if emulate_pointer is set, emulate the motion event right
   1672      * here, so we can ignore it for button event emulation. TouchUpdate
   1673      * events which _only_ emulate motion just work normally */
   1674     if (emulate_pointer && (ev->any.type == ET_TouchBegin ||
   1675                            (ev->any.type == ET_TouchEnd && ti->num_listeners > 0)))
   1676         DeliverEmulatedMotionEvent(dev, ti, ev);
   1677 
   1678     if (emulate_pointer && IsMaster(dev))
   1679         CheckMotion(&ev->device_event, dev);
   1680 
   1681     kbd = GetMaster(dev, KEYBOARD_OR_FLOAT);
   1682     event_set_state(NULL, kbd, &ev->device_event);
   1683     ev->device_event.corestate = event_get_corestate(NULL, kbd);
   1684 
   1685     /* Make sure we have a valid window trace for event delivery; must be
   1686      * called after event type mutation. Touch end events are always processed
   1687      * in order to end touch records. */
   1688     /* FIXME: check this */
   1689     if ((type == ET_TouchBegin &&
   1690          !(ev->device_event.flags & TOUCH_REPLAYING) &&
   1691          !TouchBuildSprite(dev, ti, ev)) ||
   1692         (type != ET_TouchEnd && ti->sprite.spriteTraceGood == 0))
   1693         return;
   1694 
   1695     TouchCopyValuatorData(&ev->device_event, ti);
   1696     /* WARNING: the event type may change to TouchUpdate in
   1697      * DeliverTouchEvents if a TouchEnd was delivered to a grabbing
   1698      * owner */
   1699     DeliverTouchEvents(dev, ti, ev, ev->device_event.resource);
   1700     if (ev->any.type == ET_TouchEnd)
   1701         TouchEndTouch(dev, ti);
   1702 
   1703  out:
   1704     if (emulate_pointer)
   1705         UpdateDeviceState(dev, &ev->device_event);
   1706 }
   1707 
   1708 static void
   1709 ProcessBarrierEvent(InternalEvent *e, DeviceIntPtr dev)
   1710 {
   1711     Mask filter;
   1712     WindowPtr pWin;
   1713     BarrierEvent *be = &e->barrier_event;
   1714     xEvent *ev;
   1715     int rc;
   1716     GrabPtr grab = dev->deviceGrab.grab;
   1717 
   1718     if (!IsMaster(dev))
   1719         return;
   1720 
   1721     if (dixLookupWindow(&pWin, be->window, serverClient, DixReadAccess) != Success)
   1722         return;
   1723 
   1724     if (grab)
   1725         be->flags |= XIBarrierDeviceIsGrabbed;
   1726 
   1727     rc = EventToXI2(e, &ev);
   1728     if (rc != Success) {
   1729         ErrorF("[Xi] event conversion from %s failed with code %d\n", __func__, rc);
   1730         return;
   1731     }
   1732 
   1733     /* A client has a grab, deliver to this client if the grab_window is the
   1734        barrier window.
   1735 
   1736        Otherwise, deliver normally to the client.
   1737      */
   1738     if (grab &&
   1739         CLIENT_ID(be->barrierid) == CLIENT_ID(grab->resource) &&
   1740         grab->window->drawable.id == be->window) {
   1741         DeliverGrabbedEvent(e, dev, FALSE);
   1742     } else {
   1743         filter = GetEventFilter(dev, ev);
   1744 
   1745         DeliverEventsToWindow(dev, pWin, ev, 1,
   1746                               filter, NullGrab);
   1747     }
   1748     free(ev);
   1749 }
   1750 
   1751 static BOOL
   1752 IsAnotherGestureActiveOnMaster(DeviceIntPtr dev, InternalEvent* ev)
   1753 {
   1754     GestureClassPtr g = dev->gesture;
   1755     if (g->gesture.active && g->gesture.sourceid != ev->gesture_event.sourceid) {
   1756         return TRUE;
   1757     }
   1758     return FALSE;
   1759 }
   1760 
   1761 /**
   1762  * Processes and delivers a Gesture{Pinch,Swipe}{Begin,Update,End}.
   1763  *
   1764  * Due to having rather different delivery semantics (see the Xi 2.4 protocol
   1765  * spec for more information), this implements its own grab and event-selection
   1766  * delivery logic.
   1767  */
   1768 void
   1769 ProcessGestureEvent(InternalEvent *ev, DeviceIntPtr dev)
   1770 {
   1771     GestureInfoPtr gi;
   1772     DeviceIntPtr kbd;
   1773     Bool deactivateGestureGrab = FALSE;
   1774     Bool delivered = FALSE;
   1775 
   1776     if (!dev->gesture)
   1777         return;
   1778 
   1779     if (IsMaster(dev) && IsAnotherGestureActiveOnMaster(dev, ev))
   1780         return;
   1781 
   1782     if (IsGestureBeginEvent(ev))
   1783         gi = GestureBeginGesture(dev, ev);
   1784     else
   1785         gi = GestureFindActiveByEventType(dev, ev->any.type);
   1786 
   1787     if (!gi) {
   1788         /* This may happen if gesture is no longer active or was never started. */
   1789         return;
   1790     }
   1791 
   1792     kbd = GetMaster(dev, KEYBOARD_OR_FLOAT);
   1793     event_set_state_gesture(kbd, &ev->gesture_event);
   1794 
   1795     if (IsGestureBeginEvent(ev))
   1796         GestureSetupListener(dev, gi, ev);
   1797 
   1798     if (IsGestureEndEvent(ev) &&
   1799             dev->deviceGrab.grab &&
   1800             dev->deviceGrab.fromPassiveGrab &&
   1801             GrabIsGestureGrab(dev->deviceGrab.grab))
   1802         deactivateGestureGrab = TRUE;
   1803 
   1804     delivered = DeliverGestureEventToOwner(dev, gi, ev);
   1805 
   1806     if (delivered && !deactivateGestureGrab &&
   1807             (IsGestureBeginEvent(ev) || IsGestureEndEvent(ev)))
   1808         FreezeThisEventIfNeededForSyncGrab(dev, ev);
   1809 
   1810     if (IsGestureEndEvent(ev))
   1811         GestureEndGesture(gi);
   1812 
   1813     if (deactivateGestureGrab)
   1814         (*dev->deviceGrab.DeactivateGrab) (dev);
   1815 }
   1816 
   1817 /**
   1818  * Process DeviceEvents and DeviceChangedEvents.
   1819  */
   1820 static void
   1821 ProcessDeviceEvent(InternalEvent *ev, DeviceIntPtr device)
   1822 {
   1823     GrabPtr grab;
   1824     Bool deactivateDeviceGrab = FALSE;
   1825     int key = 0, rootX, rootY;
   1826     ButtonClassPtr b;
   1827     int ret = 0;
   1828     int corestate;
   1829     DeviceIntPtr mouse = NULL, kbd = NULL;
   1830     DeviceEvent *event = &ev->device_event;
   1831 
   1832     if (IsPointerDevice(device)) {
   1833         kbd = GetMaster(device, KEYBOARD_OR_FLOAT);
   1834         mouse = device;
   1835         if (!kbd->key)          /* can happen with floating SDs */
   1836             kbd = NULL;
   1837     }
   1838     else {
   1839         mouse = GetMaster(device, POINTER_OR_FLOAT);
   1840         kbd = device;
   1841         if (!mouse->valuator || !mouse->button) /* may be float. SDs */
   1842             mouse = NULL;
   1843     }
   1844 
   1845     corestate = event_get_corestate(mouse, kbd);
   1846     event_set_state(mouse, kbd, event);
   1847 
   1848     ret = UpdateDeviceState(device, event);
   1849     if (ret == DONT_PROCESS)
   1850         return;
   1851 
   1852     b = device->button;
   1853 
   1854     if (IsMaster(device) || IsFloating(device))
   1855         CheckMotion(event, device);
   1856 
   1857     switch (event->type) {
   1858     case ET_Motion:
   1859     case ET_ButtonPress:
   1860     case ET_ButtonRelease:
   1861     case ET_KeyPress:
   1862     case ET_KeyRelease:
   1863     case ET_ProximityIn:
   1864     case ET_ProximityOut:
   1865         GetSpritePosition(device, &rootX, &rootY);
   1866         event->root_x = rootX;
   1867         event->root_y = rootY;
   1868         NoticeEventTime((InternalEvent *) event, device);
   1869         event->corestate = corestate;
   1870         key = event->detail.key;
   1871         break;
   1872     default:
   1873         break;
   1874     }
   1875 
   1876     /* send KeyPress and KeyRelease events to XACE plugins */
   1877     if (XaceHookIsSet(XACE_KEY_AVAIL) &&
   1878             (event->type == ET_KeyPress || event->type == ET_KeyRelease)) {
   1879         xEvent *core;
   1880         int count;
   1881 
   1882         if (EventToCore(ev, &core, &count) == Success && count > 0) {
   1883             XaceHook(XACE_KEY_AVAIL, core, device, 0);
   1884             free(core);
   1885         }
   1886     }
   1887 
   1888     if (DeviceEventCallback && !syncEvents.playingEvents) {
   1889         DeviceEventInfoRec eventinfo;
   1890         SpritePtr pSprite = device->spriteInfo->sprite;
   1891 
   1892         /* see comment in EnqueueEvents regarding the next three lines */
   1893         if (ev->any.type == ET_Motion)
   1894             ev->device_event.root = pSprite->hotPhys.pScreen->root->drawable.id;
   1895 
   1896         eventinfo.device = device;
   1897         eventinfo.event = ev;
   1898         CallCallbacks(&DeviceEventCallback, (void *) &eventinfo);
   1899     }
   1900 
   1901     grab = device->deviceGrab.grab;
   1902 
   1903     switch (event->type) {
   1904     case ET_KeyPress:
   1905         /* Don't deliver focus events (e.g. from KeymapNotify when running
   1906          * nested) to clients. */
   1907         if (event->source_type == EVENT_SOURCE_FOCUS)
   1908             return;
   1909         if (!grab && CheckDeviceGrabs(device, ev, 0))
   1910             return;
   1911         break;
   1912     case ET_KeyRelease:
   1913         if (grab && device->deviceGrab.fromPassiveGrab &&
   1914             (key == device->deviceGrab.activatingKey) &&
   1915             GrabIsKeyboardGrab(device->deviceGrab.grab))
   1916             deactivateDeviceGrab = TRUE;
   1917         break;
   1918     case ET_ButtonPress:
   1919         if (b->map[key] == 0)   /* there's no button 0 */
   1920             return;
   1921         event->detail.button = b->map[key];
   1922         if (!grab && CheckDeviceGrabs(device, ev, 0)) {
   1923             /* if a passive grab was activated, the event has been sent
   1924              * already */
   1925             return;
   1926         }
   1927         break;
   1928     case ET_ButtonRelease:
   1929         if (b->map[key] == 0)   /* there's no button 0 */
   1930             return;
   1931         event->detail.button = b->map[key];
   1932         if (grab && !b->buttonsDown &&
   1933             device->deviceGrab.fromPassiveGrab &&
   1934             GrabIsPointerGrab(device->deviceGrab.grab))
   1935             deactivateDeviceGrab = TRUE;
   1936     default:
   1937         break;
   1938     }
   1939 
   1940     /* Don't deliver focus events (e.g. from KeymapNotify when running
   1941      * nested) to clients. */
   1942     if (event->source_type != EVENT_SOURCE_FOCUS) {
   1943         if (grab)
   1944             DeliverGrabbedEvent((InternalEvent *) event, device,
   1945                                 deactivateDeviceGrab);
   1946         else if (device->focus && !IsPointerEvent(ev))
   1947             DeliverFocusedEvent(device, (InternalEvent *) event,
   1948                                 GetSpriteWindow(device));
   1949         else
   1950             DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent *) event,
   1951                                 NullGrab, NullWindow, device);
   1952     }
   1953 
   1954     if (deactivateDeviceGrab == TRUE) {
   1955         (*device->deviceGrab.DeactivateGrab) (device);
   1956 
   1957         if (!IsMaster (device) && !IsFloating (device)) {
   1958             int flags, num_events = 0;
   1959             InternalEvent dce;
   1960 
   1961             flags = (IsPointerDevice (device)) ?
   1962                 DEVCHANGE_POINTER_EVENT : DEVCHANGE_KEYBOARD_EVENT;
   1963             UpdateFromMaster (&dce, device, flags, &num_events);
   1964             BUG_WARN(num_events > 1);
   1965 
   1966             if (num_events == 1)
   1967                 ChangeMasterDeviceClasses(GetMaster (device, MASTER_ATTACHED),
   1968                                           &dce.changed_event);
   1969         }
   1970 
   1971     }
   1972 
   1973     event->detail.key = key;
   1974 }
   1975 
   1976 /**
   1977  * Main device event processing function.
   1978  * Called from when processing the events from the event queue.
   1979  *
   1980  */
   1981 void
   1982 ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
   1983 {
   1984     verify_internal_event(ev);
   1985 
   1986     switch (ev->any.type) {
   1987     case ET_RawKeyPress:
   1988     case ET_RawKeyRelease:
   1989     case ET_RawButtonPress:
   1990     case ET_RawButtonRelease:
   1991     case ET_RawMotion:
   1992     case ET_RawTouchBegin:
   1993     case ET_RawTouchUpdate:
   1994     case ET_RawTouchEnd:
   1995         DeliverRawEvent(&ev->raw_event, device);
   1996         break;
   1997     case ET_TouchBegin:
   1998     case ET_TouchUpdate:
   1999     case ET_TouchEnd:
   2000         ProcessTouchEvent(ev, device);
   2001         break;
   2002     case ET_TouchOwnership:
   2003         /* TouchOwnership events are handled separately from the rest, as they
   2004          * have more complex semantics. */
   2005         ProcessTouchOwnershipEvent(&ev->touch_ownership_event, device);
   2006         break;
   2007     case ET_BarrierHit:
   2008     case ET_BarrierLeave:
   2009         ProcessBarrierEvent(ev, device);
   2010         break;
   2011     case ET_GesturePinchBegin:
   2012     case ET_GesturePinchUpdate:
   2013     case ET_GesturePinchEnd:
   2014     case ET_GestureSwipeBegin:
   2015     case ET_GestureSwipeUpdate:
   2016     case ET_GestureSwipeEnd:
   2017         ProcessGestureEvent(ev, device);
   2018         break;
   2019     default:
   2020         ProcessDeviceEvent(ev, device);
   2021         break;
   2022     }
   2023 }
   2024 
   2025 static int
   2026 DeliverTouchBeginEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
   2027                        InternalEvent *ev, TouchListener * listener,
   2028                        ClientPtr client, WindowPtr win, GrabPtr grab,
   2029                        XI2Mask *xi2mask)
   2030 {
   2031     enum TouchListenerState state;
   2032     int rc = Success;
   2033     Bool has_ownershipmask;
   2034 
   2035     if (listener->type == TOUCH_LISTENER_POINTER_REGULAR ||
   2036         listener->type == TOUCH_LISTENER_POINTER_GRAB) {
   2037         rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
   2038                                        grab, xi2mask);
   2039         if (rc == Success) {
   2040             listener->state = TOUCH_LISTENER_IS_OWNER;
   2041             /* async grabs cannot replay, so automatically accept this touch */
   2042             if (listener->type == TOUCH_LISTENER_POINTER_GRAB &&
   2043                 dev->deviceGrab.grab &&
   2044                 dev->deviceGrab.fromPassiveGrab &&
   2045                 dev->deviceGrab.grab->pointerMode == GrabModeAsync)
   2046                 ActivateEarlyAccept(dev, ti);
   2047         }
   2048         goto out;
   2049     }
   2050 
   2051     has_ownershipmask = xi2mask_isset(xi2mask, dev, XI_TouchOwnership);
   2052 
   2053     if (TouchResourceIsOwner(ti, listener->listener) || has_ownershipmask)
   2054         rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
   2055     if (!TouchResourceIsOwner(ti, listener->listener)) {
   2056         if (has_ownershipmask)
   2057             state = TOUCH_LISTENER_AWAITING_OWNER;
   2058         else
   2059             state = TOUCH_LISTENER_AWAITING_BEGIN;
   2060     }
   2061     else {
   2062         if (has_ownershipmask)
   2063             TouchSendOwnershipEvent(dev, ti, 0, listener->listener);
   2064 
   2065         if (listener->type == TOUCH_LISTENER_REGULAR)
   2066             state = TOUCH_LISTENER_HAS_ACCEPTED;
   2067         else
   2068             state = TOUCH_LISTENER_IS_OWNER;
   2069     }
   2070     listener->state = state;
   2071 
   2072  out:
   2073     return rc;
   2074 }
   2075 
   2076 static int
   2077 DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
   2078                      TouchListener * listener, ClientPtr client,
   2079                      WindowPtr win, GrabPtr grab, XI2Mask *xi2mask)
   2080 {
   2081     int rc = Success;
   2082 
   2083     if (listener->type == TOUCH_LISTENER_POINTER_REGULAR ||
   2084         listener->type == TOUCH_LISTENER_POINTER_GRAB) {
   2085         /* Note: If the active grab was ungrabbed, we already changed the
   2086          * state to TOUCH_LISTENER_HAS_END but still get here. So we mustn't
   2087          * actually send the event.
   2088          * This is part two of the hack in DeactivatePointerGrab
   2089          */
   2090         if (listener->state != TOUCH_LISTENER_HAS_END) {
   2091             rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
   2092                                            grab, xi2mask);
   2093 
   2094              /* Once we send a TouchEnd to a legacy listener, we're already well
   2095               * past the accepting/rejecting stage (can only happen on
   2096               * GrabModeSync + replay. This listener now gets the end event,
   2097               * and we can continue.
   2098               */
   2099             if (rc == Success)
   2100                 listener->state = TOUCH_LISTENER_HAS_END;
   2101         }
   2102         goto out;
   2103     }
   2104 
   2105     /* A client is waiting for the begin, don't give it a TouchEnd */
   2106     if (listener->state == TOUCH_LISTENER_AWAITING_BEGIN) {
   2107         listener->state = TOUCH_LISTENER_HAS_END;
   2108         goto out;
   2109     }
   2110 
   2111     /* Event in response to reject */
   2112     if (ev->device_event.flags & TOUCH_REJECT ||
   2113         (ev->device_event.flags & TOUCH_ACCEPT && !TouchResourceIsOwner(ti, listener->listener))) {
   2114         /* Touch has been rejected, or accepted by its owner which is not this listener */
   2115         if (listener->state != TOUCH_LISTENER_HAS_END)
   2116             rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
   2117         listener->state = TOUCH_LISTENER_HAS_END;
   2118     }
   2119     else if (TouchResourceIsOwner(ti, listener->listener)) {
   2120         Bool normal_end = !(ev->device_event.flags & TOUCH_ACCEPT);
   2121 
   2122         /* FIXME: what about early acceptance */
   2123         if (normal_end && listener->state != TOUCH_LISTENER_HAS_END)
   2124             rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
   2125 
   2126         if ((ti->num_listeners > 1 ||
   2127              (ti->num_grabs > 0 && listener->state != TOUCH_LISTENER_HAS_ACCEPTED)) &&
   2128             (ev->device_event.flags & (TOUCH_ACCEPT | TOUCH_REJECT)) == 0) {
   2129             ev->any.type = ET_TouchUpdate;
   2130             ev->device_event.flags |= TOUCH_PENDING_END;
   2131             ti->pending_finish = TRUE;
   2132         }
   2133 
   2134         if (normal_end)
   2135             listener->state = TOUCH_LISTENER_HAS_END;
   2136     }
   2137 
   2138  out:
   2139     return rc;
   2140 }
   2141 
   2142 static int
   2143 DeliverTouchEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
   2144                   TouchListener * listener, ClientPtr client,
   2145                   WindowPtr win, GrabPtr grab, XI2Mask *xi2mask)
   2146 {
   2147     Bool has_ownershipmask = FALSE;
   2148     int rc = Success;
   2149 
   2150     if (xi2mask)
   2151         has_ownershipmask = xi2mask_isset(xi2mask, dev, XI_TouchOwnership);
   2152 
   2153     if (ev->any.type == ET_TouchOwnership) {
   2154         ev->touch_ownership_event.deviceid = dev->id;
   2155         if (!TouchResourceIsOwner(ti, listener->listener))
   2156             goto out;
   2157         rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
   2158         listener->state = TOUCH_LISTENER_IS_OWNER;
   2159     }
   2160     else
   2161         ev->device_event.deviceid = dev->id;
   2162 
   2163     if (ev->any.type == ET_TouchBegin) {
   2164         rc = DeliverTouchBeginEvent(dev, ti, ev, listener, client, win, grab,
   2165                                     xi2mask);
   2166     }
   2167     else if (ev->any.type == ET_TouchUpdate) {
   2168         if (listener->type == TOUCH_LISTENER_POINTER_REGULAR ||
   2169             listener->type == TOUCH_LISTENER_POINTER_GRAB)
   2170             DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win, grab,
   2171                                       xi2mask);
   2172         else if (TouchResourceIsOwner(ti, listener->listener) ||
   2173                  has_ownershipmask)
   2174             rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
   2175     }
   2176     else if (ev->any.type == ET_TouchEnd)
   2177         rc = DeliverTouchEndEvent(dev, ti, ev, listener, client, win, grab,
   2178                                   xi2mask);
   2179 
   2180  out:
   2181     return rc;
   2182 }
   2183 
   2184 /**
   2185  * Delivers a touch events to all interested clients.  For TouchBegin events,
   2186  * will update ti->listeners, ti->num_listeners, and ti->num_grabs.
   2187  * May also mutate ev (type and flags) upon successful delivery.  If
   2188  * @resource is non-zero, will only attempt delivery to the owner of that
   2189  * resource.
   2190  *
   2191  * @return TRUE if the event was delivered at least once, FALSE otherwise
   2192  */
   2193 void
   2194 DeliverTouchEvents(DeviceIntPtr dev, TouchPointInfoPtr ti,
   2195                    InternalEvent *ev, XID resource)
   2196 {
   2197     int i;
   2198 
   2199     if (ev->any.type == ET_TouchBegin &&
   2200         !(ev->device_event.flags & (TOUCH_CLIENT_ID | TOUCH_REPLAYING)))
   2201         TouchSetupListeners(dev, ti, ev);
   2202 
   2203     TouchEventHistoryPush(ti, &ev->device_event);
   2204 
   2205     for (i = 0; i < ti->num_listeners; i++) {
   2206         GrabPtr grab = NULL;
   2207         ClientPtr client;
   2208         WindowPtr win;
   2209         XI2Mask *mask;
   2210         TouchListener *listener = &ti->listeners[i];
   2211 
   2212         if (resource && listener->listener != resource)
   2213             continue;
   2214 
   2215         if (!RetrieveTouchDeliveryData(dev, ti, ev, listener, &client, &win,
   2216                                        &grab, &mask))
   2217             continue;
   2218 
   2219         DeliverTouchEvent(dev, ti, ev, listener, client, win, grab, mask);
   2220     }
   2221 }
   2222 
   2223 /**
   2224  * Attempts to deliver a gesture event to the given client.
   2225  */
   2226 static Bool
   2227 DeliverOneGestureEvent(ClientPtr client, DeviceIntPtr dev, GestureInfoPtr gi,
   2228                        GrabPtr grab, WindowPtr win, InternalEvent *ev)
   2229 {
   2230     int err;
   2231     xEvent *xi2;
   2232     Mask filter;
   2233     Window child = DeepestSpriteWin(&gi->sprite)->drawable.id;
   2234 
   2235     /* If we fail here, we're going to leave a client hanging. */
   2236     err = EventToXI2(ev, &xi2);
   2237     if (err != Success)
   2238         FatalError("[Xi] %s: XI2 conversion failed in %s"
   2239                    " (%d)\n", dev->name, __func__, err);
   2240 
   2241     FixUpEventFromWindow(&gi->sprite, xi2, win, child, FALSE);
   2242     filter = GetEventFilter(dev, xi2);
   2243     if (XaceHook(XACE_RECEIVE_ACCESS, client, win, xi2, 1) != Success)
   2244         return FALSE;
   2245     err = TryClientEvents(client, dev, xi2, 1, filter, filter, NullGrab);
   2246     free(xi2);
   2247 
   2248     /* Returning the value from TryClientEvents isn't useful, since all our
   2249      * resource-gone cleanups will update the delivery list anyway. */
   2250     return TRUE;
   2251 }
   2252 
   2253 /**
   2254  * Given a gesture event and a potential listener, retrieve info needed for processing the event.
   2255  *
   2256  * @param dev The device generating the gesture event.
   2257  * @param ev The gesture event to process.
   2258  * @param listener The gesture event listener that may receive the gesture event.
   2259  * @param[out] client The client that should receive the gesture event.
   2260  * @param[out] win The window to deliver the event on.
   2261  * @param[out] grab The grab to deliver the event through, if any.
   2262  * @return TRUE if an event should be delivered to the listener, FALSE
   2263  *         otherwise.
   2264  */
   2265 static Bool
   2266 RetrieveGestureDeliveryData(DeviceIntPtr dev, InternalEvent *ev, GestureListener* listener,
   2267                             ClientPtr *client, WindowPtr *win, GrabPtr *grab)
   2268 {
   2269     int rc;
   2270     int evtype;
   2271     InputClients *iclients = NULL;
   2272     *grab = NULL;
   2273 
   2274     if (listener->type == GESTURE_LISTENER_GRAB ||
   2275         listener->type == GESTURE_LISTENER_NONGESTURE_GRAB) {
   2276         *grab = listener->grab;
   2277 
   2278         BUG_RETURN_VAL(!*grab, FALSE);
   2279 
   2280         *client = rClient(*grab);
   2281         *win = (*grab)->window;
   2282     }
   2283     else {
   2284         rc = dixLookupResourceByType((void **) win, listener->listener, listener->resource_type,
   2285                                      serverClient, DixSendAccess);
   2286         if (rc != Success)
   2287             return FALSE;
   2288 
   2289         /* note that we only will have XI2 listeners as
   2290            listener->type == GESTURE_LISTENER_REGULAR */
   2291         evtype = GetXI2Type(ev->any.type);
   2292 
   2293         BUG_RETURN_VAL(!wOtherInputMasks(*win), FALSE);
   2294         nt_list_for_each_entry(iclients, wOtherInputMasks(*win)->inputClients, next)
   2295             if (xi2mask_isset(iclients->xi2mask, dev, evtype))
   2296                 break;
   2297 
   2298         BUG_RETURN_VAL(!iclients, FALSE);
   2299 
   2300         *client = rClient(iclients);
   2301     }
   2302 
   2303     return TRUE;
   2304 }
   2305 
   2306 /**
   2307  * Delivers a gesture to the owner, if possible and needed. Returns whether
   2308  * an event was delivered.
   2309  */
   2310 Bool
   2311 DeliverGestureEventToOwner(DeviceIntPtr dev, GestureInfoPtr gi, InternalEvent *ev)
   2312 {
   2313     GrabPtr grab = NULL;
   2314     ClientPtr client;
   2315     WindowPtr win;
   2316 
   2317     if (!gi->has_listener || gi->listener.type == GESTURE_LISTENER_NONGESTURE_GRAB) {
   2318         return 0;
   2319     }
   2320 
   2321     if (!RetrieveGestureDeliveryData(dev, ev, &gi->listener, &client, &win, &grab))
   2322         return 0;
   2323 
   2324     ev->gesture_event.deviceid = dev->id;
   2325 
   2326     return DeliverOneGestureEvent(client, dev, gi, grab, win, ev);
   2327 }
   2328 
   2329 int
   2330 InitProximityClassDeviceStruct(DeviceIntPtr dev)
   2331 {
   2332     ProximityClassPtr proxc;
   2333 
   2334     BUG_RETURN_VAL(dev == NULL, FALSE);
   2335     BUG_RETURN_VAL(dev->proximity != NULL, FALSE);
   2336 
   2337     proxc = (ProximityClassPtr) malloc(sizeof(ProximityClassRec));
   2338     if (!proxc)
   2339         return FALSE;
   2340     proxc->sourceid = dev->id;
   2341     proxc->in_proximity = TRUE;
   2342     dev->proximity = proxc;
   2343     return TRUE;
   2344 }
   2345 
   2346 /**
   2347  * Initialise the device's valuators. The memory must already be allocated,
   2348  * this function merely inits the matching axis (specified through axnum) to
   2349  * sane values.
   2350  *
   2351  * It is a condition that (minval < maxval).
   2352  *
   2353  * @see InitValuatorClassDeviceStruct
   2354  */
   2355 Bool
   2356 InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval,
   2357                        int maxval, int resolution, int min_res, int max_res,
   2358                        int mode)
   2359 {
   2360     AxisInfoPtr ax;
   2361 
   2362     BUG_RETURN_VAL(dev == NULL, FALSE);
   2363     BUG_RETURN_VAL(dev->valuator == NULL, FALSE);
   2364     BUG_RETURN_VAL(axnum >= dev->valuator->numAxes, FALSE);
   2365     BUG_RETURN_VAL(minval > maxval && mode == Absolute, FALSE);
   2366 
   2367     ax = dev->valuator->axes + axnum;
   2368 
   2369     ax->min_value = minval;
   2370     ax->max_value = maxval;
   2371     ax->resolution = resolution;
   2372     ax->min_resolution = min_res;
   2373     ax->max_resolution = max_res;
   2374     ax->label = label;
   2375     ax->mode = mode;
   2376 
   2377     if (mode & OutOfProximity)
   2378         dev->proximity->in_proximity = FALSE;
   2379 
   2380     return SetScrollValuator(dev, axnum, SCROLL_TYPE_NONE, 0, SCROLL_FLAG_NONE);
   2381 }
   2382 
   2383 /**
   2384  * Set the given axis number as a scrolling valuator.
   2385  */
   2386 Bool
   2387 SetScrollValuator(DeviceIntPtr dev, int axnum, enum ScrollType type,
   2388                   double increment, int flags)
   2389 {
   2390     AxisInfoPtr ax;
   2391     int *current_ax;
   2392     InternalEvent dce;
   2393     DeviceIntPtr master;
   2394 
   2395     BUG_RETURN_VAL(dev == NULL, FALSE);
   2396     BUG_RETURN_VAL(dev->valuator == NULL, FALSE);
   2397     BUG_RETURN_VAL(axnum >= dev->valuator->numAxes, FALSE);
   2398 
   2399     switch (type) {
   2400     case SCROLL_TYPE_VERTICAL:
   2401         current_ax = &dev->valuator->v_scroll_axis;
   2402         break;
   2403     case SCROLL_TYPE_HORIZONTAL:
   2404         current_ax = &dev->valuator->h_scroll_axis;
   2405         break;
   2406     case SCROLL_TYPE_NONE:
   2407         ax = &dev->valuator->axes[axnum];
   2408         ax->scroll.type = type;
   2409         return TRUE;
   2410     default:
   2411         return FALSE;
   2412     }
   2413 
   2414     if (increment == 0.0)
   2415         return FALSE;
   2416 
   2417     if (*current_ax != -1 && axnum != *current_ax) {
   2418         ax = &dev->valuator->axes[*current_ax];
   2419         if (ax->scroll.type == type &&
   2420             (flags & SCROLL_FLAG_PREFERRED) &&
   2421             (ax->scroll.flags & SCROLL_FLAG_PREFERRED))
   2422             return FALSE;
   2423     }
   2424     *current_ax = axnum;
   2425 
   2426     ax = &dev->valuator->axes[axnum];
   2427     ax->scroll.type = type;
   2428     ax->scroll.increment = increment;
   2429     ax->scroll.flags = flags;
   2430 
   2431     master = GetMaster(dev, MASTER_ATTACHED);
   2432     CreateClassesChangedEvent(&dce, master, dev,
   2433                               DEVCHANGE_POINTER_EVENT |
   2434                               DEVCHANGE_DEVICE_CHANGE);
   2435     XISendDeviceChangedEvent(dev, &dce.changed_event);
   2436 
   2437     /* if the current slave is us, update the master. If not, we'll update
   2438      * whenever the next slave switch happens anyway. CMDC sends the event
   2439      * for us */
   2440     if (master && master->lastSlave == dev)
   2441         ChangeMasterDeviceClasses(master, &dce.changed_event);
   2442 
   2443     return TRUE;
   2444 }
   2445 
   2446 int
   2447 CheckGrabValues(ClientPtr client, GrabParameters *param)
   2448 {
   2449     if (param->grabtype != CORE &&
   2450         param->grabtype != XI && param->grabtype != XI2) {
   2451         ErrorF("[Xi] grabtype is invalid. This is a bug.\n");
   2452         return BadImplementation;
   2453     }
   2454 
   2455     if ((param->this_device_mode != GrabModeSync) &&
   2456         (param->this_device_mode != GrabModeAsync) &&
   2457         (param->this_device_mode != XIGrabModeTouch)) {
   2458         client->errorValue = param->this_device_mode;
   2459         return BadValue;
   2460     }
   2461     if ((param->other_devices_mode != GrabModeSync) &&
   2462         (param->other_devices_mode != GrabModeAsync) &&
   2463         (param->other_devices_mode != XIGrabModeTouch)) {
   2464         client->errorValue = param->other_devices_mode;
   2465         return BadValue;
   2466     }
   2467 
   2468     if (param->modifiers != AnyModifier &&
   2469         param->modifiers != XIAnyModifier &&
   2470         (param->modifiers & ~AllModifiersMask)) {
   2471         client->errorValue = param->modifiers;
   2472         return BadValue;
   2473     }
   2474 
   2475     if ((param->ownerEvents != xFalse) && (param->ownerEvents != xTrue)) {
   2476         client->errorValue = param->ownerEvents;
   2477         return BadValue;
   2478     }
   2479     return Success;
   2480 }
   2481 
   2482 int
   2483 GrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
   2484            int button, GrabParameters *param, enum InputLevel grabtype,
   2485            GrabMask *mask)
   2486 {
   2487     WindowPtr pWin, confineTo;
   2488     CursorPtr cursor;
   2489     GrabPtr grab;
   2490     int rc, type = -1;
   2491     Mask access_mode = DixGrabAccess;
   2492 
   2493     rc = CheckGrabValues(client, param);
   2494     if (rc != Success)
   2495         return rc;
   2496     if (param->confineTo == None)
   2497         confineTo = NullWindow;
   2498     else {
   2499         rc = dixLookupWindow(&confineTo, param->confineTo, client,
   2500                              DixSetAttrAccess);
   2501         if (rc != Success)
   2502             return rc;
   2503     }
   2504     if (param->cursor == None)
   2505         cursor = NullCursor;
   2506     else {
   2507         rc = dixLookupResourceByType((void **) &cursor, param->cursor,
   2508                                      RT_CURSOR, client, DixUseAccess);
   2509         if (rc != Success) {
   2510             client->errorValue = param->cursor;
   2511             return rc;
   2512         }
   2513         access_mode |= DixForceAccess;
   2514     }
   2515     if (param->this_device_mode == GrabModeSync ||
   2516         param->other_devices_mode == GrabModeSync)
   2517         access_mode |= DixFreezeAccess;
   2518     rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
   2519     if (rc != Success)
   2520         return rc;
   2521     rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
   2522     if (rc != Success)
   2523         return rc;
   2524 
   2525     if (grabtype == XI)
   2526         type = DeviceButtonPress;
   2527     else if (grabtype == XI2)
   2528         type = XI_ButtonPress;
   2529 
   2530     grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype,
   2531                       mask, param, type, button, confineTo, cursor);
   2532     if (!grab)
   2533         return BadAlloc;
   2534     return AddPassiveGrabToList(client, grab);
   2535 }
   2536 
   2537 /**
   2538  * Grab the given key.
   2539  */
   2540 int
   2541 GrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
   2542         int key, GrabParameters *param, enum InputLevel grabtype,
   2543         GrabMask *mask)
   2544 {
   2545     WindowPtr pWin;
   2546     GrabPtr grab;
   2547     KeyClassPtr k = dev->key;
   2548     Mask access_mode = DixGrabAccess;
   2549     int rc, type = -1;
   2550 
   2551     rc = CheckGrabValues(client, param);
   2552     if (rc != Success)
   2553         return rc;
   2554     if ((dev->id != XIAllDevices && dev->id != XIAllMasterDevices) && k == NULL)
   2555         return BadMatch;
   2556     if (grabtype == XI) {
   2557         if ((key > k->xkbInfo->desc->max_key_code ||
   2558              key < k->xkbInfo->desc->min_key_code)
   2559             && (key != AnyKey)) {
   2560             client->errorValue = key;
   2561             return BadValue;
   2562         }
   2563         type = DeviceKeyPress;
   2564     }
   2565     else if (grabtype == XI2)
   2566         type = XI_KeyPress;
   2567 
   2568     rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
   2569     if (rc != Success)
   2570         return rc;
   2571     if (param->this_device_mode == GrabModeSync ||
   2572         param->other_devices_mode == GrabModeSync)
   2573         access_mode |= DixFreezeAccess;
   2574     rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
   2575     if (rc != Success)
   2576         return rc;
   2577 
   2578     grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype,
   2579                       mask, param, type, key, NULL, NULL);
   2580     if (!grab)
   2581         return BadAlloc;
   2582     return AddPassiveGrabToList(client, grab);
   2583 }
   2584 
   2585 /* Enter/FocusIn grab */
   2586 int
   2587 GrabWindow(ClientPtr client, DeviceIntPtr dev, int type,
   2588            GrabParameters *param, GrabMask *mask)
   2589 {
   2590     WindowPtr pWin;
   2591     CursorPtr cursor;
   2592     GrabPtr grab;
   2593     Mask access_mode = DixGrabAccess;
   2594     int rc;
   2595 
   2596     rc = CheckGrabValues(client, param);
   2597     if (rc != Success)
   2598         return rc;
   2599 
   2600     rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
   2601     if (rc != Success)
   2602         return rc;
   2603     if (param->cursor == None)
   2604         cursor = NullCursor;
   2605     else {
   2606         rc = dixLookupResourceByType((void **) &cursor, param->cursor,
   2607                                      RT_CURSOR, client, DixUseAccess);
   2608         if (rc != Success) {
   2609             client->errorValue = param->cursor;
   2610             return rc;
   2611         }
   2612         access_mode |= DixForceAccess;
   2613     }
   2614     if (param->this_device_mode == GrabModeSync ||
   2615         param->other_devices_mode == GrabModeSync)
   2616         access_mode |= DixFreezeAccess;
   2617     rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
   2618     if (rc != Success)
   2619         return rc;
   2620 
   2621     grab = CreateGrab(client->index, dev, dev, pWin, XI2,
   2622                       mask, param,
   2623                       (type == XIGrabtypeEnter) ? XI_Enter : XI_FocusIn, 0,
   2624                       NULL, cursor);
   2625 
   2626     if (!grab)
   2627         return BadAlloc;
   2628 
   2629     return AddPassiveGrabToList(client, grab);
   2630 }
   2631 
   2632 /* Touch grab */
   2633 int
   2634 GrabTouchOrGesture(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr mod_dev,
   2635                    int type, GrabParameters *param, GrabMask *mask)
   2636 {
   2637     WindowPtr pWin;
   2638     GrabPtr grab;
   2639     int rc;
   2640 
   2641     rc = CheckGrabValues(client, param);
   2642     if (rc != Success)
   2643         return rc;
   2644 
   2645     rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
   2646     if (rc != Success)
   2647         return rc;
   2648     rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGrabAccess);
   2649     if (rc != Success)
   2650         return rc;
   2651 
   2652     grab = CreateGrab(client->index, dev, mod_dev, pWin, XI2,
   2653                       mask, param, type, 0, NullWindow, NullCursor);
   2654     if (!grab)
   2655         return BadAlloc;
   2656 
   2657     return AddPassiveGrabToList(client, grab);
   2658 }
   2659 
   2660 int
   2661 SelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client,
   2662                 Mask mask, Mask exclusivemasks)
   2663 {
   2664     int mskidx = dev->id;
   2665     int i, ret;
   2666     Mask check;
   2667     InputClientsPtr others;
   2668 
   2669     check = (mask & exclusivemasks);
   2670     if (wOtherInputMasks(pWin)) {
   2671         if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) {
   2672             /* It is illegal for two different clients to select on any of
   2673              * the events for maskcheck. However, it is OK, for some client
   2674              * to continue selecting on one of those events.
   2675              */
   2676             for (others = wOtherInputMasks(pWin)->inputClients; others;
   2677                  others = others->next) {
   2678                 if (!SameClient(others, client) && (check &
   2679                                                     others->mask[mskidx]))
   2680                     return BadAccess;
   2681             }
   2682         }
   2683         for (others = wOtherInputMasks(pWin)->inputClients; others;
   2684              others = others->next) {
   2685             if (SameClient(others, client)) {
   2686                 check = others->mask[mskidx];
   2687                 others->mask[mskidx] = mask;
   2688                 if (mask == 0) {
   2689                     for (i = 0; i < EMASKSIZE; i++)
   2690                         if (i != mskidx && others->mask[i] != 0)
   2691                             break;
   2692                     if (i == EMASKSIZE) {
   2693                         RecalculateDeviceDeliverableEvents(pWin);
   2694                         if (ShouldFreeInputMasks(pWin, FALSE))
   2695                             FreeResource(others->resource, RT_NONE);
   2696                         return Success;
   2697                     }
   2698                 }
   2699                 goto maskSet;
   2700             }
   2701         }
   2702     }
   2703     check = 0;
   2704     if ((ret = AddExtensionClient(pWin, client, mask, mskidx)) != Success)
   2705         return ret;
   2706  maskSet:
   2707     if (dev->valuator)
   2708         if ((dev->valuator->motionHintWindow == pWin) &&
   2709             (mask & DevicePointerMotionHintMask) &&
   2710             !(check & DevicePointerMotionHintMask) && !dev->deviceGrab.grab)
   2711             dev->valuator->motionHintWindow = NullWindow;
   2712     RecalculateDeviceDeliverableEvents(pWin);
   2713     return Success;
   2714 }
   2715 
   2716 static void
   2717 FreeInputClient(InputClientsPtr * other)
   2718 {
   2719     xi2mask_free(&(*other)->xi2mask);
   2720     free(*other);
   2721     *other = NULL;
   2722 }
   2723 
   2724 static InputClientsPtr
   2725 AllocInputClient(void)
   2726 {
   2727     return calloc(1, sizeof(InputClients));
   2728 }
   2729 
   2730 int
   2731 AddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx)
   2732 {
   2733     InputClientsPtr others;
   2734 
   2735     if (!pWin->optional && !MakeWindowOptional(pWin))
   2736         return BadAlloc;
   2737     others = AllocInputClient();
   2738     if (!others)
   2739         return BadAlloc;
   2740     if (!pWin->optional->inputMasks && !MakeInputMasks(pWin))
   2741         goto bail;
   2742     others->xi2mask = xi2mask_new();
   2743     if (!others->xi2mask)
   2744         goto bail;
   2745     others->mask[mskidx] = mask;
   2746     others->resource = FakeClientID(client->index);
   2747     others->next = pWin->optional->inputMasks->inputClients;
   2748     pWin->optional->inputMasks->inputClients = others;
   2749     if (!AddResource(others->resource, RT_INPUTCLIENT, (void *) pWin))
   2750         goto bail;
   2751     return Success;
   2752 
   2753  bail:
   2754     FreeInputClient(&others);
   2755     return BadAlloc;
   2756 }
   2757 
   2758 static Bool
   2759 MakeInputMasks(WindowPtr pWin)
   2760 {
   2761     struct _OtherInputMasks *imasks;
   2762 
   2763     imasks = calloc(1, sizeof(struct _OtherInputMasks));
   2764     if (!imasks)
   2765         return FALSE;
   2766     imasks->xi2mask = xi2mask_new();
   2767     if (!imasks->xi2mask) {
   2768         free(imasks);
   2769         return FALSE;
   2770     }
   2771     pWin->optional->inputMasks = imasks;
   2772     return TRUE;
   2773 }
   2774 
   2775 static void
   2776 FreeInputMask(OtherInputMasks ** imask)
   2777 {
   2778     xi2mask_free(&(*imask)->xi2mask);
   2779     free(*imask);
   2780     *imask = NULL;
   2781 }
   2782 
   2783 #define XIPropagateMask (KeyPressMask | \
   2784                          KeyReleaseMask | \
   2785                          ButtonPressMask | \
   2786                          ButtonReleaseMask | \
   2787                          PointerMotionMask)
   2788 
   2789 void
   2790 RecalculateDeviceDeliverableEvents(WindowPtr pWin)
   2791 {
   2792     InputClientsPtr others;
   2793     struct _OtherInputMasks *inputMasks;        /* default: NULL */
   2794     WindowPtr pChild, tmp;
   2795     int i;
   2796 
   2797     pChild = pWin;
   2798     while (1) {
   2799         if ((inputMasks = wOtherInputMasks(pChild)) != 0) {
   2800             xi2mask_zero(inputMasks->xi2mask, -1);
   2801             for (others = inputMasks->inputClients; others;
   2802                  others = others->next) {
   2803                 for (i = 0; i < EMASKSIZE; i++)
   2804                     inputMasks->inputEvents[i] |= others->mask[i];
   2805                 xi2mask_merge(inputMasks->xi2mask, others->xi2mask);
   2806             }
   2807             for (i = 0; i < EMASKSIZE; i++)
   2808                 inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i];
   2809             for (tmp = pChild->parent; tmp; tmp = tmp->parent)
   2810                 if (wOtherInputMasks(tmp))
   2811                     for (i = 0; i < EMASKSIZE; i++)
   2812                         inputMasks->deliverableEvents[i] |=
   2813                             (wOtherInputMasks(tmp)->deliverableEvents[i]
   2814                              & ~inputMasks->dontPropagateMask[i] &
   2815                              XIPropagateMask);
   2816         }
   2817         if (pChild->firstChild) {
   2818             pChild = pChild->firstChild;
   2819             continue;
   2820         }
   2821         while (!pChild->nextSib && (pChild != pWin))
   2822             pChild = pChild->parent;
   2823         if (pChild == pWin)
   2824             break;
   2825         pChild = pChild->nextSib;
   2826     }
   2827 }
   2828 
   2829 int
   2830 InputClientGone(WindowPtr pWin, XID id)
   2831 {
   2832     InputClientsPtr other, prev;
   2833 
   2834     if (!wOtherInputMasks(pWin))
   2835         return Success;
   2836     prev = 0;
   2837     for (other = wOtherInputMasks(pWin)->inputClients; other;
   2838          other = other->next) {
   2839         if (other->resource == id) {
   2840             if (prev) {
   2841                 prev->next = other->next;
   2842                 FreeInputClient(&other);
   2843             }
   2844             else if (!(other->next)) {
   2845                 if (ShouldFreeInputMasks(pWin, TRUE)) {
   2846                     OtherInputMasks *mask = wOtherInputMasks(pWin);
   2847 
   2848                     mask->inputClients = other->next;
   2849                     FreeInputMask(&mask);
   2850                     pWin->optional->inputMasks = (OtherInputMasks *) NULL;
   2851                     CheckWindowOptionalNeed(pWin);
   2852                     FreeInputClient(&other);
   2853                 }
   2854                 else {
   2855                     other->resource = FakeClientID(0);
   2856                     if (!AddResource(other->resource, RT_INPUTCLIENT,
   2857                                      (void *) pWin))
   2858                         return BadAlloc;
   2859                 }
   2860             }
   2861             else {
   2862                 wOtherInputMasks(pWin)->inputClients = other->next;
   2863                 FreeInputClient(&other);
   2864             }
   2865             RecalculateDeviceDeliverableEvents(pWin);
   2866             return Success;
   2867         }
   2868         prev = other;
   2869     }
   2870     FatalError("client not on device event list");
   2871 }
   2872 
   2873 /**
   2874  * Search for window in each touch trace for each device. Remove the window
   2875  * and all its subwindows from the trace when found. The initial window
   2876  * order is preserved.
   2877  */
   2878 void
   2879 WindowGone(WindowPtr win)
   2880 {
   2881     DeviceIntPtr dev;
   2882 
   2883     for (dev = inputInfo.devices; dev; dev = dev->next) {
   2884         TouchClassPtr t = dev->touch;
   2885         int i;
   2886 
   2887         if (!t)
   2888             continue;
   2889 
   2890         for (i = 0; i < t->num_touches; i++) {
   2891             SpritePtr sprite = &t->touches[i].sprite;
   2892             int j;
   2893 
   2894             for (j = 0; j < sprite->spriteTraceGood; j++) {
   2895                 if (sprite->spriteTrace[j] == win) {
   2896                     sprite->spriteTraceGood = j;
   2897                     break;
   2898                 }
   2899             }
   2900         }
   2901     }
   2902 }
   2903 
   2904 int
   2905 SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate,
   2906           xEvent *ev, Mask mask, int count)
   2907 {
   2908     WindowPtr pWin;
   2909     WindowPtr effectiveFocus = NullWindow;      /* only set if dest==InputFocus */
   2910     WindowPtr spriteWin = GetSpriteWindow(d);
   2911 
   2912     if (dest == PointerWindow)
   2913         pWin = spriteWin;
   2914     else if (dest == InputFocus) {
   2915         WindowPtr inputFocus;
   2916 
   2917         if (!d->focus)
   2918             inputFocus = spriteWin;
   2919         else
   2920             inputFocus = d->focus->win;
   2921 
   2922         if (inputFocus == FollowKeyboardWin)
   2923             inputFocus = inputInfo.keyboard->focus->win;
   2924 
   2925         if (inputFocus == NoneWin)
   2926             return Success;
   2927 
   2928         /* If the input focus is PointerRootWin, send the event to where
   2929          * the pointer is if possible, then perhaps propagate up to root. */
   2930         if (inputFocus == PointerRootWin)
   2931             inputFocus = GetCurrentRootWindow(d);
   2932 
   2933         if (IsParent(inputFocus, spriteWin)) {
   2934             effectiveFocus = inputFocus;
   2935             pWin = spriteWin;
   2936         }
   2937         else
   2938             effectiveFocus = pWin = inputFocus;
   2939     }
   2940     else
   2941         dixLookupWindow(&pWin, dest, client, DixSendAccess);
   2942     if (!pWin)
   2943         return BadWindow;
   2944     if ((propagate != xFalse) && (propagate != xTrue)) {
   2945         client->errorValue = propagate;
   2946         return BadValue;
   2947     }
   2948     ev->u.u.type |= 0x80;
   2949     if (propagate) {
   2950         for (; pWin; pWin = pWin->parent) {
   2951             if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab))
   2952                 return Success;
   2953             if (pWin == effectiveFocus)
   2954                 return Success;
   2955             if (wOtherInputMasks(pWin))
   2956                 mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id];
   2957             if (!mask)
   2958                 break;
   2959         }
   2960     }
   2961     else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count))
   2962         DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab);
   2963     return Success;
   2964 }
   2965 
   2966 int
   2967 SetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map)
   2968 {
   2969     int i;
   2970     ButtonClassPtr b = dev->button;
   2971 
   2972     if (b == NULL)
   2973         return BadMatch;
   2974 
   2975     if (nElts != b->numButtons) {
   2976         client->errorValue = nElts;
   2977         return BadValue;
   2978     }
   2979     if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue))
   2980         return BadValue;
   2981     for (i = 0; i < nElts; i++)
   2982         if ((b->map[i + 1] != map[i]) && BitIsOn(b->down, i + 1))
   2983             return MappingBusy;
   2984     for (i = 0; i < nElts; i++)
   2985         b->map[i + 1] = map[i];
   2986     return Success;
   2987 }
   2988 
   2989 int
   2990 ChangeKeyMapping(ClientPtr client,
   2991                  DeviceIntPtr dev,
   2992                  unsigned len,
   2993                  int type,
   2994                  KeyCode firstKeyCode,
   2995                  CARD8 keyCodes, CARD8 keySymsPerKeyCode, KeySym * map)
   2996 {
   2997     KeySymsRec keysyms;
   2998     KeyClassPtr k = dev->key;
   2999 
   3000     if (k == NULL)
   3001         return BadMatch;
   3002 
   3003     if (len != (keyCodes * keySymsPerKeyCode))
   3004         return BadLength;
   3005 
   3006     if ((firstKeyCode < k->xkbInfo->desc->min_key_code) ||
   3007         (firstKeyCode + keyCodes - 1 > k->xkbInfo->desc->max_key_code)) {
   3008         client->errorValue = firstKeyCode;
   3009         return BadValue;
   3010     }
   3011     if (keySymsPerKeyCode == 0) {
   3012         client->errorValue = 0;
   3013         return BadValue;
   3014     }
   3015     keysyms.minKeyCode = firstKeyCode;
   3016     keysyms.maxKeyCode = firstKeyCode + keyCodes - 1;
   3017     keysyms.mapWidth = keySymsPerKeyCode;
   3018     keysyms.map = map;
   3019 
   3020     XkbApplyMappingChange(dev, &keysyms, firstKeyCode, keyCodes, NULL,
   3021                           serverClient);
   3022 
   3023     return Success;
   3024 }
   3025 
   3026 static void
   3027 DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev)
   3028 {
   3029     WindowPtr parent;
   3030 
   3031     /* Deactivate any grabs performed on this window, before making
   3032      * any input focus changes.
   3033      * Deactivating a device grab should cause focus events. */
   3034 
   3035     if (dev->deviceGrab.grab && (dev->deviceGrab.grab->window == pWin))
   3036         (*dev->deviceGrab.DeactivateGrab) (dev);
   3037 
   3038     /* If the focus window is a root window (ie. has no parent)
   3039      * then don't delete the focus from it. */
   3040 
   3041     if (dev->focus && (pWin == dev->focus->win) && (pWin->parent != NullWindow)) {
   3042         int focusEventMode = NotifyNormal;
   3043 
   3044         /* If a grab is in progress, then alter the mode of focus events. */
   3045 
   3046         if (dev->deviceGrab.grab)
   3047             focusEventMode = NotifyWhileGrabbed;
   3048 
   3049         switch (dev->focus->revert) {
   3050         case RevertToNone:
   3051             if (!ActivateFocusInGrab(dev, pWin, NoneWin))
   3052                 DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
   3053             dev->focus->win = NoneWin;
   3054             dev->focus->traceGood = 0;
   3055             break;
   3056         case RevertToParent:
   3057             parent = pWin;
   3058             do {
   3059                 parent = parent->parent;
   3060                 dev->focus->traceGood--;
   3061             }
   3062             while (!parent->realized);
   3063             if (!ActivateFocusInGrab(dev, pWin, parent))
   3064                 DoFocusEvents(dev, pWin, parent, focusEventMode);
   3065             dev->focus->win = parent;
   3066             dev->focus->revert = RevertToNone;
   3067             break;
   3068         case RevertToPointerRoot:
   3069             if (!ActivateFocusInGrab(dev, pWin, PointerRootWin))
   3070                 DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode);
   3071             dev->focus->win = PointerRootWin;
   3072             dev->focus->traceGood = 0;
   3073             break;
   3074         case RevertToFollowKeyboard:
   3075         {
   3076             DeviceIntPtr kbd = GetMaster(dev, MASTER_KEYBOARD);
   3077 
   3078             if (!kbd || (kbd == dev && kbd != inputInfo.keyboard))
   3079                 kbd = inputInfo.keyboard;
   3080             if (kbd->focus->win) {
   3081                 if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win))
   3082                     DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode);
   3083                 dev->focus->win = FollowKeyboardWin;
   3084                 dev->focus->traceGood = 0;
   3085             }
   3086             else {
   3087                 if (!ActivateFocusInGrab(dev, pWin, NoneWin))
   3088                     DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
   3089                 dev->focus->win = NoneWin;
   3090                 dev->focus->traceGood = 0;
   3091             }
   3092         }
   3093             break;
   3094         }
   3095     }
   3096 
   3097     if (dev->valuator)
   3098         if (dev->valuator->motionHintWindow == pWin)
   3099             dev->valuator->motionHintWindow = NullWindow;
   3100 }
   3101 
   3102 void
   3103 DeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources)
   3104 {
   3105     int i;
   3106     DeviceIntPtr dev;
   3107     InputClientsPtr ic;
   3108     struct _OtherInputMasks *inputMasks;
   3109 
   3110     for (dev = inputInfo.devices; dev; dev = dev->next) {
   3111         DeleteDeviceFromAnyExtEvents(pWin, dev);
   3112     }
   3113 
   3114     for (dev = inputInfo.off_devices; dev; dev = dev->next)
   3115         DeleteDeviceFromAnyExtEvents(pWin, dev);
   3116 
   3117     if (freeResources)
   3118         while ((inputMasks = wOtherInputMasks(pWin)) != 0) {
   3119             ic = inputMasks->inputClients;
   3120             for (i = 0; i < EMASKSIZE; i++)
   3121                 inputMasks->dontPropagateMask[i] = 0;
   3122             FreeResource(ic->resource, RT_NONE);
   3123         }
   3124 }
   3125 
   3126 int
   3127 MaybeSendDeviceMotionNotifyHint(deviceKeyButtonPointer *pEvents, Mask mask)
   3128 {
   3129     DeviceIntPtr dev;
   3130 
   3131     dixLookupDevice(&dev, pEvents->deviceid & DEVICE_BITS, serverClient,
   3132                     DixReadAccess);
   3133     if (!dev)
   3134         return 0;
   3135 
   3136     if (pEvents->type == DeviceMotionNotify) {
   3137         if (mask & DevicePointerMotionHintMask) {
   3138             if (WID(dev->valuator->motionHintWindow) == pEvents->event) {
   3139                 return 1;       /* don't send, but pretend we did */
   3140             }
   3141             pEvents->detail = NotifyHint;
   3142         }
   3143         else {
   3144             pEvents->detail = NotifyNormal;
   3145         }
   3146     }
   3147     return 0;
   3148 }
   3149 
   3150 void
   3151 CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type,
   3152                              deviceKeyButtonPointer *xE, GrabPtr grab,
   3153                              ClientPtr client, Mask deliveryMask)
   3154 {
   3155     DeviceIntPtr dev;
   3156 
   3157     dixLookupDevice(&dev, xE->deviceid & DEVICE_BITS, serverClient,
   3158                     DixGrabAccess);
   3159     if (!dev)
   3160         return;
   3161 
   3162     if (type == DeviceMotionNotify)
   3163         dev->valuator->motionHintWindow = pWin;
   3164     else if ((type == DeviceButtonPress) && (!grab) &&
   3165              (deliveryMask & DeviceButtonGrabMask)) {
   3166         GrabPtr tempGrab;
   3167 
   3168         tempGrab = AllocGrab(NULL);
   3169         if (!tempGrab)
   3170             return;
   3171 
   3172         tempGrab->device = dev;
   3173         tempGrab->resource = client->clientAsMask;
   3174         tempGrab->window = pWin;
   3175         tempGrab->ownerEvents =
   3176             (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE;
   3177         tempGrab->eventMask = deliveryMask;
   3178         tempGrab->keyboardMode = GrabModeAsync;
   3179         tempGrab->pointerMode = GrabModeAsync;
   3180         tempGrab->confineTo = NullWindow;
   3181         tempGrab->cursor = NullCursor;
   3182         tempGrab->next = NULL;
   3183         (*dev->deviceGrab.ActivateGrab) (dev, tempGrab, currentTime, TRUE);
   3184         FreeGrab(tempGrab);
   3185     }
   3186 }
   3187 
   3188 static Mask
   3189 DeviceEventMaskForClient(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client)
   3190 {
   3191     InputClientsPtr other;
   3192 
   3193     if (!wOtherInputMasks(pWin))
   3194         return 0;
   3195     for (other = wOtherInputMasks(pWin)->inputClients; other;
   3196          other = other->next) {
   3197         if (SameClient(other, client))
   3198             return other->mask[dev->id];
   3199     }
   3200     return 0;
   3201 }
   3202 
   3203 void
   3204 MaybeStopDeviceHint(DeviceIntPtr dev, ClientPtr client)
   3205 {
   3206     WindowPtr pWin;
   3207     GrabPtr grab = dev->deviceGrab.grab;
   3208 
   3209     pWin = dev->valuator->motionHintWindow;
   3210 
   3211     if ((grab && SameClient(grab, client) &&
   3212          ((grab->eventMask & DevicePointerMotionHintMask) ||
   3213           (grab->ownerEvents &&
   3214            (DeviceEventMaskForClient(dev, pWin, client) &
   3215             DevicePointerMotionHintMask)))) ||
   3216         (!grab &&
   3217          (DeviceEventMaskForClient(dev, pWin, client) &
   3218           DevicePointerMotionHintMask)))
   3219         dev->valuator->motionHintWindow = NullWindow;
   3220 }
   3221 
   3222 int
   3223 DeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask,
   3224                              int maskndx)
   3225 {
   3226     struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
   3227 
   3228     if (mask & ~XIPropagateMask) {
   3229         client->errorValue = mask;
   3230         return BadValue;
   3231     }
   3232 
   3233     if (mask == 0) {
   3234         if (inputMasks)
   3235             inputMasks->dontPropagateMask[maskndx] = mask;
   3236     }
   3237     else {
   3238         if (!inputMasks) {
   3239             int ret = AddExtensionClient(pWin, client, 0, 0);
   3240 
   3241             if (ret != Success)
   3242                 return ret;
   3243             inputMasks = wOtherInputMasks(pWin);
   3244             BUG_RETURN_VAL(!inputMasks, BadAlloc);
   3245         }
   3246         inputMasks->dontPropagateMask[maskndx] = mask;
   3247     }
   3248     RecalculateDeviceDeliverableEvents(pWin);
   3249     if (inputMasks && ShouldFreeInputMasks(pWin, FALSE))
   3250         FreeResource(inputMasks->inputClients->resource, RT_NONE);
   3251     return Success;
   3252 }
   3253 
   3254 Bool
   3255 ShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents)
   3256 {
   3257     int i;
   3258     Mask allInputEventMasks = 0;
   3259     struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
   3260 
   3261     for (i = 0; i < EMASKSIZE; i++)
   3262         allInputEventMasks |= inputMasks->dontPropagateMask[i];
   3263     if (!ignoreSelectedEvents)
   3264         for (i = 0; i < EMASKSIZE; i++)
   3265             allInputEventMasks |= inputMasks->inputEvents[i];
   3266     if (allInputEventMasks == 0)
   3267         return TRUE;
   3268     else
   3269         return FALSE;
   3270 }
   3271 
   3272 /***********************************************************************
   3273  *
   3274  * Walk through the window tree, finding all clients that want to know
   3275  * about the Event.
   3276  *
   3277  */
   3278 
   3279 static void
   3280 FindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask,
   3281                        xEvent *ev, int count)
   3282 {
   3283     WindowPtr p2;
   3284 
   3285     while (p1) {
   3286         p2 = p1->firstChild;
   3287         DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab);
   3288         FindInterestedChildren(dev, p2, mask, ev, count);
   3289         p1 = p1->nextSib;
   3290     }
   3291 }
   3292 
   3293 /***********************************************************************
   3294  *
   3295  * Send an event to interested clients in all windows on all screens.
   3296  *
   3297  */
   3298 
   3299 void
   3300 SendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent *ev, int count)
   3301 {
   3302     int i;
   3303     WindowPtr pWin, p1;
   3304 
   3305     for (i = 0; i < screenInfo.numScreens; i++) {
   3306         pWin = screenInfo.screens[i]->root;
   3307         if (!pWin)
   3308             continue;
   3309         DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab);
   3310         p1 = pWin->firstChild;
   3311         FindInterestedChildren(dev, p1, mask, ev, count);
   3312     }
   3313 }
   3314 
   3315 /**
   3316  * Set the XI2 mask for the given client on the given window.
   3317  * @param dev The device to set the mask for.
   3318  * @param win The window to set the mask on.
   3319  * @param client The client setting the mask.
   3320  * @param len Number of bytes in mask.
   3321  * @param mask Event mask in the form of (1 << eventtype)
   3322  */
   3323 int
   3324 XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client,
   3325                unsigned int len, unsigned char *mask)
   3326 {
   3327     OtherInputMasks *masks;
   3328     InputClientsPtr others = NULL;
   3329 
   3330     masks = wOtherInputMasks(win);
   3331     if (masks) {
   3332         for (others = wOtherInputMasks(win)->inputClients; others;
   3333              others = others->next) {
   3334             if (SameClient(others, client)) {
   3335                 xi2mask_zero(others->xi2mask, dev->id);
   3336                 break;
   3337             }
   3338         }
   3339     }
   3340 
   3341     if (len && !others) {
   3342         if (AddExtensionClient(win, client, 0, 0) != Success)
   3343             return BadAlloc;
   3344         BUG_RETURN_VAL(!wOtherInputMasks(win), BadAlloc);
   3345         others = wOtherInputMasks(win)->inputClients;
   3346     }
   3347 
   3348     if (others) {
   3349         xi2mask_zero(others->xi2mask, dev->id);
   3350         len = min(len, xi2mask_mask_size(others->xi2mask));
   3351     }
   3352 
   3353     if (len) {
   3354         xi2mask_set_one_mask(others->xi2mask, dev->id, mask, len);
   3355     }
   3356 
   3357     RecalculateDeviceDeliverableEvents(win);
   3358 
   3359     return Success;
   3360 }
   3361