exevents.c revision 9ace9065
105b261ecSmrg/************************************************************ 205b261ecSmrg 305b261ecSmrgCopyright 1989, 1998 The Open Group 405b261ecSmrg 505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its 605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that 705b261ecSmrgthe above copyright notice appear in all copies and that both that 805b261ecSmrgcopyright notice and this permission notice appear in supporting 905b261ecSmrgdocumentation. 1005b261ecSmrg 1105b261ecSmrgThe above copyright notice and this permission notice shall be included in 1205b261ecSmrgall copies or substantial portions of the Software. 1305b261ecSmrg 1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1505b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1605b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1705b261ecSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1805b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1905b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2005b261ecSmrg 2105b261ecSmrgExcept as contained in this notice, the name of The Open Group shall not be 2205b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings 2305b261ecSmrgin this Software without prior written authorization from The Open Group. 2405b261ecSmrg 2505b261ecSmrgCopyright 1989 by Hewlett-Packard Company, Palo Alto, California. 2605b261ecSmrg 2705b261ecSmrg All Rights Reserved 2805b261ecSmrg 2905b261ecSmrgPermission to use, copy, modify, and distribute this software and its 3005b261ecSmrgdocumentation for any purpose and without fee is hereby granted, 3105b261ecSmrgprovided that the above copyright notice appear in all copies and that 3205b261ecSmrgboth that copyright notice and this permission notice appear in 3305b261ecSmrgsupporting documentation, and that the name of Hewlett-Packard not be 3405b261ecSmrgused in advertising or publicity pertaining to distribution of the 3505b261ecSmrgsoftware without specific, written prior permission. 3605b261ecSmrg 3705b261ecSmrgHEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 3805b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 3905b261ecSmrgHEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 4005b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 4105b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 4205b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 4305b261ecSmrgSOFTWARE. 4405b261ecSmrg 4505b261ecSmrg********************************************************/ 4605b261ecSmrg 4705b261ecSmrg/******************************************************************** 4805b261ecSmrg * 4905b261ecSmrg * Routines to register and initialize extension input devices. 5005b261ecSmrg * This also contains ProcessOtherEvent, the routine called from DDX 5105b261ecSmrg * to route extension events. 5205b261ecSmrg * 5305b261ecSmrg */ 5405b261ecSmrg 5505b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 5605b261ecSmrg#include <dix-config.h> 5705b261ecSmrg#endif 5805b261ecSmrg 596747b715Smrg#include "inputstr.h" 6005b261ecSmrg#include <X11/X.h> 6105b261ecSmrg#include <X11/Xproto.h> 6205b261ecSmrg#include <X11/extensions/XI.h> 6305b261ecSmrg#include <X11/extensions/XIproto.h> 646747b715Smrg#include <X11/extensions/XI2proto.h> 654642e01fSmrg#include <X11/extensions/geproto.h> 6605b261ecSmrg#include "windowstr.h" 6705b261ecSmrg#include "miscstruct.h" 6805b261ecSmrg#include "region.h" 6905b261ecSmrg#include "exevents.h" 7005b261ecSmrg#include "extnsionst.h" 7105b261ecSmrg#include "exglobals.h" 7205b261ecSmrg#include "dixevents.h" /* DeliverFocusedEvent */ 7305b261ecSmrg#include "dixgrabs.h" /* CreateGrab() */ 7405b261ecSmrg#include "scrnintstr.h" 754642e01fSmrg#include "listdev.h" /* for CopySwapXXXClass */ 764642e01fSmrg#include "xace.h" 776747b715Smrg#include "xiquerydevice.h" /* For List*Info */ 786747b715Smrg#include "eventconvert.h" 796747b715Smrg#include "eventstr.h" 8005b261ecSmrg 814642e01fSmrg#include <X11/extensions/XKBproto.h> 8205b261ecSmrg#include "xkbsrv.h" 8305b261ecSmrg 8405b261ecSmrg#define WID(w) ((w) ? ((w)->drawable.id) : 0) 8505b261ecSmrg#define AllModifiersMask ( \ 8605b261ecSmrg ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \ 8705b261ecSmrg Mod3Mask | Mod4Mask | Mod5Mask ) 8805b261ecSmrg#define AllButtonsMask ( \ 8905b261ecSmrg Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask ) 9005b261ecSmrg 914642e01fSmrgBool ShouldFreeInputMasks(WindowPtr /* pWin */ , 9205b261ecSmrg Bool /* ignoreSelectedEvents */ 9305b261ecSmrg ); 9405b261ecSmrgstatic Bool MakeInputMasks(WindowPtr /* pWin */ 9505b261ecSmrg ); 9605b261ecSmrg 976747b715Smrg/* 986747b715Smrg * Only let the given client know of core events which will affect its 996747b715Smrg * interpretation of input events, if the client's ClientPointer (or the 1006747b715Smrg * paired keyboard) is the current device. 1016747b715Smrg */ 1026747b715Smrgint 1036747b715SmrgXIShouldNotify(ClientPtr client, DeviceIntPtr dev) 1046747b715Smrg{ 1056747b715Smrg DeviceIntPtr current_ptr = PickPointer(client); 1066747b715Smrg DeviceIntPtr current_kbd = GetPairedDevice(current_ptr); 1076747b715Smrg 1086747b715Smrg if (dev == current_kbd || dev == current_ptr) 1096747b715Smrg return 1; 1104642e01fSmrg 1116747b715Smrg return 0; 1126747b715Smrg} 11305b261ecSmrg 1144642e01fSmrgBool 1156747b715SmrgIsPointerEvent(InternalEvent* event) 1164642e01fSmrg{ 1176747b715Smrg switch(event->any.type) 1184642e01fSmrg { 1196747b715Smrg case ET_ButtonPress: 1206747b715Smrg case ET_ButtonRelease: 1216747b715Smrg case ET_Motion: 1226747b715Smrg /* XXX: enter/leave ?? */ 1234642e01fSmrg return TRUE; 1244642e01fSmrg default: 1256747b715Smrg break; 1264642e01fSmrg } 1274642e01fSmrg return FALSE; 1284642e01fSmrg} 1294642e01fSmrg 1304642e01fSmrg/** 1314642e01fSmrg * @return the device matching the deviceid of the device set in the event, or 1324642e01fSmrg * NULL if the event is not an XInput event. 1334642e01fSmrg */ 1344642e01fSmrgDeviceIntPtr 1354642e01fSmrgXIGetDevice(xEvent* xE) 13605b261ecSmrg{ 1374642e01fSmrg DeviceIntPtr pDev = NULL; 1384642e01fSmrg 1394642e01fSmrg if (xE->u.u.type == DeviceButtonPress || 1404642e01fSmrg xE->u.u.type == DeviceButtonRelease || 1414642e01fSmrg xE->u.u.type == DeviceMotionNotify || 1424642e01fSmrg xE->u.u.type == ProximityIn || 1434642e01fSmrg xE->u.u.type == ProximityOut || 1444642e01fSmrg xE->u.u.type == DevicePropertyNotify) 1454642e01fSmrg { 1464642e01fSmrg int rc; 1474642e01fSmrg int id; 1484642e01fSmrg 1494642e01fSmrg id = ((deviceKeyButtonPointer*)xE)->deviceid & ~MORE_EVENTS; 1504642e01fSmrg 1514642e01fSmrg rc = dixLookupDevice(&pDev, id, serverClient, DixUnknownAccess); 1524642e01fSmrg if (rc != Success) 1534642e01fSmrg ErrorF("[dix] XIGetDevice failed on XACE restrictions (%d)\n", rc); 1544642e01fSmrg } 1554642e01fSmrg return pDev; 1564642e01fSmrg} 1574642e01fSmrg 1584642e01fSmrg 1594642e01fSmrg/** 1604642e01fSmrg * Copy the device->key into master->key and send a mapping notify to the 1614642e01fSmrg * clients if appropriate. 1624642e01fSmrg * master->key needs to be allocated by the caller. 1634642e01fSmrg * 1644642e01fSmrg * Device is the slave device. If it is attached to a master device, we may 1654642e01fSmrg * need to send a mapping notify to the client because it causes the MD 1664642e01fSmrg * to change state. 1674642e01fSmrg * 1684642e01fSmrg * Mapping notify needs to be sent in the following cases: 1694642e01fSmrg * - different slave device on same master 1704642e01fSmrg * - different master 1714642e01fSmrg * 1724642e01fSmrg * XXX: They way how the code is we also send a map notify if the slave device 1734642e01fSmrg * stays the same, but the master changes. This isn't really necessary though. 1744642e01fSmrg * 1754642e01fSmrg * XXX: this gives you funny behaviour with the ClientPointer. When a 1764642e01fSmrg * MappingNotify is sent to the client, the client usually responds with a 1774642e01fSmrg * GetKeyboardMapping. This will retrieve the ClientPointer's keyboard 1784642e01fSmrg * mapping, regardless of which keyboard sent the last mapping notify request. 1794642e01fSmrg * So depending on the CP setting, your keyboard may change layout in each 1804642e01fSmrg * app... 1814642e01fSmrg * 1824642e01fSmrg * This code is basically the old SwitchCoreKeyboard. 1834642e01fSmrg */ 1844642e01fSmrg 1854642e01fSmrgvoid 1864642e01fSmrgCopyKeyClass(DeviceIntPtr device, DeviceIntPtr master) 1874642e01fSmrg{ 1886747b715Smrg KeyClassPtr mk = master->key; 1894642e01fSmrg 1904642e01fSmrg if (device == master) 1914642e01fSmrg return; 1924642e01fSmrg 1936747b715Smrg mk->sourceid = device->id; 1944642e01fSmrg 1954642e01fSmrg 1966747b715Smrg if (!XkbCopyDeviceKeymap(master, device)) 1976747b715Smrg FatalError("Couldn't pivot keymap from device to core!\n"); 1984642e01fSmrg} 19905b261ecSmrg 2004642e01fSmrg/** 2014642e01fSmrg * Copies the feedback classes from device "from" into device "to". Classes 2024642e01fSmrg * are duplicated (not just flipping the pointers). All feedback classes are 2034642e01fSmrg * linked lists, the full list is duplicated. 2044642e01fSmrg */ 2054642e01fSmrgstatic void 2064642e01fSmrgDeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) 2074642e01fSmrg{ 2084642e01fSmrg ClassesPtr classes; 2094642e01fSmrg 2104642e01fSmrg 2114642e01fSmrg if (from->intfeed) 2124642e01fSmrg { 2134642e01fSmrg IntegerFeedbackPtr *i, it; 2144642e01fSmrg 2154642e01fSmrg if (!to->intfeed) 2164642e01fSmrg { 2176747b715Smrg classes = to->unused_classes; 2184642e01fSmrg to->intfeed = classes->intfeed; 2196747b715Smrg classes->intfeed = NULL; 2204642e01fSmrg } 2214642e01fSmrg 2224642e01fSmrg i = &to->intfeed; 2234642e01fSmrg for (it = from->intfeed; it; it = it->next) 2244642e01fSmrg { 2254642e01fSmrg if (!(*i)) 2264642e01fSmrg { 2276747b715Smrg *i = calloc(1, sizeof(IntegerFeedbackClassRec)); 2284642e01fSmrg if (!(*i)) 2294642e01fSmrg { 2304642e01fSmrg ErrorF("[Xi] Cannot alloc memory for class copy."); 2314642e01fSmrg return; 2324642e01fSmrg } 2334642e01fSmrg } 2344642e01fSmrg (*i)->CtrlProc = it->CtrlProc; 2354642e01fSmrg (*i)->ctrl = it->ctrl; 2364642e01fSmrg 2374642e01fSmrg i = &(*i)->next; 2384642e01fSmrg } 2394642e01fSmrg } else if (to->intfeed && !from->intfeed) 2404642e01fSmrg { 2414642e01fSmrg ClassesPtr classes; 2426747b715Smrg classes = to->unused_classes; 2434642e01fSmrg classes->intfeed = to->intfeed; 2444642e01fSmrg to->intfeed = NULL; 2454642e01fSmrg } 2464642e01fSmrg 2474642e01fSmrg if (from->stringfeed) 2484642e01fSmrg { 2494642e01fSmrg StringFeedbackPtr *s, it; 2504642e01fSmrg 2514642e01fSmrg if (!to->stringfeed) 2524642e01fSmrg { 2536747b715Smrg classes = to->unused_classes; 2544642e01fSmrg to->stringfeed = classes->stringfeed; 2556747b715Smrg classes->stringfeed = NULL; 2564642e01fSmrg } 2574642e01fSmrg 2584642e01fSmrg s = &to->stringfeed; 2594642e01fSmrg for (it = from->stringfeed; it; it = it->next) 2604642e01fSmrg { 2614642e01fSmrg if (!(*s)) 2624642e01fSmrg { 2636747b715Smrg *s = calloc(1, sizeof(StringFeedbackClassRec)); 2644642e01fSmrg if (!(*s)) 2654642e01fSmrg { 2664642e01fSmrg ErrorF("[Xi] Cannot alloc memory for class copy."); 2674642e01fSmrg return; 2684642e01fSmrg } 2694642e01fSmrg } 2704642e01fSmrg (*s)->CtrlProc = it->CtrlProc; 2714642e01fSmrg (*s)->ctrl = it->ctrl; 2724642e01fSmrg 2734642e01fSmrg s = &(*s)->next; 2744642e01fSmrg } 2754642e01fSmrg } else if (to->stringfeed && !from->stringfeed) 2764642e01fSmrg { 2774642e01fSmrg ClassesPtr classes; 2786747b715Smrg classes = to->unused_classes; 2794642e01fSmrg classes->stringfeed = to->stringfeed; 2804642e01fSmrg to->stringfeed = NULL; 2814642e01fSmrg } 2824642e01fSmrg 2834642e01fSmrg if (from->bell) 2844642e01fSmrg { 2854642e01fSmrg BellFeedbackPtr *b, it; 2864642e01fSmrg 2874642e01fSmrg if (!to->bell) 2884642e01fSmrg { 2896747b715Smrg classes = to->unused_classes; 2904642e01fSmrg to->bell = classes->bell; 2916747b715Smrg classes->bell = NULL; 2924642e01fSmrg } 2934642e01fSmrg 2944642e01fSmrg b = &to->bell; 2954642e01fSmrg for (it = from->bell; it; it = it->next) 2964642e01fSmrg { 2974642e01fSmrg if (!(*b)) 2984642e01fSmrg { 2996747b715Smrg *b = calloc(1, sizeof(BellFeedbackClassRec)); 3004642e01fSmrg if (!(*b)) 3014642e01fSmrg { 3024642e01fSmrg ErrorF("[Xi] Cannot alloc memory for class copy."); 3034642e01fSmrg return; 3044642e01fSmrg } 3054642e01fSmrg } 3064642e01fSmrg (*b)->BellProc = it->BellProc; 3074642e01fSmrg (*b)->CtrlProc = it->CtrlProc; 3084642e01fSmrg (*b)->ctrl = it->ctrl; 3094642e01fSmrg 3104642e01fSmrg b = &(*b)->next; 3114642e01fSmrg } 3124642e01fSmrg } else if (to->bell && !from->bell) 3134642e01fSmrg { 3144642e01fSmrg ClassesPtr classes; 3156747b715Smrg classes = to->unused_classes; 3164642e01fSmrg classes->bell = to->bell; 3174642e01fSmrg to->bell = NULL; 3184642e01fSmrg } 3194642e01fSmrg 3204642e01fSmrg if (from->leds) 3214642e01fSmrg { 3224642e01fSmrg LedFeedbackPtr *l, it; 3234642e01fSmrg 3244642e01fSmrg if (!to->leds) 3254642e01fSmrg { 3266747b715Smrg classes = to->unused_classes; 3274642e01fSmrg to->leds = classes->leds; 3286747b715Smrg classes->leds = NULL; 3294642e01fSmrg } 3304642e01fSmrg 3314642e01fSmrg l = &to->leds; 3324642e01fSmrg for (it = from->leds; it; it = it->next) 3334642e01fSmrg { 3344642e01fSmrg if (!(*l)) 3354642e01fSmrg { 3366747b715Smrg *l = calloc(1, sizeof(LedFeedbackClassRec)); 3374642e01fSmrg if (!(*l)) 3384642e01fSmrg { 3394642e01fSmrg ErrorF("[Xi] Cannot alloc memory for class copy."); 3404642e01fSmrg return; 3414642e01fSmrg } 3424642e01fSmrg } 3434642e01fSmrg (*l)->CtrlProc = it->CtrlProc; 3444642e01fSmrg (*l)->ctrl = it->ctrl; 3454642e01fSmrg if ((*l)->xkb_sli) 3464642e01fSmrg XkbFreeSrvLedInfo((*l)->xkb_sli); 3474642e01fSmrg (*l)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, NULL, *l); 3484642e01fSmrg 3494642e01fSmrg l = &(*l)->next; 3504642e01fSmrg } 3514642e01fSmrg } else if (to->leds && !from->leds) 3524642e01fSmrg { 3534642e01fSmrg ClassesPtr classes; 3546747b715Smrg classes = to->unused_classes; 3554642e01fSmrg classes->leds = to->leds; 3564642e01fSmrg to->leds = NULL; 3574642e01fSmrg } 3584642e01fSmrg} 3594642e01fSmrg 3606747b715Smrgstatic void 3616747b715SmrgDeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to) 3624642e01fSmrg{ 3634642e01fSmrg ClassesPtr classes; 3644642e01fSmrg 3654642e01fSmrg /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the 3664642e01fSmrg * kbdfeed to be set up properly, so let's do the feedback classes first. 3674642e01fSmrg */ 3686747b715Smrg if (from->kbdfeed) 3696747b715Smrg { 3706747b715Smrg KbdFeedbackPtr *k, it; 3716747b715Smrg 3726747b715Smrg if (!to->kbdfeed) 3736747b715Smrg { 3746747b715Smrg classes = to->unused_classes; 3756747b715Smrg 3766747b715Smrg to->kbdfeed = classes->kbdfeed; 3776747b715Smrg if (!to->kbdfeed) 3786747b715Smrg InitKeyboardDeviceStruct(to, NULL, NULL, NULL); 3796747b715Smrg classes->kbdfeed = NULL; 3806747b715Smrg } 3816747b715Smrg 3826747b715Smrg k = &to->kbdfeed; 3836747b715Smrg for(it = from->kbdfeed; it; it = it->next) 3846747b715Smrg { 3856747b715Smrg if (!(*k)) 3866747b715Smrg { 3876747b715Smrg *k = calloc(1, sizeof(KbdFeedbackClassRec)); 3886747b715Smrg if (!*k) 3896747b715Smrg { 3906747b715Smrg ErrorF("[Xi] Cannot alloc memory for class copy."); 3916747b715Smrg return; 3926747b715Smrg } 3936747b715Smrg } 3946747b715Smrg (*k)->BellProc = it->BellProc; 3956747b715Smrg (*k)->CtrlProc = it->CtrlProc; 3966747b715Smrg (*k)->ctrl = it->ctrl; 3976747b715Smrg if ((*k)->xkb_sli) 3986747b715Smrg XkbFreeSrvLedInfo((*k)->xkb_sli); 3996747b715Smrg (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL); 4006747b715Smrg 4016747b715Smrg k = &(*k)->next; 4026747b715Smrg } 4036747b715Smrg } else if (to->kbdfeed && !from->kbdfeed) 4046747b715Smrg { 4056747b715Smrg ClassesPtr classes; 4066747b715Smrg classes = to->unused_classes; 4076747b715Smrg classes->kbdfeed = to->kbdfeed; 4086747b715Smrg to->kbdfeed = NULL; 4096747b715Smrg } 4104642e01fSmrg 4114642e01fSmrg if (from->key) 4124642e01fSmrg { 4134642e01fSmrg if (!to->key) 4144642e01fSmrg { 4156747b715Smrg classes = to->unused_classes; 4164642e01fSmrg to->key = classes->key; 4174642e01fSmrg if (!to->key) 4186747b715Smrg InitKeyboardDeviceStruct(to, NULL, NULL, NULL); 4196747b715Smrg else 4206747b715Smrg classes->key = NULL; 4216747b715Smrg } 4226747b715Smrg 4236747b715Smrg CopyKeyClass(from, to); 4246747b715Smrg } else if (to->key && !from->key) 4256747b715Smrg { 4266747b715Smrg ClassesPtr classes; 4276747b715Smrg classes = to->unused_classes; 4286747b715Smrg classes->key = to->key; 4296747b715Smrg to->key = NULL; 4306747b715Smrg } 4316747b715Smrg 4326747b715Smrg /* If a SrvLedInfoPtr's flags are XkbSLI_IsDefault, the names and maps 4336747b715Smrg * pointer point into the xkbInfo->desc struct. XkbCopySrvLedInfo 4346747b715Smrg * didn't update the pointers so we need to do it manually here. 4356747b715Smrg */ 4366747b715Smrg if (to->kbdfeed) 4376747b715Smrg { 4386747b715Smrg KbdFeedbackPtr k; 4396747b715Smrg 4406747b715Smrg for (k = to->kbdfeed; k; k = k->next) 4416747b715Smrg { 4426747b715Smrg if (!k->xkb_sli) 4436747b715Smrg continue; 4446747b715Smrg if (k->xkb_sli->flags & XkbSLI_IsDefault) 4454642e01fSmrg { 4466747b715Smrg k->xkb_sli->names = to->key->xkbInfo->desc->names->indicators; 4476747b715Smrg k->xkb_sli->maps = to->key->xkbInfo->desc->indicators->maps; 4486747b715Smrg } 4496747b715Smrg } 4506747b715Smrg } 4516747b715Smrg 4526747b715Smrg /* We can't just copy over the focus class. When an app sets the focus, 4536747b715Smrg * it'll do so on the master device. Copying the SDs focus means losing 4546747b715Smrg * the focus. 4556747b715Smrg * So we only copy the focus class if the device didn't have one, 4566747b715Smrg * otherwise we leave it as it is. 4576747b715Smrg */ 4586747b715Smrg if (from->focus) 4596747b715Smrg { 4606747b715Smrg if (!to->focus) 4616747b715Smrg { 4626747b715Smrg WindowPtr *oldTrace; 4636747b715Smrg 4646747b715Smrg classes = to->unused_classes; 4656747b715Smrg to->focus = classes->focus; 4666747b715Smrg if (!to->focus) 4676747b715Smrg { 4686747b715Smrg to->focus = calloc(1, sizeof(FocusClassRec)); 4696747b715Smrg if (!to->focus) 4704642e01fSmrg FatalError("[Xi] no memory for class shift.\n"); 4714642e01fSmrg } else 4726747b715Smrg classes->focus = NULL; 4736747b715Smrg 4746747b715Smrg oldTrace = to->focus->trace; 4756747b715Smrg memcpy(to->focus, from->focus, sizeof(FocusClassRec)); 4766747b715Smrg to->focus->trace = realloc(oldTrace, 4776747b715Smrg to->focus->traceSize * sizeof(WindowPtr)); 4786747b715Smrg if (!to->focus->trace && to->focus->traceSize) 4796747b715Smrg FatalError("[Xi] no memory for trace.\n"); 4806747b715Smrg memcpy(to->focus->trace, from->focus->trace, 4816747b715Smrg from->focus->traceSize * sizeof(WindowPtr)); 4826747b715Smrg to->focus->sourceid = from->id; 4834642e01fSmrg } 4846747b715Smrg } else if (to->focus) 4856747b715Smrg { 4866747b715Smrg ClassesPtr classes; 4876747b715Smrg classes = to->unused_classes; 4886747b715Smrg classes->focus = to->focus; 4896747b715Smrg to->focus = NULL; 4906747b715Smrg } 4914642e01fSmrg 4926747b715Smrg} 4934642e01fSmrg 4946747b715Smrgstatic void 4956747b715SmrgDeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to) 4966747b715Smrg{ 4976747b715Smrg ClassesPtr classes; 4986747b715Smrg 4996747b715Smrg /* Feedback classes must be copied first */ 5006747b715Smrg if (from->ptrfeed) 5016747b715Smrg { 5026747b715Smrg PtrFeedbackPtr *p, it; 5036747b715Smrg if (!to->ptrfeed) 5044642e01fSmrg { 5056747b715Smrg classes = to->unused_classes; 5066747b715Smrg to->ptrfeed = classes->ptrfeed; 5076747b715Smrg classes->ptrfeed = NULL; 5084642e01fSmrg } 5094642e01fSmrg 5106747b715Smrg p = &to->ptrfeed; 5116747b715Smrg for (it = from->ptrfeed; it; it = it->next) 5126747b715Smrg { 5136747b715Smrg if (!(*p)) 5146747b715Smrg { 5156747b715Smrg *p = calloc(1, sizeof(PtrFeedbackClassRec)); 5166747b715Smrg if (!*p) 5176747b715Smrg { 5186747b715Smrg ErrorF("[Xi] Cannot alloc memory for class copy."); 5196747b715Smrg return; 5206747b715Smrg } 5216747b715Smrg } 5226747b715Smrg (*p)->CtrlProc = it->CtrlProc; 5236747b715Smrg (*p)->ctrl = it->ctrl; 5244642e01fSmrg 5256747b715Smrg p = &(*p)->next; 5266747b715Smrg } 5276747b715Smrg } else if (to->ptrfeed && !from->ptrfeed) 5284642e01fSmrg { 5294642e01fSmrg ClassesPtr classes; 5306747b715Smrg classes = to->unused_classes; 5316747b715Smrg classes->ptrfeed = to->ptrfeed; 5326747b715Smrg to->ptrfeed = NULL; 5334642e01fSmrg } 5344642e01fSmrg 5354642e01fSmrg if (from->valuator) 5364642e01fSmrg { 5374642e01fSmrg ValuatorClassPtr v; 5389ace9065Smrg 5394642e01fSmrg if (!to->valuator) 5404642e01fSmrg { 5416747b715Smrg classes = to->unused_classes; 5424642e01fSmrg to->valuator = classes->valuator; 5434642e01fSmrg if (to->valuator) 5444642e01fSmrg classes->valuator = NULL; 5454642e01fSmrg } 5464642e01fSmrg 5479ace9065Smrg v = AllocValuatorClass(to->valuator, from->valuator->numAxes); 5489ace9065Smrg 5494642e01fSmrg if (!v) 5504642e01fSmrg FatalError("[Xi] no memory for class shift.\n"); 5514642e01fSmrg 5529ace9065Smrg to->valuator = v; 5534642e01fSmrg memcpy(v->axes, from->valuator->axes, v->numAxes * sizeof(AxisInfo)); 5544642e01fSmrg 5556747b715Smrg v->sourceid = from->id; 5564642e01fSmrg } else if (to->valuator && !from->valuator) 5574642e01fSmrg { 5584642e01fSmrg ClassesPtr classes; 5596747b715Smrg classes = to->unused_classes; 5604642e01fSmrg classes->valuator = to->valuator; 5614642e01fSmrg to->valuator = NULL; 5624642e01fSmrg } 5634642e01fSmrg 5644642e01fSmrg if (from->button) 5654642e01fSmrg { 5664642e01fSmrg if (!to->button) 5674642e01fSmrg { 5686747b715Smrg classes = to->unused_classes; 5694642e01fSmrg to->button = classes->button; 5704642e01fSmrg if (!to->button) 5714642e01fSmrg { 5726747b715Smrg to->button = calloc(1, sizeof(ButtonClassRec)); 5734642e01fSmrg if (!to->button) 5744642e01fSmrg FatalError("[Xi] no memory for class shift.\n"); 5754642e01fSmrg } else 5764642e01fSmrg classes->button = NULL; 5774642e01fSmrg } 5784642e01fSmrg 5794642e01fSmrg if (from->button->xkb_acts) 5804642e01fSmrg { 5814642e01fSmrg if (!to->button->xkb_acts) 5824642e01fSmrg { 5836747b715Smrg to->button->xkb_acts = calloc(1, sizeof(XkbAction)); 5844642e01fSmrg if (!to->button->xkb_acts) 5854642e01fSmrg FatalError("[Xi] not enough memory for xkb_acts.\n"); 5864642e01fSmrg } 5874642e01fSmrg memcpy(to->button->xkb_acts, from->button->xkb_acts, 5884642e01fSmrg sizeof(XkbAction)); 5894642e01fSmrg } else 5906747b715Smrg free(to->button->xkb_acts); 5916747b715Smrg 5926747b715Smrg memcpy(to->button->labels, from->button->labels, 5936747b715Smrg from->button->numButtons * sizeof(Atom)); 5946747b715Smrg to->button->sourceid = from->id; 5954642e01fSmrg } else if (to->button && !from->button) 5964642e01fSmrg { 5974642e01fSmrg ClassesPtr classes; 5986747b715Smrg classes = to->unused_classes; 5994642e01fSmrg classes->button = to->button; 6004642e01fSmrg to->button = NULL; 6014642e01fSmrg } 6024642e01fSmrg 6034642e01fSmrg if (from->proximity) 6044642e01fSmrg { 6054642e01fSmrg if (!to->proximity) 6064642e01fSmrg { 6076747b715Smrg classes = to->unused_classes; 6084642e01fSmrg to->proximity = classes->proximity; 6094642e01fSmrg if (!to->proximity) 6104642e01fSmrg { 6116747b715Smrg to->proximity = calloc(1, sizeof(ProximityClassRec)); 6124642e01fSmrg if (!to->proximity) 6134642e01fSmrg FatalError("[Xi] no memory for class shift.\n"); 6144642e01fSmrg } else 6154642e01fSmrg classes->proximity = NULL; 6164642e01fSmrg } 6174642e01fSmrg memcpy(to->proximity, from->proximity, sizeof(ProximityClassRec)); 6186747b715Smrg to->proximity->sourceid = from->id; 6194642e01fSmrg } else if (to->proximity) 6204642e01fSmrg { 6214642e01fSmrg ClassesPtr classes; 6226747b715Smrg classes = to->unused_classes; 6234642e01fSmrg classes->proximity = to->proximity; 6244642e01fSmrg to->proximity = NULL; 6254642e01fSmrg } 6264642e01fSmrg 6274642e01fSmrg if (from->absolute) 6284642e01fSmrg { 6294642e01fSmrg if (!to->absolute) 6304642e01fSmrg { 6316747b715Smrg classes = to->unused_classes; 6324642e01fSmrg to->absolute = classes->absolute; 6334642e01fSmrg if (!to->absolute) 6344642e01fSmrg { 6356747b715Smrg to->absolute = calloc(1, sizeof(AbsoluteClassRec)); 6364642e01fSmrg if (!to->absolute) 6374642e01fSmrg FatalError("[Xi] no memory for class shift.\n"); 6384642e01fSmrg } else 6394642e01fSmrg classes->absolute = NULL; 6404642e01fSmrg } 6414642e01fSmrg memcpy(to->absolute, from->absolute, sizeof(AbsoluteClassRec)); 6426747b715Smrg to->absolute->sourceid = from->id; 6434642e01fSmrg } else if (to->absolute) 6444642e01fSmrg { 6456747b715Smrg ClassesPtr classes; 6466747b715Smrg classes = to->unused_classes; 6476747b715Smrg classes->absolute = to->absolute; 6486747b715Smrg to->absolute = NULL; 6496747b715Smrg } 6506747b715Smrg} 6516747b715Smrg 6526747b715Smrg/** 6536747b715Smrg * Copies the CONTENT of the classes of device from into the classes in device 6546747b715Smrg * to. From and to are identical after finishing. 6556747b715Smrg * 6566747b715Smrg * If to does not have classes from currenly has, the classes are stored in 6576747b715Smrg * to's devPrivates system. Later, we recover it again from there if needed. 6586747b715Smrg * Saves a few memory allocations. 6596747b715Smrg */ 6606747b715Smrgvoid 6616747b715SmrgDeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to, DeviceChangedEvent *dce) 6626747b715Smrg{ 6636747b715Smrg /* generic feedback classes, not tied to pointer and/or keyboard */ 6646747b715Smrg DeepCopyFeedbackClasses(from, to); 6656747b715Smrg 6666747b715Smrg if ((dce->flags & DEVCHANGE_KEYBOARD_EVENT)) 6676747b715Smrg DeepCopyKeyboardClasses(from, to); 6686747b715Smrg if ((dce->flags & DEVCHANGE_POINTER_EVENT)) 6696747b715Smrg DeepCopyPointerClasses(from, to); 6706747b715Smrg} 6716747b715Smrg 6726747b715Smrg 6736747b715Smrg/** 6746747b715Smrg * Send an XI2 DeviceChangedEvent to all interested clients. 6756747b715Smrg */ 6766747b715Smrgvoid 6776747b715SmrgXISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChangedEvent *dce) 6786747b715Smrg{ 6796747b715Smrg xXIDeviceChangedEvent *dcce; 6806747b715Smrg int rc; 6816747b715Smrg 6826747b715Smrg rc = EventToXI2((InternalEvent*)dce, (xEvent**)&dcce); 6836747b715Smrg if (rc != Success) 6846747b715Smrg { 6856747b715Smrg ErrorF("[Xi] event conversion from DCE failed with code %d\n", rc); 6866747b715Smrg return; 6874642e01fSmrg } 6886747b715Smrg 6896747b715Smrg /* we don't actually swap if there's a NullClient, swapping is done 6906747b715Smrg * later when event is delivered. */ 6916747b715Smrg SendEventToAllWindows(master, XI_DeviceChangedMask, (xEvent*)dcce, 1); 6926747b715Smrg free(dcce); 6934642e01fSmrg} 6944642e01fSmrg 6956747b715Smrgstatic void 6966747b715SmrgChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce) 6976747b715Smrg{ 6986747b715Smrg DeviceIntPtr slave; 6996747b715Smrg int rc; 7006747b715Smrg 7016747b715Smrg /* For now, we don't have devices that change physically. */ 7026747b715Smrg if (!IsMaster(device)) 7036747b715Smrg return; 7046747b715Smrg 7056747b715Smrg rc = dixLookupDevice(&slave, dce->sourceid, serverClient, DixReadAccess); 7066747b715Smrg 7076747b715Smrg if (rc != Success) 7086747b715Smrg return; /* Device has disappeared */ 7096747b715Smrg 7106747b715Smrg if (!slave->u.master) 7116747b715Smrg return; /* set floating since the event */ 7126747b715Smrg 7136747b715Smrg if (slave->u.master->id != dce->masterid) 7146747b715Smrg return; /* not our slave anymore, don't care */ 7156747b715Smrg 7166747b715Smrg /* FIXME: we probably need to send a DCE for the new slave now */ 7176747b715Smrg 7186747b715Smrg device->public.devicePrivate = slave->public.devicePrivate; 7196747b715Smrg 7206747b715Smrg /* FIXME: the classes may have changed since we generated the event. */ 7216747b715Smrg DeepCopyDeviceClasses(slave, device, dce); 7226747b715Smrg XISendDeviceChangedEvent(slave, device, dce); 7236747b715Smrg} 7244642e01fSmrg 7254642e01fSmrg/** 7264642e01fSmrg * Update the device state according to the data in the event. 7274642e01fSmrg * 7284642e01fSmrg * return values are 7294642e01fSmrg * DEFAULT ... process as normal 7304642e01fSmrg * DONT_PROCESS ... return immediately from caller 7314642e01fSmrg */ 7324642e01fSmrg#define DEFAULT 0 7334642e01fSmrg#define DONT_PROCESS 1 7344642e01fSmrgint 7356747b715SmrgUpdateDeviceState(DeviceIntPtr device, DeviceEvent* event) 7364642e01fSmrg{ 7374642e01fSmrg int i; 7384642e01fSmrg int key = 0, 7396747b715Smrg bit = 0, 7406747b715Smrg last_valuator; 7414642e01fSmrg 7424642e01fSmrg KeyClassPtr k = NULL; 7434642e01fSmrg ButtonClassPtr b = NULL; 7444642e01fSmrg ValuatorClassPtr v = NULL; 7454642e01fSmrg 7466747b715Smrg /* This event is always the first we get, before the actual events with 7476747b715Smrg * the data. However, the way how the DDX is set up, "device" will 7486747b715Smrg * actually be the slave device that caused the event. 7496747b715Smrg */ 7506747b715Smrg switch(event->type) 7516747b715Smrg { 7526747b715Smrg case ET_DeviceChanged: 7536747b715Smrg ChangeMasterDeviceClasses(device, (DeviceChangedEvent*)event); 7546747b715Smrg return DONT_PROCESS; /* event has been sent already */ 7556747b715Smrg case ET_Motion: 7566747b715Smrg case ET_ButtonPress: 7576747b715Smrg case ET_ButtonRelease: 7586747b715Smrg case ET_KeyPress: 7596747b715Smrg case ET_KeyRelease: 7606747b715Smrg case ET_ProximityIn: 7616747b715Smrg case ET_ProximityOut: 7626747b715Smrg break; 7636747b715Smrg default: 7646747b715Smrg /* other events don't update the device */ 7656747b715Smrg return DEFAULT; 7666747b715Smrg } 7674642e01fSmrg 7684642e01fSmrg k = device->key; 7694642e01fSmrg v = device->valuator; 7704642e01fSmrg b = device->button; 7714642e01fSmrg 7726747b715Smrg key = event->detail.key; 7736747b715Smrg bit = 1 << (key & 7); 7744642e01fSmrg 7756747b715Smrg /* Update device axis */ 7766747b715Smrg /* Check valuators first */ 7776747b715Smrg last_valuator = -1; 7786747b715Smrg for (i = 0; i < MAX_VALUATORS; i++) 7794642e01fSmrg { 7806747b715Smrg if (BitIsOn(&event->valuators.mask, i)) 7816747b715Smrg { 7826747b715Smrg if (!v) 7836747b715Smrg { 7846747b715Smrg ErrorF("[Xi] Valuators reported for non-valuator device '%s'. " 7856747b715Smrg "Ignoring event.\n", device->name); 7866747b715Smrg return DONT_PROCESS; 7876747b715Smrg } else if (v->numAxes < i) 7886747b715Smrg { 7896747b715Smrg ErrorF("[Xi] Too many valuators reported for device '%s'. " 7906747b715Smrg "Ignoring event.\n", device->name); 7916747b715Smrg return DONT_PROCESS; 7926747b715Smrg } 7936747b715Smrg last_valuator = i; 7946747b715Smrg } 7954642e01fSmrg } 7964642e01fSmrg 7976747b715Smrg for (i = 0; i <= last_valuator && i < v->numAxes; i++) 7986747b715Smrg { 7996747b715Smrg if (BitIsOn(&event->valuators.mask, i)) 8006747b715Smrg { 8016747b715Smrg /* XXX: Relative/Absolute mode */ 8026747b715Smrg v->axisVal[i] = event->valuators.data[i]; 8036747b715Smrg v->axisVal[i] += (event->valuators.data_frac[i] * 1.0f / (1 << 16) / (1 << 16)); 8046747b715Smrg } 8054642e01fSmrg } 80605b261ecSmrg 8076747b715Smrg if (event->type == ET_KeyPress) { 80805b261ecSmrg if (!k) 8094642e01fSmrg return DONT_PROCESS; 81005b261ecSmrg 8116747b715Smrg /* don't allow ddx to generate multiple downs, but repeats are okay */ 8126747b715Smrg if (key_is_down(device, key, KEY_PROCESSED) && !event->key_repeat) 8136747b715Smrg return DONT_PROCESS; 8146747b715Smrg 8154642e01fSmrg if (device->valuator) 8164642e01fSmrg device->valuator->motionHintWindow = NullWindow; 8176747b715Smrg set_key_down(device, key, KEY_PROCESSED); 8186747b715Smrg } else if (event->type == ET_KeyRelease) { 81905b261ecSmrg if (!k) 8204642e01fSmrg return DONT_PROCESS; 82105b261ecSmrg 8226747b715Smrg if (!key_is_down(device, key, KEY_PROCESSED)) /* guard against duplicates */ 8234642e01fSmrg return DONT_PROCESS; 8244642e01fSmrg if (device->valuator) 8254642e01fSmrg device->valuator->motionHintWindow = NullWindow; 8266747b715Smrg set_key_up(device, key, KEY_PROCESSED); 8276747b715Smrg } else if (event->type == ET_ButtonPress) { 8286747b715Smrg Mask mask; 82905b261ecSmrg if (!b) 8304642e01fSmrg return DONT_PROCESS; 8314642e01fSmrg 8326747b715Smrg if (button_is_down(device, key, BUTTON_PROCESSED)) 8334642e01fSmrg return DONT_PROCESS; 8346747b715Smrg 8356747b715Smrg set_button_down(device, key, BUTTON_PROCESSED); 8364642e01fSmrg if (device->valuator) 8374642e01fSmrg device->valuator->motionHintWindow = NullWindow; 8384642e01fSmrg if (!b->map[key]) 8394642e01fSmrg return DONT_PROCESS; 8404642e01fSmrg b->buttonsDown++; 84105b261ecSmrg b->motionMask = DeviceButtonMotionMask; 8424642e01fSmrg if (b->map[key] <= 5) 8434642e01fSmrg b->state |= (Button1Mask >> 1) << b->map[key]; 8446747b715Smrg 8456747b715Smrg /* Add state and motionMask to the filter for this event */ 8466747b715Smrg mask = DevicePointerMotionMask | b->state | b->motionMask; 8476747b715Smrg SetMaskForEvent(device->id, mask, DeviceMotionNotify); 8486747b715Smrg mask = PointerMotionMask | b->state | b->motionMask; 8496747b715Smrg SetMaskForEvent(device->id, mask, MotionNotify); 8506747b715Smrg } else if (event->type == ET_ButtonRelease) { 8516747b715Smrg Mask mask; 85205b261ecSmrg if (!b) 8534642e01fSmrg return DONT_PROCESS; 8544642e01fSmrg 8556747b715Smrg if (!button_is_down(device, key, BUTTON_PROCESSED)) 8564642e01fSmrg return DONT_PROCESS; 8576747b715Smrg if (IsMaster(device)) { 8584642e01fSmrg DeviceIntPtr sd; 8594642e01fSmrg 8604642e01fSmrg /* 8614642e01fSmrg * Leave the button down if any slave has the 8624642e01fSmrg * button still down. Note that this depends on the 8634642e01fSmrg * event being delivered through the slave first 8644642e01fSmrg */ 8654642e01fSmrg for (sd = inputInfo.devices; sd; sd = sd->next) { 8666747b715Smrg if (IsMaster(sd) || sd->u.master != device) 8674642e01fSmrg continue; 8686747b715Smrg if (!sd->button) 8696747b715Smrg continue; 8708223e2f2Smrg for (i = 1; i <= sd->button->numButtons; i++) 8718223e2f2Smrg if (sd->button->map[i] == key && 8728223e2f2Smrg button_is_down(sd, i, BUTTON_PROCESSED)) 8738223e2f2Smrg return DONT_PROCESS; 8744642e01fSmrg } 8754642e01fSmrg } 8766747b715Smrg set_button_up(device, key, BUTTON_PROCESSED); 8774642e01fSmrg if (device->valuator) 8784642e01fSmrg device->valuator->motionHintWindow = NullWindow; 8794642e01fSmrg if (!b->map[key]) 8804642e01fSmrg return DONT_PROCESS; 88105b261ecSmrg if (b->buttonsDown >= 1 && !--b->buttonsDown) 88205b261ecSmrg b->motionMask = 0; 8834642e01fSmrg if (b->map[key] <= 5) 8844642e01fSmrg b->state &= ~((Button1Mask >> 1) << b->map[key]); 8856747b715Smrg 8866747b715Smrg /* Add state and motionMask to the filter for this event */ 8876747b715Smrg mask = DevicePointerMotionMask | b->state | b->motionMask; 8886747b715Smrg SetMaskForEvent(device->id, mask, DeviceMotionNotify); 8896747b715Smrg mask = PointerMotionMask | b->state | b->motionMask; 8906747b715Smrg SetMaskForEvent(device->id, mask, MotionNotify); 8916747b715Smrg } else if (event->type == ET_ProximityIn) 8929ace9065Smrg device->proximity->in_proximity = TRUE; 8936747b715Smrg else if (event->type == ET_ProximityOut) 8949ace9065Smrg device->proximity->in_proximity = FALSE; 8954642e01fSmrg 8964642e01fSmrg return DEFAULT; 8974642e01fSmrg} 8984642e01fSmrg 8996747b715Smrgstatic void 9006747b715SmrgProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device) 9016747b715Smrg{ 9026747b715Smrg GrabPtr grab = device->deviceGrab.grab; 9036747b715Smrg 9046747b715Smrg if (grab) 9056747b715Smrg DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE); 9066747b715Smrg else { /* deliver to all root windows */ 9076747b715Smrg xEvent *xi; 9086747b715Smrg int i; 9096747b715Smrg 9106747b715Smrg i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi); 9116747b715Smrg if (i != Success) 9126747b715Smrg { 9136747b715Smrg ErrorF("[Xi] %s: XI2 conversion failed in ProcessRawEvent (%d)\n", 9146747b715Smrg device->name, i); 9156747b715Smrg return; 9166747b715Smrg } 9176747b715Smrg 9186747b715Smrg for (i = 0; i < screenInfo.numScreens; i++) 9196747b715Smrg DeliverEventsToWindow(device, screenInfo.screens[i]->root, xi, 1, 9206747b715Smrg GetEventFilter(device, xi), NULL); 9216747b715Smrg free(xi); 9226747b715Smrg } 9236747b715Smrg} 9246747b715Smrg 9254642e01fSmrg/** 9264642e01fSmrg * Main device event processing function. 9274642e01fSmrg * Called from when processing the events from the event queue. 9284642e01fSmrg * 9294642e01fSmrg */ 9304642e01fSmrgvoid 9316747b715SmrgProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device) 9324642e01fSmrg{ 9336747b715Smrg GrabPtr grab; 9344642e01fSmrg Bool deactivateDeviceGrab = FALSE; 9354642e01fSmrg int key = 0, rootX, rootY; 9364642e01fSmrg ButtonClassPtr b; 9374642e01fSmrg KeyClassPtr k; 9384642e01fSmrg ValuatorClassPtr v; 9394642e01fSmrg int ret = 0; 9406747b715Smrg int state, i; 9414642e01fSmrg DeviceIntPtr mouse = NULL, kbd = NULL; 9426747b715Smrg DeviceEvent *event = &ev->device_event; 9436747b715Smrg 9446747b715Smrg CHECKEVENT(ev); 9456747b715Smrg 9466747b715Smrg if (ev->any.type == ET_RawKeyPress || 9476747b715Smrg ev->any.type == ET_RawKeyRelease || 9486747b715Smrg ev->any.type == ET_RawButtonPress || 9496747b715Smrg ev->any.type == ET_RawButtonRelease || 9506747b715Smrg ev->any.type == ET_RawMotion) 9516747b715Smrg { 9526747b715Smrg ProcessRawEvent(&ev->raw_event, device); 9536747b715Smrg return; 9546747b715Smrg } 9554642e01fSmrg 9564642e01fSmrg if (IsPointerDevice(device)) 9574642e01fSmrg { 9584642e01fSmrg kbd = GetPairedDevice(device); 9594642e01fSmrg mouse = device; 9604642e01fSmrg if (!kbd->key) /* can happen with floating SDs */ 9614642e01fSmrg kbd = NULL; 9624642e01fSmrg } else 9634642e01fSmrg { 9644642e01fSmrg mouse = GetPairedDevice(device); 9654642e01fSmrg kbd = device; 9664642e01fSmrg if (!mouse->valuator || !mouse->button) /* may be float. SDs */ 9674642e01fSmrg mouse = NULL; 9684642e01fSmrg } 9694642e01fSmrg 9704642e01fSmrg /* State needs to be assembled BEFORE the device is updated. */ 9716747b715Smrg state = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0; 9726747b715Smrg state |= (mouse && mouse->button) ? (mouse->button->state) : 0; 9736747b715Smrg 9746747b715Smrg for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) 9756747b715Smrg if (BitIsOn(mouse->button->down, i)) 9766747b715Smrg SetBit(event->buttons, i); 9776747b715Smrg 9786747b715Smrg if (kbd && kbd->key) 9796747b715Smrg { 9806747b715Smrg XkbStatePtr state; 9816747b715Smrg /* we need the state before the event happens */ 9826747b715Smrg if (event->type == ET_KeyPress || event->type == ET_KeyRelease) 9836747b715Smrg state = &kbd->key->xkbInfo->prev_state; 9846747b715Smrg else 9856747b715Smrg state = &kbd->key->xkbInfo->state; 9866747b715Smrg 9876747b715Smrg event->mods.base = state->base_mods; 9886747b715Smrg event->mods.latched = state->latched_mods; 9896747b715Smrg event->mods.locked = state->locked_mods; 9906747b715Smrg event->mods.effective = state->mods; 9916747b715Smrg 9926747b715Smrg event->group.base = state->base_group; 9936747b715Smrg event->group.latched = state->latched_group; 9946747b715Smrg event->group.locked = state->locked_group; 9956747b715Smrg event->group.effective = state->group; 9966747b715Smrg } 9974642e01fSmrg 9986747b715Smrg ret = UpdateDeviceState(device, event); 9994642e01fSmrg if (ret == DONT_PROCESS) 10004642e01fSmrg return; 10014642e01fSmrg 10024642e01fSmrg v = device->valuator; 10034642e01fSmrg b = device->button; 10044642e01fSmrg k = device->key; 10054642e01fSmrg 10066747b715Smrg if (IsMaster(device) || !device->u.master) 10076747b715Smrg CheckMotion(event, device); 10084642e01fSmrg 10096747b715Smrg switch (event->type) 10106747b715Smrg { 10116747b715Smrg case ET_Motion: 10126747b715Smrg case ET_ButtonPress: 10136747b715Smrg case ET_ButtonRelease: 10146747b715Smrg case ET_KeyPress: 10156747b715Smrg case ET_KeyRelease: 10166747b715Smrg case ET_ProximityIn: 10176747b715Smrg case ET_ProximityOut: 10186747b715Smrg GetSpritePosition(device, &rootX, &rootY); 10196747b715Smrg event->root_x = rootX; 10206747b715Smrg event->root_y = rootY; 10216747b715Smrg NoticeEventTime((InternalEvent*)event); 10226747b715Smrg event->corestate = state; 10236747b715Smrg key = event->detail.key; 10246747b715Smrg break; 10256747b715Smrg default: 10266747b715Smrg break; 10274642e01fSmrg } 10286747b715Smrg 10296747b715Smrg if (DeviceEventCallback && !syncEvents.playingEvents) { 10304642e01fSmrg DeviceEventInfoRec eventinfo; 10316747b715Smrg SpritePtr pSprite = device->spriteInfo->sprite; 10324642e01fSmrg 10336747b715Smrg /* see comment in EnqueueEvents regarding the next three lines */ 10346747b715Smrg if (ev->any.type == ET_Motion) 10356747b715Smrg ev->device_event.root = pSprite->hotPhys.pScreen->root->drawable.id; 10364642e01fSmrg 10376747b715Smrg eventinfo.device = device; 10386747b715Smrg eventinfo.event = ev; 10396747b715Smrg CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo); 10404642e01fSmrg } 10414642e01fSmrg 10426747b715Smrg grab = device->deviceGrab.grab; 10434642e01fSmrg 10446747b715Smrg switch(event->type) 10456747b715Smrg { 10466747b715Smrg case ET_KeyPress: 10476747b715Smrg if (!grab && CheckDeviceGrabs(device, event, 0)) { 10486747b715Smrg device->deviceGrab.activatingKey = key; 10496747b715Smrg return; 10506747b715Smrg } 10516747b715Smrg break; 10526747b715Smrg case ET_KeyRelease: 10536747b715Smrg if (grab && device->deviceGrab.fromPassiveGrab && 10546747b715Smrg (key == device->deviceGrab.activatingKey) && 10556747b715Smrg (device->deviceGrab.grab->type == KeyPress || 10566747b715Smrg device->deviceGrab.grab->type == DeviceKeyPress || 10576747b715Smrg device->deviceGrab.grab->type == XI_KeyPress)) 10586747b715Smrg deactivateDeviceGrab = TRUE; 10596747b715Smrg break; 10606747b715Smrg case ET_ButtonPress: 10616747b715Smrg event->detail.button = b->map[key]; 10626747b715Smrg if (!event->detail.button) { /* there's no button 0 */ 10636747b715Smrg event->detail.button = key; 10646747b715Smrg return; 10656747b715Smrg } 10666747b715Smrg if (!grab && CheckDeviceGrabs(device, event, 0)) 10676747b715Smrg { 10686747b715Smrg /* if a passive grab was activated, the event has been sent 10696747b715Smrg * already */ 10706747b715Smrg return; 10716747b715Smrg } 10726747b715Smrg break; 10736747b715Smrg case ET_ButtonRelease: 10746747b715Smrg event->detail.button = b->map[key]; 10756747b715Smrg if (!event->detail.button) { /* there's no button 0 */ 10766747b715Smrg event->detail.button = key; 10776747b715Smrg return; 10786747b715Smrg } 10796747b715Smrg if (grab && !b->buttonsDown && 10806747b715Smrg device->deviceGrab.fromPassiveGrab && 10816747b715Smrg (device->deviceGrab.grab->type == ButtonPress || 10826747b715Smrg device->deviceGrab.grab->type == DeviceButtonPress || 10836747b715Smrg device->deviceGrab.grab->type == XI_ButtonPress)) 10846747b715Smrg deactivateDeviceGrab = TRUE; 10856747b715Smrg default: 10866747b715Smrg break; 10874642e01fSmrg } 108805b261ecSmrg 10896747b715Smrg 109005b261ecSmrg if (grab) 10916747b715Smrg DeliverGrabbedEvent((InternalEvent*)event, device, deactivateDeviceGrab); 10926747b715Smrg else if (device->focus && !IsPointerEvent((InternalEvent*)ev)) 10936747b715Smrg DeliverFocusedEvent(device, (InternalEvent*)event, 10946747b715Smrg GetSpriteWindow(device)); 109505b261ecSmrg else 10966747b715Smrg DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent*)event, 10976747b715Smrg NullGrab, NullWindow, device); 109805b261ecSmrg 109905b261ecSmrg if (deactivateDeviceGrab == TRUE) 11004642e01fSmrg (*device->deviceGrab.DeactivateGrab) (device); 11016747b715Smrg event->detail.key = key; 110205b261ecSmrg} 110305b261ecSmrg 11046747b715Smrgint 110505b261ecSmrgInitProximityClassDeviceStruct(DeviceIntPtr dev) 110605b261ecSmrg{ 110705b261ecSmrg ProximityClassPtr proxc; 110805b261ecSmrg 11096747b715Smrg proxc = (ProximityClassPtr) malloc(sizeof(ProximityClassRec)); 111005b261ecSmrg if (!proxc) 111105b261ecSmrg return FALSE; 11126747b715Smrg proxc->sourceid = dev->id; 11139ace9065Smrg proxc->in_proximity = TRUE; 111405b261ecSmrg dev->proximity = proxc; 111505b261ecSmrg return TRUE; 111605b261ecSmrg} 111705b261ecSmrg 11184642e01fSmrg/** 11194642e01fSmrg * Initialise the device's valuators. The memory must already be allocated, 11204642e01fSmrg * this function merely inits the matching axis (specified through axnum) to 11214642e01fSmrg * sane values. 11224642e01fSmrg * 11234642e01fSmrg * It is a condition that (minval < maxval). 11244642e01fSmrg * 11254642e01fSmrg * @see InitValuatorClassDeviceStruct 11264642e01fSmrg */ 11276747b715Smrgvoid 11286747b715SmrgInitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval, 11299ace9065Smrg int resolution, int min_res, int max_res, int mode) 113005b261ecSmrg{ 113105b261ecSmrg AxisInfoPtr ax; 11324642e01fSmrg 11334642e01fSmrg if (!dev || !dev->valuator || minval > maxval) 113405b261ecSmrg return; 11356747b715Smrg if (axnum >= dev->valuator->numAxes) 11366747b715Smrg return; 113705b261ecSmrg 113805b261ecSmrg ax = dev->valuator->axes + axnum; 113905b261ecSmrg 114005b261ecSmrg ax->min_value = minval; 114105b261ecSmrg ax->max_value = maxval; 114205b261ecSmrg ax->resolution = resolution; 114305b261ecSmrg ax->min_resolution = min_res; 114405b261ecSmrg ax->max_resolution = max_res; 11456747b715Smrg ax->label = label; 11469ace9065Smrg ax->mode = mode; 11479ace9065Smrg 11489ace9065Smrg if (mode & OutOfProximity) 11499ace9065Smrg dev->proximity->in_proximity = FALSE; 115005b261ecSmrg} 115105b261ecSmrg 115205b261ecSmrgstatic void 115305b261ecSmrgFixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, 115405b261ecSmrg ButtonClassPtr b, ValuatorClassPtr v, int first) 115505b261ecSmrg{ 115605b261ecSmrg ev->type = DeviceStateNotify; 115705b261ecSmrg ev->deviceid = dev->id; 115805b261ecSmrg ev->time = currentTime.milliseconds; 115905b261ecSmrg ev->classes_reported = 0; 116005b261ecSmrg ev->num_keys = 0; 116105b261ecSmrg ev->num_buttons = 0; 116205b261ecSmrg ev->num_valuators = 0; 116305b261ecSmrg 116405b261ecSmrg if (b) { 116505b261ecSmrg ev->classes_reported |= (1 << ButtonClass); 116605b261ecSmrg ev->num_buttons = b->numButtons; 11674642e01fSmrg memcpy((char*)ev->buttons, (char*)b->down, 4); 116805b261ecSmrg } else if (k) { 116905b261ecSmrg ev->classes_reported |= (1 << KeyClass); 11706747b715Smrg ev->num_keys = k->xkbInfo->desc->max_key_code - 11716747b715Smrg k->xkbInfo->desc->min_key_code; 117205b261ecSmrg memmove((char *)&ev->keys[0], (char *)k->down, 4); 117305b261ecSmrg } 117405b261ecSmrg if (v) { 117505b261ecSmrg int nval = v->numAxes - first; 117605b261ecSmrg 117705b261ecSmrg ev->classes_reported |= (1 << ValuatorClass); 11789ace9065Smrg ev->classes_reported |= valuator_get_mode(dev, 0) << ModeBitsShift; 117905b261ecSmrg ev->num_valuators = nval < 3 ? nval : 3; 118005b261ecSmrg switch (ev->num_valuators) { 118105b261ecSmrg case 3: 118205b261ecSmrg ev->valuator2 = v->axisVal[first + 2]; 118305b261ecSmrg case 2: 118405b261ecSmrg ev->valuator1 = v->axisVal[first + 1]; 118505b261ecSmrg case 1: 118605b261ecSmrg ev->valuator0 = v->axisVal[first]; 118705b261ecSmrg break; 118805b261ecSmrg } 118905b261ecSmrg } 119005b261ecSmrg} 119105b261ecSmrg 119205b261ecSmrgstatic void 119305b261ecSmrgFixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, 119405b261ecSmrg int first) 119505b261ecSmrg{ 119605b261ecSmrg int nval = v->numAxes - first; 119705b261ecSmrg 119805b261ecSmrg ev->type = DeviceValuator; 119905b261ecSmrg ev->deviceid = dev->id; 120005b261ecSmrg ev->num_valuators = nval < 3 ? nval : 3; 120105b261ecSmrg ev->first_valuator = first; 120205b261ecSmrg switch (ev->num_valuators) { 120305b261ecSmrg case 3: 120405b261ecSmrg ev->valuator2 = v->axisVal[first + 2]; 120505b261ecSmrg case 2: 120605b261ecSmrg ev->valuator1 = v->axisVal[first + 1]; 120705b261ecSmrg case 1: 120805b261ecSmrg ev->valuator0 = v->axisVal[first]; 120905b261ecSmrg break; 121005b261ecSmrg } 121105b261ecSmrg first += ev->num_valuators; 121205b261ecSmrg} 121305b261ecSmrg 121405b261ecSmrgvoid 121505b261ecSmrgDeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, 121605b261ecSmrg WindowPtr pWin) 121705b261ecSmrg{ 121805b261ecSmrg deviceFocus event; 12196747b715Smrg xXIFocusInEvent *xi2event; 12206747b715Smrg DeviceIntPtr mouse; 12216747b715Smrg int btlen, len, i; 12226747b715Smrg 12236747b715Smrg mouse = (IsMaster(dev) || dev->u.master) ? GetMaster(dev, MASTER_POINTER) : dev; 12246747b715Smrg 12256747b715Smrg /* XI 2 event */ 12266747b715Smrg btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; 12276747b715Smrg btlen = bytes_to_int32(btlen); 12286747b715Smrg len = sizeof(xXIFocusInEvent) + btlen * 4; 12296747b715Smrg 12306747b715Smrg xi2event = calloc(1, len); 12316747b715Smrg xi2event->type = GenericEvent; 12326747b715Smrg xi2event->extension = IReqCode; 12336747b715Smrg xi2event->evtype = type; 12346747b715Smrg xi2event->length = bytes_to_int32(len - sizeof(xEvent)); 12356747b715Smrg xi2event->buttons_len = btlen; 12366747b715Smrg xi2event->detail = detail; 12376747b715Smrg xi2event->time = currentTime.milliseconds; 12386747b715Smrg xi2event->deviceid = dev->id; 12396747b715Smrg xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */ 12406747b715Smrg xi2event->mode = mode; 12416747b715Smrg xi2event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0); 12426747b715Smrg xi2event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0); 12436747b715Smrg 12446747b715Smrg for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) 12456747b715Smrg if (BitIsOn(mouse->button->down, i)) 12466747b715Smrg SetBit(&xi2event[1], i); 12476747b715Smrg 12486747b715Smrg if (dev->key) 12496747b715Smrg { 12506747b715Smrg xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods; 12516747b715Smrg xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods; 12526747b715Smrg xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods; 12536747b715Smrg xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods; 12546747b715Smrg 12556747b715Smrg xi2event->group.base_group = dev->key->xkbInfo->state.base_group; 12566747b715Smrg xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group; 12576747b715Smrg xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group; 12586747b715Smrg xi2event->group.effective_group = dev->key->xkbInfo->state.group; 12596747b715Smrg } 126005b261ecSmrg 12619ace9065Smrg FixUpEventFromWindow(dev->spriteInfo->sprite, (xEvent*)xi2event, pWin, 12629ace9065Smrg None, FALSE); 126305b261ecSmrg 12646747b715Smrg DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1, 12656747b715Smrg GetEventFilter(dev, (xEvent*)xi2event), NullGrab); 12666747b715Smrg 12676747b715Smrg free(xi2event); 12686747b715Smrg 12696747b715Smrg /* XI 1.x event */ 127005b261ecSmrg event.deviceid = dev->id; 127105b261ecSmrg event.mode = mode; 12726747b715Smrg event.type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut; 127305b261ecSmrg event.detail = detail; 127405b261ecSmrg event.window = pWin->drawable.id; 127505b261ecSmrg event.time = currentTime.milliseconds; 127605b261ecSmrg 12776747b715Smrg DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1, 12786747b715Smrg DeviceFocusChangeMask, NullGrab); 127905b261ecSmrg 12809ace9065Smrg if ((event.type == DeviceFocusIn) && 128105b261ecSmrg (wOtherInputMasks(pWin)) && 128205b261ecSmrg (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask)) 128305b261ecSmrg { 128405b261ecSmrg int evcount = 1; 128505b261ecSmrg deviceStateNotify *ev, *sev; 128605b261ecSmrg deviceKeyStateNotify *kev; 128705b261ecSmrg deviceButtonStateNotify *bev; 128805b261ecSmrg 128905b261ecSmrg KeyClassPtr k; 129005b261ecSmrg ButtonClassPtr b; 129105b261ecSmrg ValuatorClassPtr v; 129205b261ecSmrg int nval = 0, nkeys = 0, nbuttons = 0, first = 0; 129305b261ecSmrg 129405b261ecSmrg if ((b = dev->button) != NULL) { 129505b261ecSmrg nbuttons = b->numButtons; 129605b261ecSmrg if (nbuttons > 32) 129705b261ecSmrg evcount++; 129805b261ecSmrg } 129905b261ecSmrg if ((k = dev->key) != NULL) { 13006747b715Smrg nkeys = k->xkbInfo->desc->max_key_code - 13016747b715Smrg k->xkbInfo->desc->min_key_code; 130205b261ecSmrg if (nkeys > 32) 130305b261ecSmrg evcount++; 130405b261ecSmrg if (nbuttons > 0) { 130505b261ecSmrg evcount++; 130605b261ecSmrg } 130705b261ecSmrg } 130805b261ecSmrg if ((v = dev->valuator) != NULL) { 130905b261ecSmrg nval = v->numAxes; 131005b261ecSmrg 131105b261ecSmrg if (nval > 3) 131205b261ecSmrg evcount++; 131305b261ecSmrg if (nval > 6) { 131405b261ecSmrg if (!(k && b)) 131505b261ecSmrg evcount++; 131605b261ecSmrg if (nval > 9) 131705b261ecSmrg evcount += ((nval - 7) / 3); 131805b261ecSmrg } 131905b261ecSmrg } 132005b261ecSmrg 13216747b715Smrg sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent)); 132205b261ecSmrg FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); 132305b261ecSmrg 132405b261ecSmrg if (b != NULL) { 132505b261ecSmrg FixDeviceStateNotify(dev, ev++, NULL, b, v, first); 132605b261ecSmrg first += 3; 132705b261ecSmrg nval -= 3; 132805b261ecSmrg if (nbuttons > 32) { 132905b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 133005b261ecSmrg bev = (deviceButtonStateNotify *) ev++; 133105b261ecSmrg bev->type = DeviceButtonStateNotify; 133205b261ecSmrg bev->deviceid = dev->id; 13334642e01fSmrg memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4); 133405b261ecSmrg } 133505b261ecSmrg if (nval > 0) { 133605b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 133705b261ecSmrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 133805b261ecSmrg first += 3; 133905b261ecSmrg nval -= 3; 134005b261ecSmrg } 134105b261ecSmrg } 134205b261ecSmrg 134305b261ecSmrg if (k != NULL) { 134405b261ecSmrg FixDeviceStateNotify(dev, ev++, k, NULL, v, first); 134505b261ecSmrg first += 3; 134605b261ecSmrg nval -= 3; 134705b261ecSmrg if (nkeys > 32) { 134805b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 134905b261ecSmrg kev = (deviceKeyStateNotify *) ev++; 135005b261ecSmrg kev->type = DeviceKeyStateNotify; 135105b261ecSmrg kev->deviceid = dev->id; 135205b261ecSmrg memmove((char *)&kev->keys[0], (char *)&k->down[4], 28); 135305b261ecSmrg } 135405b261ecSmrg if (nval > 0) { 135505b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 135605b261ecSmrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 135705b261ecSmrg first += 3; 135805b261ecSmrg nval -= 3; 135905b261ecSmrg } 136005b261ecSmrg } 136105b261ecSmrg 136205b261ecSmrg while (nval > 0) { 136305b261ecSmrg FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); 136405b261ecSmrg first += 3; 136505b261ecSmrg nval -= 3; 136605b261ecSmrg if (nval > 0) { 136705b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 136805b261ecSmrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 136905b261ecSmrg first += 3; 137005b261ecSmrg nval -= 3; 137105b261ecSmrg } 137205b261ecSmrg } 137305b261ecSmrg 13746747b715Smrg DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount, 13756747b715Smrg DeviceStateNotifyMask, NullGrab); 13766747b715Smrg free(sev); 137705b261ecSmrg } 137805b261ecSmrg} 137905b261ecSmrg 138005b261ecSmrgint 13816747b715SmrgCheckGrabValues(ClientPtr client, GrabParameters* param) 138205b261ecSmrg{ 13836747b715Smrg if (param->grabtype != GRABTYPE_CORE && 13846747b715Smrg param->grabtype != GRABTYPE_XI && 13856747b715Smrg param->grabtype != GRABTYPE_XI2) 13866747b715Smrg { 13876747b715Smrg ErrorF("[Xi] grabtype is invalid. This is a bug.\n"); 13886747b715Smrg return BadImplementation; 13896747b715Smrg } 139005b261ecSmrg 13916747b715Smrg if ((param->this_device_mode != GrabModeSync) && 13926747b715Smrg (param->this_device_mode != GrabModeAsync)) { 13936747b715Smrg client->errorValue = param->this_device_mode; 139405b261ecSmrg return BadValue; 139505b261ecSmrg } 13966747b715Smrg if ((param->other_devices_mode != GrabModeSync) && 13976747b715Smrg (param->other_devices_mode != GrabModeAsync)) { 13986747b715Smrg client->errorValue = param->other_devices_mode; 139905b261ecSmrg return BadValue; 140005b261ecSmrg } 14016747b715Smrg 14026747b715Smrg if (param->grabtype != GRABTYPE_XI2 && (param->modifiers != AnyModifier) && 14036747b715Smrg (param->modifiers & ~AllModifiersMask)) { 14046747b715Smrg client->errorValue = param->modifiers; 140505b261ecSmrg return BadValue; 140605b261ecSmrg } 14076747b715Smrg 14086747b715Smrg if ((param->ownerEvents != xFalse) && (param->ownerEvents != xTrue)) { 14096747b715Smrg client->errorValue = param->ownerEvents; 141005b261ecSmrg return BadValue; 141105b261ecSmrg } 14126747b715Smrg return Success; 14136747b715Smrg} 14146747b715Smrg 14156747b715Smrgint 14166747b715SmrgGrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, 14176747b715Smrg int button, GrabParameters *param, GrabType grabtype, 14186747b715Smrg GrabMask *mask) 14196747b715Smrg{ 14206747b715Smrg WindowPtr pWin, confineTo; 14216747b715Smrg CursorPtr cursor; 14226747b715Smrg GrabPtr grab; 14236747b715Smrg int rc, type = -1; 14246747b715Smrg Mask access_mode = DixGrabAccess; 14256747b715Smrg 14266747b715Smrg rc = CheckGrabValues(client, param); 142705b261ecSmrg if (rc != Success) 142805b261ecSmrg return rc; 14296747b715Smrg if (param->confineTo == None) 143005b261ecSmrg confineTo = NullWindow; 143105b261ecSmrg else { 14326747b715Smrg rc = dixLookupWindow(&confineTo, param->confineTo, client, DixSetAttrAccess); 143305b261ecSmrg if (rc != Success) 143405b261ecSmrg return rc; 143505b261ecSmrg } 14366747b715Smrg if (param->cursor == None) 143705b261ecSmrg cursor = NullCursor; 143805b261ecSmrg else { 14396747b715Smrg rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, 14406747b715Smrg RT_CURSOR, client, DixUseAccess); 14414642e01fSmrg if (rc != Success) 14424642e01fSmrg { 14436747b715Smrg client->errorValue = param->cursor; 14446747b715Smrg return rc; 144505b261ecSmrg } 14464642e01fSmrg access_mode |= DixForceAccess; 144705b261ecSmrg } 14486747b715Smrg if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 14494642e01fSmrg access_mode |= DixFreezeAccess; 14504642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 14516747b715Smrg if (rc != Success) 14526747b715Smrg return rc; 14536747b715Smrg rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 14544642e01fSmrg if (rc != Success) 14554642e01fSmrg return rc; 145605b261ecSmrg 14576747b715Smrg if (grabtype == GRABTYPE_XI) 14586747b715Smrg type = DeviceButtonPress; 14596747b715Smrg else if (grabtype == GRABTYPE_XI2) 14606747b715Smrg type = XI_ButtonPress; 14616747b715Smrg 14626747b715Smrg grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, 14636747b715Smrg mask, param, type, button, confineTo, cursor); 146405b261ecSmrg if (!grab) 146505b261ecSmrg return BadAlloc; 14664642e01fSmrg return AddPassiveGrabToList(client, grab); 146705b261ecSmrg} 146805b261ecSmrg 14696747b715Smrg/** 14706747b715Smrg * Grab the given key. If grabtype is GRABTYPE_XI, the key is a keycode. If 14716747b715Smrg * grabtype is GRABTYPE_XI2, the key is a keysym. 14726747b715Smrg */ 147305b261ecSmrgint 14746747b715SmrgGrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, 14756747b715Smrg int key, GrabParameters *param, GrabType grabtype, GrabMask *mask) 147605b261ecSmrg{ 147705b261ecSmrg WindowPtr pWin; 147805b261ecSmrg GrabPtr grab; 147905b261ecSmrg KeyClassPtr k = dev->key; 14804642e01fSmrg Mask access_mode = DixGrabAccess; 14816747b715Smrg int rc, type = -1; 148205b261ecSmrg 14836747b715Smrg rc = CheckGrabValues(client, param); 14846747b715Smrg if (rc != Success) 14856747b715Smrg return rc; 148605b261ecSmrg if (k == NULL) 148705b261ecSmrg return BadMatch; 14886747b715Smrg if (grabtype == GRABTYPE_XI) 14896747b715Smrg { 14906747b715Smrg if ((key > k->xkbInfo->desc->max_key_code || 14916747b715Smrg key < k->xkbInfo->desc->min_key_code) 14926747b715Smrg && (key != AnyKey)) { 14936747b715Smrg client->errorValue = key; 14946747b715Smrg return BadValue; 14956747b715Smrg } 14966747b715Smrg type = DeviceKeyPress; 14976747b715Smrg } else if (grabtype == GRABTYPE_XI2) 14986747b715Smrg type = XI_KeyPress; 14996747b715Smrg 15006747b715Smrg rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 15014642e01fSmrg if (rc != Success) 15024642e01fSmrg return rc; 15036747b715Smrg if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 15044642e01fSmrg access_mode |= DixFreezeAccess; 15054642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 150605b261ecSmrg if (rc != Success) 150705b261ecSmrg return rc; 150805b261ecSmrg 15096747b715Smrg grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, 15106747b715Smrg mask, param, type, key, NULL, NULL); 151105b261ecSmrg if (!grab) 151205b261ecSmrg return BadAlloc; 15134642e01fSmrg return AddPassiveGrabToList(client, grab); 151405b261ecSmrg} 151505b261ecSmrg 15166747b715Smrg/* Enter/FocusIn grab */ 15176747b715Smrgint 15186747b715SmrgGrabWindow(ClientPtr client, DeviceIntPtr dev, int type, 15196747b715Smrg GrabParameters *param, GrabMask *mask) 15206747b715Smrg{ 15216747b715Smrg WindowPtr pWin; 15226747b715Smrg CursorPtr cursor; 15236747b715Smrg GrabPtr grab; 15246747b715Smrg Mask access_mode = DixGrabAccess; 15256747b715Smrg int rc; 15266747b715Smrg 15276747b715Smrg rc = CheckGrabValues(client, param); 15286747b715Smrg if (rc != Success) 15296747b715Smrg return rc; 15306747b715Smrg 15316747b715Smrg rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 15326747b715Smrg if (rc != Success) 15336747b715Smrg return rc; 15346747b715Smrg if (param->cursor == None) 15356747b715Smrg cursor = NullCursor; 15366747b715Smrg else { 15376747b715Smrg rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, 15386747b715Smrg RT_CURSOR, client, DixUseAccess); 15396747b715Smrg if (rc != Success) 15406747b715Smrg { 15416747b715Smrg client->errorValue = param->cursor; 15426747b715Smrg return rc; 15436747b715Smrg } 15446747b715Smrg access_mode |= DixForceAccess; 15456747b715Smrg } 15466747b715Smrg if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 15476747b715Smrg access_mode |= DixFreezeAccess; 15486747b715Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 15496747b715Smrg if (rc != Success) 15506747b715Smrg return rc; 15516747b715Smrg 15526747b715Smrg grab = CreateGrab(client->index, dev, dev, pWin, GRABTYPE_XI2, 15536747b715Smrg mask, param, (type == XIGrabtypeEnter) ? XI_Enter : XI_FocusIn, 15546747b715Smrg 0, NULL, cursor); 15556747b715Smrg 15566747b715Smrg if (!grab) 15576747b715Smrg return BadAlloc; 15586747b715Smrg 15596747b715Smrg return AddPassiveGrabToList(client, grab); 15606747b715Smrg} 15616747b715Smrg 156205b261ecSmrgint 156305b261ecSmrgSelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client, 15646747b715Smrg Mask mask, Mask exclusivemasks) 156505b261ecSmrg{ 156605b261ecSmrg int mskidx = dev->id; 156705b261ecSmrg int i, ret; 156805b261ecSmrg Mask check; 156905b261ecSmrg InputClientsPtr others; 157005b261ecSmrg 157105b261ecSmrg check = (mask & exclusivemasks); 157205b261ecSmrg if (wOtherInputMasks(pWin)) { 157305b261ecSmrg if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) { /* It is illegal for two different 157405b261ecSmrg * clients to select on any of the 157505b261ecSmrg * events for maskcheck. However, 157605b261ecSmrg * it is OK, for some client to 157705b261ecSmrg * continue selecting on one of those 157805b261ecSmrg * events. */ 157905b261ecSmrg for (others = wOtherInputMasks(pWin)->inputClients; others; 158005b261ecSmrg others = others->next) { 158105b261ecSmrg if (!SameClient(others, client) && (check & 158205b261ecSmrg others->mask[mskidx])) 158305b261ecSmrg return BadAccess; 158405b261ecSmrg } 158505b261ecSmrg } 158605b261ecSmrg for (others = wOtherInputMasks(pWin)->inputClients; others; 158705b261ecSmrg others = others->next) { 158805b261ecSmrg if (SameClient(others, client)) { 158905b261ecSmrg check = others->mask[mskidx]; 159005b261ecSmrg others->mask[mskidx] = mask; 159105b261ecSmrg if (mask == 0) { 159205b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 159305b261ecSmrg if (i != mskidx && others->mask[i] != 0) 159405b261ecSmrg break; 159505b261ecSmrg if (i == EMASKSIZE) { 159605b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 159705b261ecSmrg if (ShouldFreeInputMasks(pWin, FALSE)) 159805b261ecSmrg FreeResource(others->resource, RT_NONE); 159905b261ecSmrg return Success; 160005b261ecSmrg } 160105b261ecSmrg } 160205b261ecSmrg goto maskSet; 160305b261ecSmrg } 160405b261ecSmrg } 160505b261ecSmrg } 160605b261ecSmrg check = 0; 160705b261ecSmrg if ((ret = AddExtensionClient(pWin, client, mask, mskidx)) != Success) 160805b261ecSmrg return ret; 160905b261ecSmrg maskSet: 161005b261ecSmrg if (dev->valuator) 161105b261ecSmrg if ((dev->valuator->motionHintWindow == pWin) && 161205b261ecSmrg (mask & DevicePointerMotionHintMask) && 16134642e01fSmrg !(check & DevicePointerMotionHintMask) && !dev->deviceGrab.grab) 161405b261ecSmrg dev->valuator->motionHintWindow = NullWindow; 161505b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 161605b261ecSmrg return Success; 161705b261ecSmrg} 161805b261ecSmrg 161905b261ecSmrgint 162005b261ecSmrgAddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx) 162105b261ecSmrg{ 162205b261ecSmrg InputClientsPtr others; 162305b261ecSmrg 162405b261ecSmrg if (!pWin->optional && !MakeWindowOptional(pWin)) 162505b261ecSmrg return BadAlloc; 16266747b715Smrg others = calloc(1, sizeof(InputClients)); 162705b261ecSmrg if (!others) 162805b261ecSmrg return BadAlloc; 162905b261ecSmrg if (!pWin->optional->inputMasks && !MakeInputMasks(pWin)) 16309ace9065Smrg goto bail; 163105b261ecSmrg others->mask[mskidx] = mask; 163205b261ecSmrg others->resource = FakeClientID(client->index); 163305b261ecSmrg others->next = pWin->optional->inputMasks->inputClients; 163405b261ecSmrg pWin->optional->inputMasks->inputClients = others; 163505b261ecSmrg if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer) pWin)) 16369ace9065Smrg goto bail; 163705b261ecSmrg return Success; 16389ace9065Smrg 16399ace9065Smrgbail: 16409ace9065Smrg free(others); 16419ace9065Smrg return BadAlloc; 164205b261ecSmrg} 164305b261ecSmrg 164405b261ecSmrgstatic Bool 164505b261ecSmrgMakeInputMasks(WindowPtr pWin) 164605b261ecSmrg{ 164705b261ecSmrg struct _OtherInputMasks *imasks; 164805b261ecSmrg 16496747b715Smrg imasks = calloc(1, sizeof(struct _OtherInputMasks)); 165005b261ecSmrg if (!imasks) 165105b261ecSmrg return FALSE; 165205b261ecSmrg pWin->optional->inputMasks = imasks; 165305b261ecSmrg return TRUE; 165405b261ecSmrg} 165505b261ecSmrg 165605b261ecSmrgvoid 165705b261ecSmrgRecalculateDeviceDeliverableEvents(WindowPtr pWin) 165805b261ecSmrg{ 165905b261ecSmrg InputClientsPtr others; 166005b261ecSmrg struct _OtherInputMasks *inputMasks; /* default: NULL */ 166105b261ecSmrg WindowPtr pChild, tmp; 16626747b715Smrg int i, j; 166305b261ecSmrg 166405b261ecSmrg pChild = pWin; 166505b261ecSmrg while (1) { 166605b261ecSmrg if ((inputMasks = wOtherInputMasks(pChild)) != 0) { 16676747b715Smrg for (i = 0; i < EMASKSIZE; i++) 16686747b715Smrg memset(inputMasks->xi2mask[i], 0, sizeof(inputMasks->xi2mask[i])); 166905b261ecSmrg for (others = inputMasks->inputClients; others; 167005b261ecSmrg others = others->next) { 167105b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 167205b261ecSmrg inputMasks->inputEvents[i] |= others->mask[i]; 16736747b715Smrg for (i = 0; i < EMASKSIZE; i++) 16746747b715Smrg for (j = 0; j < XI2MASKSIZE; j++) 16756747b715Smrg inputMasks->xi2mask[i][j] |= others->xi2mask[i][j]; 167605b261ecSmrg } 167705b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 167805b261ecSmrg inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i]; 167905b261ecSmrg for (tmp = pChild->parent; tmp; tmp = tmp->parent) 168005b261ecSmrg if (wOtherInputMasks(tmp)) 168105b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 168205b261ecSmrg inputMasks->deliverableEvents[i] |= 168305b261ecSmrg (wOtherInputMasks(tmp)->deliverableEvents[i] 168405b261ecSmrg & ~inputMasks-> 168505b261ecSmrg dontPropagateMask[i] & PropagateMask[i]); 168605b261ecSmrg } 168705b261ecSmrg if (pChild->firstChild) { 168805b261ecSmrg pChild = pChild->firstChild; 168905b261ecSmrg continue; 169005b261ecSmrg } 169105b261ecSmrg while (!pChild->nextSib && (pChild != pWin)) 169205b261ecSmrg pChild = pChild->parent; 169305b261ecSmrg if (pChild == pWin) 169405b261ecSmrg break; 169505b261ecSmrg pChild = pChild->nextSib; 169605b261ecSmrg } 169705b261ecSmrg} 169805b261ecSmrg 169905b261ecSmrgint 170005b261ecSmrgInputClientGone(WindowPtr pWin, XID id) 170105b261ecSmrg{ 170205b261ecSmrg InputClientsPtr other, prev; 170305b261ecSmrg 170405b261ecSmrg if (!wOtherInputMasks(pWin)) 17056747b715Smrg return Success; 170605b261ecSmrg prev = 0; 170705b261ecSmrg for (other = wOtherInputMasks(pWin)->inputClients; other; 170805b261ecSmrg other = other->next) { 170905b261ecSmrg if (other->resource == id) { 171005b261ecSmrg if (prev) { 171105b261ecSmrg prev->next = other->next; 17126747b715Smrg free(other); 171305b261ecSmrg } else if (!(other->next)) { 171405b261ecSmrg if (ShouldFreeInputMasks(pWin, TRUE)) { 171505b261ecSmrg wOtherInputMasks(pWin)->inputClients = other->next; 17166747b715Smrg free(wOtherInputMasks(pWin)); 171705b261ecSmrg pWin->optional->inputMasks = (OtherInputMasks *) NULL; 171805b261ecSmrg CheckWindowOptionalNeed(pWin); 17196747b715Smrg free(other); 172005b261ecSmrg } else { 172105b261ecSmrg other->resource = FakeClientID(0); 172205b261ecSmrg if (!AddResource(other->resource, RT_INPUTCLIENT, 172305b261ecSmrg (pointer) pWin)) 172405b261ecSmrg return BadAlloc; 172505b261ecSmrg } 172605b261ecSmrg } else { 172705b261ecSmrg wOtherInputMasks(pWin)->inputClients = other->next; 17286747b715Smrg free(other); 172905b261ecSmrg } 173005b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 17316747b715Smrg return Success; 173205b261ecSmrg } 173305b261ecSmrg prev = other; 173405b261ecSmrg } 173505b261ecSmrg FatalError("client not on device event list"); 173605b261ecSmrg} 173705b261ecSmrg 173805b261ecSmrgint 173905b261ecSmrgSendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate, 174005b261ecSmrg xEvent * ev, Mask mask, int count) 174105b261ecSmrg{ 174205b261ecSmrg WindowPtr pWin; 174305b261ecSmrg WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ 17444642e01fSmrg WindowPtr spriteWin = GetSpriteWindow(d); 174505b261ecSmrg 174605b261ecSmrg if (dest == PointerWindow) 174705b261ecSmrg pWin = spriteWin; 174805b261ecSmrg else if (dest == InputFocus) { 174905b261ecSmrg WindowPtr inputFocus; 175005b261ecSmrg 175105b261ecSmrg if (!d->focus) 175205b261ecSmrg inputFocus = spriteWin; 175305b261ecSmrg else 175405b261ecSmrg inputFocus = d->focus->win; 175505b261ecSmrg 175605b261ecSmrg if (inputFocus == FollowKeyboardWin) 175705b261ecSmrg inputFocus = inputInfo.keyboard->focus->win; 175805b261ecSmrg 175905b261ecSmrg if (inputFocus == NoneWin) 176005b261ecSmrg return Success; 176105b261ecSmrg 176205b261ecSmrg /* If the input focus is PointerRootWin, send the event to where 176305b261ecSmrg * the pointer is if possible, then perhaps propogate up to root. */ 176405b261ecSmrg if (inputFocus == PointerRootWin) 17654642e01fSmrg inputFocus = GetCurrentRootWindow(d); 176605b261ecSmrg 176705b261ecSmrg if (IsParent(inputFocus, spriteWin)) { 176805b261ecSmrg effectiveFocus = inputFocus; 176905b261ecSmrg pWin = spriteWin; 177005b261ecSmrg } else 177105b261ecSmrg effectiveFocus = pWin = inputFocus; 177205b261ecSmrg } else 17734642e01fSmrg dixLookupWindow(&pWin, dest, client, DixSendAccess); 177405b261ecSmrg if (!pWin) 177505b261ecSmrg return BadWindow; 177605b261ecSmrg if ((propagate != xFalse) && (propagate != xTrue)) { 177705b261ecSmrg client->errorValue = propagate; 177805b261ecSmrg return BadValue; 177905b261ecSmrg } 178005b261ecSmrg ev->u.u.type |= 0x80; 178105b261ecSmrg if (propagate) { 178205b261ecSmrg for (; pWin; pWin = pWin->parent) { 17836747b715Smrg if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab)) 178405b261ecSmrg return Success; 178505b261ecSmrg if (pWin == effectiveFocus) 178605b261ecSmrg return Success; 178705b261ecSmrg if (wOtherInputMasks(pWin)) 178805b261ecSmrg mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id]; 178905b261ecSmrg if (!mask) 179005b261ecSmrg break; 179105b261ecSmrg } 17924642e01fSmrg } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count)) 17936747b715Smrg DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab); 179405b261ecSmrg return Success; 179505b261ecSmrg} 179605b261ecSmrg 179705b261ecSmrgint 179805b261ecSmrgSetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map) 179905b261ecSmrg{ 180005b261ecSmrg int i; 180105b261ecSmrg ButtonClassPtr b = dev->button; 180205b261ecSmrg 180305b261ecSmrg if (b == NULL) 180405b261ecSmrg return BadMatch; 180505b261ecSmrg 180605b261ecSmrg if (nElts != b->numButtons) { 180705b261ecSmrg client->errorValue = nElts; 180805b261ecSmrg return BadValue; 180905b261ecSmrg } 181005b261ecSmrg if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue)) 181105b261ecSmrg return BadValue; 181205b261ecSmrg for (i = 0; i < nElts; i++) 181305b261ecSmrg if ((b->map[i + 1] != map[i]) && BitIsOn(b->down, i + 1)) 181405b261ecSmrg return MappingBusy; 181505b261ecSmrg for (i = 0; i < nElts; i++) 181605b261ecSmrg b->map[i + 1] = map[i]; 181705b261ecSmrg return Success; 181805b261ecSmrg} 181905b261ecSmrg 182005b261ecSmrgint 182105b261ecSmrgChangeKeyMapping(ClientPtr client, 182205b261ecSmrg DeviceIntPtr dev, 182305b261ecSmrg unsigned len, 182405b261ecSmrg int type, 182505b261ecSmrg KeyCode firstKeyCode, 182605b261ecSmrg CARD8 keyCodes, CARD8 keySymsPerKeyCode, KeySym * map) 182705b261ecSmrg{ 182805b261ecSmrg KeySymsRec keysyms; 182905b261ecSmrg KeyClassPtr k = dev->key; 183005b261ecSmrg 183105b261ecSmrg if (k == NULL) 18326747b715Smrg return BadMatch; 183305b261ecSmrg 183405b261ecSmrg if (len != (keyCodes * keySymsPerKeyCode)) 183505b261ecSmrg return BadLength; 183605b261ecSmrg 18376747b715Smrg if ((firstKeyCode < k->xkbInfo->desc->min_key_code) || 18386747b715Smrg (firstKeyCode + keyCodes - 1 > k->xkbInfo->desc->max_key_code)) { 183905b261ecSmrg client->errorValue = firstKeyCode; 184005b261ecSmrg return BadValue; 184105b261ecSmrg } 184205b261ecSmrg if (keySymsPerKeyCode == 0) { 184305b261ecSmrg client->errorValue = 0; 184405b261ecSmrg return BadValue; 184505b261ecSmrg } 184605b261ecSmrg keysyms.minKeyCode = firstKeyCode; 184705b261ecSmrg keysyms.maxKeyCode = firstKeyCode + keyCodes - 1; 184805b261ecSmrg keysyms.mapWidth = keySymsPerKeyCode; 184905b261ecSmrg keysyms.map = map; 18506747b715Smrg 18516747b715Smrg XkbApplyMappingChange(dev, &keysyms, firstKeyCode, keyCodes, NULL, 18526747b715Smrg serverClient); 18536747b715Smrg 18546747b715Smrg return Success; 185505b261ecSmrg} 185605b261ecSmrg 185705b261ecSmrgstatic void 185805b261ecSmrgDeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) 185905b261ecSmrg{ 186005b261ecSmrg WindowPtr parent; 186105b261ecSmrg 186205b261ecSmrg /* Deactivate any grabs performed on this window, before making 186305b261ecSmrg * any input focus changes. 186405b261ecSmrg * Deactivating a device grab should cause focus events. */ 186505b261ecSmrg 18664642e01fSmrg if (dev->deviceGrab.grab && (dev->deviceGrab.grab->window == pWin)) 18674642e01fSmrg (*dev->deviceGrab.DeactivateGrab) (dev); 186805b261ecSmrg 18694642e01fSmrg /* If the focus window is a root window (ie. has no parent) 187005b261ecSmrg * then don't delete the focus from it. */ 187105b261ecSmrg 187205b261ecSmrg if (dev->focus && (pWin == dev->focus->win) && (pWin->parent != NullWindow)) { 187305b261ecSmrg int focusEventMode = NotifyNormal; 187405b261ecSmrg 187505b261ecSmrg /* If a grab is in progress, then alter the mode of focus events. */ 187605b261ecSmrg 18774642e01fSmrg if (dev->deviceGrab.grab) 187805b261ecSmrg focusEventMode = NotifyWhileGrabbed; 187905b261ecSmrg 188005b261ecSmrg switch (dev->focus->revert) { 188105b261ecSmrg case RevertToNone: 18826747b715Smrg if (!ActivateFocusInGrab(dev, pWin, NoneWin)) 18836747b715Smrg DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 188405b261ecSmrg dev->focus->win = NoneWin; 188505b261ecSmrg dev->focus->traceGood = 0; 188605b261ecSmrg break; 188705b261ecSmrg case RevertToParent: 188805b261ecSmrg parent = pWin; 188905b261ecSmrg do { 189005b261ecSmrg parent = parent->parent; 189105b261ecSmrg dev->focus->traceGood--; 189205b261ecSmrg } 189305b261ecSmrg while (!parent->realized); 18946747b715Smrg if (!ActivateFocusInGrab(dev, pWin, parent)) 18956747b715Smrg DoFocusEvents(dev, pWin, parent, focusEventMode); 189605b261ecSmrg dev->focus->win = parent; 189705b261ecSmrg dev->focus->revert = RevertToNone; 189805b261ecSmrg break; 189905b261ecSmrg case RevertToPointerRoot: 19006747b715Smrg if (!ActivateFocusInGrab(dev, pWin, PointerRootWin)) 19016747b715Smrg DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode); 190205b261ecSmrg dev->focus->win = PointerRootWin; 190305b261ecSmrg dev->focus->traceGood = 0; 190405b261ecSmrg break; 190505b261ecSmrg case RevertToFollowKeyboard: 19066747b715Smrg { 19076747b715Smrg DeviceIntPtr kbd = GetMaster(dev, MASTER_KEYBOARD); 19086747b715Smrg if (!kbd || (kbd == dev && kbd != inputInfo.keyboard)) 19096747b715Smrg kbd = inputInfo.keyboard; 19106747b715Smrg if (kbd->focus->win) { 19116747b715Smrg if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win)) 19126747b715Smrg DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode); 191305b261ecSmrg dev->focus->win = FollowKeyboardWin; 191405b261ecSmrg dev->focus->traceGood = 0; 191505b261ecSmrg } else { 19166747b715Smrg if (!ActivateFocusInGrab(dev, pWin, NoneWin)) 19176747b715Smrg DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 191805b261ecSmrg dev->focus->win = NoneWin; 191905b261ecSmrg dev->focus->traceGood = 0; 192005b261ecSmrg } 19216747b715Smrg } 192205b261ecSmrg break; 192305b261ecSmrg } 192405b261ecSmrg } 192505b261ecSmrg 192605b261ecSmrg if (dev->valuator) 192705b261ecSmrg if (dev->valuator->motionHintWindow == pWin) 192805b261ecSmrg dev->valuator->motionHintWindow = NullWindow; 192905b261ecSmrg} 193005b261ecSmrg 193105b261ecSmrgvoid 193205b261ecSmrgDeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources) 193305b261ecSmrg{ 193405b261ecSmrg int i; 193505b261ecSmrg DeviceIntPtr dev; 193605b261ecSmrg InputClientsPtr ic; 193705b261ecSmrg struct _OtherInputMasks *inputMasks; 193805b261ecSmrg 193905b261ecSmrg for (dev = inputInfo.devices; dev; dev = dev->next) { 194005b261ecSmrg DeleteDeviceFromAnyExtEvents(pWin, dev); 194105b261ecSmrg } 194205b261ecSmrg 194305b261ecSmrg for (dev = inputInfo.off_devices; dev; dev = dev->next) 194405b261ecSmrg DeleteDeviceFromAnyExtEvents(pWin, dev); 194505b261ecSmrg 194605b261ecSmrg if (freeResources) 194705b261ecSmrg while ((inputMasks = wOtherInputMasks(pWin)) != 0) { 194805b261ecSmrg ic = inputMasks->inputClients; 194905b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 195005b261ecSmrg inputMasks->dontPropagateMask[i] = 0; 195105b261ecSmrg FreeResource(ic->resource, RT_NONE); 195205b261ecSmrg } 195305b261ecSmrg} 195405b261ecSmrg 195505b261ecSmrgint 195605b261ecSmrgMaybeSendDeviceMotionNotifyHint(deviceKeyButtonPointer * pEvents, Mask mask) 195705b261ecSmrg{ 195805b261ecSmrg DeviceIntPtr dev; 195905b261ecSmrg 19604642e01fSmrg dixLookupDevice(&dev, pEvents->deviceid & DEVICE_BITS, serverClient, 19614642e01fSmrg DixReadAccess); 196205b261ecSmrg if (!dev) 196305b261ecSmrg return 0; 196405b261ecSmrg 196505b261ecSmrg if (pEvents->type == DeviceMotionNotify) { 196605b261ecSmrg if (mask & DevicePointerMotionHintMask) { 196705b261ecSmrg if (WID(dev->valuator->motionHintWindow) == pEvents->event) { 196805b261ecSmrg return 1; /* don't send, but pretend we did */ 196905b261ecSmrg } 197005b261ecSmrg pEvents->detail = NotifyHint; 197105b261ecSmrg } else { 197205b261ecSmrg pEvents->detail = NotifyNormal; 197305b261ecSmrg } 197405b261ecSmrg } 19756747b715Smrg return 0; 197605b261ecSmrg} 197705b261ecSmrg 197805b261ecSmrgvoid 197905b261ecSmrgCheckDeviceGrabAndHintWindow(WindowPtr pWin, int type, 198005b261ecSmrg deviceKeyButtonPointer * xE, GrabPtr grab, 198105b261ecSmrg ClientPtr client, Mask deliveryMask) 198205b261ecSmrg{ 198305b261ecSmrg DeviceIntPtr dev; 198405b261ecSmrg 19854642e01fSmrg dixLookupDevice(&dev, xE->deviceid & DEVICE_BITS, serverClient, 19866747b715Smrg DixGrabAccess); 198705b261ecSmrg if (!dev) 198805b261ecSmrg return; 198905b261ecSmrg 199005b261ecSmrg if (type == DeviceMotionNotify) 199105b261ecSmrg dev->valuator->motionHintWindow = pWin; 199205b261ecSmrg else if ((type == DeviceButtonPress) && (!grab) && 199305b261ecSmrg (deliveryMask & DeviceButtonGrabMask)) { 199405b261ecSmrg GrabRec tempGrab; 199505b261ecSmrg 199605b261ecSmrg tempGrab.device = dev; 199705b261ecSmrg tempGrab.resource = client->clientAsMask; 199805b261ecSmrg tempGrab.window = pWin; 199905b261ecSmrg tempGrab.ownerEvents = 200005b261ecSmrg (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE; 200105b261ecSmrg tempGrab.eventMask = deliveryMask; 200205b261ecSmrg tempGrab.keyboardMode = GrabModeAsync; 200305b261ecSmrg tempGrab.pointerMode = GrabModeAsync; 200405b261ecSmrg tempGrab.confineTo = NullWindow; 200505b261ecSmrg tempGrab.cursor = NullCursor; 20064642e01fSmrg tempGrab.next = NULL; 20074642e01fSmrg (*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE); 200805b261ecSmrg } 200905b261ecSmrg} 201005b261ecSmrg 201105b261ecSmrgstatic Mask 201205b261ecSmrgDeviceEventMaskForClient(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client) 201305b261ecSmrg{ 201405b261ecSmrg InputClientsPtr other; 201505b261ecSmrg 201605b261ecSmrg if (!wOtherInputMasks(pWin)) 201705b261ecSmrg return 0; 201805b261ecSmrg for (other = wOtherInputMasks(pWin)->inputClients; other; 201905b261ecSmrg other = other->next) { 202005b261ecSmrg if (SameClient(other, client)) 202105b261ecSmrg return other->mask[dev->id]; 202205b261ecSmrg } 202305b261ecSmrg return 0; 202405b261ecSmrg} 202505b261ecSmrg 202605b261ecSmrgvoid 202705b261ecSmrgMaybeStopDeviceHint(DeviceIntPtr dev, ClientPtr client) 202805b261ecSmrg{ 202905b261ecSmrg WindowPtr pWin; 20304642e01fSmrg GrabPtr grab = dev->deviceGrab.grab; 203105b261ecSmrg 203205b261ecSmrg pWin = dev->valuator->motionHintWindow; 203305b261ecSmrg 203405b261ecSmrg if ((grab && SameClient(grab, client) && 203505b261ecSmrg ((grab->eventMask & DevicePointerMotionHintMask) || 203605b261ecSmrg (grab->ownerEvents && 203705b261ecSmrg (DeviceEventMaskForClient(dev, pWin, client) & 203805b261ecSmrg DevicePointerMotionHintMask)))) || 203905b261ecSmrg (!grab && 204005b261ecSmrg (DeviceEventMaskForClient(dev, pWin, client) & 204105b261ecSmrg DevicePointerMotionHintMask))) 204205b261ecSmrg dev->valuator->motionHintWindow = NullWindow; 204305b261ecSmrg} 204405b261ecSmrg 204505b261ecSmrgint 204605b261ecSmrgDeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask, 204705b261ecSmrg int maskndx) 204805b261ecSmrg{ 204905b261ecSmrg struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 205005b261ecSmrg 205105b261ecSmrg if (mask & ~PropagateMask[maskndx]) { 205205b261ecSmrg client->errorValue = mask; 205305b261ecSmrg return BadValue; 205405b261ecSmrg } 205505b261ecSmrg 205605b261ecSmrg if (mask == 0) { 205705b261ecSmrg if (inputMasks) 205805b261ecSmrg inputMasks->dontPropagateMask[maskndx] = mask; 205905b261ecSmrg } else { 206005b261ecSmrg if (!inputMasks) 206105b261ecSmrg AddExtensionClient(pWin, client, 0, 0); 206205b261ecSmrg inputMasks = wOtherInputMasks(pWin); 206305b261ecSmrg inputMasks->dontPropagateMask[maskndx] = mask; 206405b261ecSmrg } 206505b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 206605b261ecSmrg if (ShouldFreeInputMasks(pWin, FALSE)) 206705b261ecSmrg FreeResource(inputMasks->inputClients->resource, RT_NONE); 206805b261ecSmrg return Success; 206905b261ecSmrg} 207005b261ecSmrg 20714642e01fSmrgBool 207205b261ecSmrgShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents) 207305b261ecSmrg{ 207405b261ecSmrg int i; 207505b261ecSmrg Mask allInputEventMasks = 0; 207605b261ecSmrg struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 207705b261ecSmrg 207805b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 207905b261ecSmrg allInputEventMasks |= inputMasks->dontPropagateMask[i]; 208005b261ecSmrg if (!ignoreSelectedEvents) 208105b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 208205b261ecSmrg allInputEventMasks |= inputMasks->inputEvents[i]; 208305b261ecSmrg if (allInputEventMasks == 0) 208405b261ecSmrg return TRUE; 208505b261ecSmrg else 208605b261ecSmrg return FALSE; 208705b261ecSmrg} 208805b261ecSmrg 208905b261ecSmrg/*********************************************************************** 209005b261ecSmrg * 209105b261ecSmrg * Walk through the window tree, finding all clients that want to know 209205b261ecSmrg * about the Event. 209305b261ecSmrg * 209405b261ecSmrg */ 209505b261ecSmrg 209605b261ecSmrgstatic void 209705b261ecSmrgFindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask, 209805b261ecSmrg xEvent * ev, int count) 209905b261ecSmrg{ 210005b261ecSmrg WindowPtr p2; 210105b261ecSmrg 210205b261ecSmrg while (p1) { 210305b261ecSmrg p2 = p1->firstChild; 21046747b715Smrg DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab); 210505b261ecSmrg FindInterestedChildren(dev, p2, mask, ev, count); 210605b261ecSmrg p1 = p1->nextSib; 210705b261ecSmrg } 210805b261ecSmrg} 210905b261ecSmrg 211005b261ecSmrg/*********************************************************************** 211105b261ecSmrg * 211205b261ecSmrg * Send an event to interested clients in all windows on all screens. 211305b261ecSmrg * 211405b261ecSmrg */ 211505b261ecSmrg 211605b261ecSmrgvoid 211705b261ecSmrgSendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count) 211805b261ecSmrg{ 211905b261ecSmrg int i; 212005b261ecSmrg WindowPtr pWin, p1; 212105b261ecSmrg 212205b261ecSmrg for (i = 0; i < screenInfo.numScreens; i++) { 21236747b715Smrg pWin = screenInfo.screens[i]->root; 21244642e01fSmrg if (!pWin) 21254642e01fSmrg continue; 21266747b715Smrg DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab); 212705b261ecSmrg p1 = pWin->firstChild; 212805b261ecSmrg FindInterestedChildren(dev, p1, mask, ev, count); 212905b261ecSmrg } 213005b261ecSmrg} 21314642e01fSmrg 21326747b715Smrg/** 21336747b715Smrg * Set the XI2 mask for the given client on the given window. 21346747b715Smrg * @param dev The device to set the mask for. 21356747b715Smrg * @param win The window to set the mask on. 21366747b715Smrg * @param client The client setting the mask. 21376747b715Smrg * @param len Number of bytes in mask. 21386747b715Smrg * @param mask Event mask in the form of (1 << eventtype) 21396747b715Smrg */ 21406747b715Smrgint 21416747b715SmrgXISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client, 21426747b715Smrg unsigned int len, unsigned char* mask) 21436747b715Smrg{ 21446747b715Smrg OtherInputMasks *masks; 21456747b715Smrg InputClientsPtr others = NULL; 21466747b715Smrg 21476747b715Smrg masks = wOtherInputMasks(win); 21486747b715Smrg if (masks) 21496747b715Smrg { 21506747b715Smrg for (others = wOtherInputMasks(win)->inputClients; others; 21516747b715Smrg others = others->next) { 21526747b715Smrg if (SameClient(others, client)) { 21536747b715Smrg memset(others->xi2mask[dev->id], 0, 21546747b715Smrg sizeof(others->xi2mask[dev->id])); 21556747b715Smrg break; 21566747b715Smrg } 21576747b715Smrg } 21586747b715Smrg } 21596747b715Smrg 21606747b715Smrg len = min(len, sizeof(others->xi2mask[dev->id])); 21616747b715Smrg 21626747b715Smrg if (len && !others) 21636747b715Smrg { 21646747b715Smrg if (AddExtensionClient(win, client, 0, 0) != Success) 21656747b715Smrg return BadAlloc; 21666747b715Smrg others= wOtherInputMasks(win)->inputClients; 21676747b715Smrg } 21686747b715Smrg 21696747b715Smrg if (others) 21706747b715Smrg memset(others->xi2mask[dev->id], 0, sizeof(others->xi2mask[dev->id])); 21716747b715Smrg 21726747b715Smrg if (len) 21736747b715Smrg memcpy(others->xi2mask[dev->id], mask, len); 21746747b715Smrg 21756747b715Smrg RecalculateDeviceDeliverableEvents(win); 21766747b715Smrg 21776747b715Smrg return Success; 21786747b715Smrg} 2179