XIPassiveGrab.c revision 190694da
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 "XIint.h" 34 35static int 36_XIPassiveGrabDevice(Display* dpy, int deviceid, int grabtype, int detail, 37 Window grab_window, Cursor cursor, 38 int grab_mode, int paired_device_mode, 39 Bool owner_events, XIEventMask *mask, 40 int num_modifiers, XIGrabModifiers *modifiers_inout) 41{ 42 xXIPassiveGrabDeviceReq *req; 43 xXIPassiveGrabDeviceReply reply; 44 xXIGrabModifierInfo *failed_mods; 45 int len = 0, i; 46 char *buff; 47 48 XExtDisplayInfo *extinfo = XInput_find_display(dpy); 49 50 LockDisplay(dpy); 51 if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1) 52 return -1; 53 54 GetReq(XIPassiveGrabDevice, req); 55 req->reqType = extinfo->codes->major_opcode; 56 req->ReqType = X_XIPassiveGrabDevice; 57 req->deviceid = deviceid; 58 req->grab_mode = grab_mode; 59 req->paired_device_mode = paired_device_mode; 60 req->owner_events = owner_events; 61 req->grab_window = grab_window; 62 req->cursor = cursor; 63 req->detail = detail; 64 req->num_modifiers = num_modifiers; 65 req->mask_len = (mask->mask_len + 3)/4; 66 req->grab_type = grabtype; 67 68 len = req->mask_len + num_modifiers; 69 SetReqLen(req, len, len); 70 71 buff = calloc(4, req->mask_len); 72 memcpy(buff, mask->mask, mask->mask_len); 73 Data(dpy, buff, req->mask_len * 4); 74 for (i = 0; i < num_modifiers; i++) 75 Data(dpy, (char*)&modifiers_inout[i].modifiers, 4); 76 77 free(buff); 78 79 if (!_XReply(dpy, (xReply *)&reply, 0, xFalse)) 80 { 81 UnlockDisplay(dpy); 82 SyncHandle(); 83 return -1; 84 } 85 86 failed_mods = calloc(reply.num_modifiers, sizeof(xXIGrabModifierInfo)); 87 if (!failed_mods) 88 return -1; 89 _XRead(dpy, (char*)failed_mods, reply.num_modifiers * sizeof(xXIGrabModifierInfo)); 90 91 for (i = 0; i < reply.num_modifiers && i < num_modifiers; i++) 92 { 93 modifiers_inout[i].status = failed_mods[i].status; 94 modifiers_inout[i].modifiers = failed_mods[i].modifiers; 95 } 96 free(failed_mods); 97 98 UnlockDisplay(dpy); 99 SyncHandle(); 100 return reply.num_modifiers; 101} 102 103int 104XIGrabButton(Display* dpy, int deviceid, int button, 105 Window grab_window, Cursor cursor, 106 int grab_mode, int paired_device_mode, 107 Bool owner_events, XIEventMask *mask, 108 int num_modifiers, XIGrabModifiers *modifiers_inout) 109{ 110 return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeButton, button, 111 grab_window, cursor, grab_mode, 112 paired_device_mode, owner_events, mask, 113 num_modifiers, modifiers_inout); 114} 115 116int 117XIGrabKeycode(Display* dpy, int deviceid, int keycode, 118 Window grab_window, int grab_mode, int paired_device_mode, 119 Bool owner_events, XIEventMask *mask, 120 int num_modifiers, XIGrabModifiers *modifiers_inout) 121{ 122 return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeKeycode, keycode, 123 grab_window, None, grab_mode, paired_device_mode, 124 owner_events, mask, num_modifiers, 125 modifiers_inout); 126} 127 128int 129XIGrabEnter(Display *dpy, int deviceid, Window grab_window, Cursor cursor, 130 int grab_mode, int paired_device_mode, Bool owner_events, 131 XIEventMask *mask, int num_modifiers, 132 XIGrabModifiers *modifiers_inout) 133{ 134 return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeEnter, 0, 135 grab_window, cursor, grab_mode, paired_device_mode, 136 owner_events, mask, num_modifiers, 137 modifiers_inout); 138} 139 140int 141XIGrabFocusIn(Display *dpy, int deviceid, Window grab_window, int grab_mode, 142 int paired_device_mode, Bool owner_events, XIEventMask *mask, 143 int num_modifiers, XIGrabModifiers *modifiers_inout) 144{ 145 return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeFocusIn, 0, 146 grab_window, None, grab_mode, paired_device_mode, 147 owner_events, mask, num_modifiers, 148 modifiers_inout); 149} 150 151int 152XIGrabTouchBegin(Display *dpy, int deviceid, Window grab_window, 153 Bool owner_events, XIEventMask *mask, 154 int num_modifiers, XIGrabModifiers *modifiers_inout) 155{ 156 XExtDisplayInfo *extinfo = XInput_find_display(dpy); 157 158 LockDisplay(dpy); 159 if (_XiCheckExtInit(dpy, XInput_2_2, extinfo) == -1) 160 return -1; 161 162 /* FIXME: allow selection of GrabMode for paired devices? */ 163 return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeTouchBegin, 0, 164 grab_window, None, XIGrabModeTouch, 165 GrabModeAsync, owner_events, mask, 166 num_modifiers, modifiers_inout); 167} 168 169 170static int 171_XIPassiveUngrabDevice(Display* dpy, int deviceid, int grabtype, int detail, 172 Window grab_window, int num_modifiers, XIGrabModifiers *modifiers) 173{ 174 xXIPassiveUngrabDeviceReq *req; 175 int i; 176 177 XExtDisplayInfo *extinfo = XInput_find_display(dpy); 178 179 LockDisplay(dpy); 180 if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1) 181 return -1; 182 183 GetReq(XIPassiveUngrabDevice, req); 184 req->reqType = extinfo->codes->major_opcode; 185 req->ReqType = X_XIPassiveUngrabDevice; 186 req->deviceid = deviceid; 187 req->grab_window = grab_window; 188 req->detail = detail; 189 req->num_modifiers = num_modifiers; 190 req->grab_type = grabtype; 191 192 SetReqLen(req, num_modifiers, num_modifiers); 193 for (i = 0; i < num_modifiers; i++) 194 Data32(dpy, &modifiers[i].modifiers, 4); 195 196 UnlockDisplay(dpy); 197 SyncHandle(); 198 return Success; 199} 200 201int 202XIUngrabButton(Display* display, int deviceid, int button,Window grab_window, 203 int num_modifiers, XIGrabModifiers *modifiers) 204{ 205 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeButton, button, 206 grab_window, num_modifiers, modifiers); 207} 208 209int 210XIUngrabKeycode(Display* display, int deviceid, int keycode, Window grab_window, 211 int num_modifiers, XIGrabModifiers *modifiers) 212{ 213 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeKeycode, keycode, 214 grab_window, num_modifiers, modifiers); 215} 216 217 218int 219XIUngrabEnter(Display* display, int deviceid, Window grab_window, 220 int num_modifiers, XIGrabModifiers *modifiers) 221{ 222 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeEnter, 0, 223 grab_window, num_modifiers, modifiers); 224} 225 226int 227XIUngrabFocusIn(Display* display, int deviceid, Window grab_window, 228 int num_modifiers, XIGrabModifiers *modifiers) 229{ 230 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeFocusIn, 0, 231 grab_window, num_modifiers, modifiers); 232} 233 234int 235XIUngrabTouchBegin(Display* display, int deviceid, Window grab_window, 236 int num_modifiers, XIGrabModifiers *modifiers) 237{ 238 XExtDisplayInfo *extinfo = XInput_find_display(display); 239 240 LockDisplay(display); 241 if (_XiCheckExtInit(display, XInput_2_2, extinfo) == -1) 242 return -1; 243 244 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeTouchBegin, 0, 245 grab_window, num_modifiers, modifiers); 246} 247