exevents.c revision 706f2543
1706f2543Smrg/************************************************************ 2706f2543Smrg 3706f2543SmrgCopyright 1989, 1998 The Open Group 4706f2543Smrg 5706f2543SmrgPermission to use, copy, modify, distribute, and sell this software and its 6706f2543Smrgdocumentation for any purpose is hereby granted without fee, provided that 7706f2543Smrgthe above copyright notice appear in all copies and that both that 8706f2543Smrgcopyright notice and this permission notice appear in supporting 9706f2543Smrgdocumentation. 10706f2543Smrg 11706f2543SmrgThe above copyright notice and this permission notice shall be included in 12706f2543Smrgall copies or substantial portions of the Software. 13706f2543Smrg 14706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15706f2543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16706f2543SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17706f2543SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18706f2543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19706f2543SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20706f2543Smrg 21706f2543SmrgExcept as contained in this notice, the name of The Open Group shall not be 22706f2543Smrgused in advertising or otherwise to promote the sale, use or other dealings 23706f2543Smrgin this Software without prior written authorization from The Open Group. 24706f2543Smrg 25706f2543SmrgCopyright 1989 by Hewlett-Packard Company, Palo Alto, California. 26706f2543Smrg 27706f2543Smrg All Rights Reserved 28706f2543Smrg 29706f2543SmrgPermission to use, copy, modify, and distribute this software and its 30706f2543Smrgdocumentation for any purpose and without fee is hereby granted, 31706f2543Smrgprovided that the above copyright notice appear in all copies and that 32706f2543Smrgboth that copyright notice and this permission notice appear in 33706f2543Smrgsupporting documentation, and that the name of Hewlett-Packard not be 34706f2543Smrgused in advertising or publicity pertaining to distribution of the 35706f2543Smrgsoftware without specific, written prior permission. 36706f2543Smrg 37706f2543SmrgHEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 38706f2543SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 39706f2543SmrgHEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 40706f2543SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 41706f2543SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 42706f2543SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 43706f2543SmrgSOFTWARE. 44706f2543Smrg 45706f2543Smrg********************************************************/ 46706f2543Smrg 47706f2543Smrg/******************************************************************** 48706f2543Smrg * 49706f2543Smrg * Routines to register and initialize extension input devices. 50706f2543Smrg * This also contains ProcessOtherEvent, the routine called from DDX 51706f2543Smrg * to route extension events. 52706f2543Smrg * 53706f2543Smrg */ 54706f2543Smrg 55706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 56706f2543Smrg#include <dix-config.h> 57706f2543Smrg#endif 58706f2543Smrg 59706f2543Smrg#include "inputstr.h" 60706f2543Smrg#include <X11/X.h> 61706f2543Smrg#include <X11/Xproto.h> 62706f2543Smrg#include <X11/extensions/XI.h> 63706f2543Smrg#include <X11/extensions/XIproto.h> 64706f2543Smrg#include <X11/extensions/XI2proto.h> 65706f2543Smrg#include <X11/extensions/geproto.h> 66706f2543Smrg#include "windowstr.h" 67706f2543Smrg#include "miscstruct.h" 68706f2543Smrg#include "region.h" 69706f2543Smrg#include "exevents.h" 70706f2543Smrg#include "extnsionst.h" 71706f2543Smrg#include "exglobals.h" 72706f2543Smrg#include "dixevents.h" /* DeliverFocusedEvent */ 73706f2543Smrg#include "dixgrabs.h" /* CreateGrab() */ 74706f2543Smrg#include "scrnintstr.h" 75706f2543Smrg#include "listdev.h" /* for CopySwapXXXClass */ 76706f2543Smrg#include "xace.h" 77706f2543Smrg#include "xiquerydevice.h" /* For List*Info */ 78706f2543Smrg#include "eventconvert.h" 79706f2543Smrg#include "eventstr.h" 80706f2543Smrg 81706f2543Smrg#include <X11/extensions/XKBproto.h> 82706f2543Smrg#include "xkbsrv.h" 83706f2543Smrg 84706f2543Smrg#define WID(w) ((w) ? ((w)->drawable.id) : 0) 85706f2543Smrg#define AllModifiersMask ( \ 86706f2543Smrg ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \ 87706f2543Smrg Mod3Mask | Mod4Mask | Mod5Mask ) 88706f2543Smrg#define AllButtonsMask ( \ 89706f2543Smrg Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask ) 90706f2543Smrg 91706f2543SmrgBool ShouldFreeInputMasks(WindowPtr /* pWin */ , 92706f2543Smrg Bool /* ignoreSelectedEvents */ 93706f2543Smrg ); 94706f2543Smrgstatic Bool MakeInputMasks(WindowPtr /* pWin */ 95706f2543Smrg ); 96706f2543Smrg 97706f2543Smrg/* 98706f2543Smrg * Only let the given client know of core events which will affect its 99706f2543Smrg * interpretation of input events, if the client's ClientPointer (or the 100706f2543Smrg * paired keyboard) is the current device. 101706f2543Smrg */ 102706f2543Smrgint 103706f2543SmrgXIShouldNotify(ClientPtr client, DeviceIntPtr dev) 104706f2543Smrg{ 105706f2543Smrg DeviceIntPtr current_ptr = PickPointer(client); 106706f2543Smrg DeviceIntPtr current_kbd = GetPairedDevice(current_ptr); 107706f2543Smrg 108706f2543Smrg if (dev == current_kbd || dev == current_ptr) 109706f2543Smrg return 1; 110706f2543Smrg 111706f2543Smrg return 0; 112706f2543Smrg} 113706f2543Smrg 114706f2543SmrgBool 115706f2543SmrgIsPointerEvent(InternalEvent* event) 116706f2543Smrg{ 117706f2543Smrg switch(event->any.type) 118706f2543Smrg { 119706f2543Smrg case ET_ButtonPress: 120706f2543Smrg case ET_ButtonRelease: 121706f2543Smrg case ET_Motion: 122706f2543Smrg /* XXX: enter/leave ?? */ 123706f2543Smrg return TRUE; 124706f2543Smrg default: 125706f2543Smrg break; 126706f2543Smrg } 127706f2543Smrg return FALSE; 128706f2543Smrg} 129706f2543Smrg 130706f2543Smrg/** 131706f2543Smrg * @return the device matching the deviceid of the device set in the event, or 132706f2543Smrg * NULL if the event is not an XInput event. 133706f2543Smrg */ 134706f2543SmrgDeviceIntPtr 135706f2543SmrgXIGetDevice(xEvent* xE) 136706f2543Smrg{ 137706f2543Smrg DeviceIntPtr pDev = NULL; 138706f2543Smrg 139706f2543Smrg if (xE->u.u.type == DeviceButtonPress || 140706f2543Smrg xE->u.u.type == DeviceButtonRelease || 141706f2543Smrg xE->u.u.type == DeviceMotionNotify || 142706f2543Smrg xE->u.u.type == ProximityIn || 143706f2543Smrg xE->u.u.type == ProximityOut || 144706f2543Smrg xE->u.u.type == DevicePropertyNotify) 145706f2543Smrg { 146706f2543Smrg int rc; 147706f2543Smrg int id; 148706f2543Smrg 149706f2543Smrg id = ((deviceKeyButtonPointer*)xE)->deviceid & ~MORE_EVENTS; 150706f2543Smrg 151706f2543Smrg rc = dixLookupDevice(&pDev, id, serverClient, DixUnknownAccess); 152706f2543Smrg if (rc != Success) 153706f2543Smrg ErrorF("[dix] XIGetDevice failed on XACE restrictions (%d)\n", rc); 154706f2543Smrg } 155706f2543Smrg return pDev; 156706f2543Smrg} 157706f2543Smrg 158706f2543Smrg 159706f2543Smrg/** 160706f2543Smrg * Copy the device->key into master->key and send a mapping notify to the 161706f2543Smrg * clients if appropriate. 162706f2543Smrg * master->key needs to be allocated by the caller. 163706f2543Smrg * 164706f2543Smrg * Device is the slave device. If it is attached to a master device, we may 165706f2543Smrg * need to send a mapping notify to the client because it causes the MD 166706f2543Smrg * to change state. 167706f2543Smrg * 168706f2543Smrg * Mapping notify needs to be sent in the following cases: 169706f2543Smrg * - different slave device on same master 170706f2543Smrg * - different master 171706f2543Smrg * 172706f2543Smrg * XXX: They way how the code is we also send a map notify if the slave device 173706f2543Smrg * stays the same, but the master changes. This isn't really necessary though. 174706f2543Smrg * 175706f2543Smrg * XXX: this gives you funny behaviour with the ClientPointer. When a 176706f2543Smrg * MappingNotify is sent to the client, the client usually responds with a 177706f2543Smrg * GetKeyboardMapping. This will retrieve the ClientPointer's keyboard 178706f2543Smrg * mapping, regardless of which keyboard sent the last mapping notify request. 179706f2543Smrg * So depending on the CP setting, your keyboard may change layout in each 180706f2543Smrg * app... 181706f2543Smrg * 182706f2543Smrg * This code is basically the old SwitchCoreKeyboard. 183706f2543Smrg */ 184706f2543Smrg 185706f2543Smrgvoid 186706f2543SmrgCopyKeyClass(DeviceIntPtr device, DeviceIntPtr master) 187706f2543Smrg{ 188706f2543Smrg KeyClassPtr mk = master->key; 189706f2543Smrg 190706f2543Smrg if (device == master) 191706f2543Smrg return; 192706f2543Smrg 193706f2543Smrg mk->sourceid = device->id; 194706f2543Smrg 195706f2543Smrg 196706f2543Smrg if (!XkbCopyDeviceKeymap(master, device)) 197706f2543Smrg FatalError("Couldn't pivot keymap from device to core!\n"); 198706f2543Smrg} 199706f2543Smrg 200706f2543Smrg/** 201706f2543Smrg * Copies the feedback classes from device "from" into device "to". Classes 202706f2543Smrg * are duplicated (not just flipping the pointers). All feedback classes are 203706f2543Smrg * linked lists, the full list is duplicated. 204706f2543Smrg */ 205706f2543Smrgstatic void 206706f2543SmrgDeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) 207706f2543Smrg{ 208706f2543Smrg ClassesPtr classes; 209706f2543Smrg 210706f2543Smrg 211706f2543Smrg if (from->intfeed) 212706f2543Smrg { 213706f2543Smrg IntegerFeedbackPtr *i, it; 214706f2543Smrg 215706f2543Smrg if (!to->intfeed) 216706f2543Smrg { 217706f2543Smrg classes = to->unused_classes; 218706f2543Smrg to->intfeed = classes->intfeed; 219706f2543Smrg classes->intfeed = NULL; 220706f2543Smrg } 221706f2543Smrg 222706f2543Smrg i = &to->intfeed; 223706f2543Smrg for (it = from->intfeed; it; it = it->next) 224706f2543Smrg { 225706f2543Smrg if (!(*i)) 226706f2543Smrg { 227706f2543Smrg *i = calloc(1, sizeof(IntegerFeedbackClassRec)); 228706f2543Smrg if (!(*i)) 229706f2543Smrg { 230706f2543Smrg ErrorF("[Xi] Cannot alloc memory for class copy."); 231706f2543Smrg return; 232706f2543Smrg } 233706f2543Smrg } 234706f2543Smrg (*i)->CtrlProc = it->CtrlProc; 235706f2543Smrg (*i)->ctrl = it->ctrl; 236706f2543Smrg 237706f2543Smrg i = &(*i)->next; 238706f2543Smrg } 239706f2543Smrg } else if (to->intfeed && !from->intfeed) 240706f2543Smrg { 241706f2543Smrg ClassesPtr classes; 242706f2543Smrg classes = to->unused_classes; 243706f2543Smrg classes->intfeed = to->intfeed; 244706f2543Smrg to->intfeed = NULL; 245706f2543Smrg } 246706f2543Smrg 247706f2543Smrg if (from->stringfeed) 248706f2543Smrg { 249706f2543Smrg StringFeedbackPtr *s, it; 250706f2543Smrg 251706f2543Smrg if (!to->stringfeed) 252706f2543Smrg { 253706f2543Smrg classes = to->unused_classes; 254706f2543Smrg to->stringfeed = classes->stringfeed; 255706f2543Smrg classes->stringfeed = NULL; 256706f2543Smrg } 257706f2543Smrg 258706f2543Smrg s = &to->stringfeed; 259706f2543Smrg for (it = from->stringfeed; it; it = it->next) 260706f2543Smrg { 261706f2543Smrg if (!(*s)) 262706f2543Smrg { 263706f2543Smrg *s = calloc(1, sizeof(StringFeedbackClassRec)); 264706f2543Smrg if (!(*s)) 265706f2543Smrg { 266706f2543Smrg ErrorF("[Xi] Cannot alloc memory for class copy."); 267706f2543Smrg return; 268706f2543Smrg } 269706f2543Smrg } 270706f2543Smrg (*s)->CtrlProc = it->CtrlProc; 271706f2543Smrg (*s)->ctrl = it->ctrl; 272706f2543Smrg 273706f2543Smrg s = &(*s)->next; 274706f2543Smrg } 275706f2543Smrg } else if (to->stringfeed && !from->stringfeed) 276706f2543Smrg { 277706f2543Smrg ClassesPtr classes; 278706f2543Smrg classes = to->unused_classes; 279706f2543Smrg classes->stringfeed = to->stringfeed; 280706f2543Smrg to->stringfeed = NULL; 281706f2543Smrg } 282706f2543Smrg 283706f2543Smrg if (from->bell) 284706f2543Smrg { 285706f2543Smrg BellFeedbackPtr *b, it; 286706f2543Smrg 287706f2543Smrg if (!to->bell) 288706f2543Smrg { 289706f2543Smrg classes = to->unused_classes; 290706f2543Smrg to->bell = classes->bell; 291706f2543Smrg classes->bell = NULL; 292706f2543Smrg } 293706f2543Smrg 294706f2543Smrg b = &to->bell; 295706f2543Smrg for (it = from->bell; it; it = it->next) 296706f2543Smrg { 297706f2543Smrg if (!(*b)) 298706f2543Smrg { 299706f2543Smrg *b = calloc(1, sizeof(BellFeedbackClassRec)); 300706f2543Smrg if (!(*b)) 301706f2543Smrg { 302706f2543Smrg ErrorF("[Xi] Cannot alloc memory for class copy."); 303706f2543Smrg return; 304706f2543Smrg } 305706f2543Smrg } 306706f2543Smrg (*b)->BellProc = it->BellProc; 307706f2543Smrg (*b)->CtrlProc = it->CtrlProc; 308706f2543Smrg (*b)->ctrl = it->ctrl; 309706f2543Smrg 310706f2543Smrg b = &(*b)->next; 311706f2543Smrg } 312706f2543Smrg } else if (to->bell && !from->bell) 313706f2543Smrg { 314706f2543Smrg ClassesPtr classes; 315706f2543Smrg classes = to->unused_classes; 316706f2543Smrg classes->bell = to->bell; 317706f2543Smrg to->bell = NULL; 318706f2543Smrg } 319706f2543Smrg 320706f2543Smrg if (from->leds) 321706f2543Smrg { 322706f2543Smrg LedFeedbackPtr *l, it; 323706f2543Smrg 324706f2543Smrg if (!to->leds) 325706f2543Smrg { 326706f2543Smrg classes = to->unused_classes; 327706f2543Smrg to->leds = classes->leds; 328706f2543Smrg classes->leds = NULL; 329706f2543Smrg } 330706f2543Smrg 331706f2543Smrg l = &to->leds; 332706f2543Smrg for (it = from->leds; it; it = it->next) 333706f2543Smrg { 334706f2543Smrg if (!(*l)) 335706f2543Smrg { 336706f2543Smrg *l = calloc(1, sizeof(LedFeedbackClassRec)); 337706f2543Smrg if (!(*l)) 338706f2543Smrg { 339706f2543Smrg ErrorF("[Xi] Cannot alloc memory for class copy."); 340706f2543Smrg return; 341706f2543Smrg } 342706f2543Smrg } 343706f2543Smrg (*l)->CtrlProc = it->CtrlProc; 344706f2543Smrg (*l)->ctrl = it->ctrl; 345706f2543Smrg if ((*l)->xkb_sli) 346706f2543Smrg XkbFreeSrvLedInfo((*l)->xkb_sli); 347706f2543Smrg (*l)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, NULL, *l); 348706f2543Smrg 349706f2543Smrg l = &(*l)->next; 350706f2543Smrg } 351706f2543Smrg } else if (to->leds && !from->leds) 352706f2543Smrg { 353706f2543Smrg ClassesPtr classes; 354706f2543Smrg classes = to->unused_classes; 355706f2543Smrg classes->leds = to->leds; 356706f2543Smrg to->leds = NULL; 357706f2543Smrg } 358706f2543Smrg} 359706f2543Smrg 360706f2543Smrgstatic void 361706f2543SmrgDeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to) 362706f2543Smrg{ 363706f2543Smrg ClassesPtr classes; 364706f2543Smrg 365706f2543Smrg /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the 366706f2543Smrg * kbdfeed to be set up properly, so let's do the feedback classes first. 367706f2543Smrg */ 368706f2543Smrg if (from->kbdfeed) 369706f2543Smrg { 370706f2543Smrg KbdFeedbackPtr *k, it; 371706f2543Smrg 372706f2543Smrg if (!to->kbdfeed) 373706f2543Smrg { 374706f2543Smrg classes = to->unused_classes; 375706f2543Smrg 376706f2543Smrg to->kbdfeed = classes->kbdfeed; 377706f2543Smrg if (!to->kbdfeed) 378706f2543Smrg InitKeyboardDeviceStruct(to, NULL, NULL, NULL); 379706f2543Smrg classes->kbdfeed = NULL; 380706f2543Smrg } 381706f2543Smrg 382706f2543Smrg k = &to->kbdfeed; 383706f2543Smrg for(it = from->kbdfeed; it; it = it->next) 384706f2543Smrg { 385706f2543Smrg if (!(*k)) 386706f2543Smrg { 387706f2543Smrg *k = calloc(1, sizeof(KbdFeedbackClassRec)); 388706f2543Smrg if (!*k) 389706f2543Smrg { 390706f2543Smrg ErrorF("[Xi] Cannot alloc memory for class copy."); 391706f2543Smrg return; 392706f2543Smrg } 393706f2543Smrg } 394706f2543Smrg (*k)->BellProc = it->BellProc; 395706f2543Smrg (*k)->CtrlProc = it->CtrlProc; 396706f2543Smrg (*k)->ctrl = it->ctrl; 397706f2543Smrg if ((*k)->xkb_sli) 398706f2543Smrg XkbFreeSrvLedInfo((*k)->xkb_sli); 399706f2543Smrg (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL); 400706f2543Smrg 401706f2543Smrg k = &(*k)->next; 402706f2543Smrg } 403706f2543Smrg } else if (to->kbdfeed && !from->kbdfeed) 404706f2543Smrg { 405706f2543Smrg ClassesPtr classes; 406706f2543Smrg classes = to->unused_classes; 407706f2543Smrg classes->kbdfeed = to->kbdfeed; 408706f2543Smrg to->kbdfeed = NULL; 409706f2543Smrg } 410706f2543Smrg 411706f2543Smrg if (from->key) 412706f2543Smrg { 413706f2543Smrg if (!to->key) 414706f2543Smrg { 415706f2543Smrg classes = to->unused_classes; 416706f2543Smrg to->key = classes->key; 417706f2543Smrg if (!to->key) 418706f2543Smrg InitKeyboardDeviceStruct(to, NULL, NULL, NULL); 419706f2543Smrg else 420706f2543Smrg classes->key = NULL; 421706f2543Smrg } 422706f2543Smrg 423706f2543Smrg CopyKeyClass(from, to); 424706f2543Smrg } else if (to->key && !from->key) 425706f2543Smrg { 426706f2543Smrg ClassesPtr classes; 427706f2543Smrg classes = to->unused_classes; 428706f2543Smrg classes->key = to->key; 429706f2543Smrg to->key = NULL; 430706f2543Smrg } 431706f2543Smrg 432706f2543Smrg /* If a SrvLedInfoPtr's flags are XkbSLI_IsDefault, the names and maps 433706f2543Smrg * pointer point into the xkbInfo->desc struct. XkbCopySrvLedInfo 434706f2543Smrg * didn't update the pointers so we need to do it manually here. 435706f2543Smrg */ 436706f2543Smrg if (to->kbdfeed) 437706f2543Smrg { 438706f2543Smrg KbdFeedbackPtr k; 439706f2543Smrg 440706f2543Smrg for (k = to->kbdfeed; k; k = k->next) 441706f2543Smrg { 442706f2543Smrg if (!k->xkb_sli) 443706f2543Smrg continue; 444706f2543Smrg if (k->xkb_sli->flags & XkbSLI_IsDefault) 445706f2543Smrg { 446706f2543Smrg k->xkb_sli->names = to->key->xkbInfo->desc->names->indicators; 447706f2543Smrg k->xkb_sli->maps = to->key->xkbInfo->desc->indicators->maps; 448706f2543Smrg } 449706f2543Smrg } 450706f2543Smrg } 451706f2543Smrg 452706f2543Smrg /* We can't just copy over the focus class. When an app sets the focus, 453706f2543Smrg * it'll do so on the master device. Copying the SDs focus means losing 454706f2543Smrg * the focus. 455706f2543Smrg * So we only copy the focus class if the device didn't have one, 456706f2543Smrg * otherwise we leave it as it is. 457706f2543Smrg */ 458706f2543Smrg if (from->focus) 459706f2543Smrg { 460706f2543Smrg if (!to->focus) 461706f2543Smrg { 462706f2543Smrg WindowPtr *oldTrace; 463706f2543Smrg 464706f2543Smrg classes = to->unused_classes; 465706f2543Smrg to->focus = classes->focus; 466706f2543Smrg if (!to->focus) 467706f2543Smrg { 468706f2543Smrg to->focus = calloc(1, sizeof(FocusClassRec)); 469706f2543Smrg if (!to->focus) 470706f2543Smrg FatalError("[Xi] no memory for class shift.\n"); 471706f2543Smrg } else 472706f2543Smrg classes->focus = NULL; 473706f2543Smrg 474706f2543Smrg oldTrace = to->focus->trace; 475706f2543Smrg memcpy(to->focus, from->focus, sizeof(FocusClassRec)); 476706f2543Smrg to->focus->trace = realloc(oldTrace, 477706f2543Smrg to->focus->traceSize * sizeof(WindowPtr)); 478706f2543Smrg if (!to->focus->trace && to->focus->traceSize) 479706f2543Smrg FatalError("[Xi] no memory for trace.\n"); 480706f2543Smrg memcpy(to->focus->trace, from->focus->trace, 481706f2543Smrg from->focus->traceSize * sizeof(WindowPtr)); 482706f2543Smrg to->focus->sourceid = from->id; 483706f2543Smrg } 484706f2543Smrg } else if (to->focus) 485706f2543Smrg { 486706f2543Smrg ClassesPtr classes; 487706f2543Smrg classes = to->unused_classes; 488706f2543Smrg classes->focus = to->focus; 489706f2543Smrg to->focus = NULL; 490706f2543Smrg } 491706f2543Smrg 492706f2543Smrg} 493706f2543Smrg 494706f2543Smrgstatic void 495706f2543SmrgDeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to) 496706f2543Smrg{ 497706f2543Smrg ClassesPtr classes; 498706f2543Smrg 499706f2543Smrg /* Feedback classes must be copied first */ 500706f2543Smrg if (from->ptrfeed) 501706f2543Smrg { 502706f2543Smrg PtrFeedbackPtr *p, it; 503706f2543Smrg if (!to->ptrfeed) 504706f2543Smrg { 505706f2543Smrg classes = to->unused_classes; 506706f2543Smrg to->ptrfeed = classes->ptrfeed; 507706f2543Smrg classes->ptrfeed = NULL; 508706f2543Smrg } 509706f2543Smrg 510706f2543Smrg p = &to->ptrfeed; 511706f2543Smrg for (it = from->ptrfeed; it; it = it->next) 512706f2543Smrg { 513706f2543Smrg if (!(*p)) 514706f2543Smrg { 515706f2543Smrg *p = calloc(1, sizeof(PtrFeedbackClassRec)); 516706f2543Smrg if (!*p) 517706f2543Smrg { 518706f2543Smrg ErrorF("[Xi] Cannot alloc memory for class copy."); 519706f2543Smrg return; 520706f2543Smrg } 521706f2543Smrg } 522706f2543Smrg (*p)->CtrlProc = it->CtrlProc; 523706f2543Smrg (*p)->ctrl = it->ctrl; 524706f2543Smrg 525706f2543Smrg p = &(*p)->next; 526706f2543Smrg } 527706f2543Smrg } else if (to->ptrfeed && !from->ptrfeed) 528706f2543Smrg { 529706f2543Smrg ClassesPtr classes; 530706f2543Smrg classes = to->unused_classes; 531706f2543Smrg classes->ptrfeed = to->ptrfeed; 532706f2543Smrg to->ptrfeed = NULL; 533706f2543Smrg } 534706f2543Smrg 535706f2543Smrg if (from->valuator) 536706f2543Smrg { 537706f2543Smrg ValuatorClassPtr v; 538706f2543Smrg 539706f2543Smrg if (!to->valuator) 540706f2543Smrg { 541706f2543Smrg classes = to->unused_classes; 542706f2543Smrg to->valuator = classes->valuator; 543706f2543Smrg if (to->valuator) 544706f2543Smrg classes->valuator = NULL; 545706f2543Smrg } 546706f2543Smrg 547706f2543Smrg v = AllocValuatorClass(to->valuator, from->valuator->numAxes); 548706f2543Smrg 549706f2543Smrg if (!v) 550706f2543Smrg FatalError("[Xi] no memory for class shift.\n"); 551706f2543Smrg 552706f2543Smrg to->valuator = v; 553706f2543Smrg memcpy(v->axes, from->valuator->axes, v->numAxes * sizeof(AxisInfo)); 554706f2543Smrg 555706f2543Smrg v->sourceid = from->id; 556706f2543Smrg } else if (to->valuator && !from->valuator) 557706f2543Smrg { 558706f2543Smrg ClassesPtr classes; 559706f2543Smrg classes = to->unused_classes; 560706f2543Smrg classes->valuator = to->valuator; 561706f2543Smrg to->valuator = NULL; 562706f2543Smrg } 563706f2543Smrg 564706f2543Smrg if (from->button) 565706f2543Smrg { 566706f2543Smrg if (!to->button) 567706f2543Smrg { 568706f2543Smrg classes = to->unused_classes; 569706f2543Smrg to->button = classes->button; 570706f2543Smrg if (!to->button) 571706f2543Smrg { 572706f2543Smrg to->button = calloc(1, sizeof(ButtonClassRec)); 573706f2543Smrg if (!to->button) 574706f2543Smrg FatalError("[Xi] no memory for class shift.\n"); 575706f2543Smrg } else 576706f2543Smrg classes->button = NULL; 577706f2543Smrg } 578706f2543Smrg 579706f2543Smrg if (from->button->xkb_acts) 580706f2543Smrg { 581706f2543Smrg if (!to->button->xkb_acts) 582706f2543Smrg { 583706f2543Smrg to->button->xkb_acts = calloc(1, sizeof(XkbAction)); 584706f2543Smrg if (!to->button->xkb_acts) 585706f2543Smrg FatalError("[Xi] not enough memory for xkb_acts.\n"); 586706f2543Smrg } 587706f2543Smrg memcpy(to->button->xkb_acts, from->button->xkb_acts, 588706f2543Smrg sizeof(XkbAction)); 589706f2543Smrg } else 590706f2543Smrg free(to->button->xkb_acts); 591706f2543Smrg 592706f2543Smrg memcpy(to->button->labels, from->button->labels, 593706f2543Smrg from->button->numButtons * sizeof(Atom)); 594706f2543Smrg to->button->sourceid = from->id; 595706f2543Smrg } else if (to->button && !from->button) 596706f2543Smrg { 597706f2543Smrg ClassesPtr classes; 598706f2543Smrg classes = to->unused_classes; 599706f2543Smrg classes->button = to->button; 600706f2543Smrg to->button = NULL; 601706f2543Smrg } 602706f2543Smrg 603706f2543Smrg if (from->proximity) 604706f2543Smrg { 605706f2543Smrg if (!to->proximity) 606706f2543Smrg { 607706f2543Smrg classes = to->unused_classes; 608706f2543Smrg to->proximity = classes->proximity; 609706f2543Smrg if (!to->proximity) 610706f2543Smrg { 611706f2543Smrg to->proximity = calloc(1, sizeof(ProximityClassRec)); 612706f2543Smrg if (!to->proximity) 613706f2543Smrg FatalError("[Xi] no memory for class shift.\n"); 614706f2543Smrg } else 615706f2543Smrg classes->proximity = NULL; 616706f2543Smrg } 617706f2543Smrg memcpy(to->proximity, from->proximity, sizeof(ProximityClassRec)); 618706f2543Smrg to->proximity->sourceid = from->id; 619706f2543Smrg } else if (to->proximity) 620706f2543Smrg { 621706f2543Smrg ClassesPtr classes; 622706f2543Smrg classes = to->unused_classes; 623706f2543Smrg classes->proximity = to->proximity; 624706f2543Smrg to->proximity = NULL; 625706f2543Smrg } 626706f2543Smrg 627706f2543Smrg if (from->absolute) 628706f2543Smrg { 629706f2543Smrg if (!to->absolute) 630706f2543Smrg { 631706f2543Smrg classes = to->unused_classes; 632706f2543Smrg to->absolute = classes->absolute; 633706f2543Smrg if (!to->absolute) 634706f2543Smrg { 635706f2543Smrg to->absolute = calloc(1, sizeof(AbsoluteClassRec)); 636706f2543Smrg if (!to->absolute) 637706f2543Smrg FatalError("[Xi] no memory for class shift.\n"); 638706f2543Smrg } else 639706f2543Smrg classes->absolute = NULL; 640706f2543Smrg } 641706f2543Smrg memcpy(to->absolute, from->absolute, sizeof(AbsoluteClassRec)); 642706f2543Smrg to->absolute->sourceid = from->id; 643706f2543Smrg } else if (to->absolute) 644706f2543Smrg { 645706f2543Smrg ClassesPtr classes; 646706f2543Smrg classes = to->unused_classes; 647706f2543Smrg classes->absolute = to->absolute; 648706f2543Smrg to->absolute = NULL; 649706f2543Smrg } 650706f2543Smrg} 651706f2543Smrg 652706f2543Smrg/** 653706f2543Smrg * Copies the CONTENT of the classes of device from into the classes in device 654706f2543Smrg * to. From and to are identical after finishing. 655706f2543Smrg * 656706f2543Smrg * If to does not have classes from currenly has, the classes are stored in 657706f2543Smrg * to's devPrivates system. Later, we recover it again from there if needed. 658706f2543Smrg * Saves a few memory allocations. 659706f2543Smrg */ 660706f2543Smrgvoid 661706f2543SmrgDeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to, DeviceChangedEvent *dce) 662706f2543Smrg{ 663706f2543Smrg /* generic feedback classes, not tied to pointer and/or keyboard */ 664706f2543Smrg DeepCopyFeedbackClasses(from, to); 665706f2543Smrg 666706f2543Smrg if ((dce->flags & DEVCHANGE_KEYBOARD_EVENT)) 667706f2543Smrg DeepCopyKeyboardClasses(from, to); 668706f2543Smrg if ((dce->flags & DEVCHANGE_POINTER_EVENT)) 669706f2543Smrg DeepCopyPointerClasses(from, to); 670706f2543Smrg} 671706f2543Smrg 672706f2543Smrg 673706f2543Smrg/** 674706f2543Smrg * Send an XI2 DeviceChangedEvent to all interested clients. 675706f2543Smrg */ 676706f2543Smrgvoid 677706f2543SmrgXISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChangedEvent *dce) 678706f2543Smrg{ 679706f2543Smrg xXIDeviceChangedEvent *dcce; 680706f2543Smrg int rc; 681706f2543Smrg 682706f2543Smrg rc = EventToXI2((InternalEvent*)dce, (xEvent**)&dcce); 683706f2543Smrg if (rc != Success) 684706f2543Smrg { 685706f2543Smrg ErrorF("[Xi] event conversion from DCE failed with code %d\n", rc); 686706f2543Smrg return; 687706f2543Smrg } 688706f2543Smrg 689706f2543Smrg /* we don't actually swap if there's a NullClient, swapping is done 690706f2543Smrg * later when event is delivered. */ 691706f2543Smrg SendEventToAllWindows(master, XI_DeviceChangedMask, (xEvent*)dcce, 1); 692706f2543Smrg free(dcce); 693706f2543Smrg} 694706f2543Smrg 695706f2543Smrgstatic void 696706f2543SmrgChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce) 697706f2543Smrg{ 698706f2543Smrg DeviceIntPtr slave; 699706f2543Smrg int rc; 700706f2543Smrg 701706f2543Smrg /* For now, we don't have devices that change physically. */ 702706f2543Smrg if (!IsMaster(device)) 703706f2543Smrg return; 704706f2543Smrg 705706f2543Smrg rc = dixLookupDevice(&slave, dce->sourceid, serverClient, DixReadAccess); 706706f2543Smrg 707706f2543Smrg if (rc != Success) 708706f2543Smrg return; /* Device has disappeared */ 709706f2543Smrg 710706f2543Smrg if (!slave->u.master) 711706f2543Smrg return; /* set floating since the event */ 712706f2543Smrg 713706f2543Smrg if (slave->u.master->id != dce->masterid) 714706f2543Smrg return; /* not our slave anymore, don't care */ 715706f2543Smrg 716706f2543Smrg /* FIXME: we probably need to send a DCE for the new slave now */ 717706f2543Smrg 718706f2543Smrg device->public.devicePrivate = slave->public.devicePrivate; 719706f2543Smrg 720706f2543Smrg /* FIXME: the classes may have changed since we generated the event. */ 721706f2543Smrg DeepCopyDeviceClasses(slave, device, dce); 722706f2543Smrg XISendDeviceChangedEvent(slave, device, dce); 723706f2543Smrg} 724706f2543Smrg 725706f2543Smrg/** 726706f2543Smrg * Update the device state according to the data in the event. 727706f2543Smrg * 728706f2543Smrg * return values are 729706f2543Smrg * DEFAULT ... process as normal 730706f2543Smrg * DONT_PROCESS ... return immediately from caller 731706f2543Smrg */ 732706f2543Smrg#define DEFAULT 0 733706f2543Smrg#define DONT_PROCESS 1 734706f2543Smrgint 735706f2543SmrgUpdateDeviceState(DeviceIntPtr device, DeviceEvent* event) 736706f2543Smrg{ 737706f2543Smrg int i; 738706f2543Smrg int key = 0, 739706f2543Smrg bit = 0, 740706f2543Smrg last_valuator; 741706f2543Smrg 742706f2543Smrg KeyClassPtr k = NULL; 743706f2543Smrg ButtonClassPtr b = NULL; 744706f2543Smrg ValuatorClassPtr v = NULL; 745706f2543Smrg 746706f2543Smrg /* This event is always the first we get, before the actual events with 747706f2543Smrg * the data. However, the way how the DDX is set up, "device" will 748706f2543Smrg * actually be the slave device that caused the event. 749706f2543Smrg */ 750706f2543Smrg switch(event->type) 751706f2543Smrg { 752706f2543Smrg case ET_DeviceChanged: 753706f2543Smrg ChangeMasterDeviceClasses(device, (DeviceChangedEvent*)event); 754706f2543Smrg return DONT_PROCESS; /* event has been sent already */ 755706f2543Smrg case ET_Motion: 756706f2543Smrg case ET_ButtonPress: 757706f2543Smrg case ET_ButtonRelease: 758706f2543Smrg case ET_KeyPress: 759706f2543Smrg case ET_KeyRelease: 760706f2543Smrg case ET_ProximityIn: 761706f2543Smrg case ET_ProximityOut: 762706f2543Smrg break; 763706f2543Smrg default: 764706f2543Smrg /* other events don't update the device */ 765706f2543Smrg return DEFAULT; 766706f2543Smrg } 767706f2543Smrg 768706f2543Smrg k = device->key; 769706f2543Smrg v = device->valuator; 770706f2543Smrg b = device->button; 771706f2543Smrg 772706f2543Smrg key = event->detail.key; 773706f2543Smrg bit = 1 << (key & 7); 774706f2543Smrg 775706f2543Smrg /* Update device axis */ 776706f2543Smrg /* Check valuators first */ 777706f2543Smrg last_valuator = -1; 778706f2543Smrg for (i = 0; i < MAX_VALUATORS; i++) 779706f2543Smrg { 780706f2543Smrg if (BitIsOn(&event->valuators.mask, i)) 781706f2543Smrg { 782706f2543Smrg if (!v) 783706f2543Smrg { 784706f2543Smrg ErrorF("[Xi] Valuators reported for non-valuator device '%s'. " 785706f2543Smrg "Ignoring event.\n", device->name); 786706f2543Smrg return DONT_PROCESS; 787706f2543Smrg } else if (v->numAxes < i) 788706f2543Smrg { 789706f2543Smrg ErrorF("[Xi] Too many valuators reported for device '%s'. " 790706f2543Smrg "Ignoring event.\n", device->name); 791706f2543Smrg return DONT_PROCESS; 792706f2543Smrg } 793706f2543Smrg last_valuator = i; 794706f2543Smrg } 795706f2543Smrg } 796706f2543Smrg 797706f2543Smrg for (i = 0; i <= last_valuator && i < v->numAxes; i++) 798706f2543Smrg { 799706f2543Smrg if (BitIsOn(&event->valuators.mask, i)) 800706f2543Smrg { 801706f2543Smrg /* XXX: Relative/Absolute mode */ 802706f2543Smrg v->axisVal[i] = event->valuators.data[i]; 803706f2543Smrg v->axisVal[i] += (event->valuators.data_frac[i] * 1.0f / (1 << 16) / (1 << 16)); 804706f2543Smrg } 805706f2543Smrg } 806706f2543Smrg 807706f2543Smrg if (event->type == ET_KeyPress) { 808706f2543Smrg if (!k) 809706f2543Smrg return DONT_PROCESS; 810706f2543Smrg 811706f2543Smrg /* don't allow ddx to generate multiple downs, but repeats are okay */ 812706f2543Smrg if (key_is_down(device, key, KEY_PROCESSED) && !event->key_repeat) 813706f2543Smrg return DONT_PROCESS; 814706f2543Smrg 815706f2543Smrg if (device->valuator) 816706f2543Smrg device->valuator->motionHintWindow = NullWindow; 817706f2543Smrg set_key_down(device, key, KEY_PROCESSED); 818706f2543Smrg } else if (event->type == ET_KeyRelease) { 819706f2543Smrg if (!k) 820706f2543Smrg return DONT_PROCESS; 821706f2543Smrg 822706f2543Smrg if (!key_is_down(device, key, KEY_PROCESSED)) /* guard against duplicates */ 823706f2543Smrg return DONT_PROCESS; 824706f2543Smrg if (device->valuator) 825706f2543Smrg device->valuator->motionHintWindow = NullWindow; 826706f2543Smrg set_key_up(device, key, KEY_PROCESSED); 827706f2543Smrg } else if (event->type == ET_ButtonPress) { 828706f2543Smrg Mask mask; 829706f2543Smrg if (!b) 830706f2543Smrg return DONT_PROCESS; 831706f2543Smrg 832706f2543Smrg if (button_is_down(device, key, BUTTON_PROCESSED)) 833706f2543Smrg return DONT_PROCESS; 834706f2543Smrg 835706f2543Smrg set_button_down(device, key, BUTTON_PROCESSED); 836706f2543Smrg if (device->valuator) 837706f2543Smrg device->valuator->motionHintWindow = NullWindow; 838706f2543Smrg if (!b->map[key]) 839706f2543Smrg return DONT_PROCESS; 840706f2543Smrg b->buttonsDown++; 841706f2543Smrg b->motionMask = DeviceButtonMotionMask; 842706f2543Smrg if (b->map[key] <= 5) 843706f2543Smrg b->state |= (Button1Mask >> 1) << b->map[key]; 844706f2543Smrg 845706f2543Smrg /* Add state and motionMask to the filter for this event */ 846706f2543Smrg mask = DevicePointerMotionMask | b->state | b->motionMask; 847706f2543Smrg SetMaskForEvent(device->id, mask, DeviceMotionNotify); 848706f2543Smrg mask = PointerMotionMask | b->state | b->motionMask; 849706f2543Smrg SetMaskForEvent(device->id, mask, MotionNotify); 850706f2543Smrg } else if (event->type == ET_ButtonRelease) { 851706f2543Smrg Mask mask; 852706f2543Smrg if (!b) 853706f2543Smrg return DONT_PROCESS; 854706f2543Smrg 855706f2543Smrg if (!button_is_down(device, key, BUTTON_PROCESSED)) 856706f2543Smrg return DONT_PROCESS; 857706f2543Smrg if (IsMaster(device)) { 858706f2543Smrg DeviceIntPtr sd; 859706f2543Smrg 860706f2543Smrg /* 861706f2543Smrg * Leave the button down if any slave has the 862706f2543Smrg * button still down. Note that this depends on the 863706f2543Smrg * event being delivered through the slave first 864706f2543Smrg */ 865706f2543Smrg for (sd = inputInfo.devices; sd; sd = sd->next) { 866706f2543Smrg if (IsMaster(sd) || sd->u.master != device) 867706f2543Smrg continue; 868706f2543Smrg if (!sd->button) 869706f2543Smrg continue; 870706f2543Smrg for (i = 1; i <= sd->button->numButtons; i++) 871706f2543Smrg if (sd->button->map[i] == key && 872706f2543Smrg button_is_down(sd, i, BUTTON_PROCESSED)) 873706f2543Smrg return DONT_PROCESS; 874706f2543Smrg } 875706f2543Smrg } 876706f2543Smrg set_button_up(device, key, BUTTON_PROCESSED); 877706f2543Smrg if (device->valuator) 878706f2543Smrg device->valuator->motionHintWindow = NullWindow; 879706f2543Smrg if (!b->map[key]) 880706f2543Smrg return DONT_PROCESS; 881706f2543Smrg if (b->buttonsDown >= 1 && !--b->buttonsDown) 882706f2543Smrg b->motionMask = 0; 883706f2543Smrg if (b->map[key] <= 5) 884706f2543Smrg b->state &= ~((Button1Mask >> 1) << b->map[key]); 885706f2543Smrg 886706f2543Smrg /* Add state and motionMask to the filter for this event */ 887706f2543Smrg mask = DevicePointerMotionMask | b->state | b->motionMask; 888706f2543Smrg SetMaskForEvent(device->id, mask, DeviceMotionNotify); 889706f2543Smrg mask = PointerMotionMask | b->state | b->motionMask; 890706f2543Smrg SetMaskForEvent(device->id, mask, MotionNotify); 891706f2543Smrg } else if (event->type == ET_ProximityIn) 892706f2543Smrg device->proximity->in_proximity = TRUE; 893706f2543Smrg else if (event->type == ET_ProximityOut) 894706f2543Smrg device->proximity->in_proximity = FALSE; 895706f2543Smrg 896706f2543Smrg return DEFAULT; 897706f2543Smrg} 898706f2543Smrg 899706f2543Smrgstatic void 900706f2543SmrgProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device) 901706f2543Smrg{ 902706f2543Smrg GrabPtr grab = device->deviceGrab.grab; 903706f2543Smrg 904706f2543Smrg if (grab) 905706f2543Smrg DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE); 906706f2543Smrg else { /* deliver to all root windows */ 907706f2543Smrg xEvent *xi; 908706f2543Smrg int i; 909706f2543Smrg 910706f2543Smrg i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi); 911706f2543Smrg if (i != Success) 912706f2543Smrg { 913706f2543Smrg ErrorF("[Xi] %s: XI2 conversion failed in ProcessRawEvent (%d)\n", 914706f2543Smrg device->name, i); 915706f2543Smrg return; 916706f2543Smrg } 917706f2543Smrg 918706f2543Smrg for (i = 0; i < screenInfo.numScreens; i++) 919706f2543Smrg DeliverEventsToWindow(device, screenInfo.screens[i]->root, xi, 1, 920706f2543Smrg GetEventFilter(device, xi), NULL); 921706f2543Smrg free(xi); 922706f2543Smrg } 923706f2543Smrg} 924706f2543Smrg 925706f2543Smrg/** 926706f2543Smrg * Main device event processing function. 927706f2543Smrg * Called from when processing the events from the event queue. 928706f2543Smrg * 929706f2543Smrg */ 930706f2543Smrgvoid 931706f2543SmrgProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device) 932706f2543Smrg{ 933706f2543Smrg GrabPtr grab; 934706f2543Smrg Bool deactivateDeviceGrab = FALSE; 935706f2543Smrg int key = 0, rootX, rootY; 936706f2543Smrg ButtonClassPtr b; 937706f2543Smrg KeyClassPtr k; 938706f2543Smrg ValuatorClassPtr v; 939706f2543Smrg int ret = 0; 940706f2543Smrg int state, i; 941706f2543Smrg DeviceIntPtr mouse = NULL, kbd = NULL; 942706f2543Smrg DeviceEvent *event = &ev->device_event; 943706f2543Smrg 944706f2543Smrg CHECKEVENT(ev); 945706f2543Smrg 946706f2543Smrg if (ev->any.type == ET_RawKeyPress || 947706f2543Smrg ev->any.type == ET_RawKeyRelease || 948706f2543Smrg ev->any.type == ET_RawButtonPress || 949706f2543Smrg ev->any.type == ET_RawButtonRelease || 950706f2543Smrg ev->any.type == ET_RawMotion) 951706f2543Smrg { 952706f2543Smrg ProcessRawEvent(&ev->raw_event, device); 953706f2543Smrg return; 954706f2543Smrg } 955706f2543Smrg 956706f2543Smrg if (IsPointerDevice(device)) 957706f2543Smrg { 958706f2543Smrg kbd = GetPairedDevice(device); 959706f2543Smrg mouse = device; 960706f2543Smrg if (!kbd->key) /* can happen with floating SDs */ 961706f2543Smrg kbd = NULL; 962706f2543Smrg } else 963706f2543Smrg { 964706f2543Smrg mouse = GetPairedDevice(device); 965706f2543Smrg kbd = device; 966706f2543Smrg if (!mouse->valuator || !mouse->button) /* may be float. SDs */ 967706f2543Smrg mouse = NULL; 968706f2543Smrg } 969706f2543Smrg 970706f2543Smrg /* State needs to be assembled BEFORE the device is updated. */ 971706f2543Smrg state = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0; 972706f2543Smrg state |= (mouse && mouse->button) ? (mouse->button->state) : 0; 973706f2543Smrg 974706f2543Smrg for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) 975706f2543Smrg if (BitIsOn(mouse->button->down, i)) 976706f2543Smrg SetBit(event->buttons, i); 977706f2543Smrg 978706f2543Smrg if (kbd && kbd->key) 979706f2543Smrg { 980706f2543Smrg XkbStatePtr state; 981706f2543Smrg /* we need the state before the event happens */ 982706f2543Smrg if (event->type == ET_KeyPress || event->type == ET_KeyRelease) 983706f2543Smrg state = &kbd->key->xkbInfo->prev_state; 984706f2543Smrg else 985706f2543Smrg state = &kbd->key->xkbInfo->state; 986706f2543Smrg 987706f2543Smrg event->mods.base = state->base_mods; 988706f2543Smrg event->mods.latched = state->latched_mods; 989706f2543Smrg event->mods.locked = state->locked_mods; 990706f2543Smrg event->mods.effective = state->mods; 991706f2543Smrg 992706f2543Smrg event->group.base = state->base_group; 993706f2543Smrg event->group.latched = state->latched_group; 994706f2543Smrg event->group.locked = state->locked_group; 995706f2543Smrg event->group.effective = state->group; 996706f2543Smrg } 997706f2543Smrg 998706f2543Smrg ret = UpdateDeviceState(device, event); 999706f2543Smrg if (ret == DONT_PROCESS) 1000706f2543Smrg return; 1001706f2543Smrg 1002706f2543Smrg v = device->valuator; 1003706f2543Smrg b = device->button; 1004706f2543Smrg k = device->key; 1005706f2543Smrg 1006706f2543Smrg if (IsMaster(device) || !device->u.master) 1007706f2543Smrg CheckMotion(event, device); 1008706f2543Smrg 1009706f2543Smrg switch (event->type) 1010706f2543Smrg { 1011706f2543Smrg case ET_Motion: 1012706f2543Smrg case ET_ButtonPress: 1013706f2543Smrg case ET_ButtonRelease: 1014706f2543Smrg case ET_KeyPress: 1015706f2543Smrg case ET_KeyRelease: 1016706f2543Smrg case ET_ProximityIn: 1017706f2543Smrg case ET_ProximityOut: 1018706f2543Smrg GetSpritePosition(device, &rootX, &rootY); 1019706f2543Smrg event->root_x = rootX; 1020706f2543Smrg event->root_y = rootY; 1021706f2543Smrg NoticeEventTime((InternalEvent*)event); 1022706f2543Smrg event->corestate = state; 1023706f2543Smrg key = event->detail.key; 1024706f2543Smrg break; 1025706f2543Smrg default: 1026706f2543Smrg break; 1027706f2543Smrg } 1028706f2543Smrg 1029706f2543Smrg if (DeviceEventCallback && !syncEvents.playingEvents) { 1030706f2543Smrg DeviceEventInfoRec eventinfo; 1031706f2543Smrg SpritePtr pSprite = device->spriteInfo->sprite; 1032706f2543Smrg 1033706f2543Smrg /* see comment in EnqueueEvents regarding the next three lines */ 1034706f2543Smrg if (ev->any.type == ET_Motion) 1035706f2543Smrg ev->device_event.root = pSprite->hotPhys.pScreen->root->drawable.id; 1036706f2543Smrg 1037706f2543Smrg eventinfo.device = device; 1038706f2543Smrg eventinfo.event = ev; 1039706f2543Smrg CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo); 1040706f2543Smrg } 1041706f2543Smrg 1042706f2543Smrg grab = device->deviceGrab.grab; 1043706f2543Smrg 1044706f2543Smrg switch(event->type) 1045706f2543Smrg { 1046706f2543Smrg case ET_KeyPress: 1047706f2543Smrg if (!grab && CheckDeviceGrabs(device, event, 0)) { 1048706f2543Smrg device->deviceGrab.activatingKey = key; 1049706f2543Smrg return; 1050706f2543Smrg } 1051706f2543Smrg break; 1052706f2543Smrg case ET_KeyRelease: 1053706f2543Smrg if (grab && device->deviceGrab.fromPassiveGrab && 1054706f2543Smrg (key == device->deviceGrab.activatingKey) && 1055706f2543Smrg (device->deviceGrab.grab->type == KeyPress || 1056706f2543Smrg device->deviceGrab.grab->type == DeviceKeyPress || 1057706f2543Smrg device->deviceGrab.grab->type == XI_KeyPress)) 1058706f2543Smrg deactivateDeviceGrab = TRUE; 1059706f2543Smrg break; 1060706f2543Smrg case ET_ButtonPress: 1061706f2543Smrg event->detail.button = b->map[key]; 1062706f2543Smrg if (!event->detail.button) { /* there's no button 0 */ 1063706f2543Smrg event->detail.button = key; 1064706f2543Smrg return; 1065706f2543Smrg } 1066706f2543Smrg if (!grab && CheckDeviceGrabs(device, event, 0)) 1067706f2543Smrg { 1068706f2543Smrg /* if a passive grab was activated, the event has been sent 1069706f2543Smrg * already */ 1070706f2543Smrg return; 1071706f2543Smrg } 1072706f2543Smrg break; 1073706f2543Smrg case ET_ButtonRelease: 1074706f2543Smrg event->detail.button = b->map[key]; 1075706f2543Smrg if (!event->detail.button) { /* there's no button 0 */ 1076706f2543Smrg event->detail.button = key; 1077706f2543Smrg return; 1078706f2543Smrg } 1079706f2543Smrg if (grab && !b->buttonsDown && 1080706f2543Smrg device->deviceGrab.fromPassiveGrab && 1081706f2543Smrg (device->deviceGrab.grab->type == ButtonPress || 1082706f2543Smrg device->deviceGrab.grab->type == DeviceButtonPress || 1083706f2543Smrg device->deviceGrab.grab->type == XI_ButtonPress)) 1084706f2543Smrg deactivateDeviceGrab = TRUE; 1085706f2543Smrg default: 1086706f2543Smrg break; 1087706f2543Smrg } 1088706f2543Smrg 1089706f2543Smrg 1090706f2543Smrg if (grab) 1091706f2543Smrg DeliverGrabbedEvent((InternalEvent*)event, device, deactivateDeviceGrab); 1092706f2543Smrg else if (device->focus && !IsPointerEvent((InternalEvent*)ev)) 1093706f2543Smrg DeliverFocusedEvent(device, (InternalEvent*)event, 1094706f2543Smrg GetSpriteWindow(device)); 1095706f2543Smrg else 1096706f2543Smrg DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent*)event, 1097706f2543Smrg NullGrab, NullWindow, device); 1098706f2543Smrg 1099706f2543Smrg if (deactivateDeviceGrab == TRUE) 1100706f2543Smrg (*device->deviceGrab.DeactivateGrab) (device); 1101706f2543Smrg event->detail.key = key; 1102706f2543Smrg} 1103706f2543Smrg 1104706f2543Smrgint 1105706f2543SmrgInitProximityClassDeviceStruct(DeviceIntPtr dev) 1106706f2543Smrg{ 1107706f2543Smrg ProximityClassPtr proxc; 1108706f2543Smrg 1109706f2543Smrg proxc = (ProximityClassPtr) malloc(sizeof(ProximityClassRec)); 1110706f2543Smrg if (!proxc) 1111706f2543Smrg return FALSE; 1112706f2543Smrg proxc->sourceid = dev->id; 1113706f2543Smrg proxc->in_proximity = TRUE; 1114706f2543Smrg dev->proximity = proxc; 1115706f2543Smrg return TRUE; 1116706f2543Smrg} 1117706f2543Smrg 1118706f2543Smrg/** 1119706f2543Smrg * Initialise the device's valuators. The memory must already be allocated, 1120706f2543Smrg * this function merely inits the matching axis (specified through axnum) to 1121706f2543Smrg * sane values. 1122706f2543Smrg * 1123706f2543Smrg * It is a condition that (minval < maxval). 1124706f2543Smrg * 1125706f2543Smrg * @see InitValuatorClassDeviceStruct 1126706f2543Smrg */ 1127706f2543Smrgvoid 1128706f2543SmrgInitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval, 1129706f2543Smrg int resolution, int min_res, int max_res, int mode) 1130706f2543Smrg{ 1131706f2543Smrg AxisInfoPtr ax; 1132706f2543Smrg 1133706f2543Smrg if (!dev || !dev->valuator || minval > maxval) 1134706f2543Smrg return; 1135706f2543Smrg if (axnum >= dev->valuator->numAxes) 1136706f2543Smrg return; 1137706f2543Smrg 1138706f2543Smrg ax = dev->valuator->axes + axnum; 1139706f2543Smrg 1140706f2543Smrg ax->min_value = minval; 1141706f2543Smrg ax->max_value = maxval; 1142706f2543Smrg ax->resolution = resolution; 1143706f2543Smrg ax->min_resolution = min_res; 1144706f2543Smrg ax->max_resolution = max_res; 1145706f2543Smrg ax->label = label; 1146706f2543Smrg ax->mode = mode; 1147706f2543Smrg 1148706f2543Smrg if (mode & OutOfProximity) 1149706f2543Smrg dev->proximity->in_proximity = FALSE; 1150706f2543Smrg} 1151706f2543Smrg 1152706f2543Smrgstatic void 1153706f2543SmrgFixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, 1154706f2543Smrg ButtonClassPtr b, ValuatorClassPtr v, int first) 1155706f2543Smrg{ 1156706f2543Smrg ev->type = DeviceStateNotify; 1157706f2543Smrg ev->deviceid = dev->id; 1158706f2543Smrg ev->time = currentTime.milliseconds; 1159706f2543Smrg ev->classes_reported = 0; 1160706f2543Smrg ev->num_keys = 0; 1161706f2543Smrg ev->num_buttons = 0; 1162706f2543Smrg ev->num_valuators = 0; 1163706f2543Smrg 1164706f2543Smrg if (b) { 1165706f2543Smrg ev->classes_reported |= (1 << ButtonClass); 1166706f2543Smrg ev->num_buttons = b->numButtons; 1167706f2543Smrg memcpy((char*)ev->buttons, (char*)b->down, 4); 1168706f2543Smrg } else if (k) { 1169706f2543Smrg ev->classes_reported |= (1 << KeyClass); 1170706f2543Smrg ev->num_keys = k->xkbInfo->desc->max_key_code - 1171706f2543Smrg k->xkbInfo->desc->min_key_code; 1172706f2543Smrg memmove((char *)&ev->keys[0], (char *)k->down, 4); 1173706f2543Smrg } 1174706f2543Smrg if (v) { 1175706f2543Smrg int nval = v->numAxes - first; 1176706f2543Smrg 1177706f2543Smrg ev->classes_reported |= (1 << ValuatorClass); 1178706f2543Smrg ev->classes_reported |= valuator_get_mode(dev, 0) << ModeBitsShift; 1179706f2543Smrg ev->num_valuators = nval < 3 ? nval : 3; 1180706f2543Smrg switch (ev->num_valuators) { 1181706f2543Smrg case 3: 1182706f2543Smrg ev->valuator2 = v->axisVal[first + 2]; 1183706f2543Smrg case 2: 1184706f2543Smrg ev->valuator1 = v->axisVal[first + 1]; 1185706f2543Smrg case 1: 1186706f2543Smrg ev->valuator0 = v->axisVal[first]; 1187706f2543Smrg break; 1188706f2543Smrg } 1189706f2543Smrg } 1190706f2543Smrg} 1191706f2543Smrg 1192706f2543Smrgstatic void 1193706f2543SmrgFixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, 1194706f2543Smrg int first) 1195706f2543Smrg{ 1196706f2543Smrg int nval = v->numAxes - first; 1197706f2543Smrg 1198706f2543Smrg ev->type = DeviceValuator; 1199706f2543Smrg ev->deviceid = dev->id; 1200706f2543Smrg ev->num_valuators = nval < 3 ? nval : 3; 1201706f2543Smrg ev->first_valuator = first; 1202706f2543Smrg switch (ev->num_valuators) { 1203706f2543Smrg case 3: 1204706f2543Smrg ev->valuator2 = v->axisVal[first + 2]; 1205706f2543Smrg case 2: 1206706f2543Smrg ev->valuator1 = v->axisVal[first + 1]; 1207706f2543Smrg case 1: 1208706f2543Smrg ev->valuator0 = v->axisVal[first]; 1209706f2543Smrg break; 1210706f2543Smrg } 1211706f2543Smrg first += ev->num_valuators; 1212706f2543Smrg} 1213706f2543Smrg 1214706f2543Smrgvoid 1215706f2543SmrgDeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, 1216706f2543Smrg WindowPtr pWin) 1217706f2543Smrg{ 1218706f2543Smrg deviceFocus event; 1219706f2543Smrg xXIFocusInEvent *xi2event; 1220706f2543Smrg DeviceIntPtr mouse; 1221706f2543Smrg int btlen, len, i; 1222706f2543Smrg 1223706f2543Smrg mouse = (IsMaster(dev) || dev->u.master) ? GetMaster(dev, MASTER_POINTER) : dev; 1224706f2543Smrg 1225706f2543Smrg /* XI 2 event */ 1226706f2543Smrg btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; 1227706f2543Smrg btlen = bytes_to_int32(btlen); 1228706f2543Smrg len = sizeof(xXIFocusInEvent) + btlen * 4; 1229706f2543Smrg 1230706f2543Smrg xi2event = calloc(1, len); 1231706f2543Smrg xi2event->type = GenericEvent; 1232706f2543Smrg xi2event->extension = IReqCode; 1233706f2543Smrg xi2event->evtype = type; 1234706f2543Smrg xi2event->length = bytes_to_int32(len - sizeof(xEvent)); 1235706f2543Smrg xi2event->buttons_len = btlen; 1236706f2543Smrg xi2event->detail = detail; 1237706f2543Smrg xi2event->time = currentTime.milliseconds; 1238706f2543Smrg xi2event->deviceid = dev->id; 1239706f2543Smrg xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */ 1240706f2543Smrg xi2event->mode = mode; 1241706f2543Smrg xi2event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0); 1242706f2543Smrg xi2event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0); 1243706f2543Smrg 1244706f2543Smrg for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) 1245706f2543Smrg if (BitIsOn(mouse->button->down, i)) 1246706f2543Smrg SetBit(&xi2event[1], i); 1247706f2543Smrg 1248706f2543Smrg if (dev->key) 1249706f2543Smrg { 1250706f2543Smrg xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods; 1251706f2543Smrg xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods; 1252706f2543Smrg xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods; 1253706f2543Smrg xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods; 1254706f2543Smrg 1255706f2543Smrg xi2event->group.base_group = dev->key->xkbInfo->state.base_group; 1256706f2543Smrg xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group; 1257706f2543Smrg xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group; 1258706f2543Smrg xi2event->group.effective_group = dev->key->xkbInfo->state.group; 1259706f2543Smrg } 1260706f2543Smrg 1261706f2543Smrg FixUpEventFromWindow(dev->spriteInfo->sprite, (xEvent*)xi2event, pWin, 1262706f2543Smrg None, FALSE); 1263706f2543Smrg 1264706f2543Smrg DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1, 1265706f2543Smrg GetEventFilter(dev, (xEvent*)xi2event), NullGrab); 1266706f2543Smrg 1267706f2543Smrg free(xi2event); 1268706f2543Smrg 1269706f2543Smrg /* XI 1.x event */ 1270706f2543Smrg event.deviceid = dev->id; 1271706f2543Smrg event.mode = mode; 1272706f2543Smrg event.type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut; 1273706f2543Smrg event.detail = detail; 1274706f2543Smrg event.window = pWin->drawable.id; 1275706f2543Smrg event.time = currentTime.milliseconds; 1276706f2543Smrg 1277706f2543Smrg DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1, 1278706f2543Smrg DeviceFocusChangeMask, NullGrab); 1279706f2543Smrg 1280706f2543Smrg if ((event.type == DeviceFocusIn) && 1281706f2543Smrg (wOtherInputMasks(pWin)) && 1282706f2543Smrg (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask)) 1283706f2543Smrg { 1284706f2543Smrg int evcount = 1; 1285706f2543Smrg deviceStateNotify *ev, *sev; 1286706f2543Smrg deviceKeyStateNotify *kev; 1287706f2543Smrg deviceButtonStateNotify *bev; 1288706f2543Smrg 1289706f2543Smrg KeyClassPtr k; 1290706f2543Smrg ButtonClassPtr b; 1291706f2543Smrg ValuatorClassPtr v; 1292706f2543Smrg int nval = 0, nkeys = 0, nbuttons = 0, first = 0; 1293706f2543Smrg 1294706f2543Smrg if ((b = dev->button) != NULL) { 1295706f2543Smrg nbuttons = b->numButtons; 1296706f2543Smrg if (nbuttons > 32) 1297706f2543Smrg evcount++; 1298706f2543Smrg } 1299706f2543Smrg if ((k = dev->key) != NULL) { 1300706f2543Smrg nkeys = k->xkbInfo->desc->max_key_code - 1301706f2543Smrg k->xkbInfo->desc->min_key_code; 1302706f2543Smrg if (nkeys > 32) 1303706f2543Smrg evcount++; 1304706f2543Smrg if (nbuttons > 0) { 1305706f2543Smrg evcount++; 1306706f2543Smrg } 1307706f2543Smrg } 1308706f2543Smrg if ((v = dev->valuator) != NULL) { 1309706f2543Smrg nval = v->numAxes; 1310706f2543Smrg 1311706f2543Smrg if (nval > 3) 1312706f2543Smrg evcount++; 1313706f2543Smrg if (nval > 6) { 1314706f2543Smrg if (!(k && b)) 1315706f2543Smrg evcount++; 1316706f2543Smrg if (nval > 9) 1317706f2543Smrg evcount += ((nval - 7) / 3); 1318706f2543Smrg } 1319706f2543Smrg } 1320706f2543Smrg 1321706f2543Smrg sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent)); 1322706f2543Smrg FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); 1323706f2543Smrg 1324706f2543Smrg if (b != NULL) { 1325706f2543Smrg FixDeviceStateNotify(dev, ev++, NULL, b, v, first); 1326706f2543Smrg first += 3; 1327706f2543Smrg nval -= 3; 1328706f2543Smrg if (nbuttons > 32) { 1329706f2543Smrg (ev - 1)->deviceid |= MORE_EVENTS; 1330706f2543Smrg bev = (deviceButtonStateNotify *) ev++; 1331706f2543Smrg bev->type = DeviceButtonStateNotify; 1332706f2543Smrg bev->deviceid = dev->id; 1333706f2543Smrg memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4); 1334706f2543Smrg } 1335706f2543Smrg if (nval > 0) { 1336706f2543Smrg (ev - 1)->deviceid |= MORE_EVENTS; 1337706f2543Smrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 1338706f2543Smrg first += 3; 1339706f2543Smrg nval -= 3; 1340706f2543Smrg } 1341706f2543Smrg } 1342706f2543Smrg 1343706f2543Smrg if (k != NULL) { 1344706f2543Smrg FixDeviceStateNotify(dev, ev++, k, NULL, v, first); 1345706f2543Smrg first += 3; 1346706f2543Smrg nval -= 3; 1347706f2543Smrg if (nkeys > 32) { 1348706f2543Smrg (ev - 1)->deviceid |= MORE_EVENTS; 1349706f2543Smrg kev = (deviceKeyStateNotify *) ev++; 1350706f2543Smrg kev->type = DeviceKeyStateNotify; 1351706f2543Smrg kev->deviceid = dev->id; 1352706f2543Smrg memmove((char *)&kev->keys[0], (char *)&k->down[4], 28); 1353706f2543Smrg } 1354706f2543Smrg if (nval > 0) { 1355706f2543Smrg (ev - 1)->deviceid |= MORE_EVENTS; 1356706f2543Smrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 1357706f2543Smrg first += 3; 1358706f2543Smrg nval -= 3; 1359706f2543Smrg } 1360706f2543Smrg } 1361706f2543Smrg 1362706f2543Smrg while (nval > 0) { 1363706f2543Smrg FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); 1364706f2543Smrg first += 3; 1365706f2543Smrg nval -= 3; 1366706f2543Smrg if (nval > 0) { 1367706f2543Smrg (ev - 1)->deviceid |= MORE_EVENTS; 1368706f2543Smrg FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); 1369706f2543Smrg first += 3; 1370706f2543Smrg nval -= 3; 1371706f2543Smrg } 1372706f2543Smrg } 1373706f2543Smrg 1374706f2543Smrg DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount, 1375706f2543Smrg DeviceStateNotifyMask, NullGrab); 1376706f2543Smrg free(sev); 1377706f2543Smrg } 1378706f2543Smrg} 1379706f2543Smrg 1380706f2543Smrgint 1381706f2543SmrgCheckGrabValues(ClientPtr client, GrabParameters* param) 1382706f2543Smrg{ 1383706f2543Smrg if (param->grabtype != GRABTYPE_CORE && 1384706f2543Smrg param->grabtype != GRABTYPE_XI && 1385706f2543Smrg param->grabtype != GRABTYPE_XI2) 1386706f2543Smrg { 1387706f2543Smrg ErrorF("[Xi] grabtype is invalid. This is a bug.\n"); 1388706f2543Smrg return BadImplementation; 1389706f2543Smrg } 1390706f2543Smrg 1391706f2543Smrg if ((param->this_device_mode != GrabModeSync) && 1392706f2543Smrg (param->this_device_mode != GrabModeAsync)) { 1393706f2543Smrg client->errorValue = param->this_device_mode; 1394706f2543Smrg return BadValue; 1395706f2543Smrg } 1396706f2543Smrg if ((param->other_devices_mode != GrabModeSync) && 1397706f2543Smrg (param->other_devices_mode != GrabModeAsync)) { 1398706f2543Smrg client->errorValue = param->other_devices_mode; 1399706f2543Smrg return BadValue; 1400706f2543Smrg } 1401706f2543Smrg 1402706f2543Smrg if (param->grabtype != GRABTYPE_XI2 && (param->modifiers != AnyModifier) && 1403706f2543Smrg (param->modifiers & ~AllModifiersMask)) { 1404706f2543Smrg client->errorValue = param->modifiers; 1405706f2543Smrg return BadValue; 1406706f2543Smrg } 1407706f2543Smrg 1408706f2543Smrg if ((param->ownerEvents != xFalse) && (param->ownerEvents != xTrue)) { 1409706f2543Smrg client->errorValue = param->ownerEvents; 1410706f2543Smrg return BadValue; 1411706f2543Smrg } 1412706f2543Smrg return Success; 1413706f2543Smrg} 1414706f2543Smrg 1415706f2543Smrgint 1416706f2543SmrgGrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, 1417706f2543Smrg int button, GrabParameters *param, GrabType grabtype, 1418706f2543Smrg GrabMask *mask) 1419706f2543Smrg{ 1420706f2543Smrg WindowPtr pWin, confineTo; 1421706f2543Smrg CursorPtr cursor; 1422706f2543Smrg GrabPtr grab; 1423706f2543Smrg int rc, type = -1; 1424706f2543Smrg Mask access_mode = DixGrabAccess; 1425706f2543Smrg 1426706f2543Smrg rc = CheckGrabValues(client, param); 1427706f2543Smrg if (rc != Success) 1428706f2543Smrg return rc; 1429706f2543Smrg if (param->confineTo == None) 1430706f2543Smrg confineTo = NullWindow; 1431706f2543Smrg else { 1432706f2543Smrg rc = dixLookupWindow(&confineTo, param->confineTo, client, DixSetAttrAccess); 1433706f2543Smrg if (rc != Success) 1434706f2543Smrg return rc; 1435706f2543Smrg } 1436706f2543Smrg if (param->cursor == None) 1437706f2543Smrg cursor = NullCursor; 1438706f2543Smrg else { 1439706f2543Smrg rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, 1440706f2543Smrg RT_CURSOR, client, DixUseAccess); 1441706f2543Smrg if (rc != Success) 1442706f2543Smrg { 1443706f2543Smrg client->errorValue = param->cursor; 1444706f2543Smrg return rc; 1445706f2543Smrg } 1446706f2543Smrg access_mode |= DixForceAccess; 1447706f2543Smrg } 1448706f2543Smrg if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 1449706f2543Smrg access_mode |= DixFreezeAccess; 1450706f2543Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 1451706f2543Smrg if (rc != Success) 1452706f2543Smrg return rc; 1453706f2543Smrg rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 1454706f2543Smrg if (rc != Success) 1455706f2543Smrg return rc; 1456706f2543Smrg 1457706f2543Smrg if (grabtype == GRABTYPE_XI) 1458706f2543Smrg type = DeviceButtonPress; 1459706f2543Smrg else if (grabtype == GRABTYPE_XI2) 1460706f2543Smrg type = XI_ButtonPress; 1461706f2543Smrg 1462706f2543Smrg grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, 1463706f2543Smrg mask, param, type, button, confineTo, cursor); 1464706f2543Smrg if (!grab) 1465706f2543Smrg return BadAlloc; 1466706f2543Smrg return AddPassiveGrabToList(client, grab); 1467706f2543Smrg} 1468706f2543Smrg 1469706f2543Smrg/** 1470706f2543Smrg * Grab the given key. If grabtype is GRABTYPE_XI, the key is a keycode. If 1471706f2543Smrg * grabtype is GRABTYPE_XI2, the key is a keysym. 1472706f2543Smrg */ 1473706f2543Smrgint 1474706f2543SmrgGrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, 1475706f2543Smrg int key, GrabParameters *param, GrabType grabtype, GrabMask *mask) 1476706f2543Smrg{ 1477706f2543Smrg WindowPtr pWin; 1478706f2543Smrg GrabPtr grab; 1479706f2543Smrg KeyClassPtr k = dev->key; 1480706f2543Smrg Mask access_mode = DixGrabAccess; 1481706f2543Smrg int rc, type = -1; 1482706f2543Smrg 1483706f2543Smrg rc = CheckGrabValues(client, param); 1484706f2543Smrg if (rc != Success) 1485706f2543Smrg return rc; 1486706f2543Smrg if ((dev->id != XIAllDevices && dev->id != XIAllMasterDevices) && k == NULL) 1487706f2543Smrg return BadMatch; 1488706f2543Smrg if (grabtype == GRABTYPE_XI) 1489706f2543Smrg { 1490706f2543Smrg if ((key > k->xkbInfo->desc->max_key_code || 1491706f2543Smrg key < k->xkbInfo->desc->min_key_code) 1492706f2543Smrg && (key != AnyKey)) { 1493706f2543Smrg client->errorValue = key; 1494706f2543Smrg return BadValue; 1495706f2543Smrg } 1496706f2543Smrg type = DeviceKeyPress; 1497706f2543Smrg } else if (grabtype == GRABTYPE_XI2) 1498706f2543Smrg type = XI_KeyPress; 1499706f2543Smrg 1500706f2543Smrg rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 1501706f2543Smrg if (rc != Success) 1502706f2543Smrg return rc; 1503706f2543Smrg if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 1504706f2543Smrg access_mode |= DixFreezeAccess; 1505706f2543Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 1506706f2543Smrg if (rc != Success) 1507706f2543Smrg return rc; 1508706f2543Smrg 1509706f2543Smrg grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, 1510706f2543Smrg mask, param, type, key, NULL, NULL); 1511706f2543Smrg if (!grab) 1512706f2543Smrg return BadAlloc; 1513706f2543Smrg return AddPassiveGrabToList(client, grab); 1514706f2543Smrg} 1515706f2543Smrg 1516706f2543Smrg/* Enter/FocusIn grab */ 1517706f2543Smrgint 1518706f2543SmrgGrabWindow(ClientPtr client, DeviceIntPtr dev, int type, 1519706f2543Smrg GrabParameters *param, GrabMask *mask) 1520706f2543Smrg{ 1521706f2543Smrg WindowPtr pWin; 1522706f2543Smrg CursorPtr cursor; 1523706f2543Smrg GrabPtr grab; 1524706f2543Smrg Mask access_mode = DixGrabAccess; 1525706f2543Smrg int rc; 1526706f2543Smrg 1527706f2543Smrg rc = CheckGrabValues(client, param); 1528706f2543Smrg if (rc != Success) 1529706f2543Smrg return rc; 1530706f2543Smrg 1531706f2543Smrg rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); 1532706f2543Smrg if (rc != Success) 1533706f2543Smrg return rc; 1534706f2543Smrg if (param->cursor == None) 1535706f2543Smrg cursor = NullCursor; 1536706f2543Smrg else { 1537706f2543Smrg rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, 1538706f2543Smrg RT_CURSOR, client, DixUseAccess); 1539706f2543Smrg if (rc != Success) 1540706f2543Smrg { 1541706f2543Smrg client->errorValue = param->cursor; 1542706f2543Smrg return rc; 1543706f2543Smrg } 1544706f2543Smrg access_mode |= DixForceAccess; 1545706f2543Smrg } 1546706f2543Smrg if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) 1547706f2543Smrg access_mode |= DixFreezeAccess; 1548706f2543Smrg rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); 1549706f2543Smrg if (rc != Success) 1550706f2543Smrg return rc; 1551706f2543Smrg 1552706f2543Smrg grab = CreateGrab(client->index, dev, dev, pWin, GRABTYPE_XI2, 1553706f2543Smrg mask, param, (type == XIGrabtypeEnter) ? XI_Enter : XI_FocusIn, 1554706f2543Smrg 0, NULL, cursor); 1555706f2543Smrg 1556706f2543Smrg if (!grab) 1557706f2543Smrg return BadAlloc; 1558706f2543Smrg 1559706f2543Smrg return AddPassiveGrabToList(client, grab); 1560706f2543Smrg} 1561706f2543Smrg 1562706f2543Smrgint 1563706f2543SmrgSelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client, 1564706f2543Smrg Mask mask, Mask exclusivemasks) 1565706f2543Smrg{ 1566706f2543Smrg int mskidx = dev->id; 1567706f2543Smrg int i, ret; 1568706f2543Smrg Mask check; 1569706f2543Smrg InputClientsPtr others; 1570706f2543Smrg 1571706f2543Smrg check = (mask & exclusivemasks); 1572706f2543Smrg if (wOtherInputMasks(pWin)) { 1573706f2543Smrg if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) { /* It is illegal for two different 1574706f2543Smrg * clients to select on any of the 1575706f2543Smrg * events for maskcheck. However, 1576706f2543Smrg * it is OK, for some client to 1577706f2543Smrg * continue selecting on one of those 1578706f2543Smrg * events. */ 1579706f2543Smrg for (others = wOtherInputMasks(pWin)->inputClients; others; 1580706f2543Smrg others = others->next) { 1581706f2543Smrg if (!SameClient(others, client) && (check & 1582706f2543Smrg others->mask[mskidx])) 1583706f2543Smrg return BadAccess; 1584706f2543Smrg } 1585706f2543Smrg } 1586706f2543Smrg for (others = wOtherInputMasks(pWin)->inputClients; others; 1587706f2543Smrg others = others->next) { 1588706f2543Smrg if (SameClient(others, client)) { 1589706f2543Smrg check = others->mask[mskidx]; 1590706f2543Smrg others->mask[mskidx] = mask; 1591706f2543Smrg if (mask == 0) { 1592706f2543Smrg for (i = 0; i < EMASKSIZE; i++) 1593706f2543Smrg if (i != mskidx && others->mask[i] != 0) 1594706f2543Smrg break; 1595706f2543Smrg if (i == EMASKSIZE) { 1596706f2543Smrg RecalculateDeviceDeliverableEvents(pWin); 1597706f2543Smrg if (ShouldFreeInputMasks(pWin, FALSE)) 1598706f2543Smrg FreeResource(others->resource, RT_NONE); 1599706f2543Smrg return Success; 1600706f2543Smrg } 1601706f2543Smrg } 1602706f2543Smrg goto maskSet; 1603706f2543Smrg } 1604706f2543Smrg } 1605706f2543Smrg } 1606706f2543Smrg check = 0; 1607706f2543Smrg if ((ret = AddExtensionClient(pWin, client, mask, mskidx)) != Success) 1608706f2543Smrg return ret; 1609706f2543Smrg maskSet: 1610706f2543Smrg if (dev->valuator) 1611706f2543Smrg if ((dev->valuator->motionHintWindow == pWin) && 1612706f2543Smrg (mask & DevicePointerMotionHintMask) && 1613706f2543Smrg !(check & DevicePointerMotionHintMask) && !dev->deviceGrab.grab) 1614706f2543Smrg dev->valuator->motionHintWindow = NullWindow; 1615706f2543Smrg RecalculateDeviceDeliverableEvents(pWin); 1616706f2543Smrg return Success; 1617706f2543Smrg} 1618706f2543Smrg 1619706f2543Smrgint 1620706f2543SmrgAddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx) 1621706f2543Smrg{ 1622706f2543Smrg InputClientsPtr others; 1623706f2543Smrg 1624706f2543Smrg if (!pWin->optional && !MakeWindowOptional(pWin)) 1625706f2543Smrg return BadAlloc; 1626706f2543Smrg others = calloc(1, sizeof(InputClients)); 1627706f2543Smrg if (!others) 1628706f2543Smrg return BadAlloc; 1629706f2543Smrg if (!pWin->optional->inputMasks && !MakeInputMasks(pWin)) 1630706f2543Smrg goto bail; 1631706f2543Smrg others->mask[mskidx] = mask; 1632706f2543Smrg others->resource = FakeClientID(client->index); 1633706f2543Smrg others->next = pWin->optional->inputMasks->inputClients; 1634706f2543Smrg pWin->optional->inputMasks->inputClients = others; 1635706f2543Smrg if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer) pWin)) 1636706f2543Smrg goto bail; 1637706f2543Smrg return Success; 1638706f2543Smrg 1639706f2543Smrgbail: 1640706f2543Smrg free(others); 1641706f2543Smrg return BadAlloc; 1642706f2543Smrg} 1643706f2543Smrg 1644706f2543Smrgstatic Bool 1645706f2543SmrgMakeInputMasks(WindowPtr pWin) 1646706f2543Smrg{ 1647706f2543Smrg struct _OtherInputMasks *imasks; 1648706f2543Smrg 1649706f2543Smrg imasks = calloc(1, sizeof(struct _OtherInputMasks)); 1650706f2543Smrg if (!imasks) 1651706f2543Smrg return FALSE; 1652706f2543Smrg pWin->optional->inputMasks = imasks; 1653706f2543Smrg return TRUE; 1654706f2543Smrg} 1655706f2543Smrg 1656706f2543Smrgvoid 1657706f2543SmrgRecalculateDeviceDeliverableEvents(WindowPtr pWin) 1658706f2543Smrg{ 1659706f2543Smrg InputClientsPtr others; 1660706f2543Smrg struct _OtherInputMasks *inputMasks; /* default: NULL */ 1661706f2543Smrg WindowPtr pChild, tmp; 1662706f2543Smrg int i, j; 1663706f2543Smrg 1664706f2543Smrg pChild = pWin; 1665706f2543Smrg while (1) { 1666706f2543Smrg if ((inputMasks = wOtherInputMasks(pChild)) != 0) { 1667706f2543Smrg for (i = 0; i < EMASKSIZE; i++) 1668706f2543Smrg memset(inputMasks->xi2mask[i], 0, sizeof(inputMasks->xi2mask[i])); 1669706f2543Smrg for (others = inputMasks->inputClients; others; 1670706f2543Smrg others = others->next) { 1671706f2543Smrg for (i = 0; i < EMASKSIZE; i++) 1672706f2543Smrg inputMasks->inputEvents[i] |= others->mask[i]; 1673706f2543Smrg for (i = 0; i < EMASKSIZE; i++) 1674706f2543Smrg for (j = 0; j < XI2MASKSIZE; j++) 1675706f2543Smrg inputMasks->xi2mask[i][j] |= others->xi2mask[i][j]; 1676706f2543Smrg } 1677706f2543Smrg for (i = 0; i < EMASKSIZE; i++) 1678706f2543Smrg inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i]; 1679706f2543Smrg for (tmp = pChild->parent; tmp; tmp = tmp->parent) 1680706f2543Smrg if (wOtherInputMasks(tmp)) 1681706f2543Smrg for (i = 0; i < EMASKSIZE; i++) 1682706f2543Smrg inputMasks->deliverableEvents[i] |= 1683706f2543Smrg (wOtherInputMasks(tmp)->deliverableEvents[i] 1684706f2543Smrg & ~inputMasks-> 1685706f2543Smrg dontPropagateMask[i] & PropagateMask[i]); 1686706f2543Smrg } 1687706f2543Smrg if (pChild->firstChild) { 1688706f2543Smrg pChild = pChild->firstChild; 1689706f2543Smrg continue; 1690706f2543Smrg } 1691706f2543Smrg while (!pChild->nextSib && (pChild != pWin)) 1692706f2543Smrg pChild = pChild->parent; 1693706f2543Smrg if (pChild == pWin) 1694706f2543Smrg break; 1695706f2543Smrg pChild = pChild->nextSib; 1696706f2543Smrg } 1697706f2543Smrg} 1698706f2543Smrg 1699706f2543Smrgint 1700706f2543SmrgInputClientGone(WindowPtr pWin, XID id) 1701706f2543Smrg{ 1702706f2543Smrg InputClientsPtr other, prev; 1703706f2543Smrg 1704706f2543Smrg if (!wOtherInputMasks(pWin)) 1705706f2543Smrg return Success; 1706706f2543Smrg prev = 0; 1707706f2543Smrg for (other = wOtherInputMasks(pWin)->inputClients; other; 1708706f2543Smrg other = other->next) { 1709706f2543Smrg if (other->resource == id) { 1710706f2543Smrg if (prev) { 1711706f2543Smrg prev->next = other->next; 1712706f2543Smrg free(other); 1713706f2543Smrg } else if (!(other->next)) { 1714706f2543Smrg if (ShouldFreeInputMasks(pWin, TRUE)) { 1715706f2543Smrg wOtherInputMasks(pWin)->inputClients = other->next; 1716706f2543Smrg free(wOtherInputMasks(pWin)); 1717706f2543Smrg pWin->optional->inputMasks = (OtherInputMasks *) NULL; 1718706f2543Smrg CheckWindowOptionalNeed(pWin); 1719706f2543Smrg free(other); 1720706f2543Smrg } else { 1721706f2543Smrg other->resource = FakeClientID(0); 1722706f2543Smrg if (!AddResource(other->resource, RT_INPUTCLIENT, 1723706f2543Smrg (pointer) pWin)) 1724706f2543Smrg return BadAlloc; 1725706f2543Smrg } 1726706f2543Smrg } else { 1727706f2543Smrg wOtherInputMasks(pWin)->inputClients = other->next; 1728706f2543Smrg free(other); 1729706f2543Smrg } 1730706f2543Smrg RecalculateDeviceDeliverableEvents(pWin); 1731706f2543Smrg return Success; 1732706f2543Smrg } 1733706f2543Smrg prev = other; 1734706f2543Smrg } 1735706f2543Smrg FatalError("client not on device event list"); 1736706f2543Smrg} 1737706f2543Smrg 1738706f2543Smrgint 1739706f2543SmrgSendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate, 1740706f2543Smrg xEvent * ev, Mask mask, int count) 1741706f2543Smrg{ 1742706f2543Smrg WindowPtr pWin; 1743706f2543Smrg WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ 1744706f2543Smrg WindowPtr spriteWin = GetSpriteWindow(d); 1745706f2543Smrg 1746706f2543Smrg if (dest == PointerWindow) 1747706f2543Smrg pWin = spriteWin; 1748706f2543Smrg else if (dest == InputFocus) { 1749706f2543Smrg WindowPtr inputFocus; 1750706f2543Smrg 1751706f2543Smrg if (!d->focus) 1752706f2543Smrg inputFocus = spriteWin; 1753706f2543Smrg else 1754706f2543Smrg inputFocus = d->focus->win; 1755706f2543Smrg 1756706f2543Smrg if (inputFocus == FollowKeyboardWin) 1757706f2543Smrg inputFocus = inputInfo.keyboard->focus->win; 1758706f2543Smrg 1759706f2543Smrg if (inputFocus == NoneWin) 1760706f2543Smrg return Success; 1761706f2543Smrg 1762706f2543Smrg /* If the input focus is PointerRootWin, send the event to where 1763706f2543Smrg * the pointer is if possible, then perhaps propogate up to root. */ 1764706f2543Smrg if (inputFocus == PointerRootWin) 1765706f2543Smrg inputFocus = GetCurrentRootWindow(d); 1766706f2543Smrg 1767706f2543Smrg if (IsParent(inputFocus, spriteWin)) { 1768706f2543Smrg effectiveFocus = inputFocus; 1769706f2543Smrg pWin = spriteWin; 1770706f2543Smrg } else 1771706f2543Smrg effectiveFocus = pWin = inputFocus; 1772706f2543Smrg } else 1773706f2543Smrg dixLookupWindow(&pWin, dest, client, DixSendAccess); 1774706f2543Smrg if (!pWin) 1775706f2543Smrg return BadWindow; 1776706f2543Smrg if ((propagate != xFalse) && (propagate != xTrue)) { 1777706f2543Smrg client->errorValue = propagate; 1778706f2543Smrg return BadValue; 1779706f2543Smrg } 1780706f2543Smrg ev->u.u.type |= 0x80; 1781706f2543Smrg if (propagate) { 1782706f2543Smrg for (; pWin; pWin = pWin->parent) { 1783706f2543Smrg if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab)) 1784706f2543Smrg return Success; 1785706f2543Smrg if (pWin == effectiveFocus) 1786706f2543Smrg return Success; 1787706f2543Smrg if (wOtherInputMasks(pWin)) 1788706f2543Smrg mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id]; 1789706f2543Smrg if (!mask) 1790706f2543Smrg break; 1791706f2543Smrg } 1792706f2543Smrg } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count)) 1793706f2543Smrg DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab); 1794706f2543Smrg return Success; 1795706f2543Smrg} 1796706f2543Smrg 1797706f2543Smrgint 1798706f2543SmrgSetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map) 1799706f2543Smrg{ 1800706f2543Smrg int i; 1801706f2543Smrg ButtonClassPtr b = dev->button; 1802706f2543Smrg 1803706f2543Smrg if (b == NULL) 1804706f2543Smrg return BadMatch; 1805706f2543Smrg 1806706f2543Smrg if (nElts != b->numButtons) { 1807706f2543Smrg client->errorValue = nElts; 1808706f2543Smrg return BadValue; 1809706f2543Smrg } 1810706f2543Smrg if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue)) 1811706f2543Smrg return BadValue; 1812706f2543Smrg for (i = 0; i < nElts; i++) 1813706f2543Smrg if ((b->map[i + 1] != map[i]) && BitIsOn(b->down, i + 1)) 1814706f2543Smrg return MappingBusy; 1815706f2543Smrg for (i = 0; i < nElts; i++) 1816706f2543Smrg b->map[i + 1] = map[i]; 1817706f2543Smrg return Success; 1818706f2543Smrg} 1819706f2543Smrg 1820706f2543Smrgint 1821706f2543SmrgChangeKeyMapping(ClientPtr client, 1822706f2543Smrg DeviceIntPtr dev, 1823706f2543Smrg unsigned len, 1824706f2543Smrg int type, 1825706f2543Smrg KeyCode firstKeyCode, 1826706f2543Smrg CARD8 keyCodes, CARD8 keySymsPerKeyCode, KeySym * map) 1827706f2543Smrg{ 1828706f2543Smrg KeySymsRec keysyms; 1829706f2543Smrg KeyClassPtr k = dev->key; 1830706f2543Smrg 1831706f2543Smrg if (k == NULL) 1832706f2543Smrg return BadMatch; 1833706f2543Smrg 1834706f2543Smrg if (len != (keyCodes * keySymsPerKeyCode)) 1835706f2543Smrg return BadLength; 1836706f2543Smrg 1837706f2543Smrg if ((firstKeyCode < k->xkbInfo->desc->min_key_code) || 1838706f2543Smrg (firstKeyCode + keyCodes - 1 > k->xkbInfo->desc->max_key_code)) { 1839706f2543Smrg client->errorValue = firstKeyCode; 1840706f2543Smrg return BadValue; 1841706f2543Smrg } 1842706f2543Smrg if (keySymsPerKeyCode == 0) { 1843706f2543Smrg client->errorValue = 0; 1844706f2543Smrg return BadValue; 1845706f2543Smrg } 1846706f2543Smrg keysyms.minKeyCode = firstKeyCode; 1847706f2543Smrg keysyms.maxKeyCode = firstKeyCode + keyCodes - 1; 1848706f2543Smrg keysyms.mapWidth = keySymsPerKeyCode; 1849706f2543Smrg keysyms.map = map; 1850706f2543Smrg 1851706f2543Smrg XkbApplyMappingChange(dev, &keysyms, firstKeyCode, keyCodes, NULL, 1852706f2543Smrg serverClient); 1853706f2543Smrg 1854706f2543Smrg return Success; 1855706f2543Smrg} 1856706f2543Smrg 1857706f2543Smrgstatic void 1858706f2543SmrgDeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) 1859706f2543Smrg{ 1860706f2543Smrg WindowPtr parent; 1861706f2543Smrg 1862706f2543Smrg /* Deactivate any grabs performed on this window, before making 1863706f2543Smrg * any input focus changes. 1864706f2543Smrg * Deactivating a device grab should cause focus events. */ 1865706f2543Smrg 1866706f2543Smrg if (dev->deviceGrab.grab && (dev->deviceGrab.grab->window == pWin)) 1867706f2543Smrg (*dev->deviceGrab.DeactivateGrab) (dev); 1868706f2543Smrg 1869706f2543Smrg /* If the focus window is a root window (ie. has no parent) 1870706f2543Smrg * then don't delete the focus from it. */ 1871706f2543Smrg 1872706f2543Smrg if (dev->focus && (pWin == dev->focus->win) && (pWin->parent != NullWindow)) { 1873706f2543Smrg int focusEventMode = NotifyNormal; 1874706f2543Smrg 1875706f2543Smrg /* If a grab is in progress, then alter the mode of focus events. */ 1876706f2543Smrg 1877706f2543Smrg if (dev->deviceGrab.grab) 1878706f2543Smrg focusEventMode = NotifyWhileGrabbed; 1879706f2543Smrg 1880706f2543Smrg switch (dev->focus->revert) { 1881706f2543Smrg case RevertToNone: 1882706f2543Smrg if (!ActivateFocusInGrab(dev, pWin, NoneWin)) 1883706f2543Smrg DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 1884706f2543Smrg dev->focus->win = NoneWin; 1885706f2543Smrg dev->focus->traceGood = 0; 1886706f2543Smrg break; 1887706f2543Smrg case RevertToParent: 1888706f2543Smrg parent = pWin; 1889706f2543Smrg do { 1890706f2543Smrg parent = parent->parent; 1891706f2543Smrg dev->focus->traceGood--; 1892706f2543Smrg } 1893706f2543Smrg while (!parent->realized); 1894706f2543Smrg if (!ActivateFocusInGrab(dev, pWin, parent)) 1895706f2543Smrg DoFocusEvents(dev, pWin, parent, focusEventMode); 1896706f2543Smrg dev->focus->win = parent; 1897706f2543Smrg dev->focus->revert = RevertToNone; 1898706f2543Smrg break; 1899706f2543Smrg case RevertToPointerRoot: 1900706f2543Smrg if (!ActivateFocusInGrab(dev, pWin, PointerRootWin)) 1901706f2543Smrg DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode); 1902706f2543Smrg dev->focus->win = PointerRootWin; 1903706f2543Smrg dev->focus->traceGood = 0; 1904706f2543Smrg break; 1905706f2543Smrg case RevertToFollowKeyboard: 1906706f2543Smrg { 1907706f2543Smrg DeviceIntPtr kbd = GetMaster(dev, MASTER_KEYBOARD); 1908706f2543Smrg if (!kbd || (kbd == dev && kbd != inputInfo.keyboard)) 1909706f2543Smrg kbd = inputInfo.keyboard; 1910706f2543Smrg if (kbd->focus->win) { 1911706f2543Smrg if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win)) 1912706f2543Smrg DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode); 1913706f2543Smrg dev->focus->win = FollowKeyboardWin; 1914706f2543Smrg dev->focus->traceGood = 0; 1915706f2543Smrg } else { 1916706f2543Smrg if (!ActivateFocusInGrab(dev, pWin, NoneWin)) 1917706f2543Smrg DoFocusEvents(dev, pWin, NoneWin, focusEventMode); 1918706f2543Smrg dev->focus->win = NoneWin; 1919706f2543Smrg dev->focus->traceGood = 0; 1920706f2543Smrg } 1921706f2543Smrg } 1922706f2543Smrg break; 1923706f2543Smrg } 1924706f2543Smrg } 1925706f2543Smrg 1926706f2543Smrg if (dev->valuator) 1927706f2543Smrg if (dev->valuator->motionHintWindow == pWin) 1928706f2543Smrg dev->valuator->motionHintWindow = NullWindow; 1929706f2543Smrg} 1930706f2543Smrg 1931706f2543Smrgvoid 1932706f2543SmrgDeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources) 1933706f2543Smrg{ 1934706f2543Smrg int i; 1935706f2543Smrg DeviceIntPtr dev; 1936706f2543Smrg InputClientsPtr ic; 1937706f2543Smrg struct _OtherInputMasks *inputMasks; 1938706f2543Smrg 1939706f2543Smrg for (dev = inputInfo.devices; dev; dev = dev->next) { 1940706f2543Smrg DeleteDeviceFromAnyExtEvents(pWin, dev); 1941706f2543Smrg } 1942706f2543Smrg 1943706f2543Smrg for (dev = inputInfo.off_devices; dev; dev = dev->next) 1944706f2543Smrg DeleteDeviceFromAnyExtEvents(pWin, dev); 1945706f2543Smrg 1946706f2543Smrg if (freeResources) 1947706f2543Smrg while ((inputMasks = wOtherInputMasks(pWin)) != 0) { 1948706f2543Smrg ic = inputMasks->inputClients; 1949706f2543Smrg for (i = 0; i < EMASKSIZE; i++) 1950706f2543Smrg inputMasks->dontPropagateMask[i] = 0; 1951706f2543Smrg FreeResource(ic->resource, RT_NONE); 1952706f2543Smrg } 1953706f2543Smrg} 1954706f2543Smrg 1955706f2543Smrgint 1956706f2543SmrgMaybeSendDeviceMotionNotifyHint(deviceKeyButtonPointer * pEvents, Mask mask) 1957706f2543Smrg{ 1958706f2543Smrg DeviceIntPtr dev; 1959706f2543Smrg 1960706f2543Smrg dixLookupDevice(&dev, pEvents->deviceid & DEVICE_BITS, serverClient, 1961706f2543Smrg DixReadAccess); 1962706f2543Smrg if (!dev) 1963706f2543Smrg return 0; 1964706f2543Smrg 1965706f2543Smrg if (pEvents->type == DeviceMotionNotify) { 1966706f2543Smrg if (mask & DevicePointerMotionHintMask) { 1967706f2543Smrg if (WID(dev->valuator->motionHintWindow) == pEvents->event) { 1968706f2543Smrg return 1; /* don't send, but pretend we did */ 1969706f2543Smrg } 1970706f2543Smrg pEvents->detail = NotifyHint; 1971706f2543Smrg } else { 1972706f2543Smrg pEvents->detail = NotifyNormal; 1973706f2543Smrg } 1974706f2543Smrg } 1975706f2543Smrg return 0; 1976706f2543Smrg} 1977706f2543Smrg 1978706f2543Smrgvoid 1979706f2543SmrgCheckDeviceGrabAndHintWindow(WindowPtr pWin, int type, 1980706f2543Smrg deviceKeyButtonPointer * xE, GrabPtr grab, 1981706f2543Smrg ClientPtr client, Mask deliveryMask) 1982706f2543Smrg{ 1983706f2543Smrg DeviceIntPtr dev; 1984706f2543Smrg 1985706f2543Smrg dixLookupDevice(&dev, xE->deviceid & DEVICE_BITS, serverClient, 1986706f2543Smrg DixGrabAccess); 1987706f2543Smrg if (!dev) 1988706f2543Smrg return; 1989706f2543Smrg 1990706f2543Smrg if (type == DeviceMotionNotify) 1991706f2543Smrg dev->valuator->motionHintWindow = pWin; 1992706f2543Smrg else if ((type == DeviceButtonPress) && (!grab) && 1993706f2543Smrg (deliveryMask & DeviceButtonGrabMask)) { 1994706f2543Smrg GrabRec tempGrab; 1995706f2543Smrg 1996706f2543Smrg tempGrab.device = dev; 1997706f2543Smrg tempGrab.resource = client->clientAsMask; 1998706f2543Smrg tempGrab.window = pWin; 1999706f2543Smrg tempGrab.ownerEvents = 2000706f2543Smrg (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE; 2001706f2543Smrg tempGrab.eventMask = deliveryMask; 2002706f2543Smrg tempGrab.keyboardMode = GrabModeAsync; 2003706f2543Smrg tempGrab.pointerMode = GrabModeAsync; 2004706f2543Smrg tempGrab.confineTo = NullWindow; 2005706f2543Smrg tempGrab.cursor = NullCursor; 2006706f2543Smrg tempGrab.next = NULL; 2007706f2543Smrg (*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE); 2008706f2543Smrg } 2009706f2543Smrg} 2010706f2543Smrg 2011706f2543Smrgstatic Mask 2012706f2543SmrgDeviceEventMaskForClient(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client) 2013706f2543Smrg{ 2014706f2543Smrg InputClientsPtr other; 2015706f2543Smrg 2016706f2543Smrg if (!wOtherInputMasks(pWin)) 2017706f2543Smrg return 0; 2018706f2543Smrg for (other = wOtherInputMasks(pWin)->inputClients; other; 2019706f2543Smrg other = other->next) { 2020706f2543Smrg if (SameClient(other, client)) 2021706f2543Smrg return other->mask[dev->id]; 2022706f2543Smrg } 2023706f2543Smrg return 0; 2024706f2543Smrg} 2025706f2543Smrg 2026706f2543Smrgvoid 2027706f2543SmrgMaybeStopDeviceHint(DeviceIntPtr dev, ClientPtr client) 2028706f2543Smrg{ 2029706f2543Smrg WindowPtr pWin; 2030706f2543Smrg GrabPtr grab = dev->deviceGrab.grab; 2031706f2543Smrg 2032706f2543Smrg pWin = dev->valuator->motionHintWindow; 2033706f2543Smrg 2034706f2543Smrg if ((grab && SameClient(grab, client) && 2035706f2543Smrg ((grab->eventMask & DevicePointerMotionHintMask) || 2036706f2543Smrg (grab->ownerEvents && 2037706f2543Smrg (DeviceEventMaskForClient(dev, pWin, client) & 2038706f2543Smrg DevicePointerMotionHintMask)))) || 2039706f2543Smrg (!grab && 2040706f2543Smrg (DeviceEventMaskForClient(dev, pWin, client) & 2041706f2543Smrg DevicePointerMotionHintMask))) 2042706f2543Smrg dev->valuator->motionHintWindow = NullWindow; 2043706f2543Smrg} 2044706f2543Smrg 2045706f2543Smrgint 2046706f2543SmrgDeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask, 2047706f2543Smrg int maskndx) 2048706f2543Smrg{ 2049706f2543Smrg struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 2050706f2543Smrg 2051706f2543Smrg if (mask & ~PropagateMask[maskndx]) { 2052706f2543Smrg client->errorValue = mask; 2053706f2543Smrg return BadValue; 2054706f2543Smrg } 2055706f2543Smrg 2056706f2543Smrg if (mask == 0) { 2057706f2543Smrg if (inputMasks) 2058706f2543Smrg inputMasks->dontPropagateMask[maskndx] = mask; 2059706f2543Smrg } else { 2060706f2543Smrg if (!inputMasks) 2061706f2543Smrg AddExtensionClient(pWin, client, 0, 0); 2062706f2543Smrg inputMasks = wOtherInputMasks(pWin); 2063706f2543Smrg inputMasks->dontPropagateMask[maskndx] = mask; 2064706f2543Smrg } 2065706f2543Smrg RecalculateDeviceDeliverableEvents(pWin); 2066706f2543Smrg if (ShouldFreeInputMasks(pWin, FALSE)) 2067706f2543Smrg FreeResource(inputMasks->inputClients->resource, RT_NONE); 2068706f2543Smrg return Success; 2069706f2543Smrg} 2070706f2543Smrg 2071706f2543SmrgBool 2072706f2543SmrgShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents) 2073706f2543Smrg{ 2074706f2543Smrg int i; 2075706f2543Smrg Mask allInputEventMasks = 0; 2076706f2543Smrg struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); 2077706f2543Smrg 2078706f2543Smrg for (i = 0; i < EMASKSIZE; i++) 2079706f2543Smrg allInputEventMasks |= inputMasks->dontPropagateMask[i]; 2080706f2543Smrg if (!ignoreSelectedEvents) 2081706f2543Smrg for (i = 0; i < EMASKSIZE; i++) 2082706f2543Smrg allInputEventMasks |= inputMasks->inputEvents[i]; 2083706f2543Smrg if (allInputEventMasks == 0) 2084706f2543Smrg return TRUE; 2085706f2543Smrg else 2086706f2543Smrg return FALSE; 2087706f2543Smrg} 2088706f2543Smrg 2089706f2543Smrg/*********************************************************************** 2090706f2543Smrg * 2091706f2543Smrg * Walk through the window tree, finding all clients that want to know 2092706f2543Smrg * about the Event. 2093706f2543Smrg * 2094706f2543Smrg */ 2095706f2543Smrg 2096706f2543Smrgstatic void 2097706f2543SmrgFindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask, 2098706f2543Smrg xEvent * ev, int count) 2099706f2543Smrg{ 2100706f2543Smrg WindowPtr p2; 2101706f2543Smrg 2102706f2543Smrg while (p1) { 2103706f2543Smrg p2 = p1->firstChild; 2104706f2543Smrg DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab); 2105706f2543Smrg FindInterestedChildren(dev, p2, mask, ev, count); 2106706f2543Smrg p1 = p1->nextSib; 2107706f2543Smrg } 2108706f2543Smrg} 2109706f2543Smrg 2110706f2543Smrg/*********************************************************************** 2111706f2543Smrg * 2112706f2543Smrg * Send an event to interested clients in all windows on all screens. 2113706f2543Smrg * 2114706f2543Smrg */ 2115706f2543Smrg 2116706f2543Smrgvoid 2117706f2543SmrgSendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count) 2118706f2543Smrg{ 2119706f2543Smrg int i; 2120706f2543Smrg WindowPtr pWin, p1; 2121706f2543Smrg 2122706f2543Smrg for (i = 0; i < screenInfo.numScreens; i++) { 2123706f2543Smrg pWin = screenInfo.screens[i]->root; 2124706f2543Smrg if (!pWin) 2125706f2543Smrg continue; 2126706f2543Smrg DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab); 2127706f2543Smrg p1 = pWin->firstChild; 2128706f2543Smrg FindInterestedChildren(dev, p1, mask, ev, count); 2129706f2543Smrg } 2130706f2543Smrg} 2131706f2543Smrg 2132706f2543Smrg/** 2133706f2543Smrg * Set the XI2 mask for the given client on the given window. 2134706f2543Smrg * @param dev The device to set the mask for. 2135706f2543Smrg * @param win The window to set the mask on. 2136706f2543Smrg * @param client The client setting the mask. 2137706f2543Smrg * @param len Number of bytes in mask. 2138706f2543Smrg * @param mask Event mask in the form of (1 << eventtype) 2139706f2543Smrg */ 2140706f2543Smrgint 2141706f2543SmrgXISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client, 2142706f2543Smrg unsigned int len, unsigned char* mask) 2143706f2543Smrg{ 2144706f2543Smrg OtherInputMasks *masks; 2145706f2543Smrg InputClientsPtr others = NULL; 2146706f2543Smrg 2147706f2543Smrg masks = wOtherInputMasks(win); 2148706f2543Smrg if (masks) 2149706f2543Smrg { 2150706f2543Smrg for (others = wOtherInputMasks(win)->inputClients; others; 2151706f2543Smrg others = others->next) { 2152706f2543Smrg if (SameClient(others, client)) { 2153706f2543Smrg memset(others->xi2mask[dev->id], 0, 2154706f2543Smrg sizeof(others->xi2mask[dev->id])); 2155706f2543Smrg break; 2156706f2543Smrg } 2157706f2543Smrg } 2158706f2543Smrg } 2159706f2543Smrg 2160706f2543Smrg len = min(len, sizeof(others->xi2mask[dev->id])); 2161706f2543Smrg 2162706f2543Smrg if (len && !others) 2163706f2543Smrg { 2164706f2543Smrg if (AddExtensionClient(win, client, 0, 0) != Success) 2165706f2543Smrg return BadAlloc; 2166706f2543Smrg others= wOtherInputMasks(win)->inputClients; 2167706f2543Smrg } 2168706f2543Smrg 2169706f2543Smrg if (others) 2170706f2543Smrg memset(others->xi2mask[dev->id], 0, sizeof(others->xi2mask[dev->id])); 2171706f2543Smrg 2172706f2543Smrg if (len) 2173706f2543Smrg memcpy(others->xi2mask[dev->id], mask, len); 2174706f2543Smrg 2175706f2543Smrg RecalculateDeviceDeliverableEvents(win); 2176706f2543Smrg 2177706f2543Smrg return Success; 2178706f2543Smrg} 2179