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>
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)
42 xXIPassiveGrabDeviceReq *req;
43 xXIPassiveGrabDeviceReply reply;
44 xXIGrabModifierInfo *failed_mods;
48 XExtDisplayInfo *extinfo = XInput_find_display(dpy);
51 if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1)
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;
64 req->num_modifiers = num_modifiers;
65 req->mask_len = (mask->mask_len + 3)/4;
66 req->grab_type = grabtype;
68 len = req->mask_len + num_modifiers;
69 SetReqLen(req, len, len);
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);
79 if (!_XReply(dpy, (xReply *)&reply, 0, xFalse))
86 failed_mods = calloc(reply.num_modifiers, sizeof(xXIGrabModifierInfo));
89 _XRead(dpy, (char*)failed_mods, reply.num_modifiers * sizeof(xXIGrabModifierInfo));
91 for (i = 0; i < reply.num_modifiers; i++)
93 modifiers_inout[i].status = failed_mods[i].status;
94 modifiers_inout[i].modifiers = failed_mods[i].modifiers;
100 return reply.num_modifiers;
104 XIGrabButton(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)
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);
117 XIGrabKeycode(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)
122 return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeKeycode, keycode,
123 grab_window, None, grab_mode, paired_device_mode,
124 owner_events, mask, num_modifiers,
129 XIGrabEnter(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)
134 return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeEnter, 0,
135 grab_window, cursor, grab_mode, paired_device_mode,
136 owner_events, mask, num_modifiers,
141 XIGrabFocusIn(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)
145 return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeFocusIn, 0,
146 grab_window, None, grab_mode, paired_device_mode,
147 owner_events, mask, num_modifiers,
152 XIGrabTouchBegin(Display *dpy, int deviceid, Window grab_window,
153 Bool owner_events, XIEventMask *mask,
154 int num_modifiers, XIGrabModifiers *modifiers_inout)
156 XExtDisplayInfo *extinfo = XInput_find_display(dpy);
159 if (_XiCheckExtInit(dpy, XInput_2_2, extinfo) == -1)
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);
171 _XIPassiveUngrabDevice(Display* dpy, int deviceid, int grabtype, int detail,
172 Window grab_window, int num_modifiers, XIGrabModifiers *modifiers)
174 xXIPassiveUngrabDeviceReq *req;
177 XExtDisplayInfo *extinfo = XInput_find_display(dpy);
180 if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1)
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;
192 SetReqLen(req, num_modifiers, num_modifiers);
193 for (i = 0; i < num_modifiers; i++)
194 Data32(dpy, &modifiers[i].modifiers, 4);
202 XIUngrabButton(Display* display, int deviceid, int button,Window grab_window,
203 int num_modifiers, XIGrabModifiers *modifiers)
205 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeButton, button,
206 grab_window, num_modifiers, modifiers);
210 XIUngrabKeycode(Display* display, int deviceid, int keycode, Window grab_window,
211 int num_modifiers, XIGrabModifiers *modifiers)
213 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeKeycode, keycode,
214 grab_window, num_modifiers, modifiers);
219 XIUngrabEnter(Display* display, int deviceid, Window grab_window,
220 int num_modifiers, XIGrabModifiers *modifiers)
222 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeEnter, 0,
223 grab_window, num_modifiers, modifiers);
227 XIUngrabFocusIn(Display* display, int deviceid, Window grab_window,
228 int num_modifiers, XIGrabModifiers *modifiers)
230 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeFocusIn, 0,
231 grab_window, num_modifiers, modifiers);
235 XIUngrabTouchBegin(Display* display, int deviceid, Window grab_window,
236 int num_modifiers, XIGrabModifiers *modifiers)
238 XExtDisplayInfo *extinfo = XInput_find_display(display);
240 LockDisplay(display);
241 if (_XiCheckExtInit(display, XInput_2_2, extinfo) == -1)
244 return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeTouchBegin, 0,
245 grab_window, num_modifiers, modifiers);