xref: /OK3568_Linux_fs/external/xserver/Xi/xipassivegrab.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright © 2009 Red Hat, Inc.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission is hereby granted, free of charge, to any person obtaining a
5*4882a593Smuzhiyun  * copy of this software and associated documentation files (the "Software"),
6*4882a593Smuzhiyun  * to deal in the Software without restriction, including without limitation
7*4882a593Smuzhiyun  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*4882a593Smuzhiyun  * and/or sell copies of the Software, and to permit persons to whom the
9*4882a593Smuzhiyun  * Software is furnished to do so, subject to the following conditions:
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  * The above copyright notice and this permission notice (including the next
12*4882a593Smuzhiyun  * paragraph) shall be included in all copies or substantial portions of the
13*4882a593Smuzhiyun  * Software.
14*4882a593Smuzhiyun  *
15*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*4882a593Smuzhiyun  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*4882a593Smuzhiyun  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*4882a593Smuzhiyun  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*4882a593Smuzhiyun  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*4882a593Smuzhiyun  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21*4882a593Smuzhiyun  * DEALINGS IN THE SOFTWARE.
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  * Author: Peter Hutterer
24*4882a593Smuzhiyun  */
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun /***********************************************************************
27*4882a593Smuzhiyun  *
28*4882a593Smuzhiyun  * Request to grab or ungrab input device.
29*4882a593Smuzhiyun  *
30*4882a593Smuzhiyun  */
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
33*4882a593Smuzhiyun #include <dix-config.h>
34*4882a593Smuzhiyun #endif
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun #include "inputstr.h"           /* DeviceIntPtr      */
37*4882a593Smuzhiyun #include "windowstr.h"          /* window structure  */
38*4882a593Smuzhiyun #include <X11/extensions/XI2.h>
39*4882a593Smuzhiyun #include <X11/extensions/XI2proto.h>
40*4882a593Smuzhiyun #include "swaprep.h"
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun #include "exglobals.h"          /* BadDevice */
43*4882a593Smuzhiyun #include "exevents.h"
44*4882a593Smuzhiyun #include "xipassivegrab.h"
45*4882a593Smuzhiyun #include "dixgrabs.h"
46*4882a593Smuzhiyun #include "misc.h"
47*4882a593Smuzhiyun #include "inpututils.h"
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun int _X_COLD
SProcXIPassiveGrabDevice(ClientPtr client)50*4882a593Smuzhiyun SProcXIPassiveGrabDevice(ClientPtr client)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun     int i;
53*4882a593Smuzhiyun     uint32_t *mods;
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun     REQUEST(xXIPassiveGrabDeviceReq);
56*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun     swaps(&stuff->length);
59*4882a593Smuzhiyun     swaps(&stuff->deviceid);
60*4882a593Smuzhiyun     swapl(&stuff->grab_window);
61*4882a593Smuzhiyun     swapl(&stuff->cursor);
62*4882a593Smuzhiyun     swapl(&stuff->time);
63*4882a593Smuzhiyun     swapl(&stuff->detail);
64*4882a593Smuzhiyun     swaps(&stuff->mask_len);
65*4882a593Smuzhiyun     swaps(&stuff->num_modifiers);
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun     REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
68*4882a593Smuzhiyun         ((uint32_t) stuff->mask_len + stuff->num_modifiers) *4);
69*4882a593Smuzhiyun     mods = (uint32_t *) &stuff[1] + stuff->mask_len;
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun     for (i = 0; i < stuff->num_modifiers; i++, mods++) {
72*4882a593Smuzhiyun         swapl(mods);
73*4882a593Smuzhiyun     }
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun     return ProcXIPassiveGrabDevice(client);
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun int
ProcXIPassiveGrabDevice(ClientPtr client)79*4882a593Smuzhiyun ProcXIPassiveGrabDevice(ClientPtr client)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun     DeviceIntPtr dev, mod_dev;
82*4882a593Smuzhiyun     xXIPassiveGrabDeviceReply rep = {
83*4882a593Smuzhiyun         .repType = X_Reply,
84*4882a593Smuzhiyun         .RepType = X_XIPassiveGrabDevice,
85*4882a593Smuzhiyun         .sequenceNumber = client->sequence,
86*4882a593Smuzhiyun         .length = 0,
87*4882a593Smuzhiyun         .num_modifiers = 0
88*4882a593Smuzhiyun     };
89*4882a593Smuzhiyun     int i, ret = Success;
90*4882a593Smuzhiyun     uint32_t *modifiers;
91*4882a593Smuzhiyun     xXIGrabModifierInfo *modifiers_failed = NULL;
92*4882a593Smuzhiyun     GrabMask mask = { 0 };
93*4882a593Smuzhiyun     GrabParameters param;
94*4882a593Smuzhiyun     void *tmp;
95*4882a593Smuzhiyun     int mask_len;
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun     REQUEST(xXIPassiveGrabDeviceReq);
98*4882a593Smuzhiyun     REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
99*4882a593Smuzhiyun         ((uint32_t) stuff->mask_len + stuff->num_modifiers) * 4);
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun     if (stuff->deviceid == XIAllDevices)
102*4882a593Smuzhiyun         dev = inputInfo.all_devices;
103*4882a593Smuzhiyun     else if (stuff->deviceid == XIAllMasterDevices)
104*4882a593Smuzhiyun         dev = inputInfo.all_master_devices;
105*4882a593Smuzhiyun     else {
106*4882a593Smuzhiyun         ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
107*4882a593Smuzhiyun         if (ret != Success) {
108*4882a593Smuzhiyun             client->errorValue = stuff->deviceid;
109*4882a593Smuzhiyun             return ret;
110*4882a593Smuzhiyun         }
111*4882a593Smuzhiyun     }
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun     if (stuff->grab_type != XIGrabtypeButton &&
114*4882a593Smuzhiyun         stuff->grab_type != XIGrabtypeKeycode &&
115*4882a593Smuzhiyun         stuff->grab_type != XIGrabtypeEnter &&
116*4882a593Smuzhiyun         stuff->grab_type != XIGrabtypeFocusIn &&
117*4882a593Smuzhiyun         stuff->grab_type != XIGrabtypeTouchBegin) {
118*4882a593Smuzhiyun         client->errorValue = stuff->grab_type;
119*4882a593Smuzhiyun         return BadValue;
120*4882a593Smuzhiyun     }
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun     if ((stuff->grab_type == XIGrabtypeEnter ||
123*4882a593Smuzhiyun          stuff->grab_type == XIGrabtypeFocusIn ||
124*4882a593Smuzhiyun          stuff->grab_type == XIGrabtypeTouchBegin) && stuff->detail != 0) {
125*4882a593Smuzhiyun         client->errorValue = stuff->detail;
126*4882a593Smuzhiyun         return BadValue;
127*4882a593Smuzhiyun     }
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun     if (stuff->grab_type == XIGrabtypeTouchBegin &&
130*4882a593Smuzhiyun         (stuff->grab_mode != XIGrabModeTouch ||
131*4882a593Smuzhiyun          stuff->paired_device_mode != GrabModeAsync)) {
132*4882a593Smuzhiyun         client->errorValue = stuff->grab_mode;
133*4882a593Smuzhiyun         return BadValue;
134*4882a593Smuzhiyun     }
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun     if (XICheckInvalidMaskBits(client, (unsigned char *) &stuff[1],
137*4882a593Smuzhiyun                                stuff->mask_len * 4) != Success)
138*4882a593Smuzhiyun         return BadValue;
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun     mask.xi2mask = xi2mask_new();
141*4882a593Smuzhiyun     if (!mask.xi2mask)
142*4882a593Smuzhiyun         return BadAlloc;
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun     mask_len = min(xi2mask_mask_size(mask.xi2mask), stuff->mask_len * 4);
145*4882a593Smuzhiyun     xi2mask_set_one_mask(mask.xi2mask, stuff->deviceid,
146*4882a593Smuzhiyun                          (unsigned char *) &stuff[1], mask_len * 4);
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun     memset(&param, 0, sizeof(param));
149*4882a593Smuzhiyun     param.grabtype = XI2;
150*4882a593Smuzhiyun     param.ownerEvents = stuff->owner_events;
151*4882a593Smuzhiyun     param.grabWindow = stuff->grab_window;
152*4882a593Smuzhiyun     param.cursor = stuff->cursor;
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun     if (IsKeyboardDevice(dev)) {
155*4882a593Smuzhiyun         param.this_device_mode = stuff->grab_mode;
156*4882a593Smuzhiyun         param.other_devices_mode = stuff->paired_device_mode;
157*4882a593Smuzhiyun     }
158*4882a593Smuzhiyun     else {
159*4882a593Smuzhiyun         param.this_device_mode = stuff->paired_device_mode;
160*4882a593Smuzhiyun         param.other_devices_mode = stuff->grab_mode;
161*4882a593Smuzhiyun     }
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun     if (stuff->cursor != None) {
164*4882a593Smuzhiyun         ret = dixLookupResourceByType(&tmp, stuff->cursor,
165*4882a593Smuzhiyun                                       RT_CURSOR, client, DixUseAccess);
166*4882a593Smuzhiyun         if (ret != Success) {
167*4882a593Smuzhiyun             client->errorValue = stuff->cursor;
168*4882a593Smuzhiyun             goto out;
169*4882a593Smuzhiyun         }
170*4882a593Smuzhiyun     }
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun     ret =
173*4882a593Smuzhiyun         dixLookupWindow((WindowPtr *) &tmp, stuff->grab_window, client,
174*4882a593Smuzhiyun                         DixSetAttrAccess);
175*4882a593Smuzhiyun     if (ret != Success)
176*4882a593Smuzhiyun         goto out;
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun     ret = CheckGrabValues(client, &param);
179*4882a593Smuzhiyun     if (ret != Success)
180*4882a593Smuzhiyun         goto out;
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun     modifiers = (uint32_t *) &stuff[1] + stuff->mask_len;
183*4882a593Smuzhiyun     modifiers_failed =
184*4882a593Smuzhiyun         calloc(stuff->num_modifiers, sizeof(xXIGrabModifierInfo));
185*4882a593Smuzhiyun     if (!modifiers_failed) {
186*4882a593Smuzhiyun         ret = BadAlloc;
187*4882a593Smuzhiyun         goto out;
188*4882a593Smuzhiyun     }
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun     mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun     for (i = 0; i < stuff->num_modifiers; i++, modifiers++) {
193*4882a593Smuzhiyun         uint8_t status = Success;
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun         param.modifiers = *modifiers;
196*4882a593Smuzhiyun         ret = CheckGrabValues(client, &param);
197*4882a593Smuzhiyun         if (ret != Success)
198*4882a593Smuzhiyun             goto out;
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun         switch (stuff->grab_type) {
201*4882a593Smuzhiyun         case XIGrabtypeButton:
202*4882a593Smuzhiyun             status = GrabButton(client, dev, mod_dev, stuff->detail,
203*4882a593Smuzhiyun                                 &param, XI2, &mask);
204*4882a593Smuzhiyun             break;
205*4882a593Smuzhiyun         case XIGrabtypeKeycode:
206*4882a593Smuzhiyun             /* XI2 allows 32-bit keycodes but thanks to XKB we can never
207*4882a593Smuzhiyun              * implement this. Just return an error for all keycodes that
208*4882a593Smuzhiyun              * cannot work anyway */
209*4882a593Smuzhiyun             if (stuff->detail > 255)
210*4882a593Smuzhiyun                 status = XIAlreadyGrabbed;
211*4882a593Smuzhiyun             else
212*4882a593Smuzhiyun                 status = GrabKey(client, dev, mod_dev, stuff->detail,
213*4882a593Smuzhiyun                                  &param, XI2, &mask);
214*4882a593Smuzhiyun             break;
215*4882a593Smuzhiyun         case XIGrabtypeEnter:
216*4882a593Smuzhiyun         case XIGrabtypeFocusIn:
217*4882a593Smuzhiyun             status = GrabWindow(client, dev, stuff->grab_type, &param, &mask);
218*4882a593Smuzhiyun             break;
219*4882a593Smuzhiyun         case XIGrabtypeTouchBegin:
220*4882a593Smuzhiyun             status = GrabTouch(client, dev, mod_dev, &param, &mask);
221*4882a593Smuzhiyun             break;
222*4882a593Smuzhiyun         }
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun         if (status != GrabSuccess) {
225*4882a593Smuzhiyun             xXIGrabModifierInfo *info = modifiers_failed + rep.num_modifiers;
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun             info->status = status;
228*4882a593Smuzhiyun             info->modifiers = *modifiers;
229*4882a593Smuzhiyun             if (client->swapped)
230*4882a593Smuzhiyun                 swapl(&info->modifiers);
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun             rep.num_modifiers++;
233*4882a593Smuzhiyun             rep.length += bytes_to_int32(sizeof(xXIGrabModifierInfo));
234*4882a593Smuzhiyun         }
235*4882a593Smuzhiyun     }
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun     WriteReplyToClient(client, sizeof(rep), &rep);
238*4882a593Smuzhiyun     if (rep.num_modifiers)
239*4882a593Smuzhiyun         WriteToClient(client, rep.length * 4, modifiers_failed);
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun  out:
242*4882a593Smuzhiyun     free(modifiers_failed);
243*4882a593Smuzhiyun     xi2mask_free(&mask.xi2mask);
244*4882a593Smuzhiyun     return ret;
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun void _X_COLD
SRepXIPassiveGrabDevice(ClientPtr client,int size,xXIPassiveGrabDeviceReply * rep)248*4882a593Smuzhiyun SRepXIPassiveGrabDevice(ClientPtr client, int size,
249*4882a593Smuzhiyun                         xXIPassiveGrabDeviceReply * rep)
250*4882a593Smuzhiyun {
251*4882a593Smuzhiyun     swaps(&rep->sequenceNumber);
252*4882a593Smuzhiyun     swapl(&rep->length);
253*4882a593Smuzhiyun     swaps(&rep->num_modifiers);
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun     WriteToClient(client, size, rep);
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun int _X_COLD
SProcXIPassiveUngrabDevice(ClientPtr client)259*4882a593Smuzhiyun SProcXIPassiveUngrabDevice(ClientPtr client)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun     int i;
262*4882a593Smuzhiyun     uint32_t *modifiers;
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun     REQUEST(xXIPassiveUngrabDeviceReq);
265*4882a593Smuzhiyun     REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq);
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun     swaps(&stuff->length);
268*4882a593Smuzhiyun     swapl(&stuff->grab_window);
269*4882a593Smuzhiyun     swaps(&stuff->deviceid);
270*4882a593Smuzhiyun     swapl(&stuff->detail);
271*4882a593Smuzhiyun     swaps(&stuff->num_modifiers);
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun     REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq,
274*4882a593Smuzhiyun                        ((uint32_t) stuff->num_modifiers) << 2);
275*4882a593Smuzhiyun     modifiers = (uint32_t *) &stuff[1];
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun     for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
278*4882a593Smuzhiyun         swapl(modifiers);
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun     return ProcXIPassiveUngrabDevice(client);
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun int
ProcXIPassiveUngrabDevice(ClientPtr client)284*4882a593Smuzhiyun ProcXIPassiveUngrabDevice(ClientPtr client)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun     DeviceIntPtr dev, mod_dev;
287*4882a593Smuzhiyun     WindowPtr win;
288*4882a593Smuzhiyun     GrabPtr tempGrab;
289*4882a593Smuzhiyun     uint32_t *modifiers;
290*4882a593Smuzhiyun     int i, rc;
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun     REQUEST(xXIPassiveUngrabDeviceReq);
293*4882a593Smuzhiyun     REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq,
294*4882a593Smuzhiyun                        ((uint32_t) stuff->num_modifiers) << 2);
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun     if (stuff->deviceid == XIAllDevices)
297*4882a593Smuzhiyun         dev = inputInfo.all_devices;
298*4882a593Smuzhiyun     else if (stuff->deviceid == XIAllMasterDevices)
299*4882a593Smuzhiyun         dev = inputInfo.all_master_devices;
300*4882a593Smuzhiyun     else {
301*4882a593Smuzhiyun         rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
302*4882a593Smuzhiyun         if (rc != Success)
303*4882a593Smuzhiyun             return rc;
304*4882a593Smuzhiyun     }
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun     if (stuff->grab_type != XIGrabtypeButton &&
307*4882a593Smuzhiyun         stuff->grab_type != XIGrabtypeKeycode &&
308*4882a593Smuzhiyun         stuff->grab_type != XIGrabtypeEnter &&
309*4882a593Smuzhiyun         stuff->grab_type != XIGrabtypeFocusIn &&
310*4882a593Smuzhiyun         stuff->grab_type != XIGrabtypeTouchBegin) {
311*4882a593Smuzhiyun         client->errorValue = stuff->grab_type;
312*4882a593Smuzhiyun         return BadValue;
313*4882a593Smuzhiyun     }
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun     if ((stuff->grab_type == XIGrabtypeEnter ||
316*4882a593Smuzhiyun          stuff->grab_type == XIGrabtypeFocusIn ||
317*4882a593Smuzhiyun          stuff->grab_type == XIGrabtypeTouchBegin) && stuff->detail != 0) {
318*4882a593Smuzhiyun         client->errorValue = stuff->detail;
319*4882a593Smuzhiyun         return BadValue;
320*4882a593Smuzhiyun     }
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun     rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess);
323*4882a593Smuzhiyun     if (rc != Success)
324*4882a593Smuzhiyun         return rc;
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun     mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun     tempGrab = AllocGrab(NULL);
329*4882a593Smuzhiyun     if (!tempGrab)
330*4882a593Smuzhiyun         return BadAlloc;
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun     tempGrab->resource = client->clientAsMask;
333*4882a593Smuzhiyun     tempGrab->device = dev;
334*4882a593Smuzhiyun     tempGrab->window = win;
335*4882a593Smuzhiyun     switch (stuff->grab_type) {
336*4882a593Smuzhiyun     case XIGrabtypeButton:
337*4882a593Smuzhiyun         tempGrab->type = XI_ButtonPress;
338*4882a593Smuzhiyun         break;
339*4882a593Smuzhiyun     case XIGrabtypeKeycode:
340*4882a593Smuzhiyun         tempGrab->type = XI_KeyPress;
341*4882a593Smuzhiyun         break;
342*4882a593Smuzhiyun     case XIGrabtypeEnter:
343*4882a593Smuzhiyun         tempGrab->type = XI_Enter;
344*4882a593Smuzhiyun         break;
345*4882a593Smuzhiyun     case XIGrabtypeFocusIn:
346*4882a593Smuzhiyun         tempGrab->type = XI_FocusIn;
347*4882a593Smuzhiyun         break;
348*4882a593Smuzhiyun     case XIGrabtypeTouchBegin:
349*4882a593Smuzhiyun         tempGrab->type = XI_TouchBegin;
350*4882a593Smuzhiyun         break;
351*4882a593Smuzhiyun     }
352*4882a593Smuzhiyun     tempGrab->grabtype = XI2;
353*4882a593Smuzhiyun     tempGrab->modifierDevice = mod_dev;
354*4882a593Smuzhiyun     tempGrab->modifiersDetail.pMask = NULL;
355*4882a593Smuzhiyun     tempGrab->detail.exact = stuff->detail;
356*4882a593Smuzhiyun     tempGrab->detail.pMask = NULL;
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun     modifiers = (uint32_t *) &stuff[1];
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun     for (i = 0; i < stuff->num_modifiers; i++, modifiers++) {
361*4882a593Smuzhiyun         tempGrab->modifiersDetail.exact = *modifiers;
362*4882a593Smuzhiyun         DeletePassiveGrabFromList(tempGrab);
363*4882a593Smuzhiyun     }
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun     FreeGrab(tempGrab);
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun     return Success;
368*4882a593Smuzhiyun }
369