Imported Upstream version 1.6.1
[platform/upstream/libXi.git] / src / XIPassiveGrab.c
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 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdint.h>
29 #include <X11/Xlibint.h>
30 #include <X11/extensions/XI2proto.h>
31 #include <X11/extensions/XInput2.h>
32 #include <X11/extensions/extutil.h>
33 #include "XIint.h"
34
35 static int
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)
41 {
42     xXIPassiveGrabDeviceReq *req;
43     xXIPassiveGrabDeviceReply reply;
44     xXIGrabModifierInfo *failed_mods;
45     int len = 0, i;
46     char *buff;
47
48     XExtDisplayInfo *extinfo = XInput_find_display(dpy);
49
50     LockDisplay(dpy);
51     if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1)
52         return -1;
53
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;
62     req->cursor = cursor;
63     req->detail = detail;
64     req->num_modifiers = num_modifiers;
65     req->mask_len = (mask->mask_len + 3)/4;
66     req->grab_type = grabtype;
67
68     len = req->mask_len + num_modifiers;
69     SetReqLen(req, len, len);
70
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);
76
77     free(buff);
78
79     if (!_XReply(dpy, (xReply *)&reply, 0, xFalse))
80     {
81         UnlockDisplay(dpy);
82         SyncHandle();
83         return -1;
84     }
85
86     failed_mods = calloc(reply.num_modifiers, sizeof(xXIGrabModifierInfo));
87     if (!failed_mods)
88         return -1;
89     _XRead(dpy, (char*)failed_mods, reply.num_modifiers * sizeof(xXIGrabModifierInfo));
90
91     for (i = 0; i < reply.num_modifiers; i++)
92     {
93         modifiers_inout[i].status = failed_mods[i].status;
94         modifiers_inout[i].modifiers = failed_mods[i].modifiers;
95     }
96     free(failed_mods);
97
98     UnlockDisplay(dpy);
99     SyncHandle();
100     return reply.num_modifiers;
101 }
102
103 int
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)
109 {
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);
114 }
115
116 int
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)
121 {
122     return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeKeycode, keycode,
123                                 grab_window, None, grab_mode, paired_device_mode,
124                                 owner_events, mask, num_modifiers,
125                                 modifiers_inout);
126 }
127
128 int
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)
133 {
134     return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeEnter, 0,
135                                 grab_window, cursor, grab_mode, paired_device_mode,
136                                 owner_events, mask, num_modifiers,
137                                 modifiers_inout);
138 }
139
140 int
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)
144 {
145     return _XIPassiveGrabDevice(dpy, deviceid, XIGrabtypeFocusIn, 0,
146                                 grab_window, None, grab_mode, paired_device_mode,
147                                 owner_events, mask, num_modifiers,
148                                 modifiers_inout);
149 }
150
151 int
152 XIGrabTouchBegin(Display *dpy, int deviceid, Window grab_window,
153                  Bool owner_events, XIEventMask *mask,
154                  int num_modifiers, XIGrabModifiers *modifiers_inout)
155 {
156     XExtDisplayInfo *extinfo = XInput_find_display(dpy);
157
158     LockDisplay(dpy);
159     if (_XiCheckExtInit(dpy, XInput_2_2, extinfo) == -1)
160         return -1;
161
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);
167 }
168
169
170 static int
171 _XIPassiveUngrabDevice(Display* dpy, int deviceid, int grabtype, int detail,
172                        Window grab_window, int num_modifiers, XIGrabModifiers *modifiers)
173 {
174     xXIPassiveUngrabDeviceReq *req;
175     int i;
176
177     XExtDisplayInfo *extinfo = XInput_find_display(dpy);
178
179     LockDisplay(dpy);
180     if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1)
181         return -1;
182
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;
191
192     SetReqLen(req, num_modifiers, num_modifiers);
193     for (i = 0; i < num_modifiers; i++)
194         Data32(dpy, &modifiers[i].modifiers, 4);
195
196     UnlockDisplay(dpy);
197     SyncHandle();
198     return Success;
199 }
200
201 int
202 XIUngrabButton(Display* display, int deviceid, int button,Window grab_window,
203                int num_modifiers, XIGrabModifiers *modifiers)
204 {
205     return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeButton, button,
206                                   grab_window, num_modifiers, modifiers);
207 }
208
209 int
210 XIUngrabKeycode(Display* display, int deviceid, int keycode, Window grab_window,
211                int num_modifiers, XIGrabModifiers *modifiers)
212 {
213     return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeKeycode, keycode,
214                                   grab_window, num_modifiers, modifiers);
215 }
216
217
218 int
219 XIUngrabEnter(Display* display, int deviceid, Window grab_window,
220                int num_modifiers, XIGrabModifiers *modifiers)
221 {
222     return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeEnter, 0,
223                                   grab_window, num_modifiers, modifiers);
224 }
225
226 int
227 XIUngrabFocusIn(Display* display, int deviceid, Window grab_window,
228                int num_modifiers, XIGrabModifiers *modifiers)
229 {
230     return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeFocusIn, 0,
231                                   grab_window, num_modifiers, modifiers);
232 }
233
234 int
235 XIUngrabTouchBegin(Display* display, int deviceid, Window grab_window,
236                    int num_modifiers, XIGrabModifiers *modifiers)
237 {
238     XExtDisplayInfo *extinfo = XInput_find_display(display);
239
240     LockDisplay(display);
241     if (_XiCheckExtInit(display, XInput_2_2, extinfo) == -1)
242         return -1;
243
244     return _XIPassiveUngrabDevice(display, deviceid, XIGrabtypeTouchBegin, 0,
245                                   grab_window, num_modifiers, modifiers);
246 }