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