XIPassiveGrab.c revision adfa0b0c
1c27c18e8Smrg/* 2c27c18e8Smrg * Copyright © 2009 Red Hat, Inc. 3c27c18e8Smrg * 4c27c18e8Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5c27c18e8Smrg * copy of this software and associated documentation files (the "Software"), 6c27c18e8Smrg * to deal in the Software without restriction, including without limitation 7c27c18e8Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8c27c18e8Smrg * and/or sell copies of the Software, and to permit persons to whom the 9c27c18e8Smrg * Software is furnished to do so, subject to the following conditions: 10c27c18e8Smrg * 11c27c18e8Smrg * The above copyright notice and this permission notice (including the next 12c27c18e8Smrg * paragraph) shall be included in all copies or substantial portions of the 13c27c18e8Smrg * Software. 14c27c18e8Smrg * 15c27c18e8Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16c27c18e8Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17c27c18e8Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18c27c18e8Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19c27c18e8Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20c27c18e8Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21c27c18e8Smrg * DEALINGS IN THE SOFTWARE. 22c27c18e8Smrg * 23c27c18e8Smrg */ 24f1ee322dSmrg#ifdef HAVE_CONFIG_H 25f1ee322dSmrg#include <config.h> 26f1ee322dSmrg#endif 27c27c18e8Smrg 28c27c18e8Smrg#include <stdint.h> 29c27c18e8Smrg#include <X11/Xlibint.h> 30c27c18e8Smrg#include <X11/extensions/XI2proto.h> 31c27c18e8Smrg#include <X11/extensions/XInput2.h> 32c27c18e8Smrg#include <X11/extensions/extutil.h> 3310baa824Smrg#include <limits.h> 34c27c18e8Smrg#include "XIint.h" 35c27c18e8Smrg 36c27c18e8Smrgstatic int 37c27c18e8Smrg_XIPassiveGrabDevice(Display* dpy, int deviceid, int grabtype, int detail, 38c27c18e8Smrg Window grab_window, Cursor cursor, 39c27c18e8Smrg int grab_mode, int paired_device_mode, 40c27c18e8Smrg Bool owner_events, XIEventMask *mask, 41f2d49d05Smrg int num_modifiers, XIGrabModifiers *modifiers_inout, 42f2d49d05Smrg Time time) 43c27c18e8Smrg{ 44c27c18e8Smrg xXIPassiveGrabDeviceReq *req; 45c27c18e8Smrg xXIPassiveGrabDeviceReply reply; 46c27c18e8Smrg xXIGrabModifierInfo *failed_mods; 47c27c18e8Smrg int len = 0, i; 4832ed59c1Smrg int ret = -1; 49c27c18e8Smrg char *buff; 50c27c18e8Smrg 51c27c18e8Smrg XExtDisplayInfo *extinfo = XInput_find_display(dpy); 52c27c18e8Smrg 53c27c18e8Smrg LockDisplay(dpy); 54b789ec8aSmrg if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1) 55c27c18e8Smrg return -1; 56c27c18e8Smrg 5710baa824Smrg if (mask->mask_len > INT_MAX - 3 || 5810baa824Smrg (mask->mask_len + 3)/4 >= 0xffff) 5932ed59c1Smrg goto out; 6010baa824Smrg 6110baa824Smrg buff = calloc(4, (mask->mask_len + 3)/4); 6210baa824Smrg if (!buff) 6332ed59c1Smrg goto out; 6410baa824Smrg 65c27c18e8Smrg GetReq(XIPassiveGrabDevice, req); 66c27c18e8Smrg req->reqType = extinfo->codes->major_opcode; 67c27c18e8Smrg req->ReqType = X_XIPassiveGrabDevice; 68c27c18e8Smrg req->deviceid = deviceid; 69c27c18e8Smrg req->grab_mode = grab_mode; 70c27c18e8Smrg req->paired_device_mode = paired_device_mode; 71c27c18e8Smrg req->owner_events = owner_events; 72c27c18e8Smrg req->grab_window = grab_window; 73c27c18e8Smrg req->cursor = cursor; 74c27c18e8Smrg req->detail = detail; 75c27c18e8Smrg req->num_modifiers = num_modifiers; 76c27c18e8Smrg req->mask_len = (mask->mask_len + 3)/4; 77c27c18e8Smrg req->grab_type = grabtype; 78f2d49d05Smrg req->time = time; 79c27c18e8Smrg 80c27c18e8Smrg len = req->mask_len + num_modifiers; 81c27c18e8Smrg SetReqLen(req, len, len); 82c27c18e8Smrg 83c27c18e8Smrg memcpy(buff, mask->mask, mask->mask_len); 84b789ec8aSmrg Data(dpy, buff, req->mask_len * 4); 85c27c18e8Smrg for (i = 0; i < num_modifiers; i++) 86b789ec8aSmrg Data(dpy, (char*)&modifiers_inout[i].modifiers, 4); 87c27c18e8Smrg 88c27c18e8Smrg free(buff); 89c27c18e8Smrg 90b789ec8aSmrg if (!_XReply(dpy, (xReply *)&reply, 0, xFalse)) 9132ed59c1Smrg goto out; 92c27c18e8Smrg 93c27c18e8Smrg failed_mods = calloc(reply.num_modifiers, sizeof(xXIGrabModifierInfo)); 94c27c18e8Smrg if (!failed_mods) 9532ed59c1Smrg goto out; 96c27c18e8Smrg _XRead(dpy, (char*)failed_mods, reply.num_modifiers * sizeof(xXIGrabModifierInfo)); 97c27c18e8Smrg 98190694daSmrg for (i = 0; i < reply.num_modifiers && i < num_modifiers; i++) 99c27c18e8Smrg { 100c27c18e8Smrg modifiers_inout[i].status = failed_mods[i].status; 101c27c18e8Smrg modifiers_inout[i].modifiers = failed_mods[i].modifiers; 102c27c18e8Smrg } 103c27c18e8Smrg free(failed_mods); 104c27c18e8Smrg 10532ed59c1Smrg ret = reply.num_modifiers; 10632ed59c1Smrg 10732ed59c1Smrg out: 108c27c18e8Smrg UnlockDisplay(dpy); 109c27c18e8Smrg SyncHandle(); 11032ed59c1Smrg return ret; 111c27c18e8Smrg} 112c27c18e8Smrg 113c27c18e8Smrgint 114c27c18e8SmrgXIGrabButton(Display* dpy, int deviceid, int button, 115c27c18e8Smrg Window grab_window, Cursor cursor, 116c27c18e8Smrg int grab_mode, int paired_device_mode, 117c27c18e8Smrg Bool owner_events, XIEventMask *mask, 118c27c18e8Smrg int num_modifiers, XIGrabModifiers *modifiers_inout) 119c27c18e8Smrg{ 120c27c18e8Smrg return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeButton, button, 121c27c18e8Smrg grab_window, cursor, grab_mode, 122c27c18e8Smrg paired_device_mode, owner_events, mask, 123f2d49d05Smrg num_modifiers, modifiers_inout, CurrentTime); 124c27c18e8Smrg} 125c27c18e8Smrg 126c27c18e8Smrgint 127c27c18e8SmrgXIGrabKeycode(Display* dpy, int deviceid, int keycode, 128c27c18e8Smrg Window grab_window, int grab_mode, int paired_device_mode, 129c27c18e8Smrg Bool owner_events, XIEventMask *mask, 130c27c18e8Smrg int num_modifiers, XIGrabModifiers *modifiers_inout) 131c27c18e8Smrg{ 132c27c18e8Smrg return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeKeycode, keycode, 133c27c18e8Smrg grab_window, None, grab_mode, paired_device_mode, 134c27c18e8Smrg owner_events, mask, num_modifiers, 135f2d49d05Smrg modifiers_inout, CurrentTime); 136c27c18e8Smrg} 137c27c18e8Smrg 138c27c18e8Smrgint 139c27c18e8SmrgXIGrabEnter(Display *dpy, int deviceid, Window grab_window, Cursor cursor, 140c27c18e8Smrg int grab_mode, int paired_device_mode, Bool owner_events, 141c27c18e8Smrg XIEventMask *mask, int num_modifiers, 142c27c18e8Smrg XIGrabModifiers *modifiers_inout) 143c27c18e8Smrg{ 144c27c18e8Smrg return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeEnter, 0, 145c27c18e8Smrg grab_window, cursor, grab_mode, paired_device_mode, 146c27c18e8Smrg owner_events, mask, num_modifiers, 147f2d49d05Smrg modifiers_inout, CurrentTime); 148c27c18e8Smrg} 149c27c18e8Smrg 150c27c18e8Smrgint 151c27c18e8SmrgXIGrabFocusIn(Display *dpy, int deviceid, Window grab_window, int grab_mode, 152c27c18e8Smrg int paired_device_mode, Bool owner_events, XIEventMask *mask, 153c27c18e8Smrg int num_modifiers, XIGrabModifiers *modifiers_inout) 154c27c18e8Smrg{ 155c27c18e8Smrg return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeFocusIn, 0, 156c27c18e8Smrg grab_window, None, grab_mode, paired_device_mode, 157c27c18e8Smrg owner_events, mask, num_modifiers, 158f2d49d05Smrg modifiers_inout, CurrentTime); 159c27c18e8Smrg} 160c27c18e8Smrg 161f1ee322dSmrgint 162f1ee322dSmrgXIGrabTouchBegin(Display *dpy, int deviceid, Window grab_window, 163f1ee322dSmrg Bool owner_events, XIEventMask *mask, 164f1ee322dSmrg int num_modifiers, XIGrabModifiers *modifiers_inout) 165f1ee322dSmrg{ 166f1ee322dSmrg XExtDisplayInfo *extinfo = XInput_find_display(dpy); 167f1ee322dSmrg 168f1ee322dSmrg LockDisplay(dpy); 169f1ee322dSmrg if (_XiCheckExtInit(dpy, XInput_2_2, extinfo) == -1) 170f1ee322dSmrg return -1; 17132ed59c1Smrg UnlockDisplay(dpy); 172f1ee322dSmrg 173f1ee322dSmrg /* FIXME: allow selection of GrabMode for paired devices? */ 174f1ee322dSmrg return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeTouchBegin, 0, 175f1ee322dSmrg grab_window, None, XIGrabModeTouch, 176f1ee322dSmrg GrabModeAsync, owner_events, mask, 177f2d49d05Smrg num_modifiers, modifiers_inout, CurrentTime); 178f1ee322dSmrg} 179f1ee322dSmrg 180adfa0b0cSmrgint XIGrabPinchGestureBegin(Display* dpy, int deviceid, Window grab_window, int grab_mode, 181adfa0b0cSmrg int paired_device_mode, int owner_events, 182adfa0b0cSmrg XIEventMask *mask, int num_modifiers, XIGrabModifiers *modifiers_inout) 183adfa0b0cSmrg{ 184adfa0b0cSmrg XExtDisplayInfo *extinfo = XInput_find_display(dpy); 185adfa0b0cSmrg 186adfa0b0cSmrg LockDisplay(dpy); 187adfa0b0cSmrg if (_XiCheckExtInit(dpy, XInput_2_4, extinfo) == -1) 188adfa0b0cSmrg return -1; 189adfa0b0cSmrg UnlockDisplay(dpy); 190adfa0b0cSmrg 191adfa0b0cSmrg return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeGesturePinchBegin, 0, 192adfa0b0cSmrg grab_window, None, grab_mode, paired_device_mode, 193adfa0b0cSmrg owner_events, mask, num_modifiers, modifiers_inout, CurrentTime); 194adfa0b0cSmrg} 195adfa0b0cSmrg 196adfa0b0cSmrgint XIGrabSwipeGestureBegin(Display* dpy, int deviceid, Window grab_window, int grab_mode, 197adfa0b0cSmrg int paired_device_mode, int owner_events, 198adfa0b0cSmrg XIEventMask *mask, int num_modifiers, XIGrabModifiers *modifiers_inout) 199adfa0b0cSmrg{ 200adfa0b0cSmrg XExtDisplayInfo *extinfo = XInput_find_display(dpy); 201adfa0b0cSmrg 202adfa0b0cSmrg LockDisplay(dpy); 203adfa0b0cSmrg if (_XiCheckExtInit(dpy, XInput_2_4, extinfo) == -1) 204adfa0b0cSmrg return -1; 205adfa0b0cSmrg UnlockDisplay(dpy); 206adfa0b0cSmrg 207adfa0b0cSmrg return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeGestureSwipeBegin, 0, 208adfa0b0cSmrg grab_window, None, grab_mode, paired_device_mode, 209adfa0b0cSmrg owner_events, mask, num_modifiers, modifiers_inout, CurrentTime); 210adfa0b0cSmrg} 211f1ee322dSmrg 212c27c18e8Smrgstatic int 213c27c18e8Smrg_XIPassiveUngrabDevice(Display* dpy, int deviceid, int grabtype, int detail, 214c27c18e8Smrg Window grab_window, int num_modifiers, XIGrabModifiers *modifiers) 215c27c18e8Smrg{ 216c27c18e8Smrg xXIPassiveUngrabDeviceReq *req; 217c27c18e8Smrg int i; 218c27c18e8Smrg 219c27c18e8Smrg XExtDisplayInfo *extinfo = XInput_find_display(dpy); 220c27c18e8Smrg 221c27c18e8Smrg LockDisplay(dpy); 222b789ec8aSmrg if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1) 223c27c18e8Smrg return -1; 224c27c18e8Smrg 225c27c18e8Smrg GetReq(XIPassiveUngrabDevice, req); 226c27c18e8Smrg req->reqType = extinfo->codes->major_opcode; 227c27c18e8Smrg req->ReqType = X_XIPassiveUngrabDevice; 228c27c18e8Smrg req->deviceid = deviceid; 229c27c18e8Smrg req->grab_window = grab_window; 230c27c18e8Smrg req->detail = detail; 231c27c18e8Smrg req->num_modifiers = num_modifiers; 232c27c18e8Smrg req->grab_type = grabtype; 233c27c18e8Smrg 234c27c18e8Smrg SetReqLen(req, num_modifiers, num_modifiers); 235c27c18e8Smrg for (i = 0; i < num_modifiers; i++) 236c27c18e8Smrg Data32(dpy, &modifiers[i].modifiers, 4); 237c27c18e8Smrg 238c27c18e8Smrg UnlockDisplay(dpy); 239c27c18e8Smrg SyncHandle(); 240c27c18e8Smrg return Success; 241c27c18e8Smrg} 242c27c18e8Smrg 243c27c18e8Smrgint 244c27c18e8SmrgXIUngrabButton(Display* display, int deviceid, int button,Window grab_window, 245c27c18e8Smrg int num_modifiers, XIGrabModifiers *modifiers) 246c27c18e8Smrg{ 247c27c18e8Smrg return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeButton, button, 248c27c18e8Smrg grab_window, num_modifiers, modifiers); 249c27c18e8Smrg} 250c27c18e8Smrg 251c27c18e8Smrgint 252c27c18e8SmrgXIUngrabKeycode(Display* display, int deviceid, int keycode, Window grab_window, 253c27c18e8Smrg int num_modifiers, XIGrabModifiers *modifiers) 254c27c18e8Smrg{ 255c27c18e8Smrg return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeKeycode, keycode, 256c27c18e8Smrg grab_window, num_modifiers, modifiers); 257c27c18e8Smrg} 258c27c18e8Smrg 259c27c18e8Smrg 260c27c18e8Smrgint 261c27c18e8SmrgXIUngrabEnter(Display* display, int deviceid, Window grab_window, 262c27c18e8Smrg int num_modifiers, XIGrabModifiers *modifiers) 263c27c18e8Smrg{ 264c27c18e8Smrg return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeEnter, 0, 265c27c18e8Smrg grab_window, num_modifiers, modifiers); 266c27c18e8Smrg} 267c27c18e8Smrg 268c27c18e8Smrgint 269c27c18e8SmrgXIUngrabFocusIn(Display* display, int deviceid, Window grab_window, 270c27c18e8Smrg int num_modifiers, XIGrabModifiers *modifiers) 271c27c18e8Smrg{ 272c27c18e8Smrg return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeFocusIn, 0, 273c27c18e8Smrg grab_window, num_modifiers, modifiers); 274c27c18e8Smrg} 275f1ee322dSmrg 276f1ee322dSmrgint 277f1ee322dSmrgXIUngrabTouchBegin(Display* display, int deviceid, Window grab_window, 278f1ee322dSmrg int num_modifiers, XIGrabModifiers *modifiers) 279f1ee322dSmrg{ 280f1ee322dSmrg XExtDisplayInfo *extinfo = XInput_find_display(display); 281f1ee322dSmrg 282f1ee322dSmrg LockDisplay(display); 283f1ee322dSmrg if (_XiCheckExtInit(display, XInput_2_2, extinfo) == -1) 284f1ee322dSmrg return -1; 2859b530083Smrg UnlockDisplay(display); 286f1ee322dSmrg 287f1ee322dSmrg return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeTouchBegin, 0, 288f1ee322dSmrg grab_window, num_modifiers, modifiers); 289f1ee322dSmrg} 290adfa0b0cSmrg 291adfa0b0cSmrgint XIUngrabPinchGestureBegin(Display* display, int deviceid, Window grab_window, 292adfa0b0cSmrg int num_modifiers, XIGrabModifiers *modifiers) 293adfa0b0cSmrg{ 294adfa0b0cSmrg XExtDisplayInfo *extinfo = XInput_find_display(display); 295adfa0b0cSmrg 296adfa0b0cSmrg LockDisplay(display); 297adfa0b0cSmrg if (_XiCheckExtInit(display, XInput_2_4, extinfo) == -1) 298adfa0b0cSmrg return -1; 299adfa0b0cSmrg UnlockDisplay(display); 300adfa0b0cSmrg 301adfa0b0cSmrg return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeGesturePinchBegin, 0, 302adfa0b0cSmrg grab_window, num_modifiers, modifiers); 303adfa0b0cSmrg} 304adfa0b0cSmrg 305adfa0b0cSmrgint XIUngrabSwipeGestureBegin(Display* display, int deviceid, Window grab_window, 306adfa0b0cSmrg int num_modifiers, XIGrabModifiers *modifiers) 307adfa0b0cSmrg{ 308adfa0b0cSmrg XExtDisplayInfo *extinfo = XInput_find_display(display); 309adfa0b0cSmrg 310adfa0b0cSmrg LockDisplay(display); 311adfa0b0cSmrg if (_XiCheckExtInit(display, XInput_2_4, extinfo) == -1) 312adfa0b0cSmrg return -1; 313adfa0b0cSmrg UnlockDisplay(display); 314adfa0b0cSmrg 315adfa0b0cSmrg return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeGestureSwipeBegin, 0, 316adfa0b0cSmrg grab_window, num_modifiers, modifiers); 317adfa0b0cSmrg} 318