exevents.c revision 8223e2f2
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 11405b261ecSmrgvoid 11505b261ecSmrgRegisterOtherDevice(DeviceIntPtr device) 11605b261ecSmrg{ 11705b261ecSmrg device->public.processInputProc = ProcessOtherEvent; 11805b261ecSmrg device->public.realInputProc = ProcessOtherEvent; 11905b261ecSmrg} 12005b261ecSmrg 1214642e01fSmrgBool 1226747b715SmrgIsPointerEvent(InternalEvent* event) 1234642e01fSmrg{ 1246747b715Smrg switch(event->any.type) 1254642e01fSmrg { 1266747b715Smrg case ET_ButtonPress: 1276747b715Smrg case ET_ButtonRelease: 1286747b715Smrg case ET_Motion: 1296747b715Smrg /* XXX: enter/leave ?? */ 1304642e01fSmrg return TRUE; 1314642e01fSmrg default: 1326747b715Smrg break; 1334642e01fSmrg } 1344642e01fSmrg return FALSE; 1354642e01fSmrg} 1364642e01fSmrg 1374642e01fSmrg/** 1384642e01fSmrg * @return the device matching the deviceid of the device set in the event, or 1394642e01fSmrg * NULL if the event is not an XInput event. 1404642e01fSmrg */ 1414642e01fSmrgDeviceIntPtr 1424642e01fSmrgXIGetDevice(xEvent* xE) 14305b261ecSmrg{ 1444642e01fSmrg DeviceIntPtr pDev = NULL; 1454642e01fSmrg 1464642e01fSmrg if (xE->u.u.type == DeviceButtonPress || 1474642e01fSmrg xE->u.u.type == DeviceButtonRelease || 1484642e01fSmrg xE->u.u.type == DeviceMotionNotify || 1494642e01fSmrg xE->u.u.type == ProximityIn || 1504642e01fSmrg xE->u.u.type == ProximityOut || 1514642e01fSmrg xE->u.u.type == DevicePropertyNotify) 1524642e01fSmrg { 1534642e01fSmrg int rc; 1544642e01fSmrg int id; 1554642e01fSmrg 1564642e01fSmrg id = ((deviceKeyButtonPointer*)xE)->deviceid & ~MORE_EVENTS; 1574642e01fSmrg 1584642e01fSmrg rc = dixLookupDevice(&pDev, id, serverClient, DixUnknownAccess); 1594642e01fSmrg if (rc != Success) 1604642e01fSmrg ErrorF("[dix] XIGetDevice failed on XACE restrictions (%d)\n", rc); 1614642e01fSmrg } 1624642e01fSmrg return pDev; 1634642e01fSmrg} 1644642e01fSmrg 1654642e01fSmrg 1664642e01fSmrg/** 1674642e01fSmrg * Copy the device->key into master->key and send a mapping notify to the 1684642e01fSmrg * clients if appropriate. 1694642e01fSmrg * master->key needs to be allocated by the caller. 1704642e01fSmrg * 1714642e01fSmrg * Device is the slave device. If it is attached to a master device, we may 1724642e01fSmrg * need to send a mapping notify to the client because it causes the MD 1734642e01fSmrg * to change state. 1744642e01fSmrg * 1754642e01fSmrg * Mapping notify needs to be sent in the following cases: 1764642e01fSmrg * - different slave device on same master 1774642e01fSmrg * - different master 1784642e01fSmrg * 1794642e01fSmrg * XXX: They way how the code is we also send a map notify if the slave device 1804642e01fSmrg * stays the same, but the master changes. This isn't really necessary though. 1814642e01fSmrg * 1824642e01fSmrg * XXX: this gives you funny behaviour with the ClientPointer. When a 1834642e01fSmrg * MappingNotify is sent to the client, the client usually responds with a 1844642e01fSmrg * GetKeyboardMapping. This will retrieve the ClientPointer's keyboard 1854642e01fSmrg * mapping, regardless of which keyboard sent the last mapping notify request. 1864642e01fSmrg * So depending on the CP setting, your keyboard may change layout in each 1874642e01fSmrg * app... 1884642e01fSmrg * 1894642e01fSmrg * This code is basically the old SwitchCoreKeyboard. 1904642e01fSmrg */ 1914642e01fSmrg 1924642e01fSmrgvoid 1934642e01fSmrgCopyKeyClass(DeviceIntPtr device, DeviceIntPtr master) 1944642e01fSmrg{ 1956747b715Smrg KeyClassPtr mk = master->key; 1964642e01fSmrg 1974642e01fSmrg if (device == master) 1984642e01fSmrg return; 1994642e01fSmrg 2006747b715Smrg mk->sourceid = device->id; 2014642e01fSmrg 2024642e01fSmrg 2036747b715Smrg if (!XkbCopyDeviceKeymap(master, device)) 2046747b715Smrg FatalError("Couldn't pivot keymap from device to core!\n"); 2054642e01fSmrg} 20605b261ecSmrg 2074642e01fSmrg/** 2084642e01fSmrg * Copies the feedback classes from device "from" into device "to". Classes 2094642e01fSmrg * are duplicated (not just flipping the pointers). All feedback classes are 2104642e01fSmrg * linked lists, the full list is duplicated. 2114642e01fSmrg */ 2124642e01fSmrgstatic void 2134642e01fSmrgDeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) 2144642e01fSmrg{ 2154642e01fSmrg ClassesPtr classes; 2164642e01fSmrg 2174642e01fSmrg 2184642e01fSmrg if (from->intfeed) 2194642e01fSmrg { 2204642e01fSmrg IntegerFeedbackPtr *i, it; 2214642e01fSmrg 2224642e01fSmrg if (!to->intfeed) 2234642e01fSmrg { 2246747b715Smrg classes = to->unused_classes; 2254642e01fSmrg to->intfeed = classes->intfeed; 2266747b715Smrg classes->intfeed = NULL; 2274642e01fSmrg } 2284642e01fSmrg 2294642e01fSmrg i = &to->intfeed; 2304642e01fSmrg for (it = from->intfeed; it; it = it->next) 2314642e01fSmrg { 2324642e01fSmrg if (!(*i)) 2334642e01fSmrg { 2346747b715Smrg *i = calloc(1, sizeof(IntegerFeedbackClassRec)); 2354642e01fSmrg if (!(*i)) 2364642e01fSmrg { 2374642e01fSmrg ErrorF("[Xi] Cannot alloc memory for class copy."); 2384642e01fSmrg return; 2394642e01fSmrg } 2404642e01fSmrg } 2414642e01fSmrg (*i)->CtrlProc = it->CtrlProc; 2424642e01fSmrg (*i)->ctrl = it->ctrl; 2434642e01fSmrg 2444642e01fSmrg i = &(*i)->next; 2454642e01fSmrg } 2464642e01fSmrg } else if (to->intfeed && !from->intfeed) 2474642e01fSmrg { 2484642e01fSmrg ClassesPtr classes; 2496747b715Smrg classes = to->unused_classes; 2504642e01fSmrg classes->intfeed = to->intfeed; 2514642e01fSmrg to->intfeed = NULL; 2524642e01fSmrg } 2534642e01fSmrg 2544642e01fSmrg if (from->stringfeed) 2554642e01fSmrg { 2564642e01fSmrg StringFeedbackPtr *s, it; 2574642e01fSmrg 2584642e01fSmrg if (!to->stringfeed) 2594642e01fSmrg { 2606747b715Smrg classes = to->unused_classes; 2614642e01fSmrg to->stringfeed = classes->stringfeed; 2626747b715Smrg classes->stringfeed = NULL; 2634642e01fSmrg } 2644642e01fSmrg 2654642e01fSmrg s = &to->stringfeed; 2664642e01fSmrg for (it = from->stringfeed; it; it = it->next) 2674642e01fSmrg { 2684642e01fSmrg if (!(*s)) 2694642e01fSmrg { 2706747b715Smrg *s = calloc(1, sizeof(StringFeedbackClassRec)); 2714642e01fSmrg if (!(*s)) 2724642e01fSmrg { 2734642e01fSmrg ErrorF("[Xi] Cannot alloc memory for class copy."); 2744642e01fSmrg return; 2754642e01fSmrg } 2764642e01fSmrg } 2774642e01fSmrg (*s)->CtrlProc = it->CtrlProc; 2784642e01fSmrg (*s)->ctrl = it->ctrl; 2794642e01fSmrg 2804642e01fSmrg s = &(*s)->next; 2814642e01fSmrg } 2824642e01fSmrg } else if (to->stringfeed && !from->stringfeed) 2834642e01fSmrg { 2844642e01fSmrg ClassesPtr classes; 2856747b715Smrg classes = to->unused_classes; 2864642e01fSmrg classes->stringfeed = to->stringfeed; 2874642e01fSmrg to->stringfeed = NULL; 2884642e01fSmrg } 2894642e01fSmrg 2904642e01fSmrg if (from->bell) 2914642e01fSmrg { 2924642e01fSmrg BellFeedbackPtr *b, it; 2934642e01fSmrg 2944642e01fSmrg if (!to->bell) 2954642e01fSmrg { 2966747b715Smrg classes = to->unused_classes; 2974642e01fSmrg to->bell = classes->bell; 2986747b715Smrg classes->bell = NULL; 2994642e01fSmrg } 3004642e01fSmrg 3014642e01fSmrg b = &to->bell; 3024642e01fSmrg for (it = from->bell; it; it = it->next) 3034642e01fSmrg { 3044642e01fSmrg if (!(*b)) 3054642e01fSmrg { 3066747b715Smrg *b = calloc(1, sizeof(BellFeedbackClassRec)); 3074642e01fSmrg if (!(*b)) 3084642e01fSmrg { 3094642e01fSmrg ErrorF("[Xi] Cannot alloc memory for class copy."); 3104642e01fSmrg return; 3114642e01fSmrg } 3124642e01fSmrg } 3134642e01fSmrg (*b)->BellProc = it->BellProc; 3144642e01fSmrg (*b)->CtrlProc = it->CtrlProc; 3154642e01fSmrg (*b)->ctrl = it->ctrl; 3164642e01fSmrg 3174642e01fSmrg b = &(*b)->next; 3184642e01fSmrg } 3194642e01fSmrg } else if (to->bell && !from->bell) 3204642e01fSmrg { 3214642e01fSmrg ClassesPtr classes; 3226747b715Smrg classes = to->unused_classes; 3234642e01fSmrg classes->bell = to->bell; 3244642e01fSmrg to->bell = NULL; 3254642e01fSmrg } 3264642e01fSmrg 3274642e01fSmrg if (from->leds) 3284642e01fSmrg { 3294642e01fSmrg LedFeedbackPtr *l, it; 3304642e01fSmrg 3314642e01fSmrg if (!to->leds) 3324642e01fSmrg { 3336747b715Smrg classes = to->unused_classes; 3344642e01fSmrg to->leds = classes->leds; 3356747b715Smrg classes->leds = NULL; 3364642e01fSmrg } 3374642e01fSmrg 3384642e01fSmrg l = &to->leds; 3394642e01fSmrg for (it = from->leds; it; it = it->next) 3404642e01fSmrg { 3414642e01fSmrg if (!(*l)) 3424642e01fSmrg { 3436747b715Smrg *l = calloc(1, sizeof(LedFeedbackClassRec)); 3444642e01fSmrg if (!(*l)) 3454642e01fSmrg { 3464642e01fSmrg ErrorF("[Xi] Cannot alloc memory for class copy."); 3474642e01fSmrg return; 3484642e01fSmrg } 3494642e01fSmrg } 3504642e01fSmrg (*l)->CtrlProc = it->CtrlProc; 3514642e01fSmrg (*l)->ctrl = it->ctrl; 3524642e01fSmrg if ((*l)->xkb_sli) 3534642e01fSmrg XkbFreeSrvLedInfo((*l)->xkb_sli); 3544642e01fSmrg (*l)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, NULL, *l); 3554642e01fSmrg 3564642e01fSmrg l = &(*l)->next; 3574642e01fSmrg } 3584642e01fSmrg } else if (to->leds && !from->leds) 3594642e01fSmrg { 3604642e01fSmrg ClassesPtr classes; 3616747b715Smrg classes = to->unused_classes; 3624642e01fSmrg classes->leds = to->leds; 3634642e01fSmrg to->leds = NULL; 3644642e01fSmrg } 3654642e01fSmrg} 3664642e01fSmrg 3676747b715Smrgstatic void 3686747b715SmrgDeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to) 3694642e01fSmrg{ 3704642e01fSmrg ClassesPtr classes; 3714642e01fSmrg 3724642e01fSmrg /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the 3734642e01fSmrg * kbdfeed to be set up properly, so let's do the feedback classes first. 3744642e01fSmrg */ 3756747b715Smrg if (from->kbdfeed) 3766747b715Smrg { 3776747b715Smrg KbdFeedbackPtr *k, it; 3786747b715Smrg 3796747b715Smrg if (!to->kbdfeed) 3806747b715Smrg { 3816747b715Smrg classes = to->unused_classes; 3826747b715Smrg 3836747b715Smrg to->kbdfeed = classes->kbdfeed; 3846747b715Smrg if (!to->kbdfeed) 3856747b715Smrg InitKeyboardDeviceStruct(to, NULL, NULL, NULL); 3866747b715Smrg classes->kbdfeed = NULL; 3876747b715Smrg } 3886747b715Smrg 3896747b715Smrg k = &to->kbdfeed; 3906747b715Smrg for(it = from->kbdfeed; it; it = it->next) 3916747b715Smrg { 3926747b715Smrg if (!(*k)) 3936747b715Smrg { 3946747b715Smrg *k = calloc(1, sizeof(KbdFeedbackClassRec)); 3956747b715Smrg if (!*k) 3966747b715Smrg { 3976747b715Smrg ErrorF("[Xi] Cannot alloc memory for class copy."); 3986747b715Smrg return; 3996747b715Smrg } 4006747b715Smrg } 4016747b715Smrg (*k)->BellProc = it->BellProc; 4026747b715Smrg (*k)->CtrlProc = it->CtrlProc; 4036747b715Smrg (*k)->ctrl = it->ctrl; 4046747b715Smrg if ((*k)->xkb_sli) 4056747b715Smrg XkbFreeSrvLedInfo((*k)->xkb_sli); 4066747b715Smrg (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL); 4076747b715Smrg 4086747b715Smrg k = &(*k)->next; 4096747b715Smrg } 4106747b715Smrg } else if (to->kbdfeed && !from->kbdfeed) 4116747b715Smrg { 4126747b715Smrg ClassesPtr classes; 4136747b715Smrg classes = to->unused_classes; 4146747b715Smrg classes->kbdfeed = to->kbdfeed; 4156747b715Smrg to->kbdfeed = NULL; 4166747b715Smrg } 4174642e01fSmrg 4184642e01fSmrg if (from->key) 4194642e01fSmrg { 4204642e01fSmrg if (!to->key) 4214642e01fSmrg { 4226747b715Smrg classes = to->unused_classes; 4234642e01fSmrg to->key = classes->key; 4244642e01fSmrg if (!to->key) 4256747b715Smrg InitKeyboardDeviceStruct(to, NULL, NULL, NULL); 4266747b715Smrg else 4276747b715Smrg classes->key = NULL; 4286747b715Smrg } 4296747b715Smrg 4306747b715Smrg CopyKeyClass(from, to); 4316747b715Smrg } else if (to->key && !from->key) 4326747b715Smrg { 4336747b715Smrg ClassesPtr classes; 4346747b715Smrg classes = to->unused_classes; 4356747b715Smrg classes->key = to->key; 4366747b715Smrg to->key = NULL; 4376747b715Smrg } 4386747b715Smrg 4396747b715Smrg /* If a SrvLedInfoPtr's flags are XkbSLI_IsDefault, the names and maps 4406747b715Smrg * pointer point into the xkbInfo->desc struct. XkbCopySrvLedInfo 4416747b715Smrg * didn't update the pointers so we need to do it manually here. 4426747b715Smrg */ 4436747b715Smrg if (to->kbdfeed) 4446747b715Smrg { 4456747b715Smrg KbdFeedbackPtr k; 4466747b715Smrg 4476747b715Smrg for (k = to->kbdfeed; k; k = k->next) 4486747b715Smrg { 4496747b715Smrg if (!k->xkb_sli) 4506747b715Smrg continue; 4516747b715Smrg if (k->xkb_sli->flags & XkbSLI_IsDefault) 4524642e01fSmrg { 4536747b715Smrg k->xkb_sli->names = to->key->xkbInfo->desc->names->indicators; 4546747b715Smrg k->xkb_sli->maps = to->key->xkbInfo->desc->indicators->maps; 4556747b715Smrg } 4566747b715Smrg } 4576747b715Smrg } 4586747b715Smrg 4596747b715Smrg /* We can't just copy over the focus class. When an app sets the focus, 4606747b715Smrg * it'll do so on the master device. Copying the SDs focus means losing 4616747b715Smrg * the focus. 4626747b715Smrg * So we only copy the focus class if the device didn't have one, 4636747b715Smrg * otherwise we leave it as it is. 4646747b715Smrg */ 4656747b715Smrg if (from->focus) 4666747b715Smrg { 4676747b715Smrg if (!to->focus) 4686747b715Smrg { 4696747b715Smrg WindowPtr *oldTrace; 4706747b715Smrg 4716747b715Smrg classes = to->unused_classes; 4726747b715Smrg to->focus = classes->focus; 4736747b715Smrg if (!to->focus) 4746747b715Smrg { 4756747b715Smrg to->focus = calloc(1, sizeof(FocusClassRec)); 4766747b715Smrg if (!to->focus) 4774642e01fSmrg FatalError("[Xi] no memory for class shift.\n"); 4784642e01fSmrg } else 4796747b715Smrg classes->focus = NULL; 4806747b715Smrg 4816747b715Smrg oldTrace = to->focus->trace; 4826747b715Smrg memcpy(to->focus, from->focus, sizeof(FocusClassRec)); 4836747b715Smrg to->focus->trace = realloc(oldTrace, 4846747b715Smrg to->focus->traceSize * sizeof(WindowPtr)); 4856747b715Smrg if (!to->focus->trace && to->focus->traceSize) 4866747b715Smrg FatalError("[Xi] no memory for trace.\n"); 4876747b715Smrg memcpy(to->focus->trace, from->focus->trace, 4886747b715Smrg from->focus->traceSize * sizeof(WindowPtr)); 4896747b715Smrg to->focus->sourceid = from->id; 4904642e01fSmrg } 4916747b715Smrg } else if (to->focus) 4926747b715Smrg { 4936747b715Smrg ClassesPtr classes; 4946747b715Smrg classes = to->unused_classes; 4956747b715Smrg classes->focus = to->focus; 4966747b715Smrg to->focus = NULL; 4976747b715Smrg } 4984642e01fSmrg 4996747b715Smrg} 5004642e01fSmrg 5016747b715Smrgstatic void 5026747b715SmrgDeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to) 5036747b715Smrg{ 5046747b715Smrg ClassesPtr classes; 5056747b715Smrg 5066747b715Smrg /* Feedback classes must be copied first */ 5076747b715Smrg if (from->ptrfeed) 5086747b715Smrg { 5096747b715Smrg PtrFeedbackPtr *p, it; 5106747b715Smrg if (!to->ptrfeed) 5114642e01fSmrg { 5126747b715Smrg classes = to->unused_classes; 5136747b715Smrg to->ptrfeed = classes->ptrfeed; 5146747b715Smrg classes->ptrfeed = NULL; 5154642e01fSmrg } 5164642e01fSmrg 5176747b715Smrg p = &to->ptrfeed; 5186747b715Smrg for (it = from->ptrfeed; it; it = it->next) 5196747b715Smrg { 5206747b715Smrg if (!(*p)) 5216747b715Smrg { 5226747b715Smrg *p = calloc(1, sizeof(PtrFeedbackClassRec)); 5236747b715Smrg if (!*p) 5246747b715Smrg { 5256747b715Smrg ErrorF("[Xi] Cannot alloc memory for class copy."); 5266747b715Smrg return; 5276747b715Smrg } 5286747b715Smrg } 5296747b715Smrg (*p)->CtrlProc = it->CtrlProc; 5306747b715Smrg (*p)->ctrl = it->ctrl; 5314642e01fSmrg 5326747b715Smrg p = &(*p)->next; 5336747b715Smrg } 5346747b715Smrg } else if (to->ptrfeed && !from->ptrfeed) 5354642e01fSmrg { 5364642e01fSmrg ClassesPtr classes; 5376747b715Smrg classes = to->unused_classes; 5386747b715Smrg classes->ptrfeed = to->ptrfeed; 5396747b715Smrg to->ptrfeed = NULL; 5404642e01fSmrg } 5414642e01fSmrg 5424642e01fSmrg if (from->valuator) 5434642e01fSmrg { 5444642e01fSmrg ValuatorClassPtr v; 5454642e01fSmrg if (!to->valuator) 5464642e01fSmrg { 5476747b715Smrg classes = to->unused_classes; 5484642e01fSmrg to->valuator = classes->valuator; 5494642e01fSmrg if (to->valuator) 5504642e01fSmrg classes->valuator = NULL; 5514642e01fSmrg } 5524642e01fSmrg 5536747b715Smrg to->valuator = realloc(to->valuator, sizeof(ValuatorClassRec) + 5544642e01fSmrg from->valuator->numAxes * sizeof(AxisInfo) + 5556747b715Smrg from->valuator->numAxes * sizeof(double)); 5564642e01fSmrg v = to->valuator; 5574642e01fSmrg if (!v) 5584642e01fSmrg FatalError("[Xi] no memory for class shift.\n"); 5594642e01fSmrg 5604642e01fSmrg v->numAxes = from->valuator->numAxes; 5614642e01fSmrg v->axes = (AxisInfoPtr)&v[1]; 5624642e01fSmrg memcpy(v->axes, from->valuator->axes, v->numAxes * sizeof(AxisInfo)); 5634642e01fSmrg 5646747b715Smrg v->axisVal = (double*)(v->axes + from->valuator->numAxes); 5656747b715Smrg v->sourceid = from->id; 5666747b715Smrg v->mode = from->valuator->mode; 5674642e01fSmrg } else if (to->valuator && !from->valuator) 5684642e01fSmrg { 5694642e01fSmrg ClassesPtr classes; 5706747b715Smrg classes = to->unused_classes; 5714642e01fSmrg classes->valuator = to->valuator; 5724642e01fSmrg to->valuator = NULL; 5734642e01fSmrg } 5744642e01fSmrg 5754642e01fSmrg if (from->button) 5764642e01fSmrg { 5774642e01fSmrg if (!to->button) 5784642e01fSmrg { 5796747b715Smrg classes = to->unused_classes; 5804642e01fSmrg to->button = classes->button; 5814642e01fSmrg if (!to->button) 5824642e01fSmrg { 5836747b715Smrg to->button = calloc(1, sizeof(ButtonClassRec)); 5844642e01fSmrg if (!to->button) 5854642e01fSmrg FatalError("[Xi] no memory for class shift.\n"); 5864642e01fSmrg } else 5874642e01fSmrg classes->button = NULL; 5884642e01fSmrg } 5894642e01fSmrg 5904642e01fSmrg if (from->button->xkb_acts) 5914642e01fSmrg { 5924642e01fSmrg if (!to->button->xkb_acts) 5934642e01fSmrg { 5946747b715Smrg to->button->xkb_acts = calloc(1, sizeof(XkbAction)); 5954642e01fSmrg if (!to->button->xkb_acts) 5964642e01fSmrg FatalError("[Xi] not enough memory for xkb_acts.\n"); 5974642e01fSmrg } 5984642e01fSmrg memcpy(to->button->xkb_acts, from->button->xkb_acts, 5994642e01fSmrg sizeof(XkbAction)); 6004642e01fSmrg } else 6016747b715Smrg free(to->button->xkb_acts); 6026747b715Smrg 6036747b715Smrg memcpy(to->button->labels, from->button->labels, 6046747b715Smrg from->button->numButtons * sizeof(Atom)); 6056747b715Smrg to->button->sourceid = from->id; 6064642e01fSmrg } else if (to->button && !from->button) 6074642e01fSmrg { 6084642e01fSmrg ClassesPtr classes; 6096747b715Smrg classes = to->unused_classes; 6104642e01fSmrg classes->button = to->button; 6114642e01fSmrg to->button = NULL; 6124642e01fSmrg } 6134642e01fSmrg 6144642e01fSmrg if (from->proximity) 6154642e01fSmrg { 6164642e01fSmrg if (!to->proximity) 6174642e01fSmrg { 6186747b715Smrg classes = to->unused_classes; 6194642e01fSmrg to->proximity = classes->proximity; 6204642e01fSmrg if (!to->proximity) 6214642e01fSmrg { 6226747b715Smrg to->proximity = calloc(1, sizeof(ProximityClassRec)); 6234642e01fSmrg if (!to->proximity) 6244642e01fSmrg FatalError("[Xi] no memory for class shift.\n"); 6254642e01fSmrg } else 6264642e01fSmrg classes->proximity = NULL; 6274642e01fSmrg } 6284642e01fSmrg memcpy(to->proximity, from->proximity, sizeof(ProximityClassRec)); 6296747b715Smrg to->proximity->sourceid = from->id; 6304642e01fSmrg } else if (to->proximity) 6314642e01fSmrg { 6324642e01fSmrg ClassesPtr classes; 6336747b715Smrg classes = to->unused_classes; 6344642e01fSmrg classes->proximity = to->proximity; 6354642e01fSmrg to->proximity = NULL; 6364642e01fSmrg } 6374642e01fSmrg 6384642e01fSmrg if (from->absolute) 6394642e01fSmrg { 6404642e01fSmrg if (!to->absolute) 6414642e01fSmrg { 6426747b715Smrg classes = to->unused_classes; 6434642e01fSmrg to->absolute = classes->absolute; 6444642e01fSmrg if (!to->absolute) 6454642e01fSmrg { 6466747b715Smrg to->absolute = calloc(1, sizeof(AbsoluteClassRec)); 6474642e01fSmrg if (!to->absolute) 6484642e01fSmrg FatalError("[Xi] no memory for class shift.\n"); 6494642e01fSmrg } else 6504642e01fSmrg classes->absolute = NULL; 6514642e01fSmrg } 6524642e01fSmrg memcpy(to->absolute, from->absolute, sizeof(AbsoluteClassRec)); 6536747b715Smrg to->absolute->sourceid = from->id; 6544642e01fSmrg } else if (to->absolute) 6554642e01fSmrg { 6566747b715Smrg ClassesPtr classes; 6576747b715Smrg classes = to->unused_classes; 6586747b715Smrg classes->absolute = to->absolute; 6596747b715Smrg to->absolute = NULL; 6606747b715Smrg } 6616747b715Smrg} 6626747b715Smrg 6636747b715Smrg/** 6646747b715Smrg * Copies the CONTENT of the classes of device from into the classes in device 6656747b715Smrg * to. From and to are identical after finishing. 6666747b715Smrg * 6676747b715Smrg * If to does not have classes from currenly has, the classes are stored in 6686747b715Smrg * to's devPrivates system. Later, we recover it again from there if needed. 6696747b715Smrg * Saves a few memory allocations. 6706747b715Smrg */ 6716747b715Smrgvoid 6726747b715SmrgDeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to, DeviceChangedEvent *dce) 6736747b715Smrg{ 6746747b715Smrg /* generic feedback classes, not tied to pointer and/or keyboard */ 6756747b715Smrg DeepCopyFeedbackClasses(from, to); 6766747b715Smrg 6776747b715Smrg if ((dce->flags & DEVCHANGE_KEYBOARD_EVENT)) 6786747b715Smrg DeepCopyKeyboardClasses(from, to); 6796747b715Smrg if ((dce->flags & DEVCHANGE_POINTER_EVENT)) 6806747b715Smrg DeepCopyPointerClasses(from, to); 6816747b715Smrg} 6826747b715Smrg 6836747b715Smrg 6846747b715Smrg/** 6856747b715Smrg * Send an XI2 DeviceChangedEvent to all interested clients. 6866747b715Smrg */ 6876747b715Smrgvoid 6886747b715SmrgXISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChangedEvent *dce) 6896747b715Smrg{ 6906747b715Smrg xXIDeviceChangedEvent *dcce; 6916747b715Smrg int rc; 6926747b715Smrg 6936747b715Smrg rc = EventToXI2((InternalEvent*)dce, (xEvent**)&dcce); 6946747b715Smrg if (rc != Success) 6956747b715Smrg { 6966747b715Smrg ErrorF("[Xi] event conversion from DCE failed with code %d\n", rc); 6976747b715Smrg return; 6984642e01fSmrg } 6996747b715Smrg 7006747b715Smrg /* we don't actually swap if there's a NullClient, swapping is done 7016747b715Smrg * later when event is delivered. */ 7026747b715Smrg SendEventToAllWindows(master, XI_DeviceChangedMask, (xEvent*)dcce, 1); 7036747b715Smrg free(dcce); 7044642e01fSmrg} 7054642e01fSmrg 7066747b715Smrgstatic void 7076747b715SmrgChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce) 7086747b715Smrg{ 7096747b715Smrg DeviceIntPtr slave; 7106747b715Smrg int rc; 7116747b715Smrg 7126747b715Smrg /* For now, we don't have devices that change physically. */ 7136747b715Smrg if (!IsMaster(device)) 7146747b715Smrg return; 7156747b715Smrg 7166747b715Smrg rc = dixLookupDevice(&slave, dce->sourceid, serverClient, DixReadAccess); 7176747b715Smrg 7186747b715Smrg if (rc != Success) 7196747b715Smrg return; /* Device has disappeared */ 7206747b715Smrg 7216747b715Smrg if (!slave->u.master) 7226747b715Smrg return; /* set floating since the event */ 7236747b715Smrg 7246747b715Smrg if (slave->u.master->id != dce->masterid) 7256747b715Smrg return; /* not our slave anymore, don't care */ 7266747b715Smrg 7276747b715Smrg /* FIXME: we probably need to send a DCE for the new slave now */ 7286747b715Smrg 7296747b715Smrg device->public.devicePrivate = slave->public.devicePrivate; 7306747b715Smrg 7316747b715Smrg /* FIXME: the classes may have changed since we generated the event. */ 7326747b715Smrg DeepCopyDeviceClasses(slave, device, dce); 7336747b715Smrg XISendDeviceChangedEvent(slave, device, dce); 7346747b715Smrg} 7354642e01fSmrg 7364642e01fSmrg/** 7374642e01fSmrg * Update the device state according to the data in the event. 7384642e01fSmrg * 7394642e01fSmrg * return values are 7404642e01fSmrg * DEFAULT ... process as normal 7414642e01fSmrg * DONT_PROCESS ... return immediately from caller 7424642e01fSmrg */ 7434642e01fSmrg#define DEFAULT 0 7444642e01fSmrg#define DONT_PROCESS 1 7454642e01fSmrgint 7466747b715SmrgUpdateDeviceState(DeviceIntPtr device, DeviceEvent* event) 7474642e01fSmrg{ 7484642e01fSmrg int i; 7494642e01fSmrg int key = 0, 7506747b715Smrg bit = 0, 7516747b715Smrg last_valuator; 7524642e01fSmrg 7534642e01fSmrg KeyClassPtr k = NULL; 7544642e01fSmrg ButtonClassPtr b = NULL; 7554642e01fSmrg ValuatorClassPtr v = NULL; 7564642e01fSmrg 7576747b715Smrg /* This event is always the first we get, before the actual events with 7586747b715Smrg * the data. However, the way how the DDX is set up, "device" will 7596747b715Smrg * actually be the slave device that caused the event. 7606747b715Smrg */ 7616747b715Smrg switch(event->type) 7626747b715Smrg { 7636747b715Smrg case ET_DeviceChanged: 7646747b715Smrg ChangeMasterDeviceClasses(device, (DeviceChangedEvent*)event); 7656747b715Smrg return DONT_PROCESS; /* event has been sent already */ 7666747b715Smrg case ET_Motion: 7676747b715Smrg case ET_ButtonPress: 7686747b715Smrg case ET_ButtonRelease: 7696747b715Smrg case ET_KeyPress: 7706747b715Smrg case ET_KeyRelease: 7716747b715Smrg case ET_ProximityIn: 7726747b715Smrg case ET_ProximityOut: 7736747b715Smrg break; 7746747b715Smrg default: 7756747b715Smrg /* other events don't update the device */ 7766747b715Smrg return DEFAULT; 7776747b715Smrg } 7784642e01fSmrg 7794642e01fSmrg k = device->key; 7804642e01fSmrg v = device->valuator; 7814642e01fSmrg b = device->button; 7824642e01fSmrg 7836747b715Smrg key = event->detail.key; 7846747b715Smrg bit = 1 << (key & 7); 7854642e01fSmrg 7866747b715Smrg /* Update device axis */ 7876747b715Smrg /* Check valuators first */ 7886747b715Smrg last_valuator = -1; 7896747b715Smrg for (i = 0; i < MAX_VALUATORS; i++) 7904642e01fSmrg { 7916747b715Smrg if (BitIsOn(&event->valuators.mask, i)) 7926747b715Smrg { 7936747b715Smrg if (!v) 7946747b715Smrg { 7956747b715Smrg ErrorF("[Xi] Valuators reported for non-valuator device '%s'. " 7966747b715Smrg "Ignoring event.\n", device->name); 7976747b715Smrg return DONT_PROCESS; 7986747b715Smrg } else if (v->numAxes < i) 7996747b715Smrg { 8006747b715Smrg ErrorF("[Xi] Too many valuators reported for device '%s'. " 8016747b715Smrg "Ignoring event.\n", device->name); 8026747b715Smrg return DONT_PROCESS; 8036747b715Smrg } 8046747b715Smrg last_valuator = i; 8056747b715Smrg } 8064642e01fSmrg } 8074642e01fSmrg 8086747b715Smrg for (i = 0; i <= last_valuator && i < v->numAxes; i++) 8096747b715Smrg { 8106747b715Smrg if (BitIsOn(&event->valuators.mask, i)) 8116747b715Smrg { 8126747b715Smrg /* XXX: Relative/Absolute mode */ 8136747b715Smrg v->axisVal[i] = event->valuators.data[i]; 8146747b715Smrg v->axisVal[i] += (event->valuators.data_frac[i] * 1.0f / (1 << 16) / (1 << 16)); 8156747b715Smrg } 8164642e01fSmrg } 81705b261ecSmrg 8186747b715Smrg if (event->type == ET_KeyPress) { 81905b261ecSmrg if (!k) 8204642e01fSmrg return DONT_PROCESS; 82105b261ecSmrg 8226747b715Smrg /* don't allow ddx to generate multiple downs, but repeats are okay */ 8236747b715Smrg if (key_is_down(device, key, KEY_PROCESSED) && !event->key_repeat) 8246747b715Smrg return DONT_PROCESS; 8256747b715Smrg 8264642e01fSmrg if (device->valuator) 8274642e01fSmrg device->valuator->motionHintWindow = NullWindow; 8286747b715Smrg set_key_down(device, key, KEY_PROCESSED); 8296747b715Smrg } else if (event->type == ET_KeyRelease) { 83005b261ecSmrg if (!k) 8314642e01fSmrg return DONT_PROCESS; 83205b261ecSmrg 8336747b715Smrg if (!key_is_down(device, key, KEY_PROCESSED)) /* guard against duplicates */ 8344642e01fSmrg return DONT_PROCESS; 8354642e01fSmrg if (device->valuator) 8364642e01fSmrg device->valuator->motionHintWindow = NullWindow; 8376747b715Smrg set_key_up(device, key, KEY_PROCESSED); 8386747b715Smrg } else if (event->type == ET_ButtonPress) { 8396747b715Smrg Mask mask; 84005b261ecSmrg if (!b) 8414642e01fSmrg return DONT_PROCESS; 8424642e01fSmrg 8436747b715Smrg if (button_is_down(device, key, BUTTON_PROCESSED)) 8444642e01fSmrg return DONT_PROCESS; 8456747b715Smrg 8466747b715Smrg set_button_down(device, key, BUTTON_PROCESSED); 8474642e01fSmrg if (device->valuator) 8484642e01fSmrg device->valuator->motionHintWindow = NullWindow; 8494642e01fSmrg if (!b->map[key]) 8504642e01fSmrg return DONT_PROCESS; 8514642e01fSmrg b->buttonsDown++; 85205b261ecSmrg b->motionMask = DeviceButtonMotionMask; 8534642e01fSmrg if (b->map[key] <= 5) 8544642e01fSmrg b->state |= (Button1Mask >> 1) << b->map[key]; 8556747b715Smrg 8566747b715Smrg /* Add state and motionMask to the filter for this event */ 8576747b715Smrg mask = DevicePointerMotionMask | b->state | b->motionMask; 8586747b715Smrg SetMaskForEvent(device->id, mask, DeviceMotionNotify); 8596747b715Smrg mask = PointerMotionMask | b->state | b->motionMask; 8606747b715Smrg SetMaskForEvent(device->id, mask, MotionNotify); 8616747b715Smrg } else if (event->type == ET_ButtonRelease) { 8626747b715Smrg Mask mask; 86305b261ecSmrg if (!b) 8644642e01fSmrg return DONT_PROCESS; 8654642e01fSmrg 8666747b715Smrg if (!button_is_down(device, key, BUTTON_PROCESSED)) 8674642e01fSmrg return DONT_PROCESS; 8686747b715Smrg if (IsMaster(device)) { 8694642e01fSmrg DeviceIntPtr sd; 8704642e01fSmrg 8714642e01fSmrg /* 8724642e01fSmrg * Leave the button down if any slave has the 8734642e01fSmrg * button still down. Note that this depends on the 8744642e01fSmrg * event being delivered through the slave first 8754642e01fSmrg */ 8764642e01fSmrg for (sd = inputInfo.devices; sd; sd = sd->next) { 8776747b715Smrg if (IsMaster(sd) || sd->u.master != device) 8784642e01fSmrg continue; 8796747b715Smrg if (!sd->button) 8806747b715Smrg continue; 8818223e2f2Smrg for (i = 1; i <= sd->button->numButtons; i++) 8828223e2f2Smrg if (sd->button->map[i] == key && 8838223e2f2Smrg button_is_down(sd, i, BUTTON_PROCESSED)) 8848223e2f2Smrg return DONT_PROCESS; 8854642e01fSmrg } 8864642e01fSmrg } 8876747b715Smrg set_button_up(device, key, BUTTON_PROCESSED); 8884642e01fSmrg if (device->valuator) 8894642e01fSmrg device->valuator->motionHintWindow = NullWindow; 8904642e01fSmrg if (!b->map[key]) 8914642e01fSmrg return DONT_PROCESS; 89205b261ecSmrg if (b->buttonsDown >= 1 && !--b->buttonsDown) 89305b261ecSmrg b->motionMask = 0; 8944642e01fSmrg if (b->map[key] <= 5) 8954642e01fSmrg b->state &= ~((Button1Mask >> 1) << b->map[key]); 8966747b715Smrg 8976747b715Smrg /* Add state and motionMask to the filter for this event */ 8986747b715Smrg mask = DevicePointerMotionMask | b->state | b->motionMask; 8996747b715Smrg SetMaskForEvent(device->id, mask, DeviceMotionNotify); 9006747b715Smrg mask = PointerMotionMask | b->state | b->motionMask; 9016747b715Smrg SetMaskForEvent(device->id, mask, MotionNotify); 9026747b715Smrg } else if (event->type == ET_ProximityIn) 9034642e01fSmrg device->valuator->mode &= ~OutOfProximity; 9046747b715Smrg else if (event->type == ET_ProximityOut) 9054642e01fSmrg device->valuator->mode |= OutOfProximity; 9064642e01fSmrg 9074642e01fSmrg return DEFAULT; 9084642e01fSmrg} 9094642e01fSmrg 9106747b715Smrgstatic void 9116747b715SmrgProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device) 9126747b715Smrg{ 9136747b715Smrg GrabPtr grab = device->deviceGrab.grab; 9146747b715Smrg 9156747b715Smrg if (grab) 9166747b715Smrg DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE); 9176747b715Smrg else { /* deliver to all root windows */ 9186747b715Smrg xEvent *xi; 9196747b715Smrg int i; 9206747b715Smrg 9216747b715Smrg i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi); 9226747b715Smrg if (i != Success) 9236747b715Smrg { 9246747b715Smrg ErrorF("[Xi] %s: XI2 conversion failed in ProcessRawEvent (%d)\n", 9256747b715Smrg device->name, i); 9266747b715Smrg return; 9276747b715Smrg } 9286747b715Smrg 9296747b715Smrg for (i = 0; i < screenInfo.numScreens; i++) 9306747b715Smrg DeliverEventsToWindow(device, screenInfo.screens[i]->root, xi, 1, 9316747b715Smrg GetEventFilter(device, xi), NULL); 9326747b715Smrg free(xi); 9336747b715Smrg } 9346747b715Smrg} 9356747b715Smrg 9364642e01fSmrg/** 9374642e01fSmrg * Main device event processing function. 9384642e01fSmrg * Called from when processing the events from the event queue. 9394642e01fSmrg * 9404642e01fSmrg */ 9414642e01fSmrgvoid 9426747b715SmrgProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device) 9434642e01fSmrg{ 9446747b715Smrg GrabPtr grab; 9454642e01fSmrg Bool deactivateDeviceGrab = FALSE; 9464642e01fSmrg int key = 0, rootX, rootY; 9474642e01fSmrg ButtonClassPtr b; 9484642e01fSmrg KeyClassPtr k; 9494642e01fSmrg ValuatorClassPtr v; 9504642e01fSmrg int ret = 0; 9516747b715Smrg int state, i; 9524642e01fSmrg DeviceIntPtr mouse = NULL, kbd = NULL; 9536747b715Smrg DeviceEvent *event = &ev->device_event; 9546747b715Smrg 9556747b715Smrg CHECKEVENT(ev); 9566747b715Smrg 9576747b715Smrg if (ev->any.type == ET_RawKeyPress || 9586747b715Smrg ev->any.type == ET_RawKeyRelease || 9596747b715Smrg ev->any.type == ET_RawButtonPress || 9606747b715Smrg ev->any.type == ET_RawButtonRelease || 9616747b715Smrg ev->any.type == ET_RawMotion) 9626747b715Smrg { 9636747b715Smrg ProcessRawEvent(&ev->raw_event, device); 9646747b715Smrg return; 9656747b715Smrg } 9664642e01fSmrg 9674642e01fSmrg if (IsPointerDevice(device)) 9684642e01fSmrg { 9694642e01fSmrg kbd = GetPairedDevice(device); 9704642e01fSmrg mouse = device; 9714642e01fSmrg if (!kbd->key) /* can happen with floating SDs */ 9724642e01fSmrg kbd = NULL; 9734642e01fSmrg } else 9744642e01fSmrg { 9754642e01fSmrg mouse = GetPairedDevice(device); 9764642e01fSmrg kbd = device; 9774642e01fSmrg if (!mouse->valuator || !mouse->button) /* may be float. SDs */ 9784642e01fSmrg mouse = NULL; 9794642e01fSmrg } 9804642e01fSmrg 9814642e01fSmrg /* State needs to be assembled BEFORE the device is updated. */ 9826747b715Smrg state = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0; 9836747b715Smrg state |= (mouse && mouse->button) ? (mouse->button->state) : 0; 9846747b715Smrg 9856747b715Smrg for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) 9866747b715Smrg if (BitIsOn(mouse->button->down, i)) 9876747b715Smrg SetBit(event->buttons, i); 9886747b715Smrg 9896747b715Smrg if (kbd && kbd->key) 9906747b715Smrg { 9916747b715Smrg XkbStatePtr state; 9926747b715Smrg /* we need the state before the event happens */ 9936747b715Smrg if (event->type == ET_KeyPress || event->type == ET_KeyRelease) 9946747b715Smrg state = &kbd->key->xkbInfo->prev_state; 9956747b715Smrg else 9966747b715Smrg state = &kbd->key->xkbInfo->state; 9976747b715Smrg 9986747b715Smrg event->mods.base = state->base_mods; 9996747b715Smrg event->mods.latched = state->latched_mods; 10006747b715Smrg event->mods.locked = state->locked_mods; 10016747b715Smrg event->mods.effective = state->mods; 10026747b715Smrg 10036747b715Smrg event->group.base = state->base_group; 10046747b715Smrg event->group.latched = state->latched_group; 10056747b715Smrg event->group.locked = state->locked_group; 10066747b715Smrg event->group.effective = state->group; 10076747b715Smrg } 10084642e01fSmrg 10096747b715Smrg ret = UpdateDeviceState(device, event); 10104642e01fSmrg if (ret == DONT_PROCESS) 10114642e01fSmrg return; 10124642e01fSmrg 10134642e01fSmrg v = device->valuator; 10144642e01fSmrg b = device->button; 10154642e01fSmrg k = device->key; 10164642e01fSmrg 10176747b715Smrg if (IsMaster(device) || !device->u.master) 10186747b715Smrg CheckMotion(event, device); 10194642e01fSmrg 10206747b715Smrg switch (event->type) 10216747b715Smrg { 10226747b715Smrg case ET_Motion: 10236747b715Smrg case ET_ButtonPress: 10246747b715Smrg case ET_ButtonRelease: 10256747b715Smrg case ET_KeyPress: 10266747b715Smrg case ET_KeyRelease: 10276747b715Smrg case ET_ProximityIn: 10286747b715Smrg case ET_ProximityOut: 10296747b715Smrg GetSpritePosition(device, &rootX, &rootY); 10306747b715Smrg event->root_x = rootX; 10316747b715Smrg event->root_y = rootY; 10326747b715Smrg NoticeEventTime((InternalEvent*)event); 10336747b715Smrg event->corestate = state; 10346747b715Smrg key = event->detail.key; 10356747b715Smrg break; 10366747b715Smrg default: 10376747b715Smrg break; 10384642e01fSmrg } 10396747b715Smrg 10406747b715Smrg if (DeviceEventCallback && !syncEvents.playingEvents) { 10414642e01fSmrg DeviceEventInfoRec eventinfo; 10426747b715Smrg SpritePtr pSprite = device->spriteInfo->sprite; 10434642e01fSmrg 10446747b715Smrg /* see comment in EnqueueEvents regarding the next three lines */ 10456747b715Smrg if (ev->any.type == ET_Motion) 10466747b715Smrg ev->device_event.root = pSprite->hotPhys.pScreen->root->drawable.id; 10474642e01fSmrg 10486747b715Smrg eventinfo.device = device; 10496747b715Smrg eventinfo.event = ev; 10506747b715Smrg CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo); 10514642e01fSmrg } 10524642e01fSmrg 10536747b715Smrg grab = device->deviceGrab.grab; 10544642e01fSmrg 10556747b715Smrg switch(event->type) 10566747b715Smrg { 10576747b715Smrg case ET_KeyPress: 10586747b715Smrg if (!grab && CheckDeviceGrabs(device, event, 0)) { 10596747b715Smrg device->deviceGrab.activatingKey = key; 10606747b715Smrg return; 10616747b715Smrg } 10626747b715Smrg break; 10636747b715Smrg case ET_KeyRelease: 10646747b715Smrg if (grab && device->deviceGrab.fromPassiveGrab && 10656747b715Smrg (key == device->deviceGrab.activatingKey) && 10666747b715Smrg (device->deviceGrab.grab->type == KeyPress || 10676747b715Smrg device->deviceGrab.grab->type == DeviceKeyPress || 10686747b715Smrg device->deviceGrab.grab->type == XI_KeyPress)) 10696747b715Smrg deactivateDeviceGrab = TRUE; 10706747b715Smrg break; 10716747b715Smrg case ET_ButtonPress: 10726747b715Smrg event->detail.button = b->map[key]; 10736747b715Smrg if (!event->detail.button) { /* there's no button 0 */ 10746747b715Smrg event->detail.button = key; 10756747b715Smrg return; 10766747b715Smrg } 10776747b715Smrg if (!grab && CheckDeviceGrabs(device, event, 0)) 10786747b715Smrg { 10796747b715Smrg /* if a passive grab was activated, the event has been sent 10806747b715Smrg * already */ 10816747b715Smrg return; 10826747b715Smrg } 10836747b715Smrg break; 10846747b715Smrg case ET_ButtonRelease: 10856747b715Smrg event->detail.button = b->map[key]; 10866747b715Smrg if (!event->detail.button) { /* there's no button 0 */ 10876747b715Smrg event->detail.button = key; 10886747b715Smrg return; 10896747b715Smrg } 10906747b715Smrg if (grab && !b->buttonsDown && 10916747b715Smrg device->deviceGrab.fromPassiveGrab && 10926747b715Smrg (device->deviceGrab.grab->type == ButtonPress || 10936747b715Smrg device->deviceGrab.grab->type == DeviceButtonPress || 10946747b715Smrg device->deviceGrab.grab->type == XI_ButtonPress)) 10956747b715Smrg deactivateDeviceGrab = TRUE; 10966747b715Smrg default: 10976747b715Smrg break; 10984642e01fSmrg } 109905b261ecSmrg 11006747b715Smrg 110105b261ecSmrg if (grab) 11026747b715Smrg DeliverGrabbedEvent((InternalEvent*)event, device, deactivateDeviceGrab); 11036747b715Smrg else if (device->focus && !IsPointerEvent((InternalEvent*)ev)) 11046747b715Smrg DeliverFocusedEvent(device, (InternalEvent*)event, 11056747b715Smrg GetSpriteWindow(device)); 110605b261ecSmrg else 11076747b715Smrg DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent*)event, 11086747b715Smrg NullGrab, NullWindow, device); 110905b261ecSmrg 111005b261ecSmrg if (deactivateDeviceGrab == TRUE) 11114642e01fSmrg (*device->deviceGrab.DeactivateGrab) (device); 11126747b715Smrg event->detail.key = key; 111305b261ecSmrg} 111405b261ecSmrg 11156747b715Smrgint 111605b261ecSmrgInitProximityClassDeviceStruct(DeviceIntPtr dev) 111705b261ecSmrg{ 111805b261ecSmrg ProximityClassPtr proxc; 111905b261ecSmrg 11206747b715Smrg proxc = (ProximityClassPtr) malloc(sizeof(ProximityClassRec)); 112105b261ecSmrg if (!proxc) 112205b261ecSmrg return FALSE; 11236747b715Smrg proxc->sourceid = dev->id; 112405b261ecSmrg dev->proximity = proxc; 112505b261ecSmrg return TRUE; 112605b261ecSmrg} 112705b261ecSmrg 11284642e01fSmrg/** 11294642e01fSmrg * Initialise the device's valuators. The memory must already be allocated, 11304642e01fSmrg * this function merely inits the matching axis (specified through axnum) to 11314642e01fSmrg * sane values. 11324642e01fSmrg * 11334642e01fSmrg * It is a condition that (minval < maxval). 11344642e01fSmrg * 11354642e01fSmrg * @see InitValuatorClassDeviceStruct 11364642e01fSmrg */ 11376747b715Smrgvoid 11386747b715SmrgInitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval, 113905b261ecSmrg int resolution, int min_res, int max_res) 114005b261ecSmrg{ 114105b261ecSmrg AxisInfoPtr ax; 11424642e01fSmrg 11434642e01fSmrg if (!dev || !dev->valuator || minval > maxval) 114405b261ecSmrg return; 11456747b715Smrg if (axnum >= dev->valuator->numAxes) 11466747b715Smrg return; 114705b261ecSmrg 114805b261ecSmrg ax = dev->valuator->axes + axnum; 114905b261ecSmrg 115005b261ecSmrg ax->min_value = minval; 115105b261ecSmrg ax->max_value = maxval; 115205b261ecSmrg ax->resolution = resolution; 115305b261ecSmrg ax->min_resolution = min_res; 115405b261ecSmrg ax->max_resolution = max_res; 11556747b715Smrg ax->label = label; 115605b261ecSmrg} 115705b261ecSmrg 115805b261ecSmrgstatic void 115905b261ecSmrgFixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, 116005b261ecSmrg ButtonClassPtr b, ValuatorClassPtr v, int first) 116105b261ecSmrg{ 116205b261ecSmrg ev->type = DeviceStateNotify; 116305b261ecSmrg ev->deviceid = dev->id; 116405b261ecSmrg ev->time = currentTime.milliseconds; 116505b261ecSmrg ev->classes_reported = 0; 116605b261ecSmrg ev->num_keys = 0; 116705b261ecSmrg ev->num_buttons = 0; 116805b261ecSmrg ev->num_valuators = 0; 116905b261ecSmrg 117005b261ecSmrg if (b) { 117105b261ecSmrg ev->classes_reported |= (1 << ButtonClass); 117205b261ecSmrg ev->num_buttons = b->numButtons; 11734642e01fSmrg memcpy((char*)ev->buttons, (char*)b->down, 4); 117405b261ecSmrg } else if (k) { 117505b261ecSmrg ev->classes_reported |= (1 << KeyClass); 11766747b715Smrg ev->num_keys = k->xkbInfo->desc->max_key_code - 11776747b715Smrg k->xkbInfo->desc->min_key_code; 117805b261ecSmrg memmove((char *)&ev->keys[0], (char *)k->down, 4); 117905b261ecSmrg } 118005b261ecSmrg if (v) { 118105b261ecSmrg int nval = v->numAxes - first; 118205b261ecSmrg 118305b261ecSmrg ev->classes_reported |= (1 << ValuatorClass); 118405b261ecSmrg ev->classes_reported |= (dev->valuator->mode << ModeBitsShift); 118505b261ecSmrg ev->num_valuators = nval < 3 ? nval : 3; 118605b261ecSmrg switch (ev->num_valuators) { 118705b261ecSmrg case 3: 118805b261ecSmrg ev->valuator2 = v->axisVal[first + 2]; 118905b261ecSmrg case 2: 119005b261ecSmrg ev->valuator1 = v->axisVal[first + 1]; 119105b261ecSmrg case 1: 119205b261ecSmrg ev->valuator0 = v->axisVal[first]; 119305b261ecSmrg break; 119405b261ecSmrg } 119505b261ecSmrg } 119605b261ecSmrg} 119705b261ecSmrg 119805b261ecSmrgstatic void 119905b261ecSmrgFixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, 120005b261ecSmrg int first) 120105b261ecSmrg{ 120205b261ecSmrg int nval = v->numAxes - first; 120305b261ecSmrg 120405b261ecSmrg ev->type = DeviceValuator; 120505b261ecSmrg ev->deviceid = dev->id; 120605b261ecSmrg ev->num_valuators = nval < 3 ? nval : 3; 120705b261ecSmrg ev->first_valuator = first; 120805b261ecSmrg switch (ev->num_valuators) { 120905b261ecSmrg case 3: 121005b261ecSmrg ev->valuator2 = v->axisVal[first + 2]; 121105b261ecSmrg case 2: 121205b261ecSmrg ev->valuator1 = v->axisVal[first + 1]; 121305b261ecSmrg case 1: 121405b261ecSmrg ev->valuator0 = v->axisVal[first]; 121505b261ecSmrg break; 121605b261ecSmrg } 121705b261ecSmrg first += ev->num_valuators; 121805b261ecSmrg} 121905b261ecSmrg 122005b261ecSmrgvoid 122105b261ecSmrgDeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, 122205b261ecSmrg WindowPtr pWin) 122305b261ecSmrg{ 122405b261ecSmrg deviceFocus event; 12256747b715Smrg xXIFocusInEvent *xi2event; 12266747b715Smrg DeviceIntPtr mouse; 12276747b715Smrg int btlen, len, i; 12286747b715Smrg 12296747b715Smrg mouse = (IsMaster(dev) || dev->u.master) ? GetMaster(dev, MASTER_POINTER) : dev; 12306747b715Smrg 12316747b715Smrg /* XI 2 event */ 12326747b715Smrg btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; 12336747b715Smrg btlen = bytes_to_int32(btlen); 12346747b715Smrg len = sizeof(xXIFocusInEvent) + btlen * 4; 12356747b715Smrg 12366747b715Smrg xi2event = calloc(1, len); 12376747b715Smrg xi2event->type = GenericEvent; 12386747b715Smrg xi2event->extension = IReqCode; 12396747b715Smrg xi2event->evtype = type; 12406747b715Smrg xi2event->length = bytes_to_int32(len - sizeof(xEvent)); 12416747b715Smrg xi2event->buttons_len = btlen; 12426747b715Smrg xi2event->detail = detail; 12436747b715Smrg xi2event->time = currentTime.milliseconds; 12446747b715Smrg xi2event->deviceid = dev->id; 12456747b715Smrg xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */ 12466747b715Smrg xi2event->mode = mode; 12476747b715Smrg xi2event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0); 12486747b715Smrg xi2event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0); 12496747b715Smrg 12506747b715Smrg for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) 12516747b715Smrg if (BitIsOn(mouse->button->down, i)) 12526747b715Smrg SetBit(&xi2event[1], i); 12536747b715Smrg 12546747b715Smrg if (dev->key) 12556747b715Smrg { 12566747b715Smrg xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods; 12576747b715Smrg xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods; 12586747b715Smrg xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods; 12596747b715Smrg xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods; 12606747b715Smrg 12616747b715Smrg xi2event->group.base_group = dev->key->xkbInfo->state.base_group; 12626747b715Smrg xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group; 12636747b715Smrg xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group; 12646747b715Smrg xi2event->group.effective_group = dev->key->xkbInfo->state.group; 12656747b715Smrg } 126605b261ecSmrg 12676747b715Smrg FixUpEventFromWindow(dev, (xEvent*)xi2event, pWin, None, FALSE); 126805b261ecSmrg 12696747b715Smrg DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1, 12706747b715Smrg GetEventFilter(dev, (xEvent*)xi2event), NullGrab); 12716747b715Smrg 12726747b715Smrg free(xi2event); 12736747b715Smrg 12746747b715Smrg /* XI 1.x event */ 127505b261ecSmrg event.deviceid = dev->id; 127605b261ecSmrg event.mode = mode; 12776747b715Smrg event.type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut; 127805b261ecSmrg event.detail = detail; 127905b261ecSmrg event.window = pWin->drawable.id; 128005b261ecSmrg event.time = currentTime.milliseconds; 128105b261ecSmrg 12826747b715Smrg DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1, 12836747b715Smrg DeviceFocusChangeMask, NullGrab); 128405b261ecSmrg 128505b261ecSmrg if ((type == DeviceFocusIn) && 128605b261ecSmrg (wOtherInputMasks(pWin)) && 128705b261ecSmrg (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask)) 128805b261ecSmrg { 128905b261ecSmrg int evcount = 1; 129005b261ecSmrg deviceStateNotify *ev, *sev; 129105b261ecSmrg deviceKeyStateNotify *kev; 129205b261ecSmrg deviceButtonStateNotify *bev; 129305b261ecSmrg 129405b261ecSmrg KeyClassPtr k; 129505b261ecSmrg ButtonClassPtr b; 129605b261ecSmrg ValuatorClassPtr v; 129705b261ecSmrg int nval = 0, nkeys = 0, nbuttons = 0, first = 0; 129805b261ecSmrg 129905b261ecSmrg if ((b = dev->button) != NULL) { 130005b261ecSmrg nbuttons = b->numButtons; 130105b261ecSmrg if (nbuttons > 32) 130205b261ecSmrg evcount++; 130305b261ecSmrg } 130405b261ecSmrg if ((k = dev->key) != NULL) { 13056747b715Smrg nkeys = k->xkbInfo->desc->max_key_code - 13066747b715Smrg k->xkbInfo->desc->min_key_code; 130705b261ecSmrg if (nkeys > 32) 130805b261ecSmrg evcount++; 130905b261ecSmrg if (nbuttons > 0) { 131005b261ecSmrg evcount++; 131105b261ecSmrg } 131205b261ecSmrg } 131305b261ecSmrg if ((v = dev->valuator) != NULL) { 131405b261ecSmrg nval = v->numAxes; 131505b261ecSmrg 131605b261ecSmrg if (nval > 3) 131705b261ecSmrg evcount++; 131805b261ecSmrg if (nval > 6) { 131905b261ecSmrg if (!(k && b)) 132005b261ecSmrg evcount++; 132105b261ecSmrg if (nval > 9) 132205b261ecSmrg evcount += ((nval - 7) / 3); 132305b261ecSmrg } 132405b261ecSmrg } 132505b261ecSmrg 13266747b715Smrg sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent)); 132705b261ecSmrg FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); 132805b261ecSmrg 132905b261ecSmrg if (b != NULL) { 133005b261ecSmrg FixDeviceStateNotify(dev, ev++, NULL, b, v, first); 133105b261ecSmrg first += 3; 133205b261ecSmrg nval -= 3; 133305b261ecSmrg if (nbuttons > 32) { 133405b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 133505b261ecSmrg bev = (deviceButtonStateNotify *) ev++; 133605b261ecSmrg bev->type = DeviceButtonStateNotify; 133705b261ecSmrg bev->deviceid = dev->id; 13384642e01fSmrg memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4); 133905b261ecSmrg } 134005b261ecSmrg if (nval > 0) { 134105b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 134205b261ecSmrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 134305b261ecSmrg first += 3; 134405b261ecSmrg nval -= 3; 134505b261ecSmrg } 134605b261ecSmrg } 134705b261ecSmrg 134805b261ecSmrg if (k != NULL) { 134905b261ecSmrg FixDeviceStateNotify(dev, ev++, k, NULL, v, first); 135005b261ecSmrg first += 3; 135105b261ecSmrg nval -= 3; 135205b261ecSmrg if (nkeys > 32) { 135305b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 135405b261ecSmrg kev = (deviceKeyStateNotify *) ev++; 135505b261ecSmrg kev->type = DeviceKeyStateNotify; 135605b261ecSmrg kev->deviceid = dev->id; 135705b261ecSmrg memmove((char *)&kev->keys[0], (char *)&k->down[4], 28); 135805b261ecSmrg } 135905b261ecSmrg if (nval > 0) { 136005b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 136105b261ecSmrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 136205b261ecSmrg first += 3; 136305b261ecSmrg nval -= 3; 136405b261ecSmrg } 136505b261ecSmrg } 136605b261ecSmrg 136705b261ecSmrg while (nval > 0) { 136805b261ecSmrg FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); 136905b261ecSmrg first += 3; 137005b261ecSmrg nval -= 3; 137105b261ecSmrg if (nval > 0) { 137205b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 137305b261ecSmrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 137405b261ecSmrg first += 3; 137505b261ecSmrg nval -= 3; 137605b261ecSmrg } 137705b261ecSmrg } 137805b261ecSmrg 13796747b715Smrg DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount, 13806747b715Smrg DeviceStateNotifyMask, NullGrab); 13816747b715Smrg free(sev); 138205b261ecSmrg } 138305b261ecSmrg} 138405b261ecSmrg 138505b261ecSmrgint 13866747b715SmrgCheckGrabValues(ClientPtr client, GrabParameters* param) 138705b261ecSmrg{ 13886747b715Smrg if (param->grabtype != GRABTYPE_CORE && 13896747b715Smrg param->grabtype != GRABTYPE_XI && 13906747b715Smrg param->grabtype != GRABTYPE_XI2) 13916747b715Smrg { 13926747b715Smrg ErrorF("[Xi] grabtype is invalid. This is a bug.\n"); 13936747b715Smrg return BadImplementation; 13946747b715Smrg } 139505b261ecSmrg 13966747b715Smrg if ((param->this_device_mode != GrabModeSync) && 13976747b715Smrg (param->this_device_mode != GrabModeAsync)) { 13986747b715Smrg client->errorValue = param->this_device_mode; 139905b261ecSmrg return BadValue; 140005b261ecSmrg } 14016747b715Smrg if ((param->other_devices_mode != GrabModeSync) && 14026747b715Smrg (param->other_devices_mode != GrabModeAsync)) { 14036747b715Smrg client->errorValue = param->other_devices_mode; 140405b261ecSmrg return BadValue; 140505b261ecSmrg } 14066747b715Smrg 14076747b715Smrg if (param->grabtype != GRABTYPE_XI2 && (param->modifiers != AnyModifier) && 14086747b715Smrg (param->modifiers & ~AllModifiersMask)) { 14096747b715Smrg client->errorValue = param->modifiers; 141005b261ecSmrg return BadValue; 141105b261ecSmrg } 14126747b715Smrg 14136747b715Smrg if ((param->ownerEvents != xFalse) && (param->ownerEvents != xTrue)) { 14146747b715Smrg client->errorValue = param->ownerEvents; 141505b261ecSmrg return BadValue; 141605b261ecSmrg } 14176747b715Smrg return Success; 14186747b715Smrg} 14196747b715Smrg 14206747b715Smrgint 14216747b715SmrgGrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, 14226747b715Smrg int button, GrabParameters *param, GrabType grabtype, 14236747b715Smrg GrabMask *mask) 14246747b715Smrg{ 14256747b715Smrg WindowPtr pWin, confineTo; 14266747b715Smrg CursorPtr cursor; 14276747b715Smrg GrabPtr grab; 14286747b715Smrg int rc, type = -1; 14296747b715Smrg Mask access_mode = DixGrabAccess; 14306747b715Smrg 14316747b715Smrg rc = CheckGrabValues(client, param); 143205b261ecSmrg if (rc != Success) 143305b261ecSmrg return rc; 14346747b715Smrg if (param->confineTo == None) 143505b261ecSmrg confineTo = NullWindow; 143605b261ecSmrg else { 14376747b715Smrg rc = dixLookupWindow(&confineTo, param->confineTo, client, DixSetAttrAccess); 143805b261ecSmrg if (rc != Success) 143905b261ecSmrg return rc; 144005b261ecSmrg } 14416747b715Smrg if (param->cursor == None) 144205b261ecSmrg cursor = NullCursor; 144305b261ecSmrg else { 14446747b715Smrg rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, 14456747b715Smrg RT_CURSOR, client, DixUseAccess); 14464642e01fSmrg if (rc != Success) 14474642e01fSmrg { 14486747b715Smrg client->errorValue = param->cursor; 14496747b715Smrg return rc; 145005b261ecSmrg } 14514642e01fSmrg access_mode |= DixForceAccess; 145205b261ecSmrg } 14536747b715Smrg if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 14544642e01fSmrg access_mode |= DixFreezeAccess; 14554642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 14566747b715Smrg if (rc != Success) 14576747b715Smrg return rc; 14586747b715Smrg rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 14594642e01fSmrg if (rc != Success) 14604642e01fSmrg return rc; 146105b261ecSmrg 14626747b715Smrg if (grabtype == GRABTYPE_XI) 14636747b715Smrg type = DeviceButtonPress; 14646747b715Smrg else if (grabtype == GRABTYPE_XI2) 14656747b715Smrg type = XI_ButtonPress; 14666747b715Smrg 14676747b715Smrg grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, 14686747b715Smrg mask, param, type, button, confineTo, cursor); 146905b261ecSmrg if (!grab) 147005b261ecSmrg return BadAlloc; 14714642e01fSmrg return AddPassiveGrabToList(client, grab); 147205b261ecSmrg} 147305b261ecSmrg 14746747b715Smrg/** 14756747b715Smrg * Grab the given key. If grabtype is GRABTYPE_XI, the key is a keycode. If 14766747b715Smrg * grabtype is GRABTYPE_XI2, the key is a keysym. 14776747b715Smrg */ 147805b261ecSmrgint 14796747b715SmrgGrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, 14806747b715Smrg int key, GrabParameters *param, GrabType grabtype, GrabMask *mask) 148105b261ecSmrg{ 148205b261ecSmrg WindowPtr pWin; 148305b261ecSmrg GrabPtr grab; 148405b261ecSmrg KeyClassPtr k = dev->key; 14854642e01fSmrg Mask access_mode = DixGrabAccess; 14866747b715Smrg int rc, type = -1; 148705b261ecSmrg 14886747b715Smrg rc = CheckGrabValues(client, param); 14896747b715Smrg if (rc != Success) 14906747b715Smrg return rc; 149105b261ecSmrg if (k == NULL) 149205b261ecSmrg return BadMatch; 14936747b715Smrg if (grabtype == GRABTYPE_XI) 14946747b715Smrg { 14956747b715Smrg if ((key > k->xkbInfo->desc->max_key_code || 14966747b715Smrg key < k->xkbInfo->desc->min_key_code) 14976747b715Smrg && (key != AnyKey)) { 14986747b715Smrg client->errorValue = key; 14996747b715Smrg return BadValue; 15006747b715Smrg } 15016747b715Smrg type = DeviceKeyPress; 15026747b715Smrg } else if (grabtype == GRABTYPE_XI2) 15036747b715Smrg type = XI_KeyPress; 15046747b715Smrg 15056747b715Smrg rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 15064642e01fSmrg if (rc != Success) 15074642e01fSmrg return rc; 15086747b715Smrg if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 15094642e01fSmrg access_mode |= DixFreezeAccess; 15104642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 151105b261ecSmrg if (rc != Success) 151205b261ecSmrg return rc; 151305b261ecSmrg 15146747b715Smrg grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, 15156747b715Smrg mask, param, type, key, NULL, NULL); 151605b261ecSmrg if (!grab) 151705b261ecSmrg return BadAlloc; 15184642e01fSmrg return AddPassiveGrabToList(client, grab); 151905b261ecSmrg} 152005b261ecSmrg 15216747b715Smrg/* Enter/FocusIn grab */ 15226747b715Smrgint 15236747b715SmrgGrabWindow(ClientPtr client, DeviceIntPtr dev, int type, 15246747b715Smrg GrabParameters *param, GrabMask *mask) 15256747b715Smrg{ 15266747b715Smrg WindowPtr pWin; 15276747b715Smrg CursorPtr cursor; 15286747b715Smrg GrabPtr grab; 15296747b715Smrg Mask access_mode = DixGrabAccess; 15306747b715Smrg int rc; 15316747b715Smrg 15326747b715Smrg rc = CheckGrabValues(client, param); 15336747b715Smrg if (rc != Success) 15346747b715Smrg return rc; 15356747b715Smrg 15366747b715Smrg rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 15376747b715Smrg if (rc != Success) 15386747b715Smrg return rc; 15396747b715Smrg if (param->cursor == None) 15406747b715Smrg cursor = NullCursor; 15416747b715Smrg else { 15426747b715Smrg rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, 15436747b715Smrg RT_CURSOR, client, DixUseAccess); 15446747b715Smrg if (rc != Success) 15456747b715Smrg { 15466747b715Smrg client->errorValue = param->cursor; 15476747b715Smrg return rc; 15486747b715Smrg } 15496747b715Smrg access_mode |= DixForceAccess; 15506747b715Smrg } 15516747b715Smrg if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 15526747b715Smrg access_mode |= DixFreezeAccess; 15536747b715Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 15546747b715Smrg if (rc != Success) 15556747b715Smrg return rc; 15566747b715Smrg 15576747b715Smrg grab = CreateGrab(client->index, dev, dev, pWin, GRABTYPE_XI2, 15586747b715Smrg mask, param, (type == XIGrabtypeEnter) ? XI_Enter : XI_FocusIn, 15596747b715Smrg 0, NULL, cursor); 15606747b715Smrg 15616747b715Smrg if (!grab) 15626747b715Smrg return BadAlloc; 15636747b715Smrg 15646747b715Smrg return AddPassiveGrabToList(client, grab); 15656747b715Smrg} 15666747b715Smrg 156705b261ecSmrgint 156805b261ecSmrgSelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client, 15696747b715Smrg Mask mask, Mask exclusivemasks) 157005b261ecSmrg{ 157105b261ecSmrg int mskidx = dev->id; 157205b261ecSmrg int i, ret; 157305b261ecSmrg Mask check; 157405b261ecSmrg InputClientsPtr others; 157505b261ecSmrg 157605b261ecSmrg check = (mask & exclusivemasks); 157705b261ecSmrg if (wOtherInputMasks(pWin)) { 157805b261ecSmrg if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) { /* It is illegal for two different 157905b261ecSmrg * clients to select on any of the 158005b261ecSmrg * events for maskcheck. However, 158105b261ecSmrg * it is OK, for some client to 158205b261ecSmrg * continue selecting on one of those 158305b261ecSmrg * events. */ 158405b261ecSmrg for (others = wOtherInputMasks(pWin)->inputClients; others; 158505b261ecSmrg others = others->next) { 158605b261ecSmrg if (!SameClient(others, client) && (check & 158705b261ecSmrg others->mask[mskidx])) 158805b261ecSmrg return BadAccess; 158905b261ecSmrg } 159005b261ecSmrg } 159105b261ecSmrg for (others = wOtherInputMasks(pWin)->inputClients; others; 159205b261ecSmrg others = others->next) { 159305b261ecSmrg if (SameClient(others, client)) { 159405b261ecSmrg check = others->mask[mskidx]; 159505b261ecSmrg others->mask[mskidx] = mask; 159605b261ecSmrg if (mask == 0) { 159705b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 159805b261ecSmrg if (i != mskidx && others->mask[i] != 0) 159905b261ecSmrg break; 160005b261ecSmrg if (i == EMASKSIZE) { 160105b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 160205b261ecSmrg if (ShouldFreeInputMasks(pWin, FALSE)) 160305b261ecSmrg FreeResource(others->resource, RT_NONE); 160405b261ecSmrg return Success; 160505b261ecSmrg } 160605b261ecSmrg } 160705b261ecSmrg goto maskSet; 160805b261ecSmrg } 160905b261ecSmrg } 161005b261ecSmrg } 161105b261ecSmrg check = 0; 161205b261ecSmrg if ((ret = AddExtensionClient(pWin, client, mask, mskidx)) != Success) 161305b261ecSmrg return ret; 161405b261ecSmrg maskSet: 161505b261ecSmrg if (dev->valuator) 161605b261ecSmrg if ((dev->valuator->motionHintWindow == pWin) && 161705b261ecSmrg (mask & DevicePointerMotionHintMask) && 16184642e01fSmrg !(check & DevicePointerMotionHintMask) && !dev->deviceGrab.grab) 161905b261ecSmrg dev->valuator->motionHintWindow = NullWindow; 162005b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 162105b261ecSmrg return Success; 162205b261ecSmrg} 162305b261ecSmrg 162405b261ecSmrgint 162505b261ecSmrgAddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx) 162605b261ecSmrg{ 162705b261ecSmrg InputClientsPtr others; 162805b261ecSmrg 162905b261ecSmrg if (!pWin->optional && !MakeWindowOptional(pWin)) 163005b261ecSmrg return BadAlloc; 16316747b715Smrg others = calloc(1, sizeof(InputClients)); 163205b261ecSmrg if (!others) 163305b261ecSmrg return BadAlloc; 163405b261ecSmrg if (!pWin->optional->inputMasks && !MakeInputMasks(pWin)) 163505b261ecSmrg return BadAlloc; 163605b261ecSmrg others->mask[mskidx] = mask; 163705b261ecSmrg others->resource = FakeClientID(client->index); 163805b261ecSmrg others->next = pWin->optional->inputMasks->inputClients; 163905b261ecSmrg pWin->optional->inputMasks->inputClients = others; 164005b261ecSmrg if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer) pWin)) 164105b261ecSmrg return BadAlloc; 164205b261ecSmrg return Success; 164305b261ecSmrg} 164405b261ecSmrg 164505b261ecSmrgstatic Bool 164605b261ecSmrgMakeInputMasks(WindowPtr pWin) 164705b261ecSmrg{ 164805b261ecSmrg struct _OtherInputMasks *imasks; 164905b261ecSmrg 16506747b715Smrg imasks = calloc(1, sizeof(struct _OtherInputMasks)); 165105b261ecSmrg if (!imasks) 165205b261ecSmrg return FALSE; 165305b261ecSmrg pWin->optional->inputMasks = imasks; 165405b261ecSmrg return TRUE; 165505b261ecSmrg} 165605b261ecSmrg 165705b261ecSmrgvoid 165805b261ecSmrgRecalculateDeviceDeliverableEvents(WindowPtr pWin) 165905b261ecSmrg{ 166005b261ecSmrg InputClientsPtr others; 166105b261ecSmrg struct _OtherInputMasks *inputMasks; /* default: NULL */ 166205b261ecSmrg WindowPtr pChild, tmp; 16636747b715Smrg int i, j; 166405b261ecSmrg 166505b261ecSmrg pChild = pWin; 166605b261ecSmrg while (1) { 166705b261ecSmrg if ((inputMasks = wOtherInputMasks(pChild)) != 0) { 16686747b715Smrg for (i = 0; i < EMASKSIZE; i++) 16696747b715Smrg memset(inputMasks->xi2mask[i], 0, sizeof(inputMasks->xi2mask[i])); 167005b261ecSmrg for (others = inputMasks->inputClients; others; 167105b261ecSmrg others = others->next) { 167205b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 167305b261ecSmrg inputMasks->inputEvents[i] |= others->mask[i]; 16746747b715Smrg for (i = 0; i < EMASKSIZE; i++) 16756747b715Smrg for (j = 0; j < XI2MASKSIZE; j++) 16766747b715Smrg inputMasks->xi2mask[i][j] |= others->xi2mask[i][j]; 167705b261ecSmrg } 167805b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 167905b261ecSmrg inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i]; 168005b261ecSmrg for (tmp = pChild->parent; tmp; tmp = tmp->parent) 168105b261ecSmrg if (wOtherInputMasks(tmp)) 168205b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 168305b261ecSmrg inputMasks->deliverableEvents[i] |= 168405b261ecSmrg (wOtherInputMasks(tmp)->deliverableEvents[i] 168505b261ecSmrg & ~inputMasks-> 168605b261ecSmrg dontPropagateMask[i] & PropagateMask[i]); 168705b261ecSmrg } 168805b261ecSmrg if (pChild->firstChild) { 168905b261ecSmrg pChild = pChild->firstChild; 169005b261ecSmrg continue; 169105b261ecSmrg } 169205b261ecSmrg while (!pChild->nextSib && (pChild != pWin)) 169305b261ecSmrg pChild = pChild->parent; 169405b261ecSmrg if (pChild == pWin) 169505b261ecSmrg break; 169605b261ecSmrg pChild = pChild->nextSib; 169705b261ecSmrg } 169805b261ecSmrg} 169905b261ecSmrg 170005b261ecSmrgint 170105b261ecSmrgInputClientGone(WindowPtr pWin, XID id) 170205b261ecSmrg{ 170305b261ecSmrg InputClientsPtr other, prev; 170405b261ecSmrg 170505b261ecSmrg if (!wOtherInputMasks(pWin)) 17066747b715Smrg return Success; 170705b261ecSmrg prev = 0; 170805b261ecSmrg for (other = wOtherInputMasks(pWin)->inputClients; other; 170905b261ecSmrg other = other->next) { 171005b261ecSmrg if (other->resource == id) { 171105b261ecSmrg if (prev) { 171205b261ecSmrg prev->next = other->next; 17136747b715Smrg free(other); 171405b261ecSmrg } else if (!(other->next)) { 171505b261ecSmrg if (ShouldFreeInputMasks(pWin, TRUE)) { 171605b261ecSmrg wOtherInputMasks(pWin)->inputClients = other->next; 17176747b715Smrg free(wOtherInputMasks(pWin)); 171805b261ecSmrg pWin->optional->inputMasks = (OtherInputMasks *) NULL; 171905b261ecSmrg CheckWindowOptionalNeed(pWin); 17206747b715Smrg free(other); 172105b261ecSmrg } else { 172205b261ecSmrg other->resource = FakeClientID(0); 172305b261ecSmrg if (!AddResource(other->resource, RT_INPUTCLIENT, 172405b261ecSmrg (pointer) pWin)) 172505b261ecSmrg return BadAlloc; 172605b261ecSmrg } 172705b261ecSmrg } else { 172805b261ecSmrg wOtherInputMasks(pWin)->inputClients = other->next; 17296747b715Smrg free(other); 173005b261ecSmrg } 173105b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 17326747b715Smrg return Success; 173305b261ecSmrg } 173405b261ecSmrg prev = other; 173505b261ecSmrg } 173605b261ecSmrg FatalError("client not on device event list"); 173705b261ecSmrg} 173805b261ecSmrg 173905b261ecSmrgint 174005b261ecSmrgSendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate, 174105b261ecSmrg xEvent * ev, Mask mask, int count) 174205b261ecSmrg{ 174305b261ecSmrg WindowPtr pWin; 174405b261ecSmrg WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ 17454642e01fSmrg WindowPtr spriteWin = GetSpriteWindow(d); 174605b261ecSmrg 174705b261ecSmrg if (dest == PointerWindow) 174805b261ecSmrg pWin = spriteWin; 174905b261ecSmrg else if (dest == InputFocus) { 175005b261ecSmrg WindowPtr inputFocus; 175105b261ecSmrg 175205b261ecSmrg if (!d->focus) 175305b261ecSmrg inputFocus = spriteWin; 175405b261ecSmrg else 175505b261ecSmrg inputFocus = d->focus->win; 175605b261ecSmrg 175705b261ecSmrg if (inputFocus == FollowKeyboardWin) 175805b261ecSmrg inputFocus = inputInfo.keyboard->focus->win; 175905b261ecSmrg 176005b261ecSmrg if (inputFocus == NoneWin) 176105b261ecSmrg return Success; 176205b261ecSmrg 176305b261ecSmrg /* If the input focus is PointerRootWin, send the event to where 176405b261ecSmrg * the pointer is if possible, then perhaps propogate up to root. */ 176505b261ecSmrg if (inputFocus == PointerRootWin) 17664642e01fSmrg inputFocus = GetCurrentRootWindow(d); 176705b261ecSmrg 176805b261ecSmrg if (IsParent(inputFocus, spriteWin)) { 176905b261ecSmrg effectiveFocus = inputFocus; 177005b261ecSmrg pWin = spriteWin; 177105b261ecSmrg } else 177205b261ecSmrg effectiveFocus = pWin = inputFocus; 177305b261ecSmrg } else 17744642e01fSmrg dixLookupWindow(&pWin, dest, client, DixSendAccess); 177505b261ecSmrg if (!pWin) 177605b261ecSmrg return BadWindow; 177705b261ecSmrg if ((propagate != xFalse) && (propagate != xTrue)) { 177805b261ecSmrg client->errorValue = propagate; 177905b261ecSmrg return BadValue; 178005b261ecSmrg } 178105b261ecSmrg ev->u.u.type |= 0x80; 178205b261ecSmrg if (propagate) { 178305b261ecSmrg for (; pWin; pWin = pWin->parent) { 17846747b715Smrg if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab)) 178505b261ecSmrg return Success; 178605b261ecSmrg if (pWin == effectiveFocus) 178705b261ecSmrg return Success; 178805b261ecSmrg if (wOtherInputMasks(pWin)) 178905b261ecSmrg mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id]; 179005b261ecSmrg if (!mask) 179105b261ecSmrg break; 179205b261ecSmrg } 17934642e01fSmrg } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count)) 17946747b715Smrg DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab); 179505b261ecSmrg return Success; 179605b261ecSmrg} 179705b261ecSmrg 179805b261ecSmrgint 179905b261ecSmrgSetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map) 180005b261ecSmrg{ 180105b261ecSmrg int i; 180205b261ecSmrg ButtonClassPtr b = dev->button; 180305b261ecSmrg 180405b261ecSmrg if (b == NULL) 180505b261ecSmrg return BadMatch; 180605b261ecSmrg 180705b261ecSmrg if (nElts != b->numButtons) { 180805b261ecSmrg client->errorValue = nElts; 180905b261ecSmrg return BadValue; 181005b261ecSmrg } 181105b261ecSmrg if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue)) 181205b261ecSmrg return BadValue; 181305b261ecSmrg for (i = 0; i < nElts; i++) 181405b261ecSmrg if ((b->map[i + 1] != map[i]) && BitIsOn(b->down, i + 1)) 181505b261ecSmrg return MappingBusy; 181605b261ecSmrg for (i = 0; i < nElts; i++) 181705b261ecSmrg b->map[i + 1] = map[i]; 181805b261ecSmrg return Success; 181905b261ecSmrg} 182005b261ecSmrg 182105b261ecSmrgint 182205b261ecSmrgChangeKeyMapping(ClientPtr client, 182305b261ecSmrg DeviceIntPtr dev, 182405b261ecSmrg unsigned len, 182505b261ecSmrg int type, 182605b261ecSmrg KeyCode firstKeyCode, 182705b261ecSmrg CARD8 keyCodes, CARD8 keySymsPerKeyCode, KeySym * map) 182805b261ecSmrg{ 182905b261ecSmrg KeySymsRec keysyms; 183005b261ecSmrg KeyClassPtr k = dev->key; 183105b261ecSmrg 183205b261ecSmrg if (k == NULL) 18336747b715Smrg return BadMatch; 183405b261ecSmrg 183505b261ecSmrg if (len != (keyCodes * keySymsPerKeyCode)) 183605b261ecSmrg return BadLength; 183705b261ecSmrg 18386747b715Smrg if ((firstKeyCode < k->xkbInfo->desc->min_key_code) || 18396747b715Smrg (firstKeyCode + keyCodes - 1 > k->xkbInfo->desc->max_key_code)) { 184005b261ecSmrg client->errorValue = firstKeyCode; 184105b261ecSmrg return BadValue; 184205b261ecSmrg } 184305b261ecSmrg if (keySymsPerKeyCode == 0) { 184405b261ecSmrg client->errorValue = 0; 184505b261ecSmrg return BadValue; 184605b261ecSmrg } 184705b261ecSmrg keysyms.minKeyCode = firstKeyCode; 184805b261ecSmrg keysyms.maxKeyCode = firstKeyCode + keyCodes - 1; 184905b261ecSmrg keysyms.mapWidth = keySymsPerKeyCode; 185005b261ecSmrg keysyms.map = map; 18516747b715Smrg 18526747b715Smrg XkbApplyMappingChange(dev, &keysyms, firstKeyCode, keyCodes, NULL, 18536747b715Smrg serverClient); 18546747b715Smrg 18556747b715Smrg return Success; 185605b261ecSmrg} 185705b261ecSmrg 185805b261ecSmrgstatic void 185905b261ecSmrgDeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) 186005b261ecSmrg{ 186105b261ecSmrg WindowPtr parent; 186205b261ecSmrg 186305b261ecSmrg /* Deactivate any grabs performed on this window, before making 186405b261ecSmrg * any input focus changes. 186505b261ecSmrg * Deactivating a device grab should cause focus events. */ 186605b261ecSmrg 18674642e01fSmrg if (dev->deviceGrab.grab && (dev->deviceGrab.grab->window == pWin)) 18684642e01fSmrg (*dev->deviceGrab.DeactivateGrab) (dev); 186905b261ecSmrg 18704642e01fSmrg /* If the focus window is a root window (ie. has no parent) 187105b261ecSmrg * then don't delete the focus from it. */ 187205b261ecSmrg 187305b261ecSmrg if (dev->focus && (pWin == dev->focus->win) && (pWin->parent != NullWindow)) { 187405b261ecSmrg int focusEventMode = NotifyNormal; 187505b261ecSmrg 187605b261ecSmrg /* If a grab is in progress, then alter the mode of focus events. */ 187705b261ecSmrg 18784642e01fSmrg if (dev->deviceGrab.grab) 187905b261ecSmrg focusEventMode = NotifyWhileGrabbed; 188005b261ecSmrg 188105b261ecSmrg switch (dev->focus->revert) { 188205b261ecSmrg case RevertToNone: 18836747b715Smrg if (!ActivateFocusInGrab(dev, pWin, NoneWin)) 18846747b715Smrg DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 188505b261ecSmrg dev->focus->win = NoneWin; 188605b261ecSmrg dev->focus->traceGood = 0; 188705b261ecSmrg break; 188805b261ecSmrg case RevertToParent: 188905b261ecSmrg parent = pWin; 189005b261ecSmrg do { 189105b261ecSmrg parent = parent->parent; 189205b261ecSmrg dev->focus->traceGood--; 189305b261ecSmrg } 189405b261ecSmrg while (!parent->realized); 18956747b715Smrg if (!ActivateFocusInGrab(dev, pWin, parent)) 18966747b715Smrg DoFocusEvents(dev, pWin, parent, focusEventMode); 189705b261ecSmrg dev->focus->win = parent; 189805b261ecSmrg dev->focus->revert = RevertToNone; 189905b261ecSmrg break; 190005b261ecSmrg case RevertToPointerRoot: 19016747b715Smrg if (!ActivateFocusInGrab(dev, pWin, PointerRootWin)) 19026747b715Smrg DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode); 190305b261ecSmrg dev->focus->win = PointerRootWin; 190405b261ecSmrg dev->focus->traceGood = 0; 190505b261ecSmrg break; 190605b261ecSmrg case RevertToFollowKeyboard: 19076747b715Smrg { 19086747b715Smrg DeviceIntPtr kbd = GetMaster(dev, MASTER_KEYBOARD); 19096747b715Smrg if (!kbd || (kbd == dev && kbd != inputInfo.keyboard)) 19106747b715Smrg kbd = inputInfo.keyboard; 19116747b715Smrg if (kbd->focus->win) { 19126747b715Smrg if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win)) 19136747b715Smrg DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode); 191405b261ecSmrg dev->focus->win = FollowKeyboardWin; 191505b261ecSmrg dev->focus->traceGood = 0; 191605b261ecSmrg } else { 19176747b715Smrg if (!ActivateFocusInGrab(dev, pWin, NoneWin)) 19186747b715Smrg DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 191905b261ecSmrg dev->focus->win = NoneWin; 192005b261ecSmrg dev->focus->traceGood = 0; 192105b261ecSmrg } 19226747b715Smrg } 192305b261ecSmrg break; 192405b261ecSmrg } 192505b261ecSmrg } 192605b261ecSmrg 192705b261ecSmrg if (dev->valuator) 192805b261ecSmrg if (dev->valuator->motionHintWindow == pWin) 192905b261ecSmrg dev->valuator->motionHintWindow = NullWindow; 193005b261ecSmrg} 193105b261ecSmrg 193205b261ecSmrgvoid 193305b261ecSmrgDeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources) 193405b261ecSmrg{ 193505b261ecSmrg int i; 193605b261ecSmrg DeviceIntPtr dev; 193705b261ecSmrg InputClientsPtr ic; 193805b261ecSmrg struct _OtherInputMasks *inputMasks; 193905b261ecSmrg 194005b261ecSmrg for (dev = inputInfo.devices; dev; dev = dev->next) { 194105b261ecSmrg DeleteDeviceFromAnyExtEvents(pWin, dev); 194205b261ecSmrg } 194305b261ecSmrg 194405b261ecSmrg for (dev = inputInfo.off_devices; dev; dev = dev->next) 194505b261ecSmrg DeleteDeviceFromAnyExtEvents(pWin, dev); 194605b261ecSmrg 194705b261ecSmrg if (freeResources) 194805b261ecSmrg while ((inputMasks = wOtherInputMasks(pWin)) != 0) { 194905b261ecSmrg ic = inputMasks->inputClients; 195005b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 195105b261ecSmrg inputMasks->dontPropagateMask[i] = 0; 195205b261ecSmrg FreeResource(ic->resource, RT_NONE); 195305b261ecSmrg } 195405b261ecSmrg} 195505b261ecSmrg 195605b261ecSmrgint 195705b261ecSmrgMaybeSendDeviceMotionNotifyHint(deviceKeyButtonPointer * pEvents, Mask mask) 195805b261ecSmrg{ 195905b261ecSmrg DeviceIntPtr dev; 196005b261ecSmrg 19614642e01fSmrg dixLookupDevice(&dev, pEvents->deviceid & DEVICE_BITS, serverClient, 19624642e01fSmrg DixReadAccess); 196305b261ecSmrg if (!dev) 196405b261ecSmrg return 0; 196505b261ecSmrg 196605b261ecSmrg if (pEvents->type == DeviceMotionNotify) { 196705b261ecSmrg if (mask & DevicePointerMotionHintMask) { 196805b261ecSmrg if (WID(dev->valuator->motionHintWindow) == pEvents->event) { 196905b261ecSmrg return 1; /* don't send, but pretend we did */ 197005b261ecSmrg } 197105b261ecSmrg pEvents->detail = NotifyHint; 197205b261ecSmrg } else { 197305b261ecSmrg pEvents->detail = NotifyNormal; 197405b261ecSmrg } 197505b261ecSmrg } 19766747b715Smrg return 0; 197705b261ecSmrg} 197805b261ecSmrg 197905b261ecSmrgvoid 198005b261ecSmrgCheckDeviceGrabAndHintWindow(WindowPtr pWin, int type, 198105b261ecSmrg deviceKeyButtonPointer * xE, GrabPtr grab, 198205b261ecSmrg ClientPtr client, Mask deliveryMask) 198305b261ecSmrg{ 198405b261ecSmrg DeviceIntPtr dev; 198505b261ecSmrg 19864642e01fSmrg dixLookupDevice(&dev, xE->deviceid & DEVICE_BITS, serverClient, 19876747b715Smrg DixGrabAccess); 198805b261ecSmrg if (!dev) 198905b261ecSmrg return; 199005b261ecSmrg 199105b261ecSmrg if (type == DeviceMotionNotify) 199205b261ecSmrg dev->valuator->motionHintWindow = pWin; 199305b261ecSmrg else if ((type == DeviceButtonPress) && (!grab) && 199405b261ecSmrg (deliveryMask & DeviceButtonGrabMask)) { 199505b261ecSmrg GrabRec tempGrab; 199605b261ecSmrg 199705b261ecSmrg tempGrab.device = dev; 199805b261ecSmrg tempGrab.resource = client->clientAsMask; 199905b261ecSmrg tempGrab.window = pWin; 200005b261ecSmrg tempGrab.ownerEvents = 200105b261ecSmrg (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE; 200205b261ecSmrg tempGrab.eventMask = deliveryMask; 200305b261ecSmrg tempGrab.keyboardMode = GrabModeAsync; 200405b261ecSmrg tempGrab.pointerMode = GrabModeAsync; 200505b261ecSmrg tempGrab.confineTo = NullWindow; 200605b261ecSmrg tempGrab.cursor = NullCursor; 20074642e01fSmrg tempGrab.next = NULL; 20084642e01fSmrg (*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE); 200905b261ecSmrg } 201005b261ecSmrg} 201105b261ecSmrg 201205b261ecSmrgstatic Mask 201305b261ecSmrgDeviceEventMaskForClient(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client) 201405b261ecSmrg{ 201505b261ecSmrg InputClientsPtr other; 201605b261ecSmrg 201705b261ecSmrg if (!wOtherInputMasks(pWin)) 201805b261ecSmrg return 0; 201905b261ecSmrg for (other = wOtherInputMasks(pWin)->inputClients; other; 202005b261ecSmrg other = other->next) { 202105b261ecSmrg if (SameClient(other, client)) 202205b261ecSmrg return other->mask[dev->id]; 202305b261ecSmrg } 202405b261ecSmrg return 0; 202505b261ecSmrg} 202605b261ecSmrg 202705b261ecSmrgvoid 202805b261ecSmrgMaybeStopDeviceHint(DeviceIntPtr dev, ClientPtr client) 202905b261ecSmrg{ 203005b261ecSmrg WindowPtr pWin; 20314642e01fSmrg GrabPtr grab = dev->deviceGrab.grab; 203205b261ecSmrg 203305b261ecSmrg pWin = dev->valuator->motionHintWindow; 203405b261ecSmrg 203505b261ecSmrg if ((grab && SameClient(grab, client) && 203605b261ecSmrg ((grab->eventMask & DevicePointerMotionHintMask) || 203705b261ecSmrg (grab->ownerEvents && 203805b261ecSmrg (DeviceEventMaskForClient(dev, pWin, client) & 203905b261ecSmrg DevicePointerMotionHintMask)))) || 204005b261ecSmrg (!grab && 204105b261ecSmrg (DeviceEventMaskForClient(dev, pWin, client) & 204205b261ecSmrg DevicePointerMotionHintMask))) 204305b261ecSmrg dev->valuator->motionHintWindow = NullWindow; 204405b261ecSmrg} 204505b261ecSmrg 204605b261ecSmrgint 204705b261ecSmrgDeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask, 204805b261ecSmrg int maskndx) 204905b261ecSmrg{ 205005b261ecSmrg struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 205105b261ecSmrg 205205b261ecSmrg if (mask & ~PropagateMask[maskndx]) { 205305b261ecSmrg client->errorValue = mask; 205405b261ecSmrg return BadValue; 205505b261ecSmrg } 205605b261ecSmrg 205705b261ecSmrg if (mask == 0) { 205805b261ecSmrg if (inputMasks) 205905b261ecSmrg inputMasks->dontPropagateMask[maskndx] = mask; 206005b261ecSmrg } else { 206105b261ecSmrg if (!inputMasks) 206205b261ecSmrg AddExtensionClient(pWin, client, 0, 0); 206305b261ecSmrg inputMasks = wOtherInputMasks(pWin); 206405b261ecSmrg inputMasks->dontPropagateMask[maskndx] = mask; 206505b261ecSmrg } 206605b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 206705b261ecSmrg if (ShouldFreeInputMasks(pWin, FALSE)) 206805b261ecSmrg FreeResource(inputMasks->inputClients->resource, RT_NONE); 206905b261ecSmrg return Success; 207005b261ecSmrg} 207105b261ecSmrg 20724642e01fSmrgBool 207305b261ecSmrgShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents) 207405b261ecSmrg{ 207505b261ecSmrg int i; 207605b261ecSmrg Mask allInputEventMasks = 0; 207705b261ecSmrg struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 207805b261ecSmrg 207905b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 208005b261ecSmrg allInputEventMasks |= inputMasks->dontPropagateMask[i]; 208105b261ecSmrg if (!ignoreSelectedEvents) 208205b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 208305b261ecSmrg allInputEventMasks |= inputMasks->inputEvents[i]; 208405b261ecSmrg if (allInputEventMasks == 0) 208505b261ecSmrg return TRUE; 208605b261ecSmrg else 208705b261ecSmrg return FALSE; 208805b261ecSmrg} 208905b261ecSmrg 209005b261ecSmrg/*********************************************************************** 209105b261ecSmrg * 209205b261ecSmrg * Walk through the window tree, finding all clients that want to know 209305b261ecSmrg * about the Event. 209405b261ecSmrg * 209505b261ecSmrg */ 209605b261ecSmrg 209705b261ecSmrgstatic void 209805b261ecSmrgFindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask, 209905b261ecSmrg xEvent * ev, int count) 210005b261ecSmrg{ 210105b261ecSmrg WindowPtr p2; 210205b261ecSmrg 210305b261ecSmrg while (p1) { 210405b261ecSmrg p2 = p1->firstChild; 21056747b715Smrg DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab); 210605b261ecSmrg FindInterestedChildren(dev, p2, mask, ev, count); 210705b261ecSmrg p1 = p1->nextSib; 210805b261ecSmrg } 210905b261ecSmrg} 211005b261ecSmrg 211105b261ecSmrg/*********************************************************************** 211205b261ecSmrg * 211305b261ecSmrg * Send an event to interested clients in all windows on all screens. 211405b261ecSmrg * 211505b261ecSmrg */ 211605b261ecSmrg 211705b261ecSmrgvoid 211805b261ecSmrgSendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count) 211905b261ecSmrg{ 212005b261ecSmrg int i; 212105b261ecSmrg WindowPtr pWin, p1; 212205b261ecSmrg 212305b261ecSmrg for (i = 0; i < screenInfo.numScreens; i++) { 21246747b715Smrg pWin = screenInfo.screens[i]->root; 21254642e01fSmrg if (!pWin) 21264642e01fSmrg continue; 21276747b715Smrg DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab); 212805b261ecSmrg p1 = pWin->firstChild; 212905b261ecSmrg FindInterestedChildren(dev, p1, mask, ev, count); 213005b261ecSmrg } 213105b261ecSmrg} 21324642e01fSmrg 21336747b715Smrg/** 21346747b715Smrg * Set the XI2 mask for the given client on the given window. 21356747b715Smrg * @param dev The device to set the mask for. 21366747b715Smrg * @param win The window to set the mask on. 21376747b715Smrg * @param client The client setting the mask. 21386747b715Smrg * @param len Number of bytes in mask. 21396747b715Smrg * @param mask Event mask in the form of (1 << eventtype) 21406747b715Smrg */ 21416747b715Smrgint 21426747b715SmrgXISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client, 21436747b715Smrg unsigned int len, unsigned char* mask) 21446747b715Smrg{ 21456747b715Smrg OtherInputMasks *masks; 21466747b715Smrg InputClientsPtr others = NULL; 21476747b715Smrg 21486747b715Smrg masks = wOtherInputMasks(win); 21496747b715Smrg if (masks) 21506747b715Smrg { 21516747b715Smrg for (others = wOtherInputMasks(win)->inputClients; others; 21526747b715Smrg others = others->next) { 21536747b715Smrg if (SameClient(others, client)) { 21546747b715Smrg memset(others->xi2mask[dev->id], 0, 21556747b715Smrg sizeof(others->xi2mask[dev->id])); 21566747b715Smrg break; 21576747b715Smrg } 21586747b715Smrg } 21596747b715Smrg } 21606747b715Smrg 21616747b715Smrg len = min(len, sizeof(others->xi2mask[dev->id])); 21626747b715Smrg 21636747b715Smrg if (len && !others) 21646747b715Smrg { 21656747b715Smrg if (AddExtensionClient(win, client, 0, 0) != Success) 21666747b715Smrg return BadAlloc; 21676747b715Smrg others= wOtherInputMasks(win)->inputClients; 21686747b715Smrg } 21696747b715Smrg 21706747b715Smrg if (others) 21716747b715Smrg memset(others->xi2mask[dev->id], 0, sizeof(others->xi2mask[dev->id])); 21726747b715Smrg 21736747b715Smrg if (len) 21746747b715Smrg memcpy(others->xi2mask[dev->id], mask, len); 21756747b715Smrg 21766747b715Smrg RecalculateDeviceDeliverableEvents(win); 21776747b715Smrg 21786747b715Smrg return Success; 21796747b715Smrg} 2180