exevents.c revision 4642e01f
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#define NEED_EVENTS 5605b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 5705b261ecSmrg#include <dix-config.h> 5805b261ecSmrg#endif 5905b261ecSmrg 6005b261ecSmrg#include <X11/X.h> 6105b261ecSmrg#include <X11/Xproto.h> 6205b261ecSmrg#include <X11/extensions/XI.h> 6305b261ecSmrg#include <X11/extensions/XIproto.h> 644642e01fSmrg#include <X11/extensions/geproto.h> 6505b261ecSmrg#include "inputstr.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" 7705b261ecSmrg 7805b261ecSmrg#ifdef XKB 794642e01fSmrg#include <X11/extensions/XKBproto.h> 8005b261ecSmrg#include "xkbsrv.h" 814642e01fSmrgextern Bool XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies); 8205b261ecSmrg#endif 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#define Motion_Filter(class) (DevicePointerMotionMask | \ 9105b261ecSmrg (class)->state | (class)->motionMask) 9205b261ecSmrg 934642e01fSmrgBool ShouldFreeInputMasks(WindowPtr /* pWin */ , 9405b261ecSmrg Bool /* ignoreSelectedEvents */ 9505b261ecSmrg ); 9605b261ecSmrgstatic Bool MakeInputMasks(WindowPtr /* pWin */ 9705b261ecSmrg ); 9805b261ecSmrg 994642e01fSmrg/* Used to sture classes currently not in use by an MD */ 1004642e01fSmrgextern DevPrivateKey UnusedClassesPrivateKey; 1014642e01fSmrg 10205b261ecSmrg 10305b261ecSmrgvoid 10405b261ecSmrgRegisterOtherDevice(DeviceIntPtr device) 10505b261ecSmrg{ 10605b261ecSmrg device->public.processInputProc = ProcessOtherEvent; 10705b261ecSmrg device->public.realInputProc = ProcessOtherEvent; 10805b261ecSmrg} 10905b261ecSmrg 1104642e01fSmrgBool 1114642e01fSmrgIsPointerEvent(xEvent* xE) 1124642e01fSmrg{ 1134642e01fSmrg switch(xE->u.u.type) 1144642e01fSmrg { 1154642e01fSmrg case ButtonPress: 1164642e01fSmrg case ButtonRelease: 1174642e01fSmrg case MotionNotify: 1184642e01fSmrg case EnterNotify: 1194642e01fSmrg case LeaveNotify: 1204642e01fSmrg return TRUE; 1214642e01fSmrg default: 1224642e01fSmrg if (xE->u.u.type == DeviceButtonPress || 1234642e01fSmrg xE->u.u.type == DeviceButtonRelease || 1244642e01fSmrg xE->u.u.type == DeviceMotionNotify || 1254642e01fSmrg xE->u.u.type == ProximityIn || 1264642e01fSmrg xE->u.u.type == ProximityOut) 1274642e01fSmrg { 1284642e01fSmrg return TRUE; 1294642e01fSmrg } 1304642e01fSmrg } 1314642e01fSmrg return FALSE; 1324642e01fSmrg} 1334642e01fSmrg 1344642e01fSmrg/** 1354642e01fSmrg * @return the device matching the deviceid of the device set in the event, or 1364642e01fSmrg * NULL if the event is not an XInput event. 1374642e01fSmrg */ 1384642e01fSmrgDeviceIntPtr 1394642e01fSmrgXIGetDevice(xEvent* xE) 14005b261ecSmrg{ 1414642e01fSmrg DeviceIntPtr pDev = NULL; 1424642e01fSmrg 1434642e01fSmrg if (xE->u.u.type == DeviceButtonPress || 1444642e01fSmrg xE->u.u.type == DeviceButtonRelease || 1454642e01fSmrg xE->u.u.type == DeviceMotionNotify || 1464642e01fSmrg xE->u.u.type == ProximityIn || 1474642e01fSmrg xE->u.u.type == ProximityOut || 1484642e01fSmrg xE->u.u.type == DevicePropertyNotify) 1494642e01fSmrg { 1504642e01fSmrg int rc; 1514642e01fSmrg int id; 1524642e01fSmrg 1534642e01fSmrg id = ((deviceKeyButtonPointer*)xE)->deviceid & ~MORE_EVENTS; 1544642e01fSmrg 1554642e01fSmrg rc = dixLookupDevice(&pDev, id, serverClient, DixUnknownAccess); 1564642e01fSmrg if (rc != Success) 1574642e01fSmrg ErrorF("[dix] XIGetDevice failed on XACE restrictions (%d)\n", rc); 1584642e01fSmrg } 1594642e01fSmrg return pDev; 1604642e01fSmrg} 1614642e01fSmrg 1624642e01fSmrg 1634642e01fSmrg/** 1644642e01fSmrg * Copy the device->key into master->key and send a mapping notify to the 1654642e01fSmrg * clients if appropriate. 1664642e01fSmrg * master->key needs to be allocated by the caller. 1674642e01fSmrg * 1684642e01fSmrg * Device is the slave device. If it is attached to a master device, we may 1694642e01fSmrg * need to send a mapping notify to the client because it causes the MD 1704642e01fSmrg * to change state. 1714642e01fSmrg * 1724642e01fSmrg * Mapping notify needs to be sent in the following cases: 1734642e01fSmrg * - different slave device on same master 1744642e01fSmrg * - different master 1754642e01fSmrg * 1764642e01fSmrg * XXX: They way how the code is we also send a map notify if the slave device 1774642e01fSmrg * stays the same, but the master changes. This isn't really necessary though. 1784642e01fSmrg * 1794642e01fSmrg * XXX: this gives you funny behaviour with the ClientPointer. When a 1804642e01fSmrg * MappingNotify is sent to the client, the client usually responds with a 1814642e01fSmrg * GetKeyboardMapping. This will retrieve the ClientPointer's keyboard 1824642e01fSmrg * mapping, regardless of which keyboard sent the last mapping notify request. 1834642e01fSmrg * So depending on the CP setting, your keyboard may change layout in each 1844642e01fSmrg * app... 1854642e01fSmrg * 1864642e01fSmrg * This code is basically the old SwitchCoreKeyboard. 1874642e01fSmrg */ 1884642e01fSmrg 1894642e01fSmrgvoid 1904642e01fSmrgCopyKeyClass(DeviceIntPtr device, DeviceIntPtr master) 1914642e01fSmrg{ 1924642e01fSmrg static DeviceIntPtr lastMapNotifyDevice = NULL; 1934642e01fSmrg KeyClassPtr mk, dk; /* master, device */ 1944642e01fSmrg BOOL sendNotify = FALSE; 19505b261ecSmrg int i; 1964642e01fSmrg 1974642e01fSmrg if (device == master) 1984642e01fSmrg return; 1994642e01fSmrg 2004642e01fSmrg dk = device->key; 2014642e01fSmrg mk = master->key; 2024642e01fSmrg 2034642e01fSmrg if (device != dixLookupPrivate(&master->devPrivates, 2044642e01fSmrg CoreDevicePrivateKey)) { 2054642e01fSmrg memcpy(mk->modifierMap, dk->modifierMap, MAP_LENGTH); 2064642e01fSmrg 2074642e01fSmrg if (dk->maxKeysPerModifier) 2084642e01fSmrg { 2094642e01fSmrg mk->modifierKeyMap = xrealloc(mk->modifierKeyMap, 2104642e01fSmrg 8 * dk->maxKeysPerModifier); 2114642e01fSmrg if (!mk->modifierKeyMap) 2124642e01fSmrg FatalError("[Xi] no memory for class shift.\n"); 2134642e01fSmrg memcpy(mk->modifierKeyMap, dk->modifierKeyMap, 2144642e01fSmrg (8 * dk->maxKeysPerModifier)); 2154642e01fSmrg } else 2164642e01fSmrg { 2174642e01fSmrg xfree(mk->modifierKeyMap); 2184642e01fSmrg mk->modifierKeyMap = NULL; 21905b261ecSmrg } 22005b261ecSmrg 2214642e01fSmrg mk->maxKeysPerModifier = dk->maxKeysPerModifier; 2224642e01fSmrg mk->curKeySyms.minKeyCode = dk->curKeySyms.minKeyCode; 2234642e01fSmrg mk->curKeySyms.maxKeyCode = dk->curKeySyms.maxKeyCode; 2244642e01fSmrg SetKeySymsMap(&mk->curKeySyms, &dk->curKeySyms); 2254642e01fSmrg 2264642e01fSmrg /* 2274642e01fSmrg * Copy state from the extended keyboard to core. If you omit this, 2284642e01fSmrg * holding Ctrl on keyboard one, and pressing Q on keyboard two, will 2294642e01fSmrg * cause your app to quit. This feels wrong to me, hence the below 2304642e01fSmrg * code. 2314642e01fSmrg * 2324642e01fSmrg * XXX: If you synthesise core modifier events, the state will get 2334642e01fSmrg * clobbered here. You'll have to work out something sensible 2344642e01fSmrg * to fix that. Good luck. 2354642e01fSmrg */ 2364642e01fSmrg 2374642e01fSmrg#define KEYBOARD_MASK (ShiftMask | LockMask | ControlMask | Mod1Mask | \ 2384642e01fSmrg Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask) 2394642e01fSmrg mk->state &= ~(KEYBOARD_MASK); 2404642e01fSmrg mk->state |= (dk->state & KEYBOARD_MASK); 2414642e01fSmrg#undef KEYBOARD_MASK 2424642e01fSmrg for (i = 0; i < 8; i++) 2434642e01fSmrg mk->modifierKeyCount[i] = dk->modifierKeyCount[i]; 2444642e01fSmrg 2454642e01fSmrg#ifdef XKB 2464642e01fSmrg if (!noXkbExtension && dk->xkbInfo && dk->xkbInfo->desc) { 2474642e01fSmrg if (!mk->xkbInfo || !mk->xkbInfo->desc) 2484642e01fSmrg { 2494642e01fSmrg XkbInitDevice(master); 2504642e01fSmrg XkbFinishDeviceInit(master); 2514642e01fSmrg } 2524642e01fSmrg if (!XkbCopyKeymap(dk->xkbInfo->desc, mk->xkbInfo->desc, True)) 2534642e01fSmrg FatalError("Couldn't pivot keymap from device to core!\n"); 2544642e01fSmrg } 2554642e01fSmrg#endif 2564642e01fSmrg 2574642e01fSmrg dixSetPrivate(&master->devPrivates, CoreDevicePrivateKey, device); 2584642e01fSmrg sendNotify = TRUE; 2594642e01fSmrg } else if (lastMapNotifyDevice != master) 2604642e01fSmrg sendNotify = TRUE; 2614642e01fSmrg 2624642e01fSmrg if (sendNotify) 2634642e01fSmrg { 2644642e01fSmrg SendMappingNotify(master, MappingKeyboard, 2654642e01fSmrg mk->curKeySyms.minKeyCode, 2664642e01fSmrg (mk->curKeySyms.maxKeyCode - 2674642e01fSmrg mk->curKeySyms.minKeyCode), 2684642e01fSmrg serverClient); 2694642e01fSmrg lastMapNotifyDevice = master; 27005b261ecSmrg } 2714642e01fSmrg} 27205b261ecSmrg 2734642e01fSmrg/** 2744642e01fSmrg * Copies the feedback classes from device "from" into device "to". Classes 2754642e01fSmrg * are duplicated (not just flipping the pointers). All feedback classes are 2764642e01fSmrg * linked lists, the full list is duplicated. 2774642e01fSmrg */ 2784642e01fSmrgstatic void 2794642e01fSmrgDeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) 2804642e01fSmrg{ 2814642e01fSmrg ClassesPtr classes; 2824642e01fSmrg 2834642e01fSmrg if (from->kbdfeed) 2844642e01fSmrg { 2854642e01fSmrg KbdFeedbackPtr *k, it; 2864642e01fSmrg 2874642e01fSmrg if (!to->kbdfeed) 2884642e01fSmrg { 2894642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, 2904642e01fSmrg UnusedClassesPrivateKey); 2914642e01fSmrg to->kbdfeed = classes->kbdfeed; 2924642e01fSmrg } 2934642e01fSmrg 2944642e01fSmrg k = &to->kbdfeed; 2954642e01fSmrg for(it = from->kbdfeed; it; it = it->next) 2964642e01fSmrg { 2974642e01fSmrg if (!(*k)) 2984642e01fSmrg { 2994642e01fSmrg *k = xcalloc(1, sizeof(KbdFeedbackClassRec)); 3004642e01fSmrg if (!*k) 3014642e01fSmrg { 3024642e01fSmrg ErrorF("[Xi] Cannot alloc memory for class copy."); 3034642e01fSmrg return; 3044642e01fSmrg } 3054642e01fSmrg } 3064642e01fSmrg (*k)->BellProc = it->BellProc; 3074642e01fSmrg (*k)->CtrlProc = it->CtrlProc; 3084642e01fSmrg (*k)->ctrl = it->ctrl; 3094642e01fSmrg#ifdef XKB 3104642e01fSmrg if ((*k)->xkb_sli) 3114642e01fSmrg XkbFreeSrvLedInfo((*k)->xkb_sli); 3124642e01fSmrg (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL); 3134642e01fSmrg#endif 3144642e01fSmrg 3154642e01fSmrg k = &(*k)->next; 3164642e01fSmrg } 3174642e01fSmrg } else if (to->kbdfeed && !from->kbdfeed) 3184642e01fSmrg { 3194642e01fSmrg ClassesPtr classes; 3204642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 3214642e01fSmrg classes->kbdfeed = to->kbdfeed; 3224642e01fSmrg to->kbdfeed = NULL; 3234642e01fSmrg } 3244642e01fSmrg 3254642e01fSmrg if (from->ptrfeed) 3264642e01fSmrg { 3274642e01fSmrg PtrFeedbackPtr *p, it; 3284642e01fSmrg if (!to->ptrfeed) 3294642e01fSmrg { 3304642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, 3314642e01fSmrg UnusedClassesPrivateKey); 3324642e01fSmrg to->ptrfeed = classes->ptrfeed; 3334642e01fSmrg } 3344642e01fSmrg 3354642e01fSmrg p = &to->ptrfeed; 3364642e01fSmrg for (it = from->ptrfeed; it; it = it->next) 3374642e01fSmrg { 3384642e01fSmrg if (!(*p)) 3394642e01fSmrg { 3404642e01fSmrg *p = xcalloc(1, sizeof(PtrFeedbackClassRec)); 3414642e01fSmrg if (!*p) 3424642e01fSmrg { 3434642e01fSmrg ErrorF("[Xi] Cannot alloc memory for class copy."); 3444642e01fSmrg return; 3454642e01fSmrg } 3464642e01fSmrg } 3474642e01fSmrg (*p)->CtrlProc = it->CtrlProc; 3484642e01fSmrg (*p)->ctrl = it->ctrl; 3494642e01fSmrg 3504642e01fSmrg p = &(*p)->next; 3514642e01fSmrg } 3524642e01fSmrg } else if (to->ptrfeed && !from->ptrfeed) 3534642e01fSmrg { 3544642e01fSmrg ClassesPtr classes; 3554642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 3564642e01fSmrg classes->ptrfeed = to->ptrfeed; 3574642e01fSmrg to->ptrfeed = NULL; 35805b261ecSmrg } 3594642e01fSmrg 3604642e01fSmrg if (from->intfeed) 3614642e01fSmrg { 3624642e01fSmrg IntegerFeedbackPtr *i, it; 3634642e01fSmrg 3644642e01fSmrg if (!to->intfeed) 3654642e01fSmrg { 3664642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, 3674642e01fSmrg UnusedClassesPrivateKey); 3684642e01fSmrg to->intfeed = classes->intfeed; 3694642e01fSmrg } 3704642e01fSmrg 3714642e01fSmrg i = &to->intfeed; 3724642e01fSmrg for (it = from->intfeed; it; it = it->next) 3734642e01fSmrg { 3744642e01fSmrg if (!(*i)) 3754642e01fSmrg { 3764642e01fSmrg *i = xcalloc(1, sizeof(IntegerFeedbackClassRec)); 3774642e01fSmrg if (!(*i)) 3784642e01fSmrg { 3794642e01fSmrg ErrorF("[Xi] Cannot alloc memory for class copy."); 3804642e01fSmrg return; 3814642e01fSmrg } 3824642e01fSmrg } 3834642e01fSmrg (*i)->CtrlProc = it->CtrlProc; 3844642e01fSmrg (*i)->ctrl = it->ctrl; 3854642e01fSmrg 3864642e01fSmrg i = &(*i)->next; 3874642e01fSmrg } 3884642e01fSmrg } else if (to->intfeed && !from->intfeed) 3894642e01fSmrg { 3904642e01fSmrg ClassesPtr classes; 3914642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 3924642e01fSmrg classes->intfeed = to->intfeed; 3934642e01fSmrg to->intfeed = NULL; 3944642e01fSmrg } 3954642e01fSmrg 3964642e01fSmrg if (from->stringfeed) 3974642e01fSmrg { 3984642e01fSmrg StringFeedbackPtr *s, it; 3994642e01fSmrg 4004642e01fSmrg if (!to->stringfeed) 4014642e01fSmrg { 4024642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, 4034642e01fSmrg UnusedClassesPrivateKey); 4044642e01fSmrg to->stringfeed = classes->stringfeed; 4054642e01fSmrg } 4064642e01fSmrg 4074642e01fSmrg s = &to->stringfeed; 4084642e01fSmrg for (it = from->stringfeed; it; it = it->next) 4094642e01fSmrg { 4104642e01fSmrg if (!(*s)) 4114642e01fSmrg { 4124642e01fSmrg *s = xcalloc(1, sizeof(StringFeedbackClassRec)); 4134642e01fSmrg if (!(*s)) 4144642e01fSmrg { 4154642e01fSmrg ErrorF("[Xi] Cannot alloc memory for class copy."); 4164642e01fSmrg return; 4174642e01fSmrg } 4184642e01fSmrg } 4194642e01fSmrg (*s)->CtrlProc = it->CtrlProc; 4204642e01fSmrg (*s)->ctrl = it->ctrl; 4214642e01fSmrg 4224642e01fSmrg s = &(*s)->next; 4234642e01fSmrg } 4244642e01fSmrg } else if (to->stringfeed && !from->stringfeed) 4254642e01fSmrg { 4264642e01fSmrg ClassesPtr classes; 4274642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 4284642e01fSmrg classes->stringfeed = to->stringfeed; 4294642e01fSmrg to->stringfeed = NULL; 4304642e01fSmrg } 4314642e01fSmrg 4324642e01fSmrg if (from->bell) 4334642e01fSmrg { 4344642e01fSmrg BellFeedbackPtr *b, it; 4354642e01fSmrg 4364642e01fSmrg if (!to->bell) 4374642e01fSmrg { 4384642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, 4394642e01fSmrg UnusedClassesPrivateKey); 4404642e01fSmrg to->bell = classes->bell; 4414642e01fSmrg } 4424642e01fSmrg 4434642e01fSmrg b = &to->bell; 4444642e01fSmrg for (it = from->bell; it; it = it->next) 4454642e01fSmrg { 4464642e01fSmrg if (!(*b)) 4474642e01fSmrg { 4484642e01fSmrg *b = xcalloc(1, sizeof(BellFeedbackClassRec)); 4494642e01fSmrg if (!(*b)) 4504642e01fSmrg { 4514642e01fSmrg ErrorF("[Xi] Cannot alloc memory for class copy."); 4524642e01fSmrg return; 4534642e01fSmrg } 4544642e01fSmrg } 4554642e01fSmrg (*b)->BellProc = it->BellProc; 4564642e01fSmrg (*b)->CtrlProc = it->CtrlProc; 4574642e01fSmrg (*b)->ctrl = it->ctrl; 4584642e01fSmrg 4594642e01fSmrg b = &(*b)->next; 4604642e01fSmrg } 4614642e01fSmrg } else if (to->bell && !from->bell) 4624642e01fSmrg { 4634642e01fSmrg ClassesPtr classes; 4644642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 4654642e01fSmrg classes->bell = to->bell; 4664642e01fSmrg to->bell = NULL; 4674642e01fSmrg } 4684642e01fSmrg 4694642e01fSmrg if (from->leds) 4704642e01fSmrg { 4714642e01fSmrg LedFeedbackPtr *l, it; 4724642e01fSmrg 4734642e01fSmrg if (!to->leds) 4744642e01fSmrg { 4754642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, 4764642e01fSmrg UnusedClassesPrivateKey); 4774642e01fSmrg to->leds = classes->leds; 4784642e01fSmrg } 4794642e01fSmrg 4804642e01fSmrg l = &to->leds; 4814642e01fSmrg for (it = from->leds; it; it = it->next) 4824642e01fSmrg { 4834642e01fSmrg if (!(*l)) 4844642e01fSmrg { 4854642e01fSmrg *l = xcalloc(1, sizeof(LedFeedbackClassRec)); 4864642e01fSmrg if (!(*l)) 4874642e01fSmrg { 4884642e01fSmrg ErrorF("[Xi] Cannot alloc memory for class copy."); 4894642e01fSmrg return; 4904642e01fSmrg } 4914642e01fSmrg } 4924642e01fSmrg (*l)->CtrlProc = it->CtrlProc; 4934642e01fSmrg (*l)->ctrl = it->ctrl; 4944642e01fSmrg#ifdef XKB 4954642e01fSmrg if ((*l)->xkb_sli) 4964642e01fSmrg XkbFreeSrvLedInfo((*l)->xkb_sli); 4974642e01fSmrg (*l)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, NULL, *l); 4984642e01fSmrg#endif 4994642e01fSmrg 5004642e01fSmrg l = &(*l)->next; 5014642e01fSmrg } 5024642e01fSmrg } else if (to->leds && !from->leds) 5034642e01fSmrg { 5044642e01fSmrg ClassesPtr classes; 5054642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 5064642e01fSmrg classes->leds = to->leds; 5074642e01fSmrg to->leds = NULL; 5084642e01fSmrg } 5094642e01fSmrg} 5104642e01fSmrg 5114642e01fSmrg/** 5124642e01fSmrg * Copies the CONTENT of the classes of device from into the classes in device 5134642e01fSmrg * to. From and to are identical after finishing. 5144642e01fSmrg * 5154642e01fSmrg * If to does not have classes from currenly has, the classes are stored in 5164642e01fSmrg * to's devPrivates system. Later, we recover it again from there if needed. 5174642e01fSmrg * Saves a few memory allocations. 5184642e01fSmrg */ 5194642e01fSmrg 5204642e01fSmrgvoid 5214642e01fSmrgDeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to) 5224642e01fSmrg{ 5234642e01fSmrg ClassesPtr classes; 5244642e01fSmrg 5254642e01fSmrg /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the 5264642e01fSmrg * kbdfeed to be set up properly, so let's do the feedback classes first. 5274642e01fSmrg */ 5284642e01fSmrg DeepCopyFeedbackClasses(from, to); 5294642e01fSmrg 5304642e01fSmrg if (from->key) 5314642e01fSmrg { 5324642e01fSmrg KeyCode *oldModKeyMap; 5334642e01fSmrg KeySym *oldMap; 5344642e01fSmrg#ifdef XKB 5354642e01fSmrg struct _XkbSrvInfo *oldXkbInfo; 5364642e01fSmrg#endif 5374642e01fSmrg if (!to->key) 5384642e01fSmrg { 5394642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, 5404642e01fSmrg UnusedClassesPrivateKey); 5414642e01fSmrg to->key = classes->key; 5424642e01fSmrg if (!to->key) 5434642e01fSmrg { 5444642e01fSmrg to->key = xcalloc(1, sizeof(KeyClassRec)); 5454642e01fSmrg if (!to->key) 5464642e01fSmrg FatalError("[Xi] no memory for class shift.\n"); 5474642e01fSmrg } else 5484642e01fSmrg classes->key = NULL; 5494642e01fSmrg } 5504642e01fSmrg 5514642e01fSmrg oldModKeyMap = to->key->modifierKeyMap; 5524642e01fSmrg oldMap = to->key->curKeySyms.map; 5534642e01fSmrg#ifdef XKB 5544642e01fSmrg oldXkbInfo = to->key->xkbInfo; 5554642e01fSmrg#endif 5564642e01fSmrg 5574642e01fSmrg if (!oldMap) /* newly created key struct */ 5584642e01fSmrg { 5594642e01fSmrg int bytes = (to->key->curKeySyms.maxKeyCode - 5604642e01fSmrg to->key->curKeySyms.minKeyCode + 1) * 5614642e01fSmrg to->key->curKeySyms.mapWidth; 5624642e01fSmrg oldMap = (KeySym *)xcalloc(sizeof(KeySym), bytes); 5634642e01fSmrg memcpy(oldMap, from->key->curKeySyms.map, bytes); 5644642e01fSmrg } 5654642e01fSmrg 5664642e01fSmrg to->key->modifierKeyMap = oldModKeyMap; 5674642e01fSmrg to->key->curKeySyms.map = oldMap; 5684642e01fSmrg#ifdef XKB 5694642e01fSmrg to->key->xkbInfo = oldXkbInfo; 5704642e01fSmrg#endif 5714642e01fSmrg 5724642e01fSmrg CopyKeyClass(from, to); 5734642e01fSmrg } else if (to->key && !from->key) 5744642e01fSmrg { 5754642e01fSmrg ClassesPtr classes; 5764642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 5774642e01fSmrg classes->key = to->key; 5784642e01fSmrg to->key = NULL; 5794642e01fSmrg } 5804642e01fSmrg 5814642e01fSmrg if (from->valuator) 5824642e01fSmrg { 5834642e01fSmrg ValuatorClassPtr v; 5844642e01fSmrg if (!to->valuator) 5854642e01fSmrg { 5864642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, 5874642e01fSmrg UnusedClassesPrivateKey); 5884642e01fSmrg to->valuator = classes->valuator; 5894642e01fSmrg if (to->valuator) 5904642e01fSmrg classes->valuator = NULL; 5914642e01fSmrg } 5924642e01fSmrg 5934642e01fSmrg to->valuator = xrealloc(to->valuator, sizeof(ValuatorClassRec) + 5944642e01fSmrg from->valuator->numAxes * sizeof(AxisInfo) + 5954642e01fSmrg from->valuator->numAxes * sizeof(unsigned int)); 5964642e01fSmrg v = to->valuator; 5974642e01fSmrg if (!v) 5984642e01fSmrg FatalError("[Xi] no memory for class shift.\n"); 5994642e01fSmrg 6004642e01fSmrg v->numAxes = from->valuator->numAxes; 6014642e01fSmrg v->axes = (AxisInfoPtr)&v[1]; 6024642e01fSmrg memcpy(v->axes, from->valuator->axes, v->numAxes * sizeof(AxisInfo)); 6034642e01fSmrg 6044642e01fSmrg v->axisVal = (int*)(v->axes + from->valuator->numAxes); 6054642e01fSmrg } else if (to->valuator && !from->valuator) 6064642e01fSmrg { 6074642e01fSmrg ClassesPtr classes; 6084642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 6094642e01fSmrg classes->valuator = to->valuator; 6104642e01fSmrg to->valuator = NULL; 6114642e01fSmrg } 6124642e01fSmrg 6134642e01fSmrg if (from->button) 6144642e01fSmrg { 6154642e01fSmrg if (!to->button) 6164642e01fSmrg { 6174642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, 6184642e01fSmrg UnusedClassesPrivateKey); 6194642e01fSmrg to->button = classes->button; 6204642e01fSmrg if (!to->button) 6214642e01fSmrg { 6224642e01fSmrg to->button = xcalloc(1, sizeof(ButtonClassRec)); 6234642e01fSmrg if (!to->button) 6244642e01fSmrg FatalError("[Xi] no memory for class shift.\n"); 6254642e01fSmrg } else 6264642e01fSmrg classes->button = NULL; 6274642e01fSmrg } 6284642e01fSmrg 6294642e01fSmrg#ifdef XKB 6304642e01fSmrg if (from->button->xkb_acts) 6314642e01fSmrg { 6324642e01fSmrg if (!to->button->xkb_acts) 6334642e01fSmrg { 6344642e01fSmrg to->button->xkb_acts = xcalloc(1, sizeof(XkbAction)); 6354642e01fSmrg if (!to->button->xkb_acts) 6364642e01fSmrg FatalError("[Xi] not enough memory for xkb_acts.\n"); 6374642e01fSmrg } 6384642e01fSmrg memcpy(to->button->xkb_acts, from->button->xkb_acts, 6394642e01fSmrg sizeof(XkbAction)); 6404642e01fSmrg } else 6414642e01fSmrg xfree(to->button->xkb_acts); 6424642e01fSmrg#endif 6434642e01fSmrg } else if (to->button && !from->button) 6444642e01fSmrg { 6454642e01fSmrg ClassesPtr classes; 6464642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 6474642e01fSmrg classes->button = to->button; 6484642e01fSmrg to->button = NULL; 6494642e01fSmrg } 6504642e01fSmrg 6514642e01fSmrg 6524642e01fSmrg /* We can't just copy over the focus class. When an app sets the focus, 6534642e01fSmrg * it'll do so on the master device. Copying the SDs focus means losing 6544642e01fSmrg * the focus. 6554642e01fSmrg * So we only copy the focus class if the device didn't have one, 6564642e01fSmrg * otherwise we leave it as it is. 6574642e01fSmrg */ 6584642e01fSmrg if (from->focus) 6594642e01fSmrg { 6604642e01fSmrg if (!to->focus) 6614642e01fSmrg { 6624642e01fSmrg WindowPtr *oldTrace; 6634642e01fSmrg 6644642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, 6654642e01fSmrg UnusedClassesPrivateKey); 6664642e01fSmrg to->focus = classes->focus; 6674642e01fSmrg if (!to->focus) 6684642e01fSmrg { 6694642e01fSmrg to->focus = xcalloc(1, sizeof(FocusClassRec)); 6704642e01fSmrg if (!to->focus) 6714642e01fSmrg FatalError("[Xi] no memory for class shift.\n"); 6724642e01fSmrg } else 6734642e01fSmrg classes->focus = NULL; 6744642e01fSmrg 6754642e01fSmrg oldTrace = to->focus->trace; 6764642e01fSmrg memcpy(to->focus, from->focus, sizeof(FocusClassRec)); 6774642e01fSmrg to->focus->trace = xrealloc(oldTrace, 6784642e01fSmrg to->focus->traceSize * sizeof(WindowPtr)); 6794642e01fSmrg if (!to->focus->trace && to->focus->traceSize) 6804642e01fSmrg FatalError("[Xi] no memory for trace.\n"); 6814642e01fSmrg memcpy(to->focus->trace, from->focus->trace, 6824642e01fSmrg from->focus->traceSize * sizeof(WindowPtr)); 6834642e01fSmrg } 6844642e01fSmrg } else if (to->focus) 6854642e01fSmrg { 6864642e01fSmrg ClassesPtr classes; 6874642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 6884642e01fSmrg classes->focus = to->focus; 6894642e01fSmrg to->focus = NULL; 6904642e01fSmrg } 6914642e01fSmrg 6924642e01fSmrg if (from->proximity) 6934642e01fSmrg { 6944642e01fSmrg if (!to->proximity) 6954642e01fSmrg { 6964642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, 6974642e01fSmrg UnusedClassesPrivateKey); 6984642e01fSmrg to->proximity = classes->proximity; 6994642e01fSmrg if (!to->proximity) 7004642e01fSmrg { 7014642e01fSmrg to->proximity = xcalloc(1, sizeof(ProximityClassRec)); 7024642e01fSmrg if (!to->proximity) 7034642e01fSmrg FatalError("[Xi] no memory for class shift.\n"); 7044642e01fSmrg } else 7054642e01fSmrg classes->proximity = NULL; 7064642e01fSmrg } 7074642e01fSmrg memcpy(to->proximity, from->proximity, sizeof(ProximityClassRec)); 7084642e01fSmrg } else if (to->proximity) 7094642e01fSmrg { 7104642e01fSmrg ClassesPtr classes; 7114642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 7124642e01fSmrg classes->proximity = to->proximity; 7134642e01fSmrg to->proximity = NULL; 7144642e01fSmrg } 7154642e01fSmrg 7164642e01fSmrg if (from->absolute) 7174642e01fSmrg { 7184642e01fSmrg if (!to->absolute) 7194642e01fSmrg { 7204642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, 7214642e01fSmrg UnusedClassesPrivateKey); 7224642e01fSmrg to->absolute = classes->absolute; 7234642e01fSmrg if (!to->absolute) 7244642e01fSmrg { 7254642e01fSmrg to->absolute = xcalloc(1, sizeof(AbsoluteClassRec)); 7264642e01fSmrg if (!to->absolute) 7274642e01fSmrg FatalError("[Xi] no memory for class shift.\n"); 7284642e01fSmrg } else 7294642e01fSmrg classes->absolute = NULL; 7304642e01fSmrg } 7314642e01fSmrg memcpy(to->absolute, from->absolute, sizeof(AbsoluteClassRec)); 7324642e01fSmrg } else if (to->absolute) 7334642e01fSmrg { 7344642e01fSmrg ClassesPtr classes; 7354642e01fSmrg classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); 7364642e01fSmrg classes->absolute = to->absolute; 7374642e01fSmrg to->absolute = NULL; 7384642e01fSmrg } 7394642e01fSmrg} 7404642e01fSmrg 7414642e01fSmrg 7424642e01fSmrg/** 7434642e01fSmrg * Update the device state according to the data in the event. 7444642e01fSmrg * 7454642e01fSmrg * return values are 7464642e01fSmrg * DEFAULT ... process as normal 7474642e01fSmrg * DONT_PROCESS ... return immediately from caller 7484642e01fSmrg * IS_REPEAT .. event is a repeat event. 7494642e01fSmrg */ 7504642e01fSmrg#define DEFAULT 0 7514642e01fSmrg#define DONT_PROCESS 1 7524642e01fSmrg#define IS_REPEAT 2 7534642e01fSmrgint 7544642e01fSmrgUpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count) 7554642e01fSmrg{ 7564642e01fSmrg int i; 7574642e01fSmrg int key = 0, 7584642e01fSmrg bit = 0; 7594642e01fSmrg 7604642e01fSmrg KeyClassPtr k = NULL; 7614642e01fSmrg ButtonClassPtr b = NULL; 7624642e01fSmrg ValuatorClassPtr v = NULL; 7634642e01fSmrg deviceValuator *xV = (deviceValuator *) xE; 7644642e01fSmrg BYTE *kptr = NULL; 7654642e01fSmrg CARD16 modifiers = 0, 7664642e01fSmrg mask = 0; 7674642e01fSmrg 7684642e01fSmrg /* currently no other generic event modifies the device */ 7694642e01fSmrg if (xE->u.u.type == GenericEvent) 7704642e01fSmrg return DEFAULT; 7714642e01fSmrg 7724642e01fSmrg k = device->key; 7734642e01fSmrg v = device->valuator; 7744642e01fSmrg b = device->button; 7754642e01fSmrg 7764642e01fSmrg 7774642e01fSmrg if (xE->u.u.type != DeviceValuator) 7784642e01fSmrg { 7794642e01fSmrg key = xE->u.u.detail; 7804642e01fSmrg bit = 1 << (key & 7); 7814642e01fSmrg } 7824642e01fSmrg 7834642e01fSmrg /* Update device axis */ 7844642e01fSmrg /* Don't update valuators for the VCP, it never sends XI events anyway */ 7854642e01fSmrg for (i = 1; !device->isMaster && i < count; i++) { 78605b261ecSmrg if ((++xV)->type == DeviceValuator) { 78705b261ecSmrg int *axisvals; 7884642e01fSmrg int first = xV->first_valuator; 7894642e01fSmrg BOOL change = FALSE; 79005b261ecSmrg 7914642e01fSmrg 7924642e01fSmrg if (xV->num_valuators && 7934642e01fSmrg (!v || (xV->num_valuators && 7944642e01fSmrg (first + xV->num_valuators > v->numAxes)))) 79505b261ecSmrg FatalError("Bad valuators reported for device %s\n", 7964642e01fSmrg device->name); 79705b261ecSmrg if (v && v->axisVal) { 7984642e01fSmrg /* v->axisVal is always in absolute coordinates. Only the 7994642e01fSmrg * delivery mode changes. 8004642e01fSmrg * If device is mode Absolute 8014642e01fSmrg * dev = event 8024642e01fSmrg * If device is mode Relative 8034642e01fSmrg * swap = (event - device) 8044642e01fSmrg * dev = event 8054642e01fSmrg * event = delta 8064642e01fSmrg */ 8074642e01fSmrg int delta; 8084642e01fSmrg axisvals = v->axisVal; 8094642e01fSmrg if (v->mode == Relative) /* device reports relative */ 8104642e01fSmrg change = TRUE; 8114642e01fSmrg 8124642e01fSmrg switch (xV->num_valuators) { 8134642e01fSmrg case 6: 8144642e01fSmrg if (change) delta = xV->valuator5 - *(axisvals + first + 5); 8154642e01fSmrg *(axisvals + first + 5) = xV->valuator5; 8164642e01fSmrg if (change) xV->valuator5 = delta; 8174642e01fSmrg case 5: 8184642e01fSmrg if (change) delta = xV->valuator4 - *(axisvals + first + 4); 8194642e01fSmrg *(axisvals + first + 4) = xV->valuator4; 8204642e01fSmrg if (change) xV->valuator4 = delta; 8214642e01fSmrg case 4: 8224642e01fSmrg if (change) delta = xV->valuator3 - *(axisvals + first + 3); 8234642e01fSmrg *(axisvals + first + 3) = xV->valuator3; 8244642e01fSmrg if (change) xV->valuator3 = delta; 8254642e01fSmrg case 3: 8264642e01fSmrg if (change) delta = xV->valuator2 - *(axisvals + first + 2); 8274642e01fSmrg *(axisvals + first + 2) = xV->valuator2; 8284642e01fSmrg if (change) xV->valuator2 = delta; 8294642e01fSmrg case 2: 8304642e01fSmrg if (change) delta = xV->valuator1 - *(axisvals + first + 1); 8314642e01fSmrg *(axisvals + first + 1) = xV->valuator1; 8324642e01fSmrg if (change) xV->valuator1 = delta; 8334642e01fSmrg case 1: 8344642e01fSmrg if (change) delta = xV->valuator0 - *(axisvals + first); 8354642e01fSmrg *(axisvals + first) = xV->valuator0; 8364642e01fSmrg if (change) xV->valuator0 = delta; 8374642e01fSmrg case 0: 8384642e01fSmrg default: 8394642e01fSmrg break; 8404642e01fSmrg } 84105b261ecSmrg } 84205b261ecSmrg } 8434642e01fSmrg } 84405b261ecSmrg 84505b261ecSmrg if (xE->u.u.type == DeviceKeyPress) { 84605b261ecSmrg if (!k) 8474642e01fSmrg return DONT_PROCESS; 84805b261ecSmrg 84905b261ecSmrg modifiers = k->modifierMap[key]; 85005b261ecSmrg kptr = &k->down[key >> 3]; 85105b261ecSmrg if (*kptr & bit) { /* allow ddx to generate multiple downs */ 8524642e01fSmrg return IS_REPEAT; 85305b261ecSmrg } 8544642e01fSmrg if (device->valuator) 8554642e01fSmrg device->valuator->motionHintWindow = NullWindow; 85605b261ecSmrg *kptr |= bit; 85705b261ecSmrg k->prev_state = k->state; 85805b261ecSmrg for (i = 0, mask = 1; modifiers; i++, mask <<= 1) { 85905b261ecSmrg if (mask & modifiers) { 86005b261ecSmrg /* This key affects modifier "i" */ 86105b261ecSmrg k->modifierKeyCount[i]++; 86205b261ecSmrg k->state |= mask; 86305b261ecSmrg modifiers &= ~mask; 86405b261ecSmrg } 86505b261ecSmrg } 86605b261ecSmrg } else if (xE->u.u.type == DeviceKeyRelease) { 86705b261ecSmrg if (!k) 8684642e01fSmrg return DONT_PROCESS; 86905b261ecSmrg 87005b261ecSmrg kptr = &k->down[key >> 3]; 87105b261ecSmrg if (!(*kptr & bit)) /* guard against duplicates */ 8724642e01fSmrg return DONT_PROCESS; 87305b261ecSmrg modifiers = k->modifierMap[key]; 8744642e01fSmrg if (device->valuator) 8754642e01fSmrg device->valuator->motionHintWindow = NullWindow; 87605b261ecSmrg *kptr &= ~bit; 87705b261ecSmrg k->prev_state = k->state; 87805b261ecSmrg for (i = 0, mask = 1; modifiers; i++, mask <<= 1) { 87905b261ecSmrg if (mask & modifiers) { 88005b261ecSmrg /* This key affects modifier "i" */ 88105b261ecSmrg if (--k->modifierKeyCount[i] <= 0) { 88205b261ecSmrg k->modifierKeyCount[i] = 0; 88305b261ecSmrg k->state &= ~mask; 88405b261ecSmrg } 88505b261ecSmrg modifiers &= ~mask; 88605b261ecSmrg } 88705b261ecSmrg } 88805b261ecSmrg } else if (xE->u.u.type == DeviceButtonPress) { 88905b261ecSmrg if (!b) 8904642e01fSmrg return DONT_PROCESS; 8914642e01fSmrg 8924642e01fSmrg kptr = &b->down[key >> 3]; 8934642e01fSmrg if ((*kptr & bit) != 0) 8944642e01fSmrg return DONT_PROCESS; 8954642e01fSmrg *kptr |= bit; 8964642e01fSmrg if (device->valuator) 8974642e01fSmrg device->valuator->motionHintWindow = NullWindow; 8984642e01fSmrg if (!b->map[key]) 8994642e01fSmrg return DONT_PROCESS; 9004642e01fSmrg b->buttonsDown++; 90105b261ecSmrg b->motionMask = DeviceButtonMotionMask; 9024642e01fSmrg if (b->map[key] <= 5) 9034642e01fSmrg b->state |= (Button1Mask >> 1) << b->map[key]; 9044642e01fSmrg SetMaskForEvent(device->id, Motion_Filter(b), DeviceMotionNotify); 90505b261ecSmrg } else if (xE->u.u.type == DeviceButtonRelease) { 90605b261ecSmrg if (!b) 9074642e01fSmrg return DONT_PROCESS; 9084642e01fSmrg 9094642e01fSmrg kptr = &b->down[key>>3]; 9104642e01fSmrg if (!(*kptr & bit)) 9114642e01fSmrg return DONT_PROCESS; 9124642e01fSmrg if (device->isMaster) { 9134642e01fSmrg DeviceIntPtr sd; 9144642e01fSmrg 9154642e01fSmrg /* 9164642e01fSmrg * Leave the button down if any slave has the 9174642e01fSmrg * button still down. Note that this depends on the 9184642e01fSmrg * event being delivered through the slave first 9194642e01fSmrg */ 9204642e01fSmrg for (sd = inputInfo.devices; sd; sd = sd->next) { 9214642e01fSmrg if (sd->isMaster || sd->u.master != device) 9224642e01fSmrg continue; 9234642e01fSmrg if ((sd->button->down[key>>3] & bit) != 0) 9244642e01fSmrg return DONT_PROCESS; 9254642e01fSmrg } 9264642e01fSmrg } 9274642e01fSmrg *kptr &= ~bit; 9284642e01fSmrg if (device->valuator) 9294642e01fSmrg device->valuator->motionHintWindow = NullWindow; 9304642e01fSmrg if (!b->map[key]) 9314642e01fSmrg return DONT_PROCESS; 93205b261ecSmrg if (b->buttonsDown >= 1 && !--b->buttonsDown) 93305b261ecSmrg b->motionMask = 0; 9344642e01fSmrg if (b->map[key] <= 5) 9354642e01fSmrg b->state &= ~((Button1Mask >> 1) << b->map[key]); 9364642e01fSmrg SetMaskForEvent(device->id, Motion_Filter(b), DeviceMotionNotify); 93705b261ecSmrg } else if (xE->u.u.type == ProximityIn) 9384642e01fSmrg device->valuator->mode &= ~OutOfProximity; 93905b261ecSmrg else if (xE->u.u.type == ProximityOut) 9404642e01fSmrg device->valuator->mode |= OutOfProximity; 9414642e01fSmrg 9424642e01fSmrg return DEFAULT; 9434642e01fSmrg} 9444642e01fSmrg 9454642e01fSmrg/** 9464642e01fSmrg * Main device event processing function. 9474642e01fSmrg * Called from when processing the events from the event queue. 9484642e01fSmrg * 9494642e01fSmrg */ 9504642e01fSmrgvoid 9514642e01fSmrgProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count) 9524642e01fSmrg{ 9534642e01fSmrg int i; 9544642e01fSmrg CARD16 modifiers; 9554642e01fSmrg GrabPtr grab = device->deviceGrab.grab; 9564642e01fSmrg Bool deactivateDeviceGrab = FALSE; 9574642e01fSmrg int key = 0, rootX, rootY; 9584642e01fSmrg ButtonClassPtr b; 9594642e01fSmrg KeyClassPtr k; 9604642e01fSmrg ValuatorClassPtr v; 9614642e01fSmrg deviceValuator *xV = (deviceValuator *) xE; 9624642e01fSmrg int ret = 0; 9634642e01fSmrg int state; 9644642e01fSmrg DeviceIntPtr mouse = NULL, kbd = NULL; 9654642e01fSmrg 9664642e01fSmrg if (IsPointerDevice(device)) 9674642e01fSmrg { 9684642e01fSmrg kbd = GetPairedDevice(device); 9694642e01fSmrg mouse = device; 9704642e01fSmrg if (!kbd->key) /* can happen with floating SDs */ 9714642e01fSmrg kbd = NULL; 9724642e01fSmrg } else 9734642e01fSmrg { 9744642e01fSmrg mouse = GetPairedDevice(device); 9754642e01fSmrg kbd = device; 9764642e01fSmrg if (!mouse->valuator || !mouse->button) /* may be float. SDs */ 9774642e01fSmrg mouse = NULL; 9784642e01fSmrg } 9794642e01fSmrg 9804642e01fSmrg /* State needs to be assembled BEFORE the device is updated. */ 9814642e01fSmrg state = (kbd) ? kbd->key->state : 0; 9824642e01fSmrg state |= (mouse) ? (mouse->button->state) : 0; 9834642e01fSmrg 9844642e01fSmrg ret = UpdateDeviceState(device, xE, count); 9854642e01fSmrg if (ret == DONT_PROCESS) 9864642e01fSmrg return; 9874642e01fSmrg 9884642e01fSmrg v = device->valuator; 9894642e01fSmrg b = device->button; 9904642e01fSmrg k = device->key; 9914642e01fSmrg 9924642e01fSmrg if (device->isMaster) 9934642e01fSmrg CheckMotion(xE, device); 9944642e01fSmrg 9954642e01fSmrg if (xE->u.u.type != DeviceValuator && xE->u.u.type != GenericEvent) { 9964642e01fSmrg GetSpritePosition(device, &rootX, &rootY); 9974642e01fSmrg xE->u.keyButtonPointer.rootX = rootX; 9984642e01fSmrg xE->u.keyButtonPointer.rootY = rootY; 9994642e01fSmrg NoticeEventTime(xE); 10004642e01fSmrg 10014642e01fSmrg xE->u.keyButtonPointer.state = state; 10024642e01fSmrg 10034642e01fSmrg key = xE->u.u.detail; 10044642e01fSmrg } 10054642e01fSmrg if (DeviceEventCallback) { 10064642e01fSmrg DeviceEventInfoRec eventinfo; 10074642e01fSmrg 10084642e01fSmrg eventinfo.events = (xEventPtr) xE; 10094642e01fSmrg eventinfo.count = count; 10104642e01fSmrg CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo); 10114642e01fSmrg } 10124642e01fSmrg 10134642e01fSmrg /* Valuator event handling */ 10144642e01fSmrg /* Don't care about valuators for the VCP, it never sends XI events */ 10154642e01fSmrg 10164642e01fSmrg for (i = 1; !device->isMaster && i < count; i++) { 10174642e01fSmrg if ((++xV)->type == DeviceValuator) { 10184642e01fSmrg int first = xV->first_valuator; 10194642e01fSmrg if (xV->num_valuators 10204642e01fSmrg && (!v 10214642e01fSmrg || (xV->num_valuators 10224642e01fSmrg && (first + xV->num_valuators > v->numAxes)))) 10234642e01fSmrg FatalError("Bad valuators reported for device %s\n", 10244642e01fSmrg device->name); 10254642e01fSmrg xV->device_state = 0; 10264642e01fSmrg if (k) 10274642e01fSmrg xV->device_state |= k->state; 10284642e01fSmrg if (b) 10294642e01fSmrg xV->device_state |= b->state; 10304642e01fSmrg } 10314642e01fSmrg } 10324642e01fSmrg 10334642e01fSmrg if (xE->u.u.type == DeviceKeyPress) { 10344642e01fSmrg if (ret == IS_REPEAT) { /* allow ddx to generate multiple downs */ 10354642e01fSmrg modifiers = k->modifierMap[key]; 10364642e01fSmrg if (!modifiers) { 10374642e01fSmrg xE->u.u.type = DeviceKeyRelease; 10384642e01fSmrg ProcessOtherEvent(xE, device, count); 10394642e01fSmrg xE->u.u.type = DeviceKeyPress; 10404642e01fSmrg /* release can have side effects, don't fall through */ 10414642e01fSmrg ProcessOtherEvent(xE, device, count); 10424642e01fSmrg } 10434642e01fSmrg return; 10444642e01fSmrg } 10454642e01fSmrg if (!grab && CheckDeviceGrabs(device, xE, 0, count)) { 10464642e01fSmrg device->deviceGrab.activatingKey = key; 10474642e01fSmrg return; 10484642e01fSmrg } 10494642e01fSmrg } else if (xE->u.u.type == DeviceKeyRelease) { 10504642e01fSmrg if (device->deviceGrab.fromPassiveGrab && 10514642e01fSmrg (key == device->deviceGrab.activatingKey)) 10524642e01fSmrg deactivateDeviceGrab = TRUE; 10534642e01fSmrg } else if (xE->u.u.type == DeviceButtonPress) { 10544642e01fSmrg xE->u.u.detail = b->map[key]; 10554642e01fSmrg if (xE->u.u.detail == 0) { 10564642e01fSmrg xE->u.u.detail = key; 10574642e01fSmrg return; 10584642e01fSmrg } 10594642e01fSmrg if (!grab && CheckDeviceGrabs(device, xE, 0, count)) 10604642e01fSmrg { 10614642e01fSmrg /* if a passive grab was activated, the event has been sent 10624642e01fSmrg * already */ 10634642e01fSmrg return; 10644642e01fSmrg } 10654642e01fSmrg 10664642e01fSmrg } else if (xE->u.u.type == DeviceButtonRelease) { 10674642e01fSmrg xE->u.u.detail = b->map[key]; 10684642e01fSmrg if (xE->u.u.detail == 0) { 10694642e01fSmrg xE->u.u.detail = key; 10704642e01fSmrg return; 10714642e01fSmrg } 10724642e01fSmrg if (!b->buttonsDown && device->deviceGrab.fromPassiveGrab) 10734642e01fSmrg deactivateDeviceGrab = TRUE; 10744642e01fSmrg } 107505b261ecSmrg 107605b261ecSmrg if (grab) 10774642e01fSmrg DeliverGrabbedEvent(xE, device, deactivateDeviceGrab, count); 10784642e01fSmrg else if (device->focus && !IsPointerEvent(xE)) 10794642e01fSmrg DeliverFocusedEvent(device, xE, GetSpriteWindow(device), count); 108005b261ecSmrg else 10814642e01fSmrg DeliverDeviceEvents(GetSpriteWindow(device), xE, NullGrab, NullWindow, 10824642e01fSmrg device, count); 108305b261ecSmrg 108405b261ecSmrg if (deactivateDeviceGrab == TRUE) 10854642e01fSmrg (*device->deviceGrab.DeactivateGrab) (device); 10864642e01fSmrg xE->u.u.detail = key; 108705b261ecSmrg} 108805b261ecSmrg 108905b261ecSmrg_X_EXPORT int 109005b261ecSmrgInitProximityClassDeviceStruct(DeviceIntPtr dev) 109105b261ecSmrg{ 109205b261ecSmrg ProximityClassPtr proxc; 109305b261ecSmrg 109405b261ecSmrg proxc = (ProximityClassPtr) xalloc(sizeof(ProximityClassRec)); 109505b261ecSmrg if (!proxc) 109605b261ecSmrg return FALSE; 109705b261ecSmrg dev->proximity = proxc; 109805b261ecSmrg return TRUE; 109905b261ecSmrg} 110005b261ecSmrg 11014642e01fSmrg/** 11024642e01fSmrg * Initialise the device's valuators. The memory must already be allocated, 11034642e01fSmrg * this function merely inits the matching axis (specified through axnum) to 11044642e01fSmrg * sane values. 11054642e01fSmrg * 11064642e01fSmrg * It is a condition that (minval < maxval). 11074642e01fSmrg * 11084642e01fSmrg * @see InitValuatorClassDeviceStruct 11094642e01fSmrg */ 111005b261ecSmrg_X_EXPORT void 111105b261ecSmrgInitValuatorAxisStruct(DeviceIntPtr dev, int axnum, int minval, int maxval, 111205b261ecSmrg int resolution, int min_res, int max_res) 111305b261ecSmrg{ 111405b261ecSmrg AxisInfoPtr ax; 11154642e01fSmrg 11164642e01fSmrg if (!dev || !dev->valuator || minval > maxval) 111705b261ecSmrg return; 111805b261ecSmrg 111905b261ecSmrg ax = dev->valuator->axes + axnum; 112005b261ecSmrg 112105b261ecSmrg ax->min_value = minval; 112205b261ecSmrg ax->max_value = maxval; 112305b261ecSmrg ax->resolution = resolution; 112405b261ecSmrg ax->min_resolution = min_res; 112505b261ecSmrg ax->max_resolution = max_res; 112605b261ecSmrg} 112705b261ecSmrg 112805b261ecSmrgstatic void 112905b261ecSmrgFixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, 113005b261ecSmrg ButtonClassPtr b, ValuatorClassPtr v, int first) 113105b261ecSmrg{ 113205b261ecSmrg ev->type = DeviceStateNotify; 113305b261ecSmrg ev->deviceid = dev->id; 113405b261ecSmrg ev->time = currentTime.milliseconds; 113505b261ecSmrg ev->classes_reported = 0; 113605b261ecSmrg ev->num_keys = 0; 113705b261ecSmrg ev->num_buttons = 0; 113805b261ecSmrg ev->num_valuators = 0; 113905b261ecSmrg 114005b261ecSmrg if (b) { 114105b261ecSmrg ev->classes_reported |= (1 << ButtonClass); 114205b261ecSmrg ev->num_buttons = b->numButtons; 11434642e01fSmrg memcpy((char*)ev->buttons, (char*)b->down, 4); 114405b261ecSmrg } else if (k) { 114505b261ecSmrg ev->classes_reported |= (1 << KeyClass); 114605b261ecSmrg ev->num_keys = k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode; 114705b261ecSmrg memmove((char *)&ev->keys[0], (char *)k->down, 4); 114805b261ecSmrg } 114905b261ecSmrg if (v) { 115005b261ecSmrg int nval = v->numAxes - first; 115105b261ecSmrg 115205b261ecSmrg ev->classes_reported |= (1 << ValuatorClass); 115305b261ecSmrg ev->classes_reported |= (dev->valuator->mode << ModeBitsShift); 115405b261ecSmrg ev->num_valuators = nval < 3 ? nval : 3; 115505b261ecSmrg switch (ev->num_valuators) { 115605b261ecSmrg case 3: 115705b261ecSmrg ev->valuator2 = v->axisVal[first + 2]; 115805b261ecSmrg case 2: 115905b261ecSmrg ev->valuator1 = v->axisVal[first + 1]; 116005b261ecSmrg case 1: 116105b261ecSmrg ev->valuator0 = v->axisVal[first]; 116205b261ecSmrg break; 116305b261ecSmrg } 116405b261ecSmrg } 116505b261ecSmrg} 116605b261ecSmrg 116705b261ecSmrgstatic void 116805b261ecSmrgFixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, 116905b261ecSmrg int first) 117005b261ecSmrg{ 117105b261ecSmrg int nval = v->numAxes - first; 117205b261ecSmrg 117305b261ecSmrg ev->type = DeviceValuator; 117405b261ecSmrg ev->deviceid = dev->id; 117505b261ecSmrg ev->num_valuators = nval < 3 ? nval : 3; 117605b261ecSmrg ev->first_valuator = first; 117705b261ecSmrg switch (ev->num_valuators) { 117805b261ecSmrg case 3: 117905b261ecSmrg ev->valuator2 = v->axisVal[first + 2]; 118005b261ecSmrg case 2: 118105b261ecSmrg ev->valuator1 = v->axisVal[first + 1]; 118205b261ecSmrg case 1: 118305b261ecSmrg ev->valuator0 = v->axisVal[first]; 118405b261ecSmrg break; 118505b261ecSmrg } 118605b261ecSmrg first += ev->num_valuators; 118705b261ecSmrg} 118805b261ecSmrg 118905b261ecSmrgvoid 119005b261ecSmrgDeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, 119105b261ecSmrg WindowPtr pWin) 119205b261ecSmrg{ 119305b261ecSmrg deviceFocus event; 119405b261ecSmrg 119505b261ecSmrg if (type == FocusIn) 119605b261ecSmrg type = DeviceFocusIn; 119705b261ecSmrg else 119805b261ecSmrg type = DeviceFocusOut; 119905b261ecSmrg 120005b261ecSmrg event.deviceid = dev->id; 120105b261ecSmrg event.mode = mode; 120205b261ecSmrg event.type = type; 120305b261ecSmrg event.detail = detail; 120405b261ecSmrg event.window = pWin->drawable.id; 120505b261ecSmrg event.time = currentTime.milliseconds; 120605b261ecSmrg 12074642e01fSmrg (void)DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1, 120805b261ecSmrg DeviceFocusChangeMask, NullGrab, dev->id); 120905b261ecSmrg 121005b261ecSmrg if ((type == DeviceFocusIn) && 121105b261ecSmrg (wOtherInputMasks(pWin)) && 121205b261ecSmrg (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask)) 121305b261ecSmrg { 121405b261ecSmrg int evcount = 1; 121505b261ecSmrg deviceStateNotify *ev, *sev; 121605b261ecSmrg deviceKeyStateNotify *kev; 121705b261ecSmrg deviceButtonStateNotify *bev; 121805b261ecSmrg 121905b261ecSmrg KeyClassPtr k; 122005b261ecSmrg ButtonClassPtr b; 122105b261ecSmrg ValuatorClassPtr v; 122205b261ecSmrg int nval = 0, nkeys = 0, nbuttons = 0, first = 0; 122305b261ecSmrg 122405b261ecSmrg if ((b = dev->button) != NULL) { 122505b261ecSmrg nbuttons = b->numButtons; 122605b261ecSmrg if (nbuttons > 32) 122705b261ecSmrg evcount++; 122805b261ecSmrg } 122905b261ecSmrg if ((k = dev->key) != NULL) { 123005b261ecSmrg nkeys = k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode; 123105b261ecSmrg if (nkeys > 32) 123205b261ecSmrg evcount++; 123305b261ecSmrg if (nbuttons > 0) { 123405b261ecSmrg evcount++; 123505b261ecSmrg } 123605b261ecSmrg } 123705b261ecSmrg if ((v = dev->valuator) != NULL) { 123805b261ecSmrg nval = v->numAxes; 123905b261ecSmrg 124005b261ecSmrg if (nval > 3) 124105b261ecSmrg evcount++; 124205b261ecSmrg if (nval > 6) { 124305b261ecSmrg if (!(k && b)) 124405b261ecSmrg evcount++; 124505b261ecSmrg if (nval > 9) 124605b261ecSmrg evcount += ((nval - 7) / 3); 124705b261ecSmrg } 124805b261ecSmrg } 124905b261ecSmrg 125005b261ecSmrg sev = ev = (deviceStateNotify *) xalloc(evcount * sizeof(xEvent)); 125105b261ecSmrg FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); 125205b261ecSmrg 125305b261ecSmrg if (b != NULL) { 125405b261ecSmrg FixDeviceStateNotify(dev, ev++, NULL, b, v, first); 125505b261ecSmrg first += 3; 125605b261ecSmrg nval -= 3; 125705b261ecSmrg if (nbuttons > 32) { 125805b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 125905b261ecSmrg bev = (deviceButtonStateNotify *) ev++; 126005b261ecSmrg bev->type = DeviceButtonStateNotify; 126105b261ecSmrg bev->deviceid = dev->id; 12624642e01fSmrg memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4); 126305b261ecSmrg } 126405b261ecSmrg if (nval > 0) { 126505b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 126605b261ecSmrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 126705b261ecSmrg first += 3; 126805b261ecSmrg nval -= 3; 126905b261ecSmrg } 127005b261ecSmrg } 127105b261ecSmrg 127205b261ecSmrg if (k != NULL) { 127305b261ecSmrg FixDeviceStateNotify(dev, ev++, k, NULL, v, first); 127405b261ecSmrg first += 3; 127505b261ecSmrg nval -= 3; 127605b261ecSmrg if (nkeys > 32) { 127705b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 127805b261ecSmrg kev = (deviceKeyStateNotify *) ev++; 127905b261ecSmrg kev->type = DeviceKeyStateNotify; 128005b261ecSmrg kev->deviceid = dev->id; 128105b261ecSmrg memmove((char *)&kev->keys[0], (char *)&k->down[4], 28); 128205b261ecSmrg } 128305b261ecSmrg if (nval > 0) { 128405b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 128505b261ecSmrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 128605b261ecSmrg first += 3; 128705b261ecSmrg nval -= 3; 128805b261ecSmrg } 128905b261ecSmrg } 129005b261ecSmrg 129105b261ecSmrg while (nval > 0) { 129205b261ecSmrg FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); 129305b261ecSmrg first += 3; 129405b261ecSmrg nval -= 3; 129505b261ecSmrg if (nval > 0) { 129605b261ecSmrg (ev - 1)->deviceid |= MORE_EVENTS; 129705b261ecSmrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 129805b261ecSmrg first += 3; 129905b261ecSmrg nval -= 3; 130005b261ecSmrg } 130105b261ecSmrg } 130205b261ecSmrg 13034642e01fSmrg (void)DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount, 130405b261ecSmrg DeviceStateNotifyMask, NullGrab, dev->id); 130505b261ecSmrg xfree(sev); 130605b261ecSmrg } 130705b261ecSmrg} 130805b261ecSmrg 130905b261ecSmrgint 131005b261ecSmrgGrabButton(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode, 131105b261ecSmrg BYTE other_devices_mode, CARD16 modifiers, 131205b261ecSmrg DeviceIntPtr modifier_device, CARD8 button, Window grabWindow, 131305b261ecSmrg BOOL ownerEvents, Cursor rcursor, Window rconfineTo, Mask eventMask) 131405b261ecSmrg{ 131505b261ecSmrg WindowPtr pWin, confineTo; 131605b261ecSmrg CursorPtr cursor; 131705b261ecSmrg GrabPtr grab; 13184642e01fSmrg Mask access_mode = DixGrabAccess; 131905b261ecSmrg int rc; 132005b261ecSmrg 132105b261ecSmrg if ((this_device_mode != GrabModeSync) && 132205b261ecSmrg (this_device_mode != GrabModeAsync)) { 132305b261ecSmrg client->errorValue = this_device_mode; 132405b261ecSmrg return BadValue; 132505b261ecSmrg } 132605b261ecSmrg if ((other_devices_mode != GrabModeSync) && 132705b261ecSmrg (other_devices_mode != GrabModeAsync)) { 132805b261ecSmrg client->errorValue = other_devices_mode; 132905b261ecSmrg return BadValue; 133005b261ecSmrg } 133105b261ecSmrg if ((modifiers != AnyModifier) && (modifiers & ~AllModifiersMask)) { 133205b261ecSmrg client->errorValue = modifiers; 133305b261ecSmrg return BadValue; 133405b261ecSmrg } 133505b261ecSmrg if ((ownerEvents != xFalse) && (ownerEvents != xTrue)) { 133605b261ecSmrg client->errorValue = ownerEvents; 133705b261ecSmrg return BadValue; 133805b261ecSmrg } 13394642e01fSmrg rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess); 134005b261ecSmrg if (rc != Success) 134105b261ecSmrg return rc; 134205b261ecSmrg if (rconfineTo == None) 134305b261ecSmrg confineTo = NullWindow; 134405b261ecSmrg else { 13454642e01fSmrg rc = dixLookupWindow(&confineTo, rconfineTo, client, DixSetAttrAccess); 134605b261ecSmrg if (rc != Success) 134705b261ecSmrg return rc; 134805b261ecSmrg } 134905b261ecSmrg if (rcursor == None) 135005b261ecSmrg cursor = NullCursor; 135105b261ecSmrg else { 13524642e01fSmrg rc = dixLookupResource((pointer *)&cursor, rcursor, RT_CURSOR, 13534642e01fSmrg client, DixUseAccess); 13544642e01fSmrg if (rc != Success) 13554642e01fSmrg { 135605b261ecSmrg client->errorValue = rcursor; 13574642e01fSmrg return (rc == BadValue) ? BadCursor : rc; 135805b261ecSmrg } 13594642e01fSmrg access_mode |= DixForceAccess; 136005b261ecSmrg } 13614642e01fSmrg if (this_device_mode == GrabModeSync || other_devices_mode == GrabModeSync) 13624642e01fSmrg access_mode |= DixFreezeAccess; 13634642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 13644642e01fSmrg if (rc != Success) 13654642e01fSmrg return rc; 136605b261ecSmrg 136705b261ecSmrg grab = CreateGrab(client->index, dev, pWin, eventMask, 136805b261ecSmrg (Bool) ownerEvents, (Bool) this_device_mode, 136905b261ecSmrg (Bool) other_devices_mode, modifier_device, modifiers, 137005b261ecSmrg DeviceButtonPress, button, confineTo, cursor); 137105b261ecSmrg if (!grab) 137205b261ecSmrg return BadAlloc; 13734642e01fSmrg return AddPassiveGrabToList(client, grab); 137405b261ecSmrg} 137505b261ecSmrg 137605b261ecSmrgint 137705b261ecSmrgGrabKey(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode, 137805b261ecSmrg BYTE other_devices_mode, CARD16 modifiers, 137905b261ecSmrg DeviceIntPtr modifier_device, CARD8 key, Window grabWindow, 138005b261ecSmrg BOOL ownerEvents, Mask mask) 138105b261ecSmrg{ 138205b261ecSmrg WindowPtr pWin; 138305b261ecSmrg GrabPtr grab; 138405b261ecSmrg KeyClassPtr k = dev->key; 13854642e01fSmrg Mask access_mode = DixGrabAccess; 138605b261ecSmrg int rc; 138705b261ecSmrg 138805b261ecSmrg if (k == NULL) 138905b261ecSmrg return BadMatch; 139005b261ecSmrg if ((other_devices_mode != GrabModeSync) && 139105b261ecSmrg (other_devices_mode != GrabModeAsync)) { 139205b261ecSmrg client->errorValue = other_devices_mode; 139305b261ecSmrg return BadValue; 139405b261ecSmrg } 139505b261ecSmrg if ((this_device_mode != GrabModeSync) && 139605b261ecSmrg (this_device_mode != GrabModeAsync)) { 139705b261ecSmrg client->errorValue = this_device_mode; 139805b261ecSmrg return BadValue; 139905b261ecSmrg } 140005b261ecSmrg if (((key > k->curKeySyms.maxKeyCode) || (key < k->curKeySyms.minKeyCode)) 140105b261ecSmrg && (key != AnyKey)) { 140205b261ecSmrg client->errorValue = key; 140305b261ecSmrg return BadValue; 140405b261ecSmrg } 140505b261ecSmrg if ((modifiers != AnyModifier) && (modifiers & ~AllModifiersMask)) { 140605b261ecSmrg client->errorValue = modifiers; 140705b261ecSmrg return BadValue; 140805b261ecSmrg } 140905b261ecSmrg if ((ownerEvents != xTrue) && (ownerEvents != xFalse)) { 141005b261ecSmrg client->errorValue = ownerEvents; 141105b261ecSmrg return BadValue; 141205b261ecSmrg } 14134642e01fSmrg rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess); 14144642e01fSmrg if (rc != Success) 14154642e01fSmrg return rc; 14164642e01fSmrg if (this_device_mode == GrabModeSync || other_devices_mode == GrabModeSync) 14174642e01fSmrg access_mode |= DixFreezeAccess; 14184642e01fSmrg rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 141905b261ecSmrg if (rc != Success) 142005b261ecSmrg return rc; 142105b261ecSmrg 142205b261ecSmrg grab = CreateGrab(client->index, dev, pWin, 142305b261ecSmrg mask, ownerEvents, this_device_mode, other_devices_mode, 142405b261ecSmrg modifier_device, modifiers, DeviceKeyPress, key, 142505b261ecSmrg NullWindow, NullCursor); 142605b261ecSmrg if (!grab) 142705b261ecSmrg return BadAlloc; 14284642e01fSmrg return AddPassiveGrabToList(client, grab); 142905b261ecSmrg} 143005b261ecSmrg 143105b261ecSmrgint 143205b261ecSmrgSelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client, 143305b261ecSmrg Mask mask, Mask exclusivemasks, Mask validmasks) 143405b261ecSmrg{ 143505b261ecSmrg int mskidx = dev->id; 143605b261ecSmrg int i, ret; 143705b261ecSmrg Mask check; 143805b261ecSmrg InputClientsPtr others; 143905b261ecSmrg 144005b261ecSmrg if (mask & ~validmasks) { 144105b261ecSmrg client->errorValue = mask; 144205b261ecSmrg return BadValue; 144305b261ecSmrg } 144405b261ecSmrg check = (mask & exclusivemasks); 144505b261ecSmrg if (wOtherInputMasks(pWin)) { 144605b261ecSmrg if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) { /* It is illegal for two different 144705b261ecSmrg * clients to select on any of the 144805b261ecSmrg * events for maskcheck. However, 144905b261ecSmrg * it is OK, for some client to 145005b261ecSmrg * continue selecting on one of those 145105b261ecSmrg * events. */ 145205b261ecSmrg for (others = wOtherInputMasks(pWin)->inputClients; others; 145305b261ecSmrg others = others->next) { 145405b261ecSmrg if (!SameClient(others, client) && (check & 145505b261ecSmrg others->mask[mskidx])) 145605b261ecSmrg return BadAccess; 145705b261ecSmrg } 145805b261ecSmrg } 145905b261ecSmrg for (others = wOtherInputMasks(pWin)->inputClients; others; 146005b261ecSmrg others = others->next) { 146105b261ecSmrg if (SameClient(others, client)) { 146205b261ecSmrg check = others->mask[mskidx]; 146305b261ecSmrg others->mask[mskidx] = mask; 146405b261ecSmrg if (mask == 0) { 146505b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 146605b261ecSmrg if (i != mskidx && others->mask[i] != 0) 146705b261ecSmrg break; 146805b261ecSmrg if (i == EMASKSIZE) { 146905b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 147005b261ecSmrg if (ShouldFreeInputMasks(pWin, FALSE)) 147105b261ecSmrg FreeResource(others->resource, RT_NONE); 147205b261ecSmrg return Success; 147305b261ecSmrg } 147405b261ecSmrg } 147505b261ecSmrg goto maskSet; 147605b261ecSmrg } 147705b261ecSmrg } 147805b261ecSmrg } 147905b261ecSmrg check = 0; 148005b261ecSmrg if ((ret = AddExtensionClient(pWin, client, mask, mskidx)) != Success) 148105b261ecSmrg return ret; 148205b261ecSmrg maskSet: 148305b261ecSmrg if (dev->valuator) 148405b261ecSmrg if ((dev->valuator->motionHintWindow == pWin) && 148505b261ecSmrg (mask & DevicePointerMotionHintMask) && 14864642e01fSmrg !(check & DevicePointerMotionHintMask) && !dev->deviceGrab.grab) 148705b261ecSmrg dev->valuator->motionHintWindow = NullWindow; 148805b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 148905b261ecSmrg return Success; 149005b261ecSmrg} 149105b261ecSmrg 149205b261ecSmrgint 149305b261ecSmrgAddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx) 149405b261ecSmrg{ 149505b261ecSmrg InputClientsPtr others; 149605b261ecSmrg 149705b261ecSmrg if (!pWin->optional && !MakeWindowOptional(pWin)) 149805b261ecSmrg return BadAlloc; 14994642e01fSmrg others = xcalloc(1, sizeof(InputClients)); 150005b261ecSmrg if (!others) 150105b261ecSmrg return BadAlloc; 150205b261ecSmrg if (!pWin->optional->inputMasks && !MakeInputMasks(pWin)) 150305b261ecSmrg return BadAlloc; 150405b261ecSmrg others->mask[mskidx] = mask; 150505b261ecSmrg others->resource = FakeClientID(client->index); 150605b261ecSmrg others->next = pWin->optional->inputMasks->inputClients; 150705b261ecSmrg pWin->optional->inputMasks->inputClients = others; 150805b261ecSmrg if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer) pWin)) 150905b261ecSmrg return BadAlloc; 151005b261ecSmrg return Success; 151105b261ecSmrg} 151205b261ecSmrg 151305b261ecSmrgstatic Bool 151405b261ecSmrgMakeInputMasks(WindowPtr pWin) 151505b261ecSmrg{ 151605b261ecSmrg struct _OtherInputMasks *imasks; 151705b261ecSmrg 15184642e01fSmrg imasks = xcalloc(1, sizeof(struct _OtherInputMasks)); 151905b261ecSmrg if (!imasks) 152005b261ecSmrg return FALSE; 152105b261ecSmrg pWin->optional->inputMasks = imasks; 152205b261ecSmrg return TRUE; 152305b261ecSmrg} 152405b261ecSmrg 152505b261ecSmrgvoid 152605b261ecSmrgRecalculateDeviceDeliverableEvents(WindowPtr pWin) 152705b261ecSmrg{ 152805b261ecSmrg InputClientsPtr others; 152905b261ecSmrg struct _OtherInputMasks *inputMasks; /* default: NULL */ 153005b261ecSmrg WindowPtr pChild, tmp; 153105b261ecSmrg int i; 153205b261ecSmrg 153305b261ecSmrg pChild = pWin; 153405b261ecSmrg while (1) { 153505b261ecSmrg if ((inputMasks = wOtherInputMasks(pChild)) != 0) { 153605b261ecSmrg for (others = inputMasks->inputClients; others; 153705b261ecSmrg others = others->next) { 153805b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 153905b261ecSmrg inputMasks->inputEvents[i] |= others->mask[i]; 154005b261ecSmrg } 154105b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 154205b261ecSmrg inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i]; 154305b261ecSmrg for (tmp = pChild->parent; tmp; tmp = tmp->parent) 154405b261ecSmrg if (wOtherInputMasks(tmp)) 154505b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 154605b261ecSmrg inputMasks->deliverableEvents[i] |= 154705b261ecSmrg (wOtherInputMasks(tmp)->deliverableEvents[i] 154805b261ecSmrg & ~inputMasks-> 154905b261ecSmrg dontPropagateMask[i] & PropagateMask[i]); 155005b261ecSmrg } 155105b261ecSmrg if (pChild->firstChild) { 155205b261ecSmrg pChild = pChild->firstChild; 155305b261ecSmrg continue; 155405b261ecSmrg } 155505b261ecSmrg while (!pChild->nextSib && (pChild != pWin)) 155605b261ecSmrg pChild = pChild->parent; 155705b261ecSmrg if (pChild == pWin) 155805b261ecSmrg break; 155905b261ecSmrg pChild = pChild->nextSib; 156005b261ecSmrg } 156105b261ecSmrg} 156205b261ecSmrg 156305b261ecSmrgint 156405b261ecSmrgInputClientGone(WindowPtr pWin, XID id) 156505b261ecSmrg{ 156605b261ecSmrg InputClientsPtr other, prev; 156705b261ecSmrg 156805b261ecSmrg if (!wOtherInputMasks(pWin)) 156905b261ecSmrg return (Success); 157005b261ecSmrg prev = 0; 157105b261ecSmrg for (other = wOtherInputMasks(pWin)->inputClients; other; 157205b261ecSmrg other = other->next) { 157305b261ecSmrg if (other->resource == id) { 157405b261ecSmrg if (prev) { 157505b261ecSmrg prev->next = other->next; 157605b261ecSmrg xfree(other); 157705b261ecSmrg } else if (!(other->next)) { 157805b261ecSmrg if (ShouldFreeInputMasks(pWin, TRUE)) { 157905b261ecSmrg wOtherInputMasks(pWin)->inputClients = other->next; 158005b261ecSmrg xfree(wOtherInputMasks(pWin)); 158105b261ecSmrg pWin->optional->inputMasks = (OtherInputMasks *) NULL; 158205b261ecSmrg CheckWindowOptionalNeed(pWin); 158305b261ecSmrg xfree(other); 158405b261ecSmrg } else { 158505b261ecSmrg other->resource = FakeClientID(0); 158605b261ecSmrg if (!AddResource(other->resource, RT_INPUTCLIENT, 158705b261ecSmrg (pointer) pWin)) 158805b261ecSmrg return BadAlloc; 158905b261ecSmrg } 159005b261ecSmrg } else { 159105b261ecSmrg wOtherInputMasks(pWin)->inputClients = other->next; 159205b261ecSmrg xfree(other); 159305b261ecSmrg } 159405b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 159505b261ecSmrg return (Success); 159605b261ecSmrg } 159705b261ecSmrg prev = other; 159805b261ecSmrg } 159905b261ecSmrg FatalError("client not on device event list"); 160005b261ecSmrg} 160105b261ecSmrg 160205b261ecSmrgint 160305b261ecSmrgSendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate, 160405b261ecSmrg xEvent * ev, Mask mask, int count) 160505b261ecSmrg{ 160605b261ecSmrg WindowPtr pWin; 160705b261ecSmrg WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ 16084642e01fSmrg WindowPtr spriteWin = GetSpriteWindow(d); 160905b261ecSmrg 161005b261ecSmrg if (dest == PointerWindow) 161105b261ecSmrg pWin = spriteWin; 161205b261ecSmrg else if (dest == InputFocus) { 161305b261ecSmrg WindowPtr inputFocus; 161405b261ecSmrg 161505b261ecSmrg if (!d->focus) 161605b261ecSmrg inputFocus = spriteWin; 161705b261ecSmrg else 161805b261ecSmrg inputFocus = d->focus->win; 161905b261ecSmrg 162005b261ecSmrg if (inputFocus == FollowKeyboardWin) 162105b261ecSmrg inputFocus = inputInfo.keyboard->focus->win; 162205b261ecSmrg 162305b261ecSmrg if (inputFocus == NoneWin) 162405b261ecSmrg return Success; 162505b261ecSmrg 162605b261ecSmrg /* If the input focus is PointerRootWin, send the event to where 162705b261ecSmrg * the pointer is if possible, then perhaps propogate up to root. */ 162805b261ecSmrg if (inputFocus == PointerRootWin) 16294642e01fSmrg inputFocus = GetCurrentRootWindow(d); 163005b261ecSmrg 163105b261ecSmrg if (IsParent(inputFocus, spriteWin)) { 163205b261ecSmrg effectiveFocus = inputFocus; 163305b261ecSmrg pWin = spriteWin; 163405b261ecSmrg } else 163505b261ecSmrg effectiveFocus = pWin = inputFocus; 163605b261ecSmrg } else 16374642e01fSmrg dixLookupWindow(&pWin, dest, client, DixSendAccess); 163805b261ecSmrg if (!pWin) 163905b261ecSmrg return BadWindow; 164005b261ecSmrg if ((propagate != xFalse) && (propagate != xTrue)) { 164105b261ecSmrg client->errorValue = propagate; 164205b261ecSmrg return BadValue; 164305b261ecSmrg } 164405b261ecSmrg ev->u.u.type |= 0x80; 164505b261ecSmrg if (propagate) { 164605b261ecSmrg for (; pWin; pWin = pWin->parent) { 16474642e01fSmrg if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab, d->id)) 164805b261ecSmrg return Success; 164905b261ecSmrg if (pWin == effectiveFocus) 165005b261ecSmrg return Success; 165105b261ecSmrg if (wOtherInputMasks(pWin)) 165205b261ecSmrg mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id]; 165305b261ecSmrg if (!mask) 165405b261ecSmrg break; 165505b261ecSmrg } 16564642e01fSmrg } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count)) 16574642e01fSmrg (void)(DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab, d->id)); 165805b261ecSmrg return Success; 165905b261ecSmrg} 166005b261ecSmrg 166105b261ecSmrgint 166205b261ecSmrgSetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map) 166305b261ecSmrg{ 166405b261ecSmrg int i; 166505b261ecSmrg ButtonClassPtr b = dev->button; 166605b261ecSmrg 166705b261ecSmrg if (b == NULL) 166805b261ecSmrg return BadMatch; 166905b261ecSmrg 167005b261ecSmrg if (nElts != b->numButtons) { 167105b261ecSmrg client->errorValue = nElts; 167205b261ecSmrg return BadValue; 167305b261ecSmrg } 167405b261ecSmrg if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue)) 167505b261ecSmrg return BadValue; 167605b261ecSmrg for (i = 0; i < nElts; i++) 167705b261ecSmrg if ((b->map[i + 1] != map[i]) && BitIsOn(b->down, i + 1)) 167805b261ecSmrg return MappingBusy; 167905b261ecSmrg for (i = 0; i < nElts; i++) 168005b261ecSmrg b->map[i + 1] = map[i]; 168105b261ecSmrg return Success; 168205b261ecSmrg} 168305b261ecSmrg 168405b261ecSmrgint 168505b261ecSmrgSetModifierMapping(ClientPtr client, DeviceIntPtr dev, int len, int rlen, 168605b261ecSmrg int numKeyPerModifier, KeyCode * inputMap, KeyClassPtr * k) 168705b261ecSmrg{ 168805b261ecSmrg KeyCode *map = NULL; 168905b261ecSmrg int inputMapLen; 169005b261ecSmrg int i; 169105b261ecSmrg 169205b261ecSmrg *k = dev->key; 169305b261ecSmrg if (*k == NULL) 169405b261ecSmrg return BadMatch; 169505b261ecSmrg if (len != ((numKeyPerModifier << 1) + rlen)) 169605b261ecSmrg return BadLength; 169705b261ecSmrg 169805b261ecSmrg inputMapLen = 8 * numKeyPerModifier; 169905b261ecSmrg 170005b261ecSmrg /* 170105b261ecSmrg * Now enforce the restriction that "all of the non-zero keycodes must be 170205b261ecSmrg * in the range specified by min-keycode and max-keycode in the 170305b261ecSmrg * connection setup (else a Value error)" 170405b261ecSmrg */ 170505b261ecSmrg i = inputMapLen; 170605b261ecSmrg while (i--) { 170705b261ecSmrg if (inputMap[i] 170805b261ecSmrg && (inputMap[i] < (*k)->curKeySyms.minKeyCode 170905b261ecSmrg || inputMap[i] > (*k)->curKeySyms.maxKeyCode)) { 171005b261ecSmrg client->errorValue = inputMap[i]; 171105b261ecSmrg return -1; /* BadValue collides with MappingFailed */ 171205b261ecSmrg } 171305b261ecSmrg } 171405b261ecSmrg 171505b261ecSmrg /* 171605b261ecSmrg * Now enforce the restriction that none of the old or new 171705b261ecSmrg * modifier keys may be down while we change the mapping, and 171805b261ecSmrg * that the DDX layer likes the choice. 171905b261ecSmrg */ 172005b261ecSmrg if (!AllModifierKeysAreUp(dev, (*k)->modifierKeyMap, 172105b261ecSmrg (int)(*k)->maxKeysPerModifier, inputMap, 172205b261ecSmrg (int)numKeyPerModifier) 172305b261ecSmrg || !AllModifierKeysAreUp(dev, inputMap, (int)numKeyPerModifier, 172405b261ecSmrg (*k)->modifierKeyMap, 172505b261ecSmrg (int)(*k)->maxKeysPerModifier)) { 172605b261ecSmrg return MappingBusy; 172705b261ecSmrg } else { 172805b261ecSmrg for (i = 0; i < inputMapLen; i++) { 172905b261ecSmrg if (inputMap[i] && !LegalModifier(inputMap[i], dev)) { 173005b261ecSmrg return MappingFailed; 173105b261ecSmrg } 173205b261ecSmrg } 173305b261ecSmrg } 173405b261ecSmrg 173505b261ecSmrg /* 173605b261ecSmrg * Now build the keyboard's modifier bitmap from the 173705b261ecSmrg * list of keycodes. 173805b261ecSmrg */ 173905b261ecSmrg if (inputMapLen) { 174005b261ecSmrg map = (KeyCode *) xalloc(inputMapLen); 174105b261ecSmrg if (!map) 174205b261ecSmrg return BadAlloc; 174305b261ecSmrg } 174405b261ecSmrg if ((*k)->modifierKeyMap) 174505b261ecSmrg xfree((*k)->modifierKeyMap); 174605b261ecSmrg if (inputMapLen) { 174705b261ecSmrg (*k)->modifierKeyMap = map; 174805b261ecSmrg memmove((char *)(*k)->modifierKeyMap, (char *)inputMap, inputMapLen); 174905b261ecSmrg } else 175005b261ecSmrg (*k)->modifierKeyMap = NULL; 175105b261ecSmrg 175205b261ecSmrg (*k)->maxKeysPerModifier = numKeyPerModifier; 175305b261ecSmrg for (i = 0; i < MAP_LENGTH; i++) 175405b261ecSmrg (*k)->modifierMap[i] = 0; 175505b261ecSmrg for (i = 0; i < inputMapLen; i++) 175605b261ecSmrg if (inputMap[i]) { 175705b261ecSmrg (*k)->modifierMap[inputMap[i]] 175805b261ecSmrg |= (1 << (i / (*k)->maxKeysPerModifier)); 175905b261ecSmrg } 176005b261ecSmrg 176105b261ecSmrg return (MappingSuccess); 176205b261ecSmrg} 176305b261ecSmrg 176405b261ecSmrgvoid 176505b261ecSmrgSendDeviceMappingNotify(ClientPtr client, CARD8 request, 176605b261ecSmrg KeyCode firstKeyCode, CARD8 count, DeviceIntPtr dev) 176705b261ecSmrg{ 176805b261ecSmrg xEvent event; 176905b261ecSmrg deviceMappingNotify *ev = (deviceMappingNotify *) & event; 177005b261ecSmrg 177105b261ecSmrg ev->type = DeviceMappingNotify; 177205b261ecSmrg ev->request = request; 177305b261ecSmrg ev->deviceid = dev->id; 177405b261ecSmrg ev->time = currentTime.milliseconds; 177505b261ecSmrg if (request == MappingKeyboard) { 177605b261ecSmrg ev->firstKeyCode = firstKeyCode; 177705b261ecSmrg ev->count = count; 177805b261ecSmrg } 177905b261ecSmrg 178005b261ecSmrg#ifdef XKB 17814642e01fSmrg if (!noXkbExtension && (request == MappingKeyboard || 17824642e01fSmrg request == MappingModifier)) 178305b261ecSmrg XkbApplyMappingChange(dev, request, firstKeyCode, count, client); 178405b261ecSmrg#endif 178505b261ecSmrg 178605b261ecSmrg SendEventToAllWindows(dev, DeviceMappingNotifyMask, (xEvent *) ev, 1); 178705b261ecSmrg} 178805b261ecSmrg 178905b261ecSmrgint 179005b261ecSmrgChangeKeyMapping(ClientPtr client, 179105b261ecSmrg DeviceIntPtr dev, 179205b261ecSmrg unsigned len, 179305b261ecSmrg int type, 179405b261ecSmrg KeyCode firstKeyCode, 179505b261ecSmrg CARD8 keyCodes, CARD8 keySymsPerKeyCode, KeySym * map) 179605b261ecSmrg{ 179705b261ecSmrg KeySymsRec keysyms; 179805b261ecSmrg KeyClassPtr k = dev->key; 179905b261ecSmrg 180005b261ecSmrg if (k == NULL) 180105b261ecSmrg return (BadMatch); 180205b261ecSmrg 180305b261ecSmrg if (len != (keyCodes * keySymsPerKeyCode)) 180405b261ecSmrg return BadLength; 180505b261ecSmrg 180605b261ecSmrg if ((firstKeyCode < k->curKeySyms.minKeyCode) || 180705b261ecSmrg (firstKeyCode + keyCodes - 1 > k->curKeySyms.maxKeyCode)) { 180805b261ecSmrg client->errorValue = firstKeyCode; 180905b261ecSmrg return BadValue; 181005b261ecSmrg } 181105b261ecSmrg if (keySymsPerKeyCode == 0) { 181205b261ecSmrg client->errorValue = 0; 181305b261ecSmrg return BadValue; 181405b261ecSmrg } 181505b261ecSmrg keysyms.minKeyCode = firstKeyCode; 181605b261ecSmrg keysyms.maxKeyCode = firstKeyCode + keyCodes - 1; 181705b261ecSmrg keysyms.mapWidth = keySymsPerKeyCode; 181805b261ecSmrg keysyms.map = map; 181905b261ecSmrg if (!SetKeySymsMap(&k->curKeySyms, &keysyms)) 182005b261ecSmrg return BadAlloc; 182105b261ecSmrg SendDeviceMappingNotify(client, MappingKeyboard, firstKeyCode, keyCodes, dev); 182205b261ecSmrg return client->noClientException; 182305b261ecSmrg} 182405b261ecSmrg 182505b261ecSmrgstatic void 182605b261ecSmrgDeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) 182705b261ecSmrg{ 182805b261ecSmrg WindowPtr parent; 182905b261ecSmrg 183005b261ecSmrg /* Deactivate any grabs performed on this window, before making 183105b261ecSmrg * any input focus changes. 183205b261ecSmrg * Deactivating a device grab should cause focus events. */ 183305b261ecSmrg 18344642e01fSmrg if (dev->deviceGrab.grab && (dev->deviceGrab.grab->window == pWin)) 18354642e01fSmrg (*dev->deviceGrab.DeactivateGrab) (dev); 183605b261ecSmrg 18374642e01fSmrg /* If the focus window is a root window (ie. has no parent) 183805b261ecSmrg * then don't delete the focus from it. */ 183905b261ecSmrg 184005b261ecSmrg if (dev->focus && (pWin == dev->focus->win) && (pWin->parent != NullWindow)) { 184105b261ecSmrg int focusEventMode = NotifyNormal; 184205b261ecSmrg 184305b261ecSmrg /* If a grab is in progress, then alter the mode of focus events. */ 184405b261ecSmrg 18454642e01fSmrg if (dev->deviceGrab.grab) 184605b261ecSmrg focusEventMode = NotifyWhileGrabbed; 184705b261ecSmrg 184805b261ecSmrg switch (dev->focus->revert) { 184905b261ecSmrg case RevertToNone: 185005b261ecSmrg DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 185105b261ecSmrg dev->focus->win = NoneWin; 185205b261ecSmrg dev->focus->traceGood = 0; 185305b261ecSmrg break; 185405b261ecSmrg case RevertToParent: 185505b261ecSmrg parent = pWin; 185605b261ecSmrg do { 185705b261ecSmrg parent = parent->parent; 185805b261ecSmrg dev->focus->traceGood--; 185905b261ecSmrg } 186005b261ecSmrg while (!parent->realized); 186105b261ecSmrg DoFocusEvents(dev, pWin, parent, focusEventMode); 186205b261ecSmrg dev->focus->win = parent; 186305b261ecSmrg dev->focus->revert = RevertToNone; 186405b261ecSmrg break; 186505b261ecSmrg case RevertToPointerRoot: 186605b261ecSmrg DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode); 186705b261ecSmrg dev->focus->win = PointerRootWin; 186805b261ecSmrg dev->focus->traceGood = 0; 186905b261ecSmrg break; 187005b261ecSmrg case RevertToFollowKeyboard: 187105b261ecSmrg if (inputInfo.keyboard->focus->win) { 187205b261ecSmrg DoFocusEvents(dev, pWin, inputInfo.keyboard->focus->win, 187305b261ecSmrg focusEventMode); 187405b261ecSmrg dev->focus->win = FollowKeyboardWin; 187505b261ecSmrg dev->focus->traceGood = 0; 187605b261ecSmrg } else { 187705b261ecSmrg DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 187805b261ecSmrg dev->focus->win = NoneWin; 187905b261ecSmrg dev->focus->traceGood = 0; 188005b261ecSmrg } 188105b261ecSmrg break; 188205b261ecSmrg } 188305b261ecSmrg } 188405b261ecSmrg 188505b261ecSmrg if (dev->valuator) 188605b261ecSmrg if (dev->valuator->motionHintWindow == pWin) 188705b261ecSmrg dev->valuator->motionHintWindow = NullWindow; 188805b261ecSmrg} 188905b261ecSmrg 189005b261ecSmrgvoid 189105b261ecSmrgDeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources) 189205b261ecSmrg{ 189305b261ecSmrg int i; 189405b261ecSmrg DeviceIntPtr dev; 189505b261ecSmrg InputClientsPtr ic; 189605b261ecSmrg struct _OtherInputMasks *inputMasks; 189705b261ecSmrg 189805b261ecSmrg for (dev = inputInfo.devices; dev; dev = dev->next) { 189905b261ecSmrg if (dev == inputInfo.pointer || dev == inputInfo.keyboard) 190005b261ecSmrg continue; 190105b261ecSmrg DeleteDeviceFromAnyExtEvents(pWin, dev); 190205b261ecSmrg } 190305b261ecSmrg 190405b261ecSmrg for (dev = inputInfo.off_devices; dev; dev = dev->next) 190505b261ecSmrg DeleteDeviceFromAnyExtEvents(pWin, dev); 190605b261ecSmrg 190705b261ecSmrg if (freeResources) 190805b261ecSmrg while ((inputMasks = wOtherInputMasks(pWin)) != 0) { 190905b261ecSmrg ic = inputMasks->inputClients; 191005b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 191105b261ecSmrg inputMasks->dontPropagateMask[i] = 0; 191205b261ecSmrg FreeResource(ic->resource, RT_NONE); 191305b261ecSmrg } 191405b261ecSmrg} 191505b261ecSmrg 191605b261ecSmrgint 191705b261ecSmrgMaybeSendDeviceMotionNotifyHint(deviceKeyButtonPointer * pEvents, Mask mask) 191805b261ecSmrg{ 191905b261ecSmrg DeviceIntPtr dev; 192005b261ecSmrg 19214642e01fSmrg dixLookupDevice(&dev, pEvents->deviceid & DEVICE_BITS, serverClient, 19224642e01fSmrg DixReadAccess); 192305b261ecSmrg if (!dev) 192405b261ecSmrg return 0; 192505b261ecSmrg 192605b261ecSmrg if (pEvents->type == DeviceMotionNotify) { 192705b261ecSmrg if (mask & DevicePointerMotionHintMask) { 192805b261ecSmrg if (WID(dev->valuator->motionHintWindow) == pEvents->event) { 192905b261ecSmrg return 1; /* don't send, but pretend we did */ 193005b261ecSmrg } 193105b261ecSmrg pEvents->detail = NotifyHint; 193205b261ecSmrg } else { 193305b261ecSmrg pEvents->detail = NotifyNormal; 193405b261ecSmrg } 193505b261ecSmrg } 193605b261ecSmrg return (0); 193705b261ecSmrg} 193805b261ecSmrg 193905b261ecSmrgvoid 194005b261ecSmrgCheckDeviceGrabAndHintWindow(WindowPtr pWin, int type, 194105b261ecSmrg deviceKeyButtonPointer * xE, GrabPtr grab, 194205b261ecSmrg ClientPtr client, Mask deliveryMask) 194305b261ecSmrg{ 194405b261ecSmrg DeviceIntPtr dev; 194505b261ecSmrg 19464642e01fSmrg dixLookupDevice(&dev, xE->deviceid & DEVICE_BITS, serverClient, 19474642e01fSmrg DixReadAccess); 194805b261ecSmrg if (!dev) 194905b261ecSmrg return; 195005b261ecSmrg 195105b261ecSmrg if (type == DeviceMotionNotify) 195205b261ecSmrg dev->valuator->motionHintWindow = pWin; 195305b261ecSmrg else if ((type == DeviceButtonPress) && (!grab) && 195405b261ecSmrg (deliveryMask & DeviceButtonGrabMask)) { 195505b261ecSmrg GrabRec tempGrab; 195605b261ecSmrg 195705b261ecSmrg tempGrab.device = dev; 195805b261ecSmrg tempGrab.resource = client->clientAsMask; 195905b261ecSmrg tempGrab.window = pWin; 196005b261ecSmrg tempGrab.ownerEvents = 196105b261ecSmrg (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE; 196205b261ecSmrg tempGrab.eventMask = deliveryMask; 196305b261ecSmrg tempGrab.keyboardMode = GrabModeAsync; 196405b261ecSmrg tempGrab.pointerMode = GrabModeAsync; 196505b261ecSmrg tempGrab.confineTo = NullWindow; 196605b261ecSmrg tempGrab.cursor = NullCursor; 19674642e01fSmrg tempGrab.genericMasks = NULL; 19684642e01fSmrg tempGrab.next = NULL; 19694642e01fSmrg (*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE); 197005b261ecSmrg } 197105b261ecSmrg} 197205b261ecSmrg 197305b261ecSmrgstatic Mask 197405b261ecSmrgDeviceEventMaskForClient(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client) 197505b261ecSmrg{ 197605b261ecSmrg InputClientsPtr other; 197705b261ecSmrg 197805b261ecSmrg if (!wOtherInputMasks(pWin)) 197905b261ecSmrg return 0; 198005b261ecSmrg for (other = wOtherInputMasks(pWin)->inputClients; other; 198105b261ecSmrg other = other->next) { 198205b261ecSmrg if (SameClient(other, client)) 198305b261ecSmrg return other->mask[dev->id]; 198405b261ecSmrg } 198505b261ecSmrg return 0; 198605b261ecSmrg} 198705b261ecSmrg 198805b261ecSmrgvoid 198905b261ecSmrgMaybeStopDeviceHint(DeviceIntPtr dev, ClientPtr client) 199005b261ecSmrg{ 199105b261ecSmrg WindowPtr pWin; 19924642e01fSmrg GrabPtr grab = dev->deviceGrab.grab; 199305b261ecSmrg 199405b261ecSmrg pWin = dev->valuator->motionHintWindow; 199505b261ecSmrg 199605b261ecSmrg if ((grab && SameClient(grab, client) && 199705b261ecSmrg ((grab->eventMask & DevicePointerMotionHintMask) || 199805b261ecSmrg (grab->ownerEvents && 199905b261ecSmrg (DeviceEventMaskForClient(dev, pWin, client) & 200005b261ecSmrg DevicePointerMotionHintMask)))) || 200105b261ecSmrg (!grab && 200205b261ecSmrg (DeviceEventMaskForClient(dev, pWin, client) & 200305b261ecSmrg DevicePointerMotionHintMask))) 200405b261ecSmrg dev->valuator->motionHintWindow = NullWindow; 200505b261ecSmrg} 200605b261ecSmrg 200705b261ecSmrgint 200805b261ecSmrgDeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask, 200905b261ecSmrg int maskndx) 201005b261ecSmrg{ 201105b261ecSmrg struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 201205b261ecSmrg 201305b261ecSmrg if (mask & ~PropagateMask[maskndx]) { 201405b261ecSmrg client->errorValue = mask; 201505b261ecSmrg return BadValue; 201605b261ecSmrg } 201705b261ecSmrg 201805b261ecSmrg if (mask == 0) { 201905b261ecSmrg if (inputMasks) 202005b261ecSmrg inputMasks->dontPropagateMask[maskndx] = mask; 202105b261ecSmrg } else { 202205b261ecSmrg if (!inputMasks) 202305b261ecSmrg AddExtensionClient(pWin, client, 0, 0); 202405b261ecSmrg inputMasks = wOtherInputMasks(pWin); 202505b261ecSmrg inputMasks->dontPropagateMask[maskndx] = mask; 202605b261ecSmrg } 202705b261ecSmrg RecalculateDeviceDeliverableEvents(pWin); 202805b261ecSmrg if (ShouldFreeInputMasks(pWin, FALSE)) 202905b261ecSmrg FreeResource(inputMasks->inputClients->resource, RT_NONE); 203005b261ecSmrg return Success; 203105b261ecSmrg} 203205b261ecSmrg 20334642e01fSmrgBool 203405b261ecSmrgShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents) 203505b261ecSmrg{ 203605b261ecSmrg int i; 203705b261ecSmrg Mask allInputEventMasks = 0; 203805b261ecSmrg struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 203905b261ecSmrg 204005b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 204105b261ecSmrg allInputEventMasks |= inputMasks->dontPropagateMask[i]; 204205b261ecSmrg if (!ignoreSelectedEvents) 204305b261ecSmrg for (i = 0; i < EMASKSIZE; i++) 204405b261ecSmrg allInputEventMasks |= inputMasks->inputEvents[i]; 204505b261ecSmrg if (allInputEventMasks == 0) 204605b261ecSmrg return TRUE; 204705b261ecSmrg else 204805b261ecSmrg return FALSE; 204905b261ecSmrg} 205005b261ecSmrg 205105b261ecSmrg/*********************************************************************** 205205b261ecSmrg * 205305b261ecSmrg * Walk through the window tree, finding all clients that want to know 205405b261ecSmrg * about the Event. 205505b261ecSmrg * 205605b261ecSmrg */ 205705b261ecSmrg 205805b261ecSmrgstatic void 205905b261ecSmrgFindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask, 206005b261ecSmrg xEvent * ev, int count) 206105b261ecSmrg{ 206205b261ecSmrg WindowPtr p2; 206305b261ecSmrg 206405b261ecSmrg while (p1) { 206505b261ecSmrg p2 = p1->firstChild; 20664642e01fSmrg (void)DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab, dev->id); 206705b261ecSmrg FindInterestedChildren(dev, p2, mask, ev, count); 206805b261ecSmrg p1 = p1->nextSib; 206905b261ecSmrg } 207005b261ecSmrg} 207105b261ecSmrg 207205b261ecSmrg/*********************************************************************** 207305b261ecSmrg * 207405b261ecSmrg * Send an event to interested clients in all windows on all screens. 207505b261ecSmrg * 207605b261ecSmrg */ 207705b261ecSmrg 207805b261ecSmrgvoid 207905b261ecSmrgSendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count) 208005b261ecSmrg{ 208105b261ecSmrg int i; 208205b261ecSmrg WindowPtr pWin, p1; 208305b261ecSmrg 208405b261ecSmrg for (i = 0; i < screenInfo.numScreens; i++) { 208505b261ecSmrg pWin = WindowTable[i]; 20864642e01fSmrg if (!pWin) 20874642e01fSmrg continue; 20884642e01fSmrg (void)DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab, dev->id); 208905b261ecSmrg p1 = pWin->firstChild; 209005b261ecSmrg FindInterestedChildren(dev, p1, mask, ev, count); 209105b261ecSmrg } 209205b261ecSmrg} 20934642e01fSmrg 2094