exevents.c revision 6747b715
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; 8816747b715Smrg if (button_is_down(sd, key, BUTTON_PROCESSED)) 8824642e01fSmrg return DONT_PROCESS; 8834642e01fSmrg } 8844642e01fSmrg } 8856747b715Smrg set_button_up(device, key, BUTTON_PROCESSED); 8864642e01fSmrg if (device->valuator) 8874642e01fSmrg device->valuator->motionHintWindow = NullWindow; 8884642e01fSmrg if (!b->map[key]) 8894642e01fSmrg return DONT_PROCESS; 89005b261ecSmrg if (b->buttonsDown >= 1 && !--b->buttonsDown) 89105b261ecSmrg b->motionMask = 0; 8924642e01fSmrg if (b->map[key] <= 5) 8934642e01fSmrg b->state &= ~((Button1Mask >> 1) << b->map[key]); 8946747b715Smrg 8956747b715Smrg /* Add state and motionMask to the filter for this event */ 8966747b715Smrg mask = DevicePointerMotionMask | b->state | b->motionMask; 8976747b715Smrg SetMaskForEvent(device->id, mask, DeviceMotionNotify); 8986747b715Smrg mask = PointerMotionMask | b->state | b->motionMask; 8996747b715Smrg SetMaskForEvent(device->id, mask, MotionNotify); 9006747b715Smrg } else if (event->type == ET_ProximityIn) 9014642e01fSmrg device->valuator->mode &= ~OutOfProximity; 9026747b715Smrg else if (event->type == ET_ProximityOut) 9034642e01fSmrg device->valuator->mode |= OutOfProximity; 9044642e01fSmrg 9054642e01fSmrg return DEFAULT; 9064642e01fSmrg} 9074642e01fSmrg 9086747b715Smrgstatic void 9096747b715SmrgProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device) 9106747b715Smrg{ 9116747b715Smrg GrabPtr grab = device->deviceGrab.grab; 9126747b715Smrg 9136747b715Smrg if (grab) 9146747b715Smrg DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE); 9156747b715Smrg else { /* deliver to all root windows */ 9166747b715Smrg xEvent *xi; 9176747b715Smrg int i; 9186747b715Smrg 9196747b715Smrg i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi); 9206747b715Smrg if (i != Success) 9216747b715Smrg { 9226747b715Smrg ErrorF("[Xi] %s: XI2 conversion failed in ProcessRawEvent (%d)\n", 9236747b715Smrg device->name, i); 9246747b715Smrg return; 9256747b715Smrg } 9266747b715Smrg 9276747b715Smrg for (i = 0; i < screenInfo.numScreens; i++) 9286747b715Smrg DeliverEventsToWindow(device, screenInfo.screens[i]->root, xi, 1, 9296747b715Smrg GetEventFilter(device, xi), NULL); 9306747b715Smrg free(xi); 9316747b715Smrg } 9326747b715Smrg} 9336747b715Smrg 9344642e01fSmrg/** 9354642e01fSmrg * Main device event processing function. 9364642e01fSmrg * Called from when processing the events from the event queue. 9374642e01fSmrg * 9384642e01fSmrg */ 9394642e01fSmrgvoid 9406747b715SmrgProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device) 9414642e01fSmrg{ 9426747b715Smrg GrabPtr grab; 9434642e01fSmrg Bool deactivateDeviceGrab = FALSE; 9444642e01fSmrg int key = 0, rootX, rootY; 9454642e01fSmrg ButtonClassPtr b; 9464642e01fSmrg KeyClassPtr k; 9474642e01fSmrg ValuatorClassPtr v; 9484642e01fSmrg int ret = 0; 9496747b715Smrg int state, i; 9504642e01fSmrg DeviceIntPtr mouse = NULL, kbd = NULL; 9516747b715Smrg DeviceEvent *event = &ev->device_event; 9526747b715Smrg 9536747b715Smrg CHECKEVENT(ev); 9546747b715Smrg 9556747b715Smrg if (ev->any.type == ET_RawKeyPress || 9566747b715Smrg ev->any.type == ET_RawKeyRelease || 9576747b715Smrg ev->any.type == ET_RawButtonPress || 9586747b715Smrg ev->any.type == ET_RawButtonRelease || 9596747b715Smrg ev->any.type == ET_RawMotion) 9606747b715Smrg { 9616747b715Smrg ProcessRawEvent(&ev->raw_event, device); 9626747b715Smrg return; 9636747b715Smrg } 9644642e01fSmrg 9654642e01fSmrg if (IsPointerDevice(device)) 9664642e01fSmrg { 9674642e01fSmrg kbd = GetPairedDevice(device); 9684642e01fSmrg mouse = device; 9694642e01fSmrg if (!kbd->key) /* can happen with floating SDs */ 9704642e01fSmrg kbd = NULL; 9714642e01fSmrg } else 9724642e01fSmrg { 9734642e01fSmrg mouse = GetPairedDevice(device); 9744642e01fSmrg kbd = device; 9754642e01fSmrg if (!mouse->valuator || !mouse->button) /* may be float. SDs */ 9764642e01fSmrg mouse = NULL; 9774642e01fSmrg } 9784642e01fSmrg 9794642e01fSmrg /* State needs to be assembled BEFORE the device is updated. */ 9806747b715Smrg state = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0; 9816747b715Smrg state |= (mouse && mouse->button) ? (mouse->button->state) : 0; 9826747b715Smrg 9836747b715Smrg for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) 9846747b715Smrg if (BitIsOn(mouse->button->down, i)) 9856747b715Smrg SetBit(event->buttons, i); 9866747b715Smrg 9876747b715Smrg if (kbd && kbd->key) 9886747b715Smrg { 9896747b715Smrg XkbStatePtr state; 9906747b715Smrg /* we need the state before the event happens */ 9916747b715Smrg if (event->type == ET_KeyPress || event->type == ET_KeyRelease) 9926747b715Smrg state = &kbd->key->xkbInfo->prev_state; 9936747b715Smrg else 9946747b715Smrg state = &kbd->key->xkbInfo->state; 9956747b715Smrg 9966747b715Smrg event->mods.base = state->base_mods; 9976747b715Smrg event->mods.latched = state->latched_mods; 9986747b715Smrg event->mods.locked = state->locked_mods; 9996747b715Smrg event->mods.effective = state->mods; 10006747b715Smrg 10016747b715Smrg event->group.base = state->base_group; 10026747b715Smrg event->group.latched = state->latched_group; 10036747b715Smrg event->group.locked = state->locked_group; 10046747b715Smrg event->group.effective = state->group; 10056747b715Smrg } 10064642e01fSmrg 10076747b715Smrg ret = UpdateDeviceState(device, event); 10084642e01fSmrg if (ret == DONT_PROCESS) 10094642e01fSmrg return; 10104642e01fSmrg 10114642e01fSmrg v = device->valuator; 10124642e01fSmrg b = device->button; 10134642e01fSmrg k = device->key; 10144642e01fSmrg 10156747b715Smrg if (IsMaster(device) || !device->u.master) 10166747b715Smrg CheckMotion(event, device); 10174642e01fSmrg 10186747b715Smrg switch (event->type) 10196747b715Smrg { 10206747b715Smrg case ET_Motion: 10216747b715Smrg case ET_ButtonPress: 10226747b715Smrg case ET_ButtonRelease: 10236747b715Smrg case ET_KeyPress: 10246747b715Smrg case ET_KeyRelease: 10256747b715Smrg case ET_ProximityIn: 10266747b715Smrg case ET_ProximityOut: 10276747b715Smrg GetSpritePosition(device, &rootX, &rootY); 10286747b715Smrg event->root_x = rootX; 10296747b715Smrg event->root_y = rootY; 10306747b715Smrg NoticeEventTime((InternalEvent*)event); 10316747b715Smrg event->corestate = state; 10326747b715Smrg key = event->detail.key; 10336747b715Smrg break; 10346747b715Smrg default: 10356747b715Smrg break; 10364642e01fSmrg } 10376747b715Smrg 10386747b715Smrg if (DeviceEventCallback && !syncEvents.playingEvents) { 10394642e01fSmrg DeviceEventInfoRec eventinfo; 10406747b715Smrg SpritePtr pSprite = device->spriteInfo->sprite; 10414642e01fSmrg 10426747b715Smrg /* see comment in EnqueueEvents regarding the next three lines */ 10436747b715Smrg if (ev->any.type == ET_Motion) 10446747b715Smrg ev->device_event.root = pSprite->hotPhys.pScreen->root->drawable.id; 10454642e01fSmrg 10466747b715Smrg eventinfo.device = device; 10476747b715Smrg eventinfo.event = ev; 10486747b715Smrg CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo); 10494642e01fSmrg } 10504642e01fSmrg 10516747b715Smrg grab = device->deviceGrab.grab; 10524642e01fSmrg 10536747b715Smrg switch(event->type) 10546747b715Smrg { 10556747b715Smrg case ET_KeyPress: 10566747b715Smrg if (!grab && CheckDeviceGrabs(device, event, 0)) { 10576747b715Smrg device->deviceGrab.activatingKey = key; 10586747b715Smrg return; 10596747b715Smrg } 10606747b715Smrg break; 10616747b715Smrg case ET_KeyRelease: 10626747b715Smrg if (grab && device->deviceGrab.fromPassiveGrab && 10636747b715Smrg (key == device->deviceGrab.activatingKey) && 10646747b715Smrg (device->deviceGrab.grab->type == KeyPress || 10656747b715Smrg device->deviceGrab.grab->type == DeviceKeyPress || 10666747b715Smrg device->deviceGrab.grab->type == XI_KeyPress)) 10676747b715Smrg deactivateDeviceGrab = TRUE; 10686747b715Smrg break; 10696747b715Smrg case ET_ButtonPress: 10706747b715Smrg event->detail.button = b->map[key]; 10716747b715Smrg if (!event->detail.button) { /* there's no button 0 */ 10726747b715Smrg event->detail.button = key; 10736747b715Smrg return; 10746747b715Smrg } 10756747b715Smrg if (!grab && CheckDeviceGrabs(device, event, 0)) 10766747b715Smrg { 10776747b715Smrg /* if a passive grab was activated, the event has been sent 10786747b715Smrg * already */ 10796747b715Smrg return; 10806747b715Smrg } 10816747b715Smrg break; 10826747b715Smrg case ET_ButtonRelease: 10836747b715Smrg event->detail.button = b->map[key]; 10846747b715Smrg if (!event->detail.button) { /* there's no button 0 */ 10856747b715Smrg event->detail.button = key; 10866747b715Smrg return; 10876747b715Smrg } 10886747b715Smrg if (grab && !b->buttonsDown && 10896747b715Smrg device->deviceGrab.fromPassiveGrab && 10906747b715Smrg (device->deviceGrab.grab->type == ButtonPress || 10916747b715Smrg device->deviceGrab.grab->type == DeviceButtonPress || 10926747b715Smrg device->deviceGrab.grab->type == XI_ButtonPress)) 10936747b715Smrg deactivateDeviceGrab = TRUE; 10946747b715Smrg default: 10956747b715Smrg break; 10964642e01fSmrg } 109705b261ecSmrg 10986747b715Smrg 109905b261ecSmrg if (grab) 11006747b715Smrg DeliverGrabbedEvent((InternalEvent*)event, device, deactivateDeviceGrab); 11016747b715Smrg else if (device->focus && !IsPointerEvent((InternalEvent*)ev)) 11026747b715Smrg DeliverFocusedEvent(device, (InternalEvent*)event, 11036747b715Smrg GetSpriteWindow(device)); 110405b261ecSmrg else 11056747b715Smrg DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent*)event, 11066747b715Smrg NullGrab, NullWindow, device); 110705b261ecSmrg 110805b261ecSmrg if (deactivateDeviceGrab == TRUE) 11094642e01fSmrg (*device->deviceGrab.DeactivateGrab) (device); 11106747b715Smrg event->detail.key = key; 111105b261ecSmrg} 111205b261ecSmrg 11136747b715Smrgint 111405b261ecSmrgInitProximityClassDeviceStruct(DeviceIntPtr dev) 111505b261ecSmrg{ 111605b261ecSmrg ProximityClassPtr proxc; 111705b261ecSmrg 11186747b715Smrg proxc = (ProximityClassPtr) malloc(sizeof(ProximityClassRec)); 111905b261ecSmrg if (!proxc) 112005b261ecSmrg return FALSE; 11216747b715Smrg proxc->sourceid = dev->id; 112205b261ecSmrg dev->proximity = proxc; 112305b261ecSmrg return TRUE; 112405b261ecSmrg} 112505b261ecSmrg 11264642e01fSmrg/** 11274642e01fSmrg * Initialise the device's valuators. The memory must already be allocated, 11284642e01fSmrg * this function merely inits the matching axis (specified through axnum) to 11294642e01fSmrg * sane values. 11304642e01fSmrg * 11314642e01fSmrg * It is a condition that (minval < maxval). 11324642e01fSmrg * 11334642e01fSmrg * @see InitValuatorClassDeviceStruct 11344642e01fSmrg */ 11356747b715Smrgvoid 11366747b715SmrgInitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval, 113705b261ecSmrg int resolution, int min_res, int max_res) 113805b261ecSmrg{ 113905b261ecSmrg AxisInfoPtr ax; 11404642e01fSmrg 11414642e01fSmrg if (!dev || !dev->valuator || minval > maxval) 114205b261ecSmrg return; 11436747b715Smrg if (axnum >= dev->valuator->numAxes) 11446747b715Smrg return; 114505b261ecSmrg 114605b261ecSmrg ax = dev->valuator->axes + axnum; 114705b261ecSmrg 114805b261ecSmrg ax->min_value = minval; 114905b261ecSmrg ax->max_value = maxval; 115005b261ecSmrg ax->resolution = resolution; 115105b261ecSmrg ax->min_resolution = min_res; 115205b261ecSmrg ax->max_resolution = max_res; 11536747b715Smrg ax->label = label; 115405b261ecSmrg} 115505b261ecSmrg 115605b261ecSmrgstatic void 115705b261ecSmrgFixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, 115805b261ecSmrg ButtonClassPtr b, ValuatorClassPtr v, int first) 115905b261ecSmrg{ 116005b261ecSmrg ev->type = DeviceStateNotify; 116105b261ecSmrg ev->deviceid = dev->id; 116205b261ecSmrg ev->time = currentTime.milliseconds; 116305b261ecSmrg ev->classes_reported = 0; 116405b261ecSmrg ev->num_keys = 0; 116505b261ecSmrg ev->num_buttons = 0; 116605b261ecSmrg ev->num_valuators = 0; 116705b261ecSmrg 116805b261ecSmrg if (b) { 116905b261ecSmrg ev->classes_reported |= (1 << ButtonClass); 117005b261ecSmrg ev->num_buttons = b->numButtons; 11714642e01fSmrg memcpy((char*)ev->buttons, (char*)b->down, 4); 117205b261ecSmrg } else if (k) { 117305b261ecSmrg ev->classes_reported |= (1 << KeyClass); 11746747b715Smrg ev->num_keys = k->xkbInfo->desc->max_key_code - 11756747b715Smrg k->xkbInfo->desc->min_key_code; 117605b261ecSmrg memmove((char *)&ev->keys[0], (char *)k->down, 4); 117705b261ecSmrg } 117805b261ecSmrg if (v) { 117905b261ecSmrg int nval = v->numAxes - first; 118005b261ecSmrg 118105b261ecSmrg ev->classes_reported |= (1 << ValuatorClass); 118205b261ecSmrg ev->classes_reported |= (dev->valuator->mode << ModeBitsShift); 118305b261ecSmrg ev->num_valuators = nval < 3 ? nval : 3; 118405b261ecSmrg switch (ev->num_valuators) { 118505b261ecSmrg case 3: 118605b261ecSmrg ev->valuator2 = v->axisVal[first + 2]; 118705b261ecSmrg case 2: 118805b261ecSmrg ev->valuator1 = v->axisVal[first + 1]; 118905b261ecSmrg case 1: 119005b261ecSmrg ev->valuator0 = v->axisVal[first]; 119105b261ecSmrg break; 119205b261ecSmrg } 119305b261ecSmrg } 119405b261ecSmrg} 119505b261ecSmrg 119605b261ecSmrgstatic void 119705b261ecSmrgFixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, 119805b261ecSmrg int first) 119905b261ecSmrg{ 120005b261ecSmrg int nval = v->numAxes - first; 120105b261ecSmrg 120205b261ecSmrg ev->type = DeviceValuator; 120305b261ecSmrg ev->deviceid = dev->id; 120405b261ecSmrg ev->num_valuators = nval < 3 ? nval : 3; 120505b261ecSmrg ev->first_valuator = first; 120605b261ecSmrg switch (ev->num_valuators) { 120705b261ecSmrg case 3: 120805b261ecSmrg ev->valuator2 = v->axisVal[first + 2]; 120905b261ecSmrg case 2: 121005b261ecSmrg ev->valuator1 = v->axisVal[first + 1]; 121105b261ecSmrg case 1: 121205b261ecSmrg ev->valuator0 = v->axisVal[first]; 121305b261ecSmrg break; 121405b261ecSmrg } 121505b261ecSmrg first += ev->num_valuators; 121605b261ecSmrg} 121705b261ecSmrg 121805b261ecSmrgvoid 121905b261ecSmrgDeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, 122005b261ecSmrg WindowPtr pWin) 122105b261ecSmrg{ 122205b261ecSmrg deviceFocus event; 12236747b715Smrg xXIFocusInEvent *xi2event; 12246747b715Smrg DeviceIntPtr mouse; 12256747b715Smrg int btlen, len, i; 12266747b715Smrg 12276747b715Smrg mouse = (IsMaster(dev) || dev->u.master) ? GetMaster(dev, MASTER_POINTER) : dev; 12286747b715Smrg 12296747b715Smrg /* XI 2 event */ 12306747b715Smrg btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; 12316747b715Smrg btlen = bytes_to_int32(btlen); 12326747b715Smrg len = sizeof(xXIFocusInEvent) + btlen * 4; 12336747b715Smrg 12346747b715Smrg xi2event = calloc(1, len); 12356747b715Smrg xi2event->type = GenericEvent; 12366747b715Smrg xi2event->extension = IReqCode; 12376747b715Smrg xi2event->evtype = type; 12386747b715Smrg xi2event->length = bytes_to_int32(len - sizeof(xEvent)); 12396747b715Smrg xi2event->buttons_len = btlen; 12406747b715Smrg xi2event->detail = detail; 12416747b715Smrg xi2event->time = currentTime.milliseconds; 12426747b715Smrg xi2event->deviceid = dev->id; 12436747b715Smrg xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */ 12446747b715Smrg xi2event->mode = mode; 12456747b715Smrg xi2event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0); 12466747b715Smrg xi2event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0); 12476747b715Smrg 12486747b715Smrg for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) 12496747b715Smrg if (BitIsOn(mouse->button->down, i)) 12506747b715Smrg SetBit(&xi2event[1], i); 12516747b715Smrg 12526747b715Smrg if (dev->key) 12536747b715Smrg { 12546747b715Smrg xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods; 12556747b715Smrg xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods; 12566747b715Smrg xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods; 12576747b715Smrg xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods; 12586747b715Smrg 12596747b715Smrg xi2event->group.base_group = dev->key->xkbInfo->state.base_group; 12606747b715Smrg xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group; 12616747b715Smrg xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group; 12626747b715Smrg xi2event->group.effective_group = dev->key->xkbInfo->state.group; 12636747b715Smrg } 126405b261ecSmrg 12656747b715Smrg FixUpEventFromWindow(dev, (xEvent*)xi2event, pWin, None, FALSE); 126605b261ecSmrg 12676747b715Smrg DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1, 12686747b715Smrg GetEventFilter(dev, (xEvent*)xi2event), NullGrab); 12696747b715Smrg 12706747b715Smrg free(xi2event); 12716747b715Smrg 12726747b715Smrg /* XI 1.x event */ 127305b261ecSmrg event.deviceid = dev->id; 127405b261ecSmrg event.mode = mode; 12756747b715Smrg event.type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut; 127605b261ecSmrg event.detail = detail; 127705b261ecSmrg event.window = pWin->drawable.id; 127805b261ecSmrg event.time = currentTime.milliseconds; 127905b261ecSmrg 12806747b715Smrg DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1, 12816747b715Smrg DeviceFocusChangeMask, NullGrab); 128205b261ecSmrg 128305b261ecSmrg if ((type == DeviceFocusIn) && 128405b261ecSmrg (wOtherInputMasks(pWin)) && 128505b261ecSmrg (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask)) 128605b261ecSmrg { 128705b261ecSmrg int evcount = 1; 128805b261ecSmrg deviceStateNotify *ev, *sev; 128905b261ecSmrg deviceKeyStateNotify *kev; 129005b261ecSmrg deviceButtonStateNotify *bev; 129105b261ecSmrg 129205b261ecSmrg KeyClassPtr k; 129305b261ecSmrg ButtonClassPtr b; 129405b261ecSmrg ValuatorClassPtr v; 129505b261ecSmrg int nval = 0, nkeys = 0, nbuttons = 0, first = 0; 129605b261ecSmrg 129705b261ecSmrg if ((b = dev->button) != NULL) { 129805b261ecSmrg nbuttons = b->numButtons; 129905b261ecSmrg if (nbuttons > 32) 130005b261ecSmrg evcount++; 130105b261ecSmrg } 130205b261ecSmrg if ((k = dev->key) != NULL) { 13036747b715Smrg nkeys = k->xkbInfo->desc->max_key_code - 13046747b715Smrg k->xkbInfo->desc->min_key_code; 130505b261ecSmrg if (nkeys > 32) 130605b261ecSmrg evcount++; 130705b261ecSmrg if (nbuttons > 0) { 130805b261ecSmrg evcount++; 130905b261ecSmrg } 131005b261ecSmrg } 131105b261ecSmrg if ((v = dev->valuator) != NULL) { 131205b261ecSmrg nval = v->numAxes; 131305b261ecSmrg 131405b261ecSmrg if (nval > 3) 131505b261ecSmrg evcount++; 131605b261ecSmrg if (nval > 6) { 131705b261ecSmrg if (!(k && b)) 131805b261ecSmrg evcount++; 131905b261ecSmrg if (nval > 9) 132005b261ecSmrg evcount += ((nval - 7) / 3); 132105b261ecSmrg } 132205b261ecSmrg } 132305b261ecSmrg 13246747b715Smrg sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent)); 132505b261ecSmrg FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); 132605b261ecSmrg 132705b261ecSmrg if (b != NULL) { 132805b261ecSmrg FixDeviceStateNotify(dev, ev++, NULL, b, v, first); 132905b261ecSmrg first += 3; 133005b261ecSmrg nval -= 3; 133105b261ecSmrg if (nbuttons > 32) { 133205b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 133305b261ecSmrg bev = (deviceButtonStateNotify *) ev++; 133405b261ecSmrg bev->type = DeviceButtonStateNotify; 133505b261ecSmrg bev->deviceid = dev->id; 13364642e01fSmrg memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4); 133705b261ecSmrg } 133805b261ecSmrg if (nval > 0) { 133905b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 134005b261ecSmrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 134105b261ecSmrg first += 3; 134205b261ecSmrg nval -= 3; 134305b261ecSmrg } 134405b261ecSmrg } 134505b261ecSmrg 134605b261ecSmrg if (k != NULL) { 134705b261ecSmrg FixDeviceStateNotify(dev, ev++, k, NULL, v, first); 134805b261ecSmrg first += 3; 134905b261ecSmrg nval -= 3; 135005b261ecSmrg if (nkeys > 32) { 135105b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 135205b261ecSmrg kev = (deviceKeyStateNotify *) ev++; 135305b261ecSmrg kev->type = DeviceKeyStateNotify; 135405b261ecSmrg kev->deviceid = dev->id; 135505b261ecSmrg memmove((char *)&kev->keys[0], (char *)&k->down[4], 28); 135605b261ecSmrg } 135705b261ecSmrg if (nval > 0) { 135805b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 135905b261ecSmrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 136005b261ecSmrg first += 3; 136105b261ecSmrg nval -= 3; 136205b261ecSmrg } 136305b261ecSmrg } 136405b261ecSmrg 136505b261ecSmrg while (nval > 0) { 136605b261ecSmrg FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); 136705b261ecSmrg first += 3; 136805b261ecSmrg nval -= 3; 136905b261ecSmrg if (nval > 0) { 137005b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 137105b261ecSmrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 137205b261ecSmrg first += 3; 137305b261ecSmrg nval -= 3; 137405b261ecSmrg } 137505b261ecSmrg } 137605b261ecSmrg 13776747b715Smrg DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount, 13786747b715Smrg DeviceStateNotifyMask, NullGrab); 13796747b715Smrg free(sev); 138005b261ecSmrg } 138105b261ecSmrg} 138205b261ecSmrg 138305b261ecSmrgint 13846747b715SmrgCheckGrabValues(ClientPtr client, GrabParameters* param) 138505b261ecSmrg{ 13866747b715Smrg if (param->grabtype != GRABTYPE_CORE && 13876747b715Smrg param->grabtype != GRABTYPE_XI && 13886747b715Smrg param->grabtype != GRABTYPE_XI2) 13896747b715Smrg { 13906747b715Smrg ErrorF("[Xi] grabtype is invalid. This is a bug.\n"); 13916747b715Smrg return BadImplementation; 13926747b715Smrg } 139305b261ecSmrg 13946747b715Smrg if ((param->this_device_mode != GrabModeSync) && 13956747b715Smrg (param->this_device_mode != GrabModeAsync)) { 13966747b715Smrg client->errorValue = param->this_device_mode; 139705b261ecSmrg return BadValue; 139805b261ecSmrg } 13996747b715Smrg if ((param->other_devices_mode != GrabModeSync) && 14006747b715Smrg (param->other_devices_mode != GrabModeAsync)) { 14016747b715Smrg client->errorValue = param->other_devices_mode; 140205b261ecSmrg return BadValue; 140305b261ecSmrg } 14046747b715Smrg 14056747b715Smrg if (param->grabtype != GRABTYPE_XI2 && (param->modifiers != AnyModifier) && 14066747b715Smrg (param->modifiers & ~AllModifiersMask)) { 14076747b715Smrg client->errorValue = param->modifiers; 140805b261ecSmrg return BadValue; 140905b261ecSmrg } 14106747b715Smrg 14116747b715Smrg if ((param->ownerEvents != xFalse) && (param->ownerEvents != xTrue)) { 14126747b715Smrg client->errorValue = param->ownerEvents; 141305b261ecSmrg return BadValue; 141405b261ecSmrg } 14156747b715Smrg return Success; 14166747b715Smrg} 14176747b715Smrg 14186747b715Smrgint 14196747b715SmrgGrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, 14206747b715Smrg int button, GrabParameters *param, GrabType grabtype, 14216747b715Smrg GrabMask *mask) 14226747b715Smrg{ 14236747b715Smrg WindowPtr pWin, confineTo; 14246747b715Smrg CursorPtr cursor; 14256747b715Smrg GrabPtr grab; 14266747b715Smrg int rc, type = -1; 14276747b715Smrg Mask access_mode = DixGrabAccess; 14286747b715Smrg 14296747b715Smrg rc = CheckGrabValues(client, param); 143005b261ecSmrg if (rc != Success) 143105b261ecSmrg return rc; 14326747b715Smrg if (param->confineTo == None) 143305b261ecSmrg confineTo = NullWindow; 143405b261ecSmrg else { 14356747b715Smrg rc = dixLookupWindow(&confineTo, param->confineTo, client, DixSetAttrAccess); 143605b261ecSmrg if (rc != Success) 143705b261ecSmrg return rc; 143805b261ecSmrg } 14396747b715Smrg if (param->cursor == None) 144005b261ecSmrg cursor = NullCursor; 144105b261ecSmrg else { 14426747b715Smrg rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, 14436747b715Smrg RT_CURSOR, client, DixUseAccess); 14444642e01fSmrg if (rc != Success) 14454642e01fSmrg { 14466747b715Smrg client->errorValue = param->cursor; 14476747b715Smrg return rc; 144805b261ecSmrg } 14494642e01fSmrg access_mode |= DixForceAccess; 145005b261ecSmrg } 14516747b715Smrg if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 14524642e01fSmrg access_mode |= DixFreezeAccess; 14534642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 14546747b715Smrg if (rc != Success) 14556747b715Smrg return rc; 14566747b715Smrg rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 14574642e01fSmrg if (rc != Success) 14584642e01fSmrg return rc; 145905b261ecSmrg 14606747b715Smrg if (grabtype == GRABTYPE_XI) 14616747b715Smrg type = DeviceButtonPress; 14626747b715Smrg else if (grabtype == GRABTYPE_XI2) 14636747b715Smrg type = XI_ButtonPress; 14646747b715Smrg 14656747b715Smrg grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, 14666747b715Smrg mask, param, type, button, confineTo, cursor); 146705b261ecSmrg if (!grab) 146805b261ecSmrg return BadAlloc; 14694642e01fSmrg return AddPassiveGrabToList(client, grab); 147005b261ecSmrg} 147105b261ecSmrg 14726747b715Smrg/** 14736747b715Smrg * Grab the given key. If grabtype is GRABTYPE_XI, the key is a keycode. If 14746747b715Smrg * grabtype is GRABTYPE_XI2, the key is a keysym. 14756747b715Smrg */ 147605b261ecSmrgint 14776747b715SmrgGrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, 14786747b715Smrg int key, GrabParameters *param, GrabType grabtype, GrabMask *mask) 147905b261ecSmrg{ 148005b261ecSmrg WindowPtr pWin; 148105b261ecSmrg GrabPtr grab; 148205b261ecSmrg KeyClassPtr k = dev->key; 14834642e01fSmrg Mask access_mode = DixGrabAccess; 14846747b715Smrg int rc, type = -1; 148505b261ecSmrg 14866747b715Smrg rc = CheckGrabValues(client, param); 14876747b715Smrg if (rc != Success) 14886747b715Smrg return rc; 148905b261ecSmrg if (k == NULL) 149005b261ecSmrg return BadMatch; 14916747b715Smrg if (grabtype == GRABTYPE_XI) 14926747b715Smrg { 14936747b715Smrg if ((key > k->xkbInfo->desc->max_key_code || 14946747b715Smrg key < k->xkbInfo->desc->min_key_code) 14956747b715Smrg && (key != AnyKey)) { 14966747b715Smrg client->errorValue = key; 14976747b715Smrg return BadValue; 14986747b715Smrg } 14996747b715Smrg type = DeviceKeyPress; 15006747b715Smrg } else if (grabtype == GRABTYPE_XI2) 15016747b715Smrg type = XI_KeyPress; 15026747b715Smrg 15036747b715Smrg rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 15044642e01fSmrg if (rc != Success) 15054642e01fSmrg return rc; 15066747b715Smrg if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 15074642e01fSmrg access_mode |= DixFreezeAccess; 15084642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 150905b261ecSmrg if (rc != Success) 151005b261ecSmrg return rc; 151105b261ecSmrg 15126747b715Smrg grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, 15136747b715Smrg mask, param, type, key, NULL, NULL); 151405b261ecSmrg if (!grab) 151505b261ecSmrg return BadAlloc; 15164642e01fSmrg return AddPassiveGrabToList(client, grab); 151705b261ecSmrg} 151805b261ecSmrg 15196747b715Smrg/* Enter/FocusIn grab */ 15206747b715Smrgint 15216747b715SmrgGrabWindow(ClientPtr client, DeviceIntPtr dev, int type, 15226747b715Smrg GrabParameters *param, GrabMask *mask) 15236747b715Smrg{ 15246747b715Smrg WindowPtr pWin; 15256747b715Smrg CursorPtr cursor; 15266747b715Smrg GrabPtr grab; 15276747b715Smrg Mask access_mode = DixGrabAccess; 15286747b715Smrg int rc; 15296747b715Smrg 15306747b715Smrg rc = CheckGrabValues(client, param); 15316747b715Smrg if (rc != Success) 15326747b715Smrg return rc; 15336747b715Smrg 15346747b715Smrg rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 15356747b715Smrg if (rc != Success) 15366747b715Smrg return rc; 15376747b715Smrg if (param->cursor == None) 15386747b715Smrg cursor = NullCursor; 15396747b715Smrg else { 15406747b715Smrg rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, 15416747b715Smrg RT_CURSOR, client, DixUseAccess); 15426747b715Smrg if (rc != Success) 15436747b715Smrg { 15446747b715Smrg client->errorValue = param->cursor; 15456747b715Smrg return rc; 15466747b715Smrg } 15476747b715Smrg access_mode |= DixForceAccess; 15486747b715Smrg } 15496747b715Smrg if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 15506747b715Smrg access_mode |= DixFreezeAccess; 15516747b715Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 15526747b715Smrg if (rc != Success) 15536747b715Smrg return rc; 15546747b715Smrg 15556747b715Smrg grab = CreateGrab(client->index, dev, dev, pWin, GRABTYPE_XI2, 15566747b715Smrg mask, param, (type == XIGrabtypeEnter) ? XI_Enter : XI_FocusIn, 15576747b715Smrg 0, NULL, cursor); 15586747b715Smrg 15596747b715Smrg if (!grab) 15606747b715Smrg return BadAlloc; 15616747b715Smrg 15626747b715Smrg return AddPassiveGrabToList(client, grab); 15636747b715Smrg} 15646747b715Smrg 156505b261ecSmrgint 156605b261ecSmrgSelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client, 15676747b715Smrg Mask mask, Mask exclusivemasks) 156805b261ecSmrg{ 156905b261ecSmrg int mskidx = dev->id; 157005b261ecSmrg int i, ret; 157105b261ecSmrg Mask check; 157205b261ecSmrg InputClientsPtr others; 157305b261ecSmrg 157405b261ecSmrg check = (mask & exclusivemasks); 157505b261ecSmrg if (wOtherInputMasks(pWin)) { 157605b261ecSmrg if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) { /* It is illegal for two different 157705b261ecSmrg * clients to select on any of the 157805b261ecSmrg * events for maskcheck. However, 157905b261ecSmrg * it is OK, for some client to 158005b261ecSmrg * continue selecting on one of those 158105b261ecSmrg * events. */ 158205b261ecSmrg for (others = wOtherInputMasks(pWin)->inputClients; others; 158305b261ecSmrg others = others->next) { 158405b261ecSmrg if (!SameClient(others, client) && (check & 158505b261ecSmrg others->mask[mskidx])) 158605b261ecSmrg return BadAccess; 158705b261ecSmrg } 158805b261ecSmrg } 158905b261ecSmrg for (others = wOtherInputMasks(pWin)->inputClients; others; 159005b261ecSmrg others = others->next) { 159105b261ecSmrg if (SameClient(others, client)) { 159205b261ecSmrg check = others->mask[mskidx]; 159305b261ecSmrg others->mask[mskidx] = mask; 159405b261ecSmrg if (mask == 0) { 159505b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 159605b261ecSmrg if (i != mskidx && others->mask[i] != 0) 159705b261ecSmrg break; 159805b261ecSmrg if (i == EMASKSIZE) { 159905b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 160005b261ecSmrg if (ShouldFreeInputMasks(pWin, FALSE)) 160105b261ecSmrg FreeResource(others->resource, RT_NONE); 160205b261ecSmrg return Success; 160305b261ecSmrg } 160405b261ecSmrg } 160505b261ecSmrg goto maskSet; 160605b261ecSmrg } 160705b261ecSmrg } 160805b261ecSmrg } 160905b261ecSmrg check = 0; 161005b261ecSmrg if ((ret = AddExtensionClient(pWin, client, mask, mskidx)) != Success) 161105b261ecSmrg return ret; 161205b261ecSmrg maskSet: 161305b261ecSmrg if (dev->valuator) 161405b261ecSmrg if ((dev->valuator->motionHintWindow == pWin) && 161505b261ecSmrg (mask & DevicePointerMotionHintMask) && 16164642e01fSmrg !(check & DevicePointerMotionHintMask) && !dev->deviceGrab.grab) 161705b261ecSmrg dev->valuator->motionHintWindow = NullWindow; 161805b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 161905b261ecSmrg return Success; 162005b261ecSmrg} 162105b261ecSmrg 162205b261ecSmrgint 162305b261ecSmrgAddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx) 162405b261ecSmrg{ 162505b261ecSmrg InputClientsPtr others; 162605b261ecSmrg 162705b261ecSmrg if (!pWin->optional && !MakeWindowOptional(pWin)) 162805b261ecSmrg return BadAlloc; 16296747b715Smrg others = calloc(1, sizeof(InputClients)); 163005b261ecSmrg if (!others) 163105b261ecSmrg return BadAlloc; 163205b261ecSmrg if (!pWin->optional->inputMasks && !MakeInputMasks(pWin)) 163305b261ecSmrg return BadAlloc; 163405b261ecSmrg others->mask[mskidx] = mask; 163505b261ecSmrg others->resource = FakeClientID(client->index); 163605b261ecSmrg others->next = pWin->optional->inputMasks->inputClients; 163705b261ecSmrg pWin->optional->inputMasks->inputClients = others; 163805b261ecSmrg if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer) pWin)) 163905b261ecSmrg return BadAlloc; 164005b261ecSmrg return Success; 164105b261ecSmrg} 164205b261ecSmrg 164305b261ecSmrgstatic Bool 164405b261ecSmrgMakeInputMasks(WindowPtr pWin) 164505b261ecSmrg{ 164605b261ecSmrg struct _OtherInputMasks *imasks; 164705b261ecSmrg 16486747b715Smrg imasks = calloc(1, sizeof(struct _OtherInputMasks)); 164905b261ecSmrg if (!imasks) 165005b261ecSmrg return FALSE; 165105b261ecSmrg pWin->optional->inputMasks = imasks; 165205b261ecSmrg return TRUE; 165305b261ecSmrg} 165405b261ecSmrg 165505b261ecSmrgvoid 165605b261ecSmrgRecalculateDeviceDeliverableEvents(WindowPtr pWin) 165705b261ecSmrg{ 165805b261ecSmrg InputClientsPtr others; 165905b261ecSmrg struct _OtherInputMasks *inputMasks; /* default: NULL */ 166005b261ecSmrg WindowPtr pChild, tmp; 16616747b715Smrg int i, j; 166205b261ecSmrg 166305b261ecSmrg pChild = pWin; 166405b261ecSmrg while (1) { 166505b261ecSmrg if ((inputMasks = wOtherInputMasks(pChild)) != 0) { 16666747b715Smrg for (i = 0; i < EMASKSIZE; i++) 16676747b715Smrg memset(inputMasks->xi2mask[i], 0, sizeof(inputMasks->xi2mask[i])); 166805b261ecSmrg for (others = inputMasks->inputClients; others; 166905b261ecSmrg others = others->next) { 167005b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 167105b261ecSmrg inputMasks->inputEvents[i] |= others->mask[i]; 16726747b715Smrg for (i = 0; i < EMASKSIZE; i++) 16736747b715Smrg for (j = 0; j < XI2MASKSIZE; j++) 16746747b715Smrg inputMasks->xi2mask[i][j] |= others->xi2mask[i][j]; 167505b261ecSmrg } 167605b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 167705b261ecSmrg inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i]; 167805b261ecSmrg for (tmp = pChild->parent; tmp; tmp = tmp->parent) 167905b261ecSmrg if (wOtherInputMasks(tmp)) 168005b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 168105b261ecSmrg inputMasks->deliverableEvents[i] |= 168205b261ecSmrg (wOtherInputMasks(tmp)->deliverableEvents[i] 168305b261ecSmrg & ~inputMasks-> 168405b261ecSmrg dontPropagateMask[i] & PropagateMask[i]); 168505b261ecSmrg } 168605b261ecSmrg if (pChild->firstChild) { 168705b261ecSmrg pChild = pChild->firstChild; 168805b261ecSmrg continue; 168905b261ecSmrg } 169005b261ecSmrg while (!pChild->nextSib && (pChild != pWin)) 169105b261ecSmrg pChild = pChild->parent; 169205b261ecSmrg if (pChild == pWin) 169305b261ecSmrg break; 169405b261ecSmrg pChild = pChild->nextSib; 169505b261ecSmrg } 169605b261ecSmrg} 169705b261ecSmrg 169805b261ecSmrgint 169905b261ecSmrgInputClientGone(WindowPtr pWin, XID id) 170005b261ecSmrg{ 170105b261ecSmrg InputClientsPtr other, prev; 170205b261ecSmrg 170305b261ecSmrg if (!wOtherInputMasks(pWin)) 17046747b715Smrg return Success; 170505b261ecSmrg prev = 0; 170605b261ecSmrg for (other = wOtherInputMasks(pWin)->inputClients; other; 170705b261ecSmrg other = other->next) { 170805b261ecSmrg if (other->resource == id) { 170905b261ecSmrg if (prev) { 171005b261ecSmrg prev->next = other->next; 17116747b715Smrg free(other); 171205b261ecSmrg } else if (!(other->next)) { 171305b261ecSmrg if (ShouldFreeInputMasks(pWin, TRUE)) { 171405b261ecSmrg wOtherInputMasks(pWin)->inputClients = other->next; 17156747b715Smrg free(wOtherInputMasks(pWin)); 171605b261ecSmrg pWin->optional->inputMasks = (OtherInputMasks *) NULL; 171705b261ecSmrg CheckWindowOptionalNeed(pWin); 17186747b715Smrg free(other); 171905b261ecSmrg } else { 172005b261ecSmrg other->resource = FakeClientID(0); 172105b261ecSmrg if (!AddResource(other->resource, RT_INPUTCLIENT, 172205b261ecSmrg (pointer) pWin)) 172305b261ecSmrg return BadAlloc; 172405b261ecSmrg } 172505b261ecSmrg } else { 172605b261ecSmrg wOtherInputMasks(pWin)->inputClients = other->next; 17276747b715Smrg free(other); 172805b261ecSmrg } 172905b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 17306747b715Smrg return Success; 173105b261ecSmrg } 173205b261ecSmrg prev = other; 173305b261ecSmrg } 173405b261ecSmrg FatalError("client not on device event list"); 173505b261ecSmrg} 173605b261ecSmrg 173705b261ecSmrgint 173805b261ecSmrgSendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate, 173905b261ecSmrg xEvent * ev, Mask mask, int count) 174005b261ecSmrg{ 174105b261ecSmrg WindowPtr pWin; 174205b261ecSmrg WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ 17434642e01fSmrg WindowPtr spriteWin = GetSpriteWindow(d); 174405b261ecSmrg 174505b261ecSmrg if (dest == PointerWindow) 174605b261ecSmrg pWin = spriteWin; 174705b261ecSmrg else if (dest == InputFocus) { 174805b261ecSmrg WindowPtr inputFocus; 174905b261ecSmrg 175005b261ecSmrg if (!d->focus) 175105b261ecSmrg inputFocus = spriteWin; 175205b261ecSmrg else 175305b261ecSmrg inputFocus = d->focus->win; 175405b261ecSmrg 175505b261ecSmrg if (inputFocus == FollowKeyboardWin) 175605b261ecSmrg inputFocus = inputInfo.keyboard->focus->win; 175705b261ecSmrg 175805b261ecSmrg if (inputFocus == NoneWin) 175905b261ecSmrg return Success; 176005b261ecSmrg 176105b261ecSmrg /* If the input focus is PointerRootWin, send the event to where 176205b261ecSmrg * the pointer is if possible, then perhaps propogate up to root. */ 176305b261ecSmrg if (inputFocus == PointerRootWin) 17644642e01fSmrg inputFocus = GetCurrentRootWindow(d); 176505b261ecSmrg 176605b261ecSmrg if (IsParent(inputFocus, spriteWin)) { 176705b261ecSmrg effectiveFocus = inputFocus; 176805b261ecSmrg pWin = spriteWin; 176905b261ecSmrg } else 177005b261ecSmrg effectiveFocus = pWin = inputFocus; 177105b261ecSmrg } else 17724642e01fSmrg dixLookupWindow(&pWin, dest, client, DixSendAccess); 177305b261ecSmrg if (!pWin) 177405b261ecSmrg return BadWindow; 177505b261ecSmrg if ((propagate != xFalse) && (propagate != xTrue)) { 177605b261ecSmrg client->errorValue = propagate; 177705b261ecSmrg return BadValue; 177805b261ecSmrg } 177905b261ecSmrg ev->u.u.type |= 0x80; 178005b261ecSmrg if (propagate) { 178105b261ecSmrg for (; pWin; pWin = pWin->parent) { 17826747b715Smrg if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab)) 178305b261ecSmrg return Success; 178405b261ecSmrg if (pWin == effectiveFocus) 178505b261ecSmrg return Success; 178605b261ecSmrg if (wOtherInputMasks(pWin)) 178705b261ecSmrg mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id]; 178805b261ecSmrg if (!mask) 178905b261ecSmrg break; 179005b261ecSmrg } 17914642e01fSmrg } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count)) 17926747b715Smrg DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab); 179305b261ecSmrg return Success; 179405b261ecSmrg} 179505b261ecSmrg 179605b261ecSmrgint 179705b261ecSmrgSetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map) 179805b261ecSmrg{ 179905b261ecSmrg int i; 180005b261ecSmrg ButtonClassPtr b = dev->button; 180105b261ecSmrg 180205b261ecSmrg if (b == NULL) 180305b261ecSmrg return BadMatch; 180405b261ecSmrg 180505b261ecSmrg if (nElts != b->numButtons) { 180605b261ecSmrg client->errorValue = nElts; 180705b261ecSmrg return BadValue; 180805b261ecSmrg } 180905b261ecSmrg if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue)) 181005b261ecSmrg return BadValue; 181105b261ecSmrg for (i = 0; i < nElts; i++) 181205b261ecSmrg if ((b->map[i + 1] != map[i]) && BitIsOn(b->down, i + 1)) 181305b261ecSmrg return MappingBusy; 181405b261ecSmrg for (i = 0; i < nElts; i++) 181505b261ecSmrg b->map[i + 1] = map[i]; 181605b261ecSmrg return Success; 181705b261ecSmrg} 181805b261ecSmrg 181905b261ecSmrgint 182005b261ecSmrgChangeKeyMapping(ClientPtr client, 182105b261ecSmrg DeviceIntPtr dev, 182205b261ecSmrg unsigned len, 182305b261ecSmrg int type, 182405b261ecSmrg KeyCode firstKeyCode, 182505b261ecSmrg CARD8 keyCodes, CARD8 keySymsPerKeyCode, KeySym * map) 182605b261ecSmrg{ 182705b261ecSmrg KeySymsRec keysyms; 182805b261ecSmrg KeyClassPtr k = dev->key; 182905b261ecSmrg 183005b261ecSmrg if (k == NULL) 18316747b715Smrg return BadMatch; 183205b261ecSmrg 183305b261ecSmrg if (len != (keyCodes * keySymsPerKeyCode)) 183405b261ecSmrg return BadLength; 183505b261ecSmrg 18366747b715Smrg if ((firstKeyCode < k->xkbInfo->desc->min_key_code) || 18376747b715Smrg (firstKeyCode + keyCodes - 1 > k->xkbInfo->desc->max_key_code)) { 183805b261ecSmrg client->errorValue = firstKeyCode; 183905b261ecSmrg return BadValue; 184005b261ecSmrg } 184105b261ecSmrg if (keySymsPerKeyCode == 0) { 184205b261ecSmrg client->errorValue = 0; 184305b261ecSmrg return BadValue; 184405b261ecSmrg } 184505b261ecSmrg keysyms.minKeyCode = firstKeyCode; 184605b261ecSmrg keysyms.maxKeyCode = firstKeyCode + keyCodes - 1; 184705b261ecSmrg keysyms.mapWidth = keySymsPerKeyCode; 184805b261ecSmrg keysyms.map = map; 18496747b715Smrg 18506747b715Smrg XkbApplyMappingChange(dev, &keysyms, firstKeyCode, keyCodes, NULL, 18516747b715Smrg serverClient); 18526747b715Smrg 18536747b715Smrg return Success; 185405b261ecSmrg} 185505b261ecSmrg 185605b261ecSmrgstatic void 185705b261ecSmrgDeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) 185805b261ecSmrg{ 185905b261ecSmrg WindowPtr parent; 186005b261ecSmrg 186105b261ecSmrg /* Deactivate any grabs performed on this window, before making 186205b261ecSmrg * any input focus changes. 186305b261ecSmrg * Deactivating a device grab should cause focus events. */ 186405b261ecSmrg 18654642e01fSmrg if (dev->deviceGrab.grab && (dev->deviceGrab.grab->window == pWin)) 18664642e01fSmrg (*dev->deviceGrab.DeactivateGrab) (dev); 186705b261ecSmrg 18684642e01fSmrg /* If the focus window is a root window (ie. has no parent) 186905b261ecSmrg * then don't delete the focus from it. */ 187005b261ecSmrg 187105b261ecSmrg if (dev->focus && (pWin == dev->focus->win) && (pWin->parent != NullWindow)) { 187205b261ecSmrg int focusEventMode = NotifyNormal; 187305b261ecSmrg 187405b261ecSmrg /* If a grab is in progress, then alter the mode of focus events. */ 187505b261ecSmrg 18764642e01fSmrg if (dev->deviceGrab.grab) 187705b261ecSmrg focusEventMode = NotifyWhileGrabbed; 187805b261ecSmrg 187905b261ecSmrg switch (dev->focus->revert) { 188005b261ecSmrg case RevertToNone: 18816747b715Smrg if (!ActivateFocusInGrab(dev, pWin, NoneWin)) 18826747b715Smrg DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 188305b261ecSmrg dev->focus->win = NoneWin; 188405b261ecSmrg dev->focus->traceGood = 0; 188505b261ecSmrg break; 188605b261ecSmrg case RevertToParent: 188705b261ecSmrg parent = pWin; 188805b261ecSmrg do { 188905b261ecSmrg parent = parent->parent; 189005b261ecSmrg dev->focus->traceGood--; 189105b261ecSmrg } 189205b261ecSmrg while (!parent->realized); 18936747b715Smrg if (!ActivateFocusInGrab(dev, pWin, parent)) 18946747b715Smrg DoFocusEvents(dev, pWin, parent, focusEventMode); 189505b261ecSmrg dev->focus->win = parent; 189605b261ecSmrg dev->focus->revert = RevertToNone; 189705b261ecSmrg break; 189805b261ecSmrg case RevertToPointerRoot: 18996747b715Smrg if (!ActivateFocusInGrab(dev, pWin, PointerRootWin)) 19006747b715Smrg DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode); 190105b261ecSmrg dev->focus->win = PointerRootWin; 190205b261ecSmrg dev->focus->traceGood = 0; 190305b261ecSmrg break; 190405b261ecSmrg case RevertToFollowKeyboard: 19056747b715Smrg { 19066747b715Smrg DeviceIntPtr kbd = GetMaster(dev, MASTER_KEYBOARD); 19076747b715Smrg if (!kbd || (kbd == dev && kbd != inputInfo.keyboard)) 19086747b715Smrg kbd = inputInfo.keyboard; 19096747b715Smrg if (kbd->focus->win) { 19106747b715Smrg if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win)) 19116747b715Smrg DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode); 191205b261ecSmrg dev->focus->win = FollowKeyboardWin; 191305b261ecSmrg dev->focus->traceGood = 0; 191405b261ecSmrg } else { 19156747b715Smrg if (!ActivateFocusInGrab(dev, pWin, NoneWin)) 19166747b715Smrg DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 191705b261ecSmrg dev->focus->win = NoneWin; 191805b261ecSmrg dev->focus->traceGood = 0; 191905b261ecSmrg } 19206747b715Smrg } 192105b261ecSmrg break; 192205b261ecSmrg } 192305b261ecSmrg } 192405b261ecSmrg 192505b261ecSmrg if (dev->valuator) 192605b261ecSmrg if (dev->valuator->motionHintWindow == pWin) 192705b261ecSmrg dev->valuator->motionHintWindow = NullWindow; 192805b261ecSmrg} 192905b261ecSmrg 193005b261ecSmrgvoid 193105b261ecSmrgDeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources) 193205b261ecSmrg{ 193305b261ecSmrg int i; 193405b261ecSmrg DeviceIntPtr dev; 193505b261ecSmrg InputClientsPtr ic; 193605b261ecSmrg struct _OtherInputMasks *inputMasks; 193705b261ecSmrg 193805b261ecSmrg for (dev = inputInfo.devices; dev; dev = dev->next) { 193905b261ecSmrg DeleteDeviceFromAnyExtEvents(pWin, dev); 194005b261ecSmrg } 194105b261ecSmrg 194205b261ecSmrg for (dev = inputInfo.off_devices; dev; dev = dev->next) 194305b261ecSmrg DeleteDeviceFromAnyExtEvents(pWin, dev); 194405b261ecSmrg 194505b261ecSmrg if (freeResources) 194605b261ecSmrg while ((inputMasks = wOtherInputMasks(pWin)) != 0) { 194705b261ecSmrg ic = inputMasks->inputClients; 194805b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 194905b261ecSmrg inputMasks->dontPropagateMask[i] = 0; 195005b261ecSmrg FreeResource(ic->resource, RT_NONE); 195105b261ecSmrg } 195205b261ecSmrg} 195305b261ecSmrg 195405b261ecSmrgint 195505b261ecSmrgMaybeSendDeviceMotionNotifyHint(deviceKeyButtonPointer * pEvents, Mask mask) 195605b261ecSmrg{ 195705b261ecSmrg DeviceIntPtr dev; 195805b261ecSmrg 19594642e01fSmrg dixLookupDevice(&dev, pEvents->deviceid & DEVICE_BITS, serverClient, 19604642e01fSmrg DixReadAccess); 196105b261ecSmrg if (!dev) 196205b261ecSmrg return 0; 196305b261ecSmrg 196405b261ecSmrg if (pEvents->type == DeviceMotionNotify) { 196505b261ecSmrg if (mask & DevicePointerMotionHintMask) { 196605b261ecSmrg if (WID(dev->valuator->motionHintWindow) == pEvents->event) { 196705b261ecSmrg return 1; /* don't send, but pretend we did */ 196805b261ecSmrg } 196905b261ecSmrg pEvents->detail = NotifyHint; 197005b261ecSmrg } else { 197105b261ecSmrg pEvents->detail = NotifyNormal; 197205b261ecSmrg } 197305b261ecSmrg } 19746747b715Smrg return 0; 197505b261ecSmrg} 197605b261ecSmrg 197705b261ecSmrgvoid 197805b261ecSmrgCheckDeviceGrabAndHintWindow(WindowPtr pWin, int type, 197905b261ecSmrg deviceKeyButtonPointer * xE, GrabPtr grab, 198005b261ecSmrg ClientPtr client, Mask deliveryMask) 198105b261ecSmrg{ 198205b261ecSmrg DeviceIntPtr dev; 198305b261ecSmrg 19844642e01fSmrg dixLookupDevice(&dev, xE->deviceid & DEVICE_BITS, serverClient, 19856747b715Smrg DixGrabAccess); 198605b261ecSmrg if (!dev) 198705b261ecSmrg return; 198805b261ecSmrg 198905b261ecSmrg if (type == DeviceMotionNotify) 199005b261ecSmrg dev->valuator->motionHintWindow = pWin; 199105b261ecSmrg else if ((type == DeviceButtonPress) && (!grab) && 199205b261ecSmrg (deliveryMask & DeviceButtonGrabMask)) { 199305b261ecSmrg GrabRec tempGrab; 199405b261ecSmrg 199505b261ecSmrg tempGrab.device = dev; 199605b261ecSmrg tempGrab.resource = client->clientAsMask; 199705b261ecSmrg tempGrab.window = pWin; 199805b261ecSmrg tempGrab.ownerEvents = 199905b261ecSmrg (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE; 200005b261ecSmrg tempGrab.eventMask = deliveryMask; 200105b261ecSmrg tempGrab.keyboardMode = GrabModeAsync; 200205b261ecSmrg tempGrab.pointerMode = GrabModeAsync; 200305b261ecSmrg tempGrab.confineTo = NullWindow; 200405b261ecSmrg tempGrab.cursor = NullCursor; 20054642e01fSmrg tempGrab.next = NULL; 20064642e01fSmrg (*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE); 200705b261ecSmrg } 200805b261ecSmrg} 200905b261ecSmrg 201005b261ecSmrgstatic Mask 201105b261ecSmrgDeviceEventMaskForClient(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client) 201205b261ecSmrg{ 201305b261ecSmrg InputClientsPtr other; 201405b261ecSmrg 201505b261ecSmrg if (!wOtherInputMasks(pWin)) 201605b261ecSmrg return 0; 201705b261ecSmrg for (other = wOtherInputMasks(pWin)->inputClients; other; 201805b261ecSmrg other = other->next) { 201905b261ecSmrg if (SameClient(other, client)) 202005b261ecSmrg return other->mask[dev->id]; 202105b261ecSmrg } 202205b261ecSmrg return 0; 202305b261ecSmrg} 202405b261ecSmrg 202505b261ecSmrgvoid 202605b261ecSmrgMaybeStopDeviceHint(DeviceIntPtr dev, ClientPtr client) 202705b261ecSmrg{ 202805b261ecSmrg WindowPtr pWin; 20294642e01fSmrg GrabPtr grab = dev->deviceGrab.grab; 203005b261ecSmrg 203105b261ecSmrg pWin = dev->valuator->motionHintWindow; 203205b261ecSmrg 203305b261ecSmrg if ((grab && SameClient(grab, client) && 203405b261ecSmrg ((grab->eventMask & DevicePointerMotionHintMask) || 203505b261ecSmrg (grab->ownerEvents && 203605b261ecSmrg (DeviceEventMaskForClient(dev, pWin, client) & 203705b261ecSmrg DevicePointerMotionHintMask)))) || 203805b261ecSmrg (!grab && 203905b261ecSmrg (DeviceEventMaskForClient(dev, pWin, client) & 204005b261ecSmrg DevicePointerMotionHintMask))) 204105b261ecSmrg dev->valuator->motionHintWindow = NullWindow; 204205b261ecSmrg} 204305b261ecSmrg 204405b261ecSmrgint 204505b261ecSmrgDeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask, 204605b261ecSmrg int maskndx) 204705b261ecSmrg{ 204805b261ecSmrg struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 204905b261ecSmrg 205005b261ecSmrg if (mask & ~PropagateMask[maskndx]) { 205105b261ecSmrg client->errorValue = mask; 205205b261ecSmrg return BadValue; 205305b261ecSmrg } 205405b261ecSmrg 205505b261ecSmrg if (mask == 0) { 205605b261ecSmrg if (inputMasks) 205705b261ecSmrg inputMasks->dontPropagateMask[maskndx] = mask; 205805b261ecSmrg } else { 205905b261ecSmrg if (!inputMasks) 206005b261ecSmrg AddExtensionClient(pWin, client, 0, 0); 206105b261ecSmrg inputMasks = wOtherInputMasks(pWin); 206205b261ecSmrg inputMasks->dontPropagateMask[maskndx] = mask; 206305b261ecSmrg } 206405b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 206505b261ecSmrg if (ShouldFreeInputMasks(pWin, FALSE)) 206605b261ecSmrg FreeResource(inputMasks->inputClients->resource, RT_NONE); 206705b261ecSmrg return Success; 206805b261ecSmrg} 206905b261ecSmrg 20704642e01fSmrgBool 207105b261ecSmrgShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents) 207205b261ecSmrg{ 207305b261ecSmrg int i; 207405b261ecSmrg Mask allInputEventMasks = 0; 207505b261ecSmrg struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 207605b261ecSmrg 207705b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 207805b261ecSmrg allInputEventMasks |= inputMasks->dontPropagateMask[i]; 207905b261ecSmrg if (!ignoreSelectedEvents) 208005b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 208105b261ecSmrg allInputEventMasks |= inputMasks->inputEvents[i]; 208205b261ecSmrg if (allInputEventMasks == 0) 208305b261ecSmrg return TRUE; 208405b261ecSmrg else 208505b261ecSmrg return FALSE; 208605b261ecSmrg} 208705b261ecSmrg 208805b261ecSmrg/*********************************************************************** 208905b261ecSmrg * 209005b261ecSmrg * Walk through the window tree, finding all clients that want to know 209105b261ecSmrg * about the Event. 209205b261ecSmrg * 209305b261ecSmrg */ 209405b261ecSmrg 209505b261ecSmrgstatic void 209605b261ecSmrgFindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask, 209705b261ecSmrg xEvent * ev, int count) 209805b261ecSmrg{ 209905b261ecSmrg WindowPtr p2; 210005b261ecSmrg 210105b261ecSmrg while (p1) { 210205b261ecSmrg p2 = p1->firstChild; 21036747b715Smrg DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab); 210405b261ecSmrg FindInterestedChildren(dev, p2, mask, ev, count); 210505b261ecSmrg p1 = p1->nextSib; 210605b261ecSmrg } 210705b261ecSmrg} 210805b261ecSmrg 210905b261ecSmrg/*********************************************************************** 211005b261ecSmrg * 211105b261ecSmrg * Send an event to interested clients in all windows on all screens. 211205b261ecSmrg * 211305b261ecSmrg */ 211405b261ecSmrg 211505b261ecSmrgvoid 211605b261ecSmrgSendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count) 211705b261ecSmrg{ 211805b261ecSmrg int i; 211905b261ecSmrg WindowPtr pWin, p1; 212005b261ecSmrg 212105b261ecSmrg for (i = 0; i < screenInfo.numScreens; i++) { 21226747b715Smrg pWin = screenInfo.screens[i]->root; 21234642e01fSmrg if (!pWin) 21244642e01fSmrg continue; 21256747b715Smrg DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab); 212605b261ecSmrg p1 = pWin->firstChild; 212705b261ecSmrg FindInterestedChildren(dev, p1, mask, ev, count); 212805b261ecSmrg } 212905b261ecSmrg} 21304642e01fSmrg 21316747b715Smrg/** 21326747b715Smrg * Set the XI2 mask for the given client on the given window. 21336747b715Smrg * @param dev The device to set the mask for. 21346747b715Smrg * @param win The window to set the mask on. 21356747b715Smrg * @param client The client setting the mask. 21366747b715Smrg * @param len Number of bytes in mask. 21376747b715Smrg * @param mask Event mask in the form of (1 << eventtype) 21386747b715Smrg */ 21396747b715Smrgint 21406747b715SmrgXISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client, 21416747b715Smrg unsigned int len, unsigned char* mask) 21426747b715Smrg{ 21436747b715Smrg OtherInputMasks *masks; 21446747b715Smrg InputClientsPtr others = NULL; 21456747b715Smrg 21466747b715Smrg masks = wOtherInputMasks(win); 21476747b715Smrg if (masks) 21486747b715Smrg { 21496747b715Smrg for (others = wOtherInputMasks(win)->inputClients; others; 21506747b715Smrg others = others->next) { 21516747b715Smrg if (SameClient(others, client)) { 21526747b715Smrg memset(others->xi2mask[dev->id], 0, 21536747b715Smrg sizeof(others->xi2mask[dev->id])); 21546747b715Smrg break; 21556747b715Smrg } 21566747b715Smrg } 21576747b715Smrg } 21586747b715Smrg 21596747b715Smrg len = min(len, sizeof(others->xi2mask[dev->id])); 21606747b715Smrg 21616747b715Smrg if (len && !others) 21626747b715Smrg { 21636747b715Smrg if (AddExtensionClient(win, client, 0, 0) != Success) 21646747b715Smrg return BadAlloc; 21656747b715Smrg others= wOtherInputMasks(win)->inputClients; 21666747b715Smrg } 21676747b715Smrg 21686747b715Smrg if (others) 21696747b715Smrg memset(others->xi2mask[dev->id], 0, sizeof(others->xi2mask[dev->id])); 21706747b715Smrg 21716747b715Smrg if (len) 21726747b715Smrg memcpy(others->xi2mask[dev->id], mask, len); 21736747b715Smrg 21746747b715Smrg RecalculateDeviceDeliverableEvents(win); 21756747b715Smrg 21766747b715Smrg return Success; 21776747b715Smrg} 2178