2 * Copyright © 2009 Red Hat, Inc.
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:
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
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.
29 #include <X11/Xlibint.h>
30 #include <X11/extensions/XI2proto.h>
31 #include <X11/extensions/XInput2.h>
32 #include <X11/extensions/extutil.h>
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)
43 xXIPassiveGrabDeviceReq *req;
44 xXIPassiveGrabDeviceReply reply;
45 xXIGrabModifierInfo *failed_mods;
49 XExtDisplayInfo *extinfo = XInput_find_display(dpy);
52 if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1)
55 if (mask->mask_len > INT_MAX - 3 ||
56 (mask->mask_len + 3)/4 >= 0xffff)
59 buff = calloc(4, (mask->mask_len + 3)/4);
63 GetReq(XIPassiveGrabDevice, req);
64 req->reqType = extinfo->codes->major_opcode;
65 req->ReqType = X_XIPassiveGrabDevice;
66 req->deviceid = deviceid;
67 req->grab_mode = grab_mode;
68 req->paired_device_mode = paired_device_mode;
69 req->owner_events = owner_events;
70 req->grab_window = grab_window;
73 req->num_modifiers = num_modifiers;
74 req->mask_len = (mask->mask_len + 3)/4;
75 req->grab_type = grabtype;
77 len = req->mask_len + num_modifiers;
78 SetReqLen(req, len, len);
80 memcpy(buff, mask->mask, mask->mask_len);
81 Data(dpy, buff, req->mask_len * 4);
82 for (i = 0; i < num_modifiers; i++)
83 Data(dpy, (char*)&modifiers_inout[i].modifiers, 4);
87 if (!_XReply(dpy, (xReply *)&reply, 0, xFalse))
94 failed_mods = calloc(reply.num_modifiers, sizeof(xXIGrabModifierInfo));
97 _XRead(dpy, (char*)failed_mods, reply.num_modifiers * sizeof(xXIGrabModifierInfo));
99 for (i = 0; i < reply.num_modifiers && i < num_modifiers; i++)
101 modifiers_inout[i].status = failed_mods[i].status;
102 modifiers_inout[i].modifiers = failed_mods[i].modifiers;
108 return reply.num_modifiers;
112 XIGrabButton(Display* dpy, int deviceid, int button,
113 Window grab_window, Cursor cursor,
114 int grab_mode, int paired_device_mode,
115 Bool owner_events, XIEventMask *mask,
116 int num_modifiers, XIGrabModifiers *modifiers_inout)
118 return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeButton, button,
119 grab_window, cursor, grab_mode,
120 paired_device_mode, owner_events, mask,
121 num_modifiers, modifiers_inout);
125 XIGrabKeycode(Display* dpy, int deviceid, int keycode,
126 Window grab_window, int grab_mode, int paired_device_mode,
127 Bool owner_events, XIEventMask *mask,
128 int num_modifiers, XIGrabModifiers *modifiers_inout)
130 return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeKeycode, keycode,
131 grab_window, None, grab_mode, paired_device_mode,
132 owner_events, mask, num_modifiers,
137 XIGrabEnter(Display *dpy, int deviceid, Window grab_window, Cursor cursor,
138 int grab_mode, int paired_device_mode, Bool owner_events,
139 XIEventMask *mask, int num_modifiers,
140 XIGrabModifiers *modifiers_inout)
142 return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeEnter, 0,
143 grab_window, cursor, grab_mode, paired_device_mode,
144 owner_events, mask, num_modifiers,
149 XIGrabFocusIn(Display *dpy, int deviceid, Window grab_window, int grab_mode,
150 int paired_device_mode, Bool owner_events, XIEventMask *mask,
151 int num_modifiers, XIGrabModifiers *modifiers_inout)
153 return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeFocusIn, 0,
154 grab_window, None, grab_mode, paired_device_mode,
155 owner_events, mask, num_modifiers,
160 XIGrabTouchBegin(Display *dpy, int deviceid, Window grab_window,
161 Bool owner_events, XIEventMask *mask,
162 int num_modifiers, XIGrabModifiers *modifiers_inout)
164 XExtDisplayInfo *extinfo = XInput_find_display(dpy);
167 if (_XiCheckExtInit(dpy, XInput_2_2, extinfo) == -1)
170 /* FIXME: allow selection of GrabMode for paired devices? */
171 return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeTouchBegin, 0,
172 grab_window, None, XIGrabModeTouch,
173 GrabModeAsync, owner_events, mask,
174 num_modifiers, modifiers_inout);
179 _XIPassiveUngrabDevice(Display* dpy, int deviceid, int grabtype, int detail,
180 Window grab_window, int num_modifiers, XIGrabModifiers *modifiers)
182 xXIPassiveUngrabDeviceReq *req;
185 XExtDisplayInfo *extinfo = XInput_find_display(dpy);
188 if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1)
191 GetReq(XIPassiveUngrabDevice, req);
192 req->reqType = extinfo->codes->major_opcode;
193 req->ReqType = X_XIPassiveUngrabDevice;
194 req->deviceid = deviceid;
195 req->grab_window = grab_window;
196 req->detail = detail;
197 req->num_modifiers = num_modifiers;
198 req->grab_type = grabtype;
200 SetReqLen(req, num_modifiers, num_modifiers);
201 for (i = 0; i < num_modifiers; i++)
202 Data32(dpy, &modifiers[i].modifiers, 4);
210 XIUngrabButton(Display* display, int deviceid, int button,Window grab_window,
211 int num_modifiers, XIGrabModifiers *modifiers)
213 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeButton, button,
214 grab_window, num_modifiers, modifiers);
218 XIUngrabKeycode(Display* display, int deviceid, int keycode, Window grab_window,
219 int num_modifiers, XIGrabModifiers *modifiers)
221 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeKeycode, keycode,
222 grab_window, num_modifiers, modifiers);
227 XIUngrabEnter(Display* display, int deviceid, Window grab_window,
228 int num_modifiers, XIGrabModifiers *modifiers)
230 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeEnter, 0,
231 grab_window, num_modifiers, modifiers);
235 XIUngrabFocusIn(Display* display, int deviceid, Window grab_window,
236 int num_modifiers, XIGrabModifiers *modifiers)
238 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeFocusIn, 0,
239 grab_window, num_modifiers, modifiers);
243 XIUngrabTouchBegin(Display* display, int deviceid, Window grab_window,
244 int num_modifiers, XIGrabModifiers *modifiers)
246 XExtDisplayInfo *extinfo = XInput_find_display(display);
248 LockDisplay(display);
249 if (_XiCheckExtInit(display, XInput_2_2, extinfo) == -1)
252 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeTouchBegin, 0,
253 grab_window, num_modifiers, modifiers);