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