XIPassiveGrab.c revision 32ed59c1
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, 41c27c18e8Smrg int num_modifiers, XIGrabModifiers *modifiers_inout) 42c27c18e8Smrg{ 43c27c18e8Smrg xXIPassiveGrabDeviceReq *req; 44c27c18e8Smrg xXIPassiveGrabDeviceReply reply; 45c27c18e8Smrg xXIGrabModifierInfo *failed_mods; 46c27c18e8Smrg int len = 0, i; 4732ed59c1Smrg int ret = -1; 48c27c18e8Smrg char *buff; 49c27c18e8Smrg 50c27c18e8Smrg XExtDisplayInfo *extinfo = XInput_find_display(dpy); 51c27c18e8Smrg 52c27c18e8Smrg LockDisplay(dpy); 53b789ec8aSmrg if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1) 54c27c18e8Smrg return -1; 55c27c18e8Smrg 5610baa824Smrg if (mask->mask_len > INT_MAX - 3 || 5710baa824Smrg (mask->mask_len + 3)/4 >= 0xffff) 5832ed59c1Smrg goto out; 5910baa824Smrg 6010baa824Smrg buff = calloc(4, (mask->mask_len + 3)/4); 6110baa824Smrg if (!buff) 6232ed59c1Smrg goto out; 6310baa824Smrg 64c27c18e8Smrg GetReq(XIPassiveGrabDevice, req); 65c27c18e8Smrg req->reqType = extinfo->codes->major_opcode; 66c27c18e8Smrg req->ReqType = X_XIPassiveGrabDevice; 67c27c18e8Smrg req->deviceid = deviceid; 68c27c18e8Smrg req->grab_mode = grab_mode; 69c27c18e8Smrg req->paired_device_mode = paired_device_mode; 70c27c18e8Smrg req->owner_events = owner_events; 71c27c18e8Smrg req->grab_window = grab_window; 72c27c18e8Smrg req->cursor = cursor; 73c27c18e8Smrg req->detail = detail; 74c27c18e8Smrg req->num_modifiers = num_modifiers; 75c27c18e8Smrg req->mask_len = (mask->mask_len + 3)/4; 76c27c18e8Smrg req->grab_type = grabtype; 77c27c18e8Smrg 78c27c18e8Smrg len = req->mask_len + num_modifiers; 79c27c18e8Smrg SetReqLen(req, len, len); 80c27c18e8Smrg 81c27c18e8Smrg memcpy(buff, mask->mask, mask->mask_len); 82b789ec8aSmrg Data(dpy, buff, req->mask_len * 4); 83c27c18e8Smrg for (i = 0; i < num_modifiers; i++) 84b789ec8aSmrg Data(dpy, (char*)&modifiers_inout[i].modifiers, 4); 85c27c18e8Smrg 86c27c18e8Smrg free(buff); 87c27c18e8Smrg 88b789ec8aSmrg if (!_XReply(dpy, (xReply *)&reply, 0, xFalse)) 8932ed59c1Smrg goto out; 90c27c18e8Smrg 91c27c18e8Smrg failed_mods = calloc(reply.num_modifiers, sizeof(xXIGrabModifierInfo)); 92c27c18e8Smrg if (!failed_mods) 9332ed59c1Smrg goto out; 94c27c18e8Smrg _XRead(dpy, (char*)failed_mods, reply.num_modifiers * sizeof(xXIGrabModifierInfo)); 95c27c18e8Smrg 96190694daSmrg for (i = 0; i < reply.num_modifiers && i < num_modifiers; i++) 97c27c18e8Smrg { 98c27c18e8Smrg modifiers_inout[i].status = failed_mods[i].status; 99c27c18e8Smrg modifiers_inout[i].modifiers = failed_mods[i].modifiers; 100c27c18e8Smrg } 101c27c18e8Smrg free(failed_mods); 102c27c18e8Smrg 10332ed59c1Smrg ret = reply.num_modifiers; 10432ed59c1Smrg 10532ed59c1Smrg out: 106c27c18e8Smrg UnlockDisplay(dpy); 107c27c18e8Smrg SyncHandle(); 10832ed59c1Smrg return ret; 109c27c18e8Smrg} 110c27c18e8Smrg 111c27c18e8Smrgint 112c27c18e8SmrgXIGrabButton(Display* dpy, int deviceid, int button, 113c27c18e8Smrg Window grab_window, Cursor cursor, 114c27c18e8Smrg int grab_mode, int paired_device_mode, 115c27c18e8Smrg Bool owner_events, XIEventMask *mask, 116c27c18e8Smrg int num_modifiers, XIGrabModifiers *modifiers_inout) 117c27c18e8Smrg{ 118c27c18e8Smrg return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeButton, button, 119c27c18e8Smrg grab_window, cursor, grab_mode, 120c27c18e8Smrg paired_device_mode, owner_events, mask, 121c27c18e8Smrg num_modifiers, modifiers_inout); 122c27c18e8Smrg} 123c27c18e8Smrg 124c27c18e8Smrgint 125c27c18e8SmrgXIGrabKeycode(Display* dpy, int deviceid, int keycode, 126c27c18e8Smrg Window grab_window, int grab_mode, int paired_device_mode, 127c27c18e8Smrg Bool owner_events, XIEventMask *mask, 128c27c18e8Smrg int num_modifiers, XIGrabModifiers *modifiers_inout) 129c27c18e8Smrg{ 130c27c18e8Smrg return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeKeycode, keycode, 131c27c18e8Smrg grab_window, None, grab_mode, paired_device_mode, 132c27c18e8Smrg owner_events, mask, num_modifiers, 133c27c18e8Smrg modifiers_inout); 134c27c18e8Smrg} 135c27c18e8Smrg 136c27c18e8Smrgint 137c27c18e8SmrgXIGrabEnter(Display *dpy, int deviceid, Window grab_window, Cursor cursor, 138c27c18e8Smrg int grab_mode, int paired_device_mode, Bool owner_events, 139c27c18e8Smrg XIEventMask *mask, int num_modifiers, 140c27c18e8Smrg XIGrabModifiers *modifiers_inout) 141c27c18e8Smrg{ 142c27c18e8Smrg return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeEnter, 0, 143c27c18e8Smrg grab_window, cursor, grab_mode, paired_device_mode, 144c27c18e8Smrg owner_events, mask, num_modifiers, 145c27c18e8Smrg modifiers_inout); 146c27c18e8Smrg} 147c27c18e8Smrg 148c27c18e8Smrgint 149c27c18e8SmrgXIGrabFocusIn(Display *dpy, int deviceid, Window grab_window, int grab_mode, 150c27c18e8Smrg int paired_device_mode, Bool owner_events, XIEventMask *mask, 151c27c18e8Smrg int num_modifiers, XIGrabModifiers *modifiers_inout) 152c27c18e8Smrg{ 153c27c18e8Smrg return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeFocusIn, 0, 154c27c18e8Smrg grab_window, None, grab_mode, paired_device_mode, 155c27c18e8Smrg owner_events, mask, num_modifiers, 156c27c18e8Smrg modifiers_inout); 157c27c18e8Smrg} 158c27c18e8Smrg 159f1ee322dSmrgint 160f1ee322dSmrgXIGrabTouchBegin(Display *dpy, int deviceid, Window grab_window, 161f1ee322dSmrg Bool owner_events, XIEventMask *mask, 162f1ee322dSmrg int num_modifiers, XIGrabModifiers *modifiers_inout) 163f1ee322dSmrg{ 164f1ee322dSmrg XExtDisplayInfo *extinfo = XInput_find_display(dpy); 165f1ee322dSmrg 166f1ee322dSmrg LockDisplay(dpy); 167f1ee322dSmrg if (_XiCheckExtInit(dpy, XInput_2_2, extinfo) == -1) 168f1ee322dSmrg return -1; 16932ed59c1Smrg UnlockDisplay(dpy); 170f1ee322dSmrg 171f1ee322dSmrg /* FIXME: allow selection of GrabMode for paired devices? */ 172f1ee322dSmrg return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeTouchBegin, 0, 173f1ee322dSmrg grab_window, None, XIGrabModeTouch, 174f1ee322dSmrg GrabModeAsync, owner_events, mask, 175f1ee322dSmrg num_modifiers, modifiers_inout); 176f1ee322dSmrg} 177f1ee322dSmrg 178f1ee322dSmrg 179c27c18e8Smrgstatic int 180c27c18e8Smrg_XIPassiveUngrabDevice(Display* dpy, int deviceid, int grabtype, int detail, 181c27c18e8Smrg Window grab_window, int num_modifiers, XIGrabModifiers *modifiers) 182c27c18e8Smrg{ 183c27c18e8Smrg xXIPassiveUngrabDeviceReq *req; 184c27c18e8Smrg int i; 185c27c18e8Smrg 186c27c18e8Smrg XExtDisplayInfo *extinfo = XInput_find_display(dpy); 187c27c18e8Smrg 188c27c18e8Smrg LockDisplay(dpy); 189b789ec8aSmrg if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1) 190c27c18e8Smrg return -1; 191c27c18e8Smrg 192c27c18e8Smrg GetReq(XIPassiveUngrabDevice, req); 193c27c18e8Smrg req->reqType = extinfo->codes->major_opcode; 194c27c18e8Smrg req->ReqType = X_XIPassiveUngrabDevice; 195c27c18e8Smrg req->deviceid = deviceid; 196c27c18e8Smrg req->grab_window = grab_window; 197c27c18e8Smrg req->detail = detail; 198c27c18e8Smrg req->num_modifiers = num_modifiers; 199c27c18e8Smrg req->grab_type = grabtype; 200c27c18e8Smrg 201c27c18e8Smrg SetReqLen(req, num_modifiers, num_modifiers); 202c27c18e8Smrg for (i = 0; i < num_modifiers; i++) 203c27c18e8Smrg Data32(dpy, &modifiers[i].modifiers, 4); 204c27c18e8Smrg 205c27c18e8Smrg UnlockDisplay(dpy); 206c27c18e8Smrg SyncHandle(); 207c27c18e8Smrg return Success; 208c27c18e8Smrg} 209c27c18e8Smrg 210c27c18e8Smrgint 211c27c18e8SmrgXIUngrabButton(Display* display, int deviceid, int button,Window grab_window, 212c27c18e8Smrg int num_modifiers, XIGrabModifiers *modifiers) 213c27c18e8Smrg{ 214c27c18e8Smrg return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeButton, button, 215c27c18e8Smrg grab_window, num_modifiers, modifiers); 216c27c18e8Smrg} 217c27c18e8Smrg 218c27c18e8Smrgint 219c27c18e8SmrgXIUngrabKeycode(Display* display, int deviceid, int keycode, Window grab_window, 220c27c18e8Smrg int num_modifiers, XIGrabModifiers *modifiers) 221c27c18e8Smrg{ 222c27c18e8Smrg return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeKeycode, keycode, 223c27c18e8Smrg grab_window, num_modifiers, modifiers); 224c27c18e8Smrg} 225c27c18e8Smrg 226c27c18e8Smrg 227c27c18e8Smrgint 228c27c18e8SmrgXIUngrabEnter(Display* display, int deviceid, Window grab_window, 229c27c18e8Smrg int num_modifiers, XIGrabModifiers *modifiers) 230c27c18e8Smrg{ 231c27c18e8Smrg return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeEnter, 0, 232c27c18e8Smrg grab_window, num_modifiers, modifiers); 233c27c18e8Smrg} 234c27c18e8Smrg 235c27c18e8Smrgint 236c27c18e8SmrgXIUngrabFocusIn(Display* display, int deviceid, Window grab_window, 237c27c18e8Smrg int num_modifiers, XIGrabModifiers *modifiers) 238c27c18e8Smrg{ 239c27c18e8Smrg return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeFocusIn, 0, 240c27c18e8Smrg grab_window, num_modifiers, modifiers); 241c27c18e8Smrg} 242f1ee322dSmrg 243f1ee322dSmrgint 244f1ee322dSmrgXIUngrabTouchBegin(Display* display, int deviceid, Window grab_window, 245f1ee322dSmrg int num_modifiers, XIGrabModifiers *modifiers) 246f1ee322dSmrg{ 247f1ee322dSmrg XExtDisplayInfo *extinfo = XInput_find_display(display); 248f1ee322dSmrg 249f1ee322dSmrg LockDisplay(display); 250f1ee322dSmrg if (_XiCheckExtInit(display, XInput_2_2, extinfo) == -1) 251f1ee322dSmrg return -1; 252f1ee322dSmrg 253f1ee322dSmrg return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeTouchBegin, 0, 254f1ee322dSmrg grab_window, num_modifiers, modifiers); 255f1ee322dSmrg} 256