XIPassiveGrab.c revision c27c18e8
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 25#include <stdint.h> 26#include <X11/Xlibint.h> 27#include <X11/extensions/XI2proto.h> 28#include <X11/extensions/XInput2.h> 29#include <X11/extensions/extutil.h> 30#include "XIint.h" 31 32static int 33_XIPassiveGrabDevice(Display* dpy, int deviceid, int grabtype, int detail, 34 Window grab_window, Cursor cursor, 35 int grab_mode, int paired_device_mode, 36 Bool owner_events, XIEventMask *mask, 37 int num_modifiers, XIGrabModifiers *modifiers_inout) 38{ 39 xXIPassiveGrabDeviceReq *req; 40 xXIPassiveGrabDeviceReply reply; 41 xXIGrabModifierInfo *failed_mods; 42 int len = 0, i; 43 char *buff; 44 45 XExtDisplayInfo *extinfo = XInput_find_display(dpy); 46 47 LockDisplay(dpy); 48 if (_XiCheckExtInit(dpy, Dont_Check, extinfo) == -1) 49 return -1; 50 51 GetReq(XIPassiveGrabDevice, req); 52 req->reqType = extinfo->codes->major_opcode; 53 req->ReqType = X_XIPassiveGrabDevice; 54 req->deviceid = deviceid; 55 req->grab_mode = grab_mode; 56 req->paired_device_mode = paired_device_mode; 57 req->owner_events = owner_events; 58 req->grab_window = grab_window; 59 req->cursor = cursor; 60 req->detail = detail; 61 req->num_modifiers = num_modifiers; 62 req->mask_len = (mask->mask_len + 3)/4; 63 req->grab_type = grabtype; 64 65 len = req->mask_len + num_modifiers; 66 SetReqLen(req, len, len); 67 68 buff = calloc(4, req->mask_len); 69 memcpy(buff, mask->mask, mask->mask_len); 70 Data32(dpy, buff, req->mask_len * 4); 71 for (i = 0; i < num_modifiers; i++) 72 Data32(dpy, &modifiers_inout[i].modifiers, 4); 73 74 free(buff); 75 76 if (_XReply(dpy, (xReply *)&reply, 0, xTrue)) 77 { 78 UnlockDisplay(dpy); 79 SyncHandle(); 80 return -1; 81 } 82 83 failed_mods = calloc(reply.num_modifiers, sizeof(xXIGrabModifierInfo)); 84 if (!failed_mods) 85 return -1; 86 _XRead(dpy, (char*)failed_mods, reply.num_modifiers * sizeof(xXIGrabModifierInfo)); 87 88 for (i = 0; i < reply.num_modifiers; i++) 89 { 90 modifiers_inout[i].status = failed_mods[i].status; 91 modifiers_inout[i].modifiers = failed_mods[i].modifiers; 92 } 93 free(failed_mods); 94 95 UnlockDisplay(dpy); 96 SyncHandle(); 97 return reply.num_modifiers; 98} 99 100int 101XIGrabButton(Display* dpy, int deviceid, int button, 102 Window grab_window, Cursor cursor, 103 int grab_mode, int paired_device_mode, 104 Bool owner_events, XIEventMask *mask, 105 int num_modifiers, XIGrabModifiers *modifiers_inout) 106{ 107 return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeButton, button, 108 grab_window, cursor, grab_mode, 109 paired_device_mode, owner_events, mask, 110 num_modifiers, modifiers_inout); 111} 112 113int 114XIGrabKeycode(Display* dpy, int deviceid, int keycode, 115 Window grab_window, int grab_mode, int paired_device_mode, 116 Bool owner_events, XIEventMask *mask, 117 int num_modifiers, XIGrabModifiers *modifiers_inout) 118{ 119 return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeKeycode, keycode, 120 grab_window, None, grab_mode, paired_device_mode, 121 owner_events, mask, num_modifiers, 122 modifiers_inout); 123} 124 125int 126XIGrabEnter(Display *dpy, int deviceid, Window grab_window, Cursor cursor, 127 int grab_mode, int paired_device_mode, Bool owner_events, 128 XIEventMask *mask, int num_modifiers, 129 XIGrabModifiers *modifiers_inout) 130{ 131 return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeEnter, 0, 132 grab_window, cursor, grab_mode, paired_device_mode, 133 owner_events, mask, num_modifiers, 134 modifiers_inout); 135} 136 137int 138XIGrabFocusIn(Display *dpy, int deviceid, Window grab_window, int grab_mode, 139 int paired_device_mode, Bool owner_events, XIEventMask *mask, 140 int num_modifiers, XIGrabModifiers *modifiers_inout) 141{ 142 return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeFocusIn, 0, 143 grab_window, None, grab_mode, paired_device_mode, 144 owner_events, mask, num_modifiers, 145 modifiers_inout); 146} 147 148static int 149_XIPassiveUngrabDevice(Display* dpy, int deviceid, int grabtype, int detail, 150 Window grab_window, int num_modifiers, XIGrabModifiers *modifiers) 151{ 152 xXIPassiveUngrabDeviceReq *req; 153 int i; 154 155 XExtDisplayInfo *extinfo = XInput_find_display(dpy); 156 157 LockDisplay(dpy); 158 if (_XiCheckExtInit(dpy, Dont_Check, extinfo) == -1) 159 return -1; 160 161 GetReq(XIPassiveUngrabDevice, req); 162 req->reqType = extinfo->codes->major_opcode; 163 req->ReqType = X_XIPassiveUngrabDevice; 164 req->deviceid = deviceid; 165 req->grab_window = grab_window; 166 req->detail = detail; 167 req->num_modifiers = num_modifiers; 168 req->grab_type = grabtype; 169 170 SetReqLen(req, num_modifiers, num_modifiers); 171 for (i = 0; i < num_modifiers; i++) 172 Data32(dpy, &modifiers[i].modifiers, 4); 173 174 UnlockDisplay(dpy); 175 SyncHandle(); 176 return Success; 177} 178 179int 180XIUngrabButton(Display* display, int deviceid, int button,Window grab_window, 181 int num_modifiers, XIGrabModifiers *modifiers) 182{ 183 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeButton, button, 184 grab_window, num_modifiers, modifiers); 185} 186 187int 188XIUngrabKeycode(Display* display, int deviceid, int keycode, Window grab_window, 189 int num_modifiers, XIGrabModifiers *modifiers) 190{ 191 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeKeycode, keycode, 192 grab_window, num_modifiers, modifiers); 193} 194 195 196int 197XIUngrabEnter(Display* display, int deviceid, Window grab_window, 198 int num_modifiers, XIGrabModifiers *modifiers) 199{ 200 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeEnter, 0, 201 grab_window, num_modifiers, modifiers); 202} 203 204int 205XIUngrabFocusIn(Display* display, int deviceid, Window grab_window, 206 int num_modifiers, XIGrabModifiers *modifiers) 207{ 208 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeFocusIn, 0, 209 grab_window, num_modifiers, modifiers); 210} 211