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