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.
23
* Author: Peter Hutterer
26
/***********************************************************************
28
* Request to grab or ungrab input device.
32
#ifdef HAVE_DIX_CONFIG_H
33
#include <dix-config.h>
36
#include "inputstr.h" /* DeviceIntPtr */
37
#include "windowstr.h" /* window structure */
38
#include <X11/extensions/XI2.h>
39
#include <X11/extensions/XI2proto.h>
42
#include "exglobals.h" /* BadDevice */
44
#include "xipassivegrab.h"
47
#include "inpututils.h"
50
SProcXIPassiveGrabDevice(ClientPtr client)
55
REQUEST(xXIPassiveGrabDeviceReq);
56
REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
58
swaps(&stuff->length);
59
swaps(&stuff->deviceid);
60
swapl(&stuff->grab_window);
61
swapl(&stuff->cursor);
63
swapl(&stuff->detail);
64
swaps(&stuff->mask_len);
65
swaps(&stuff->num_modifiers);
67
REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
68
((uint32_t) stuff->mask_len + stuff->num_modifiers) *4);
69
mods = (uint32_t *) &stuff[1] + stuff->mask_len;
71
for (i = 0; i < stuff->num_modifiers; i++, mods++) {
75
return ProcXIPassiveGrabDevice(client);
79
ProcXIPassiveGrabDevice(ClientPtr client)
81
DeviceIntPtr dev, mod_dev;
82
xXIPassiveGrabDeviceReply rep = {
84
.RepType = X_XIPassiveGrabDevice,
85
.sequenceNumber = client->sequence,
91
xXIGrabModifierInfo *modifiers_failed;
92
GrabMask mask = { 0 };
97
REQUEST(xXIPassiveGrabDeviceReq);
98
REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
99
((uint32_t) stuff->mask_len + stuff->num_modifiers) * 4);
101
if (stuff->deviceid == XIAllDevices)
102
dev = inputInfo.all_devices;
103
else if (stuff->deviceid == XIAllMasterDevices)
104
dev = inputInfo.all_master_devices;
106
ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
107
if (ret != Success) {
108
client->errorValue = stuff->deviceid;
113
if (stuff->grab_type != XIGrabtypeButton &&
114
stuff->grab_type != XIGrabtypeKeycode &&
115
stuff->grab_type != XIGrabtypeEnter &&
116
stuff->grab_type != XIGrabtypeFocusIn &&
117
stuff->grab_type != XIGrabtypeTouchBegin) {
118
client->errorValue = stuff->grab_type;
122
if ((stuff->grab_type == XIGrabtypeEnter ||
123
stuff->grab_type == XIGrabtypeFocusIn ||
124
stuff->grab_type == XIGrabtypeTouchBegin) && stuff->detail != 0) {
125
client->errorValue = stuff->detail;
129
if (stuff->grab_type == XIGrabtypeTouchBegin &&
130
(stuff->grab_mode != XIGrabModeTouch ||
131
stuff->paired_device_mode != GrabModeAsync)) {
132
client->errorValue = stuff->grab_mode;
136
if (XICheckInvalidMaskBits(client, (unsigned char *) &stuff[1],
137
stuff->mask_len * 4) != Success)
140
mask.xi2mask = xi2mask_new();
144
mask_len = min(xi2mask_mask_size(mask.xi2mask), stuff->mask_len * 4);
145
xi2mask_set_one_mask(mask.xi2mask, stuff->deviceid,
146
(unsigned char *) &stuff[1], mask_len * 4);
148
memset(¶m, 0, sizeof(param));
149
param.grabtype = XI2;
150
param.ownerEvents = stuff->owner_events;
151
param.grabWindow = stuff->grab_window;
152
param.cursor = stuff->cursor;
154
if (IsKeyboardDevice(dev)) {
155
param.this_device_mode = stuff->grab_mode;
156
param.other_devices_mode = stuff->paired_device_mode;
159
param.this_device_mode = stuff->paired_device_mode;
160
param.other_devices_mode = stuff->grab_mode;
163
if (stuff->cursor != None) {
164
ret = dixLookupResourceByType(&tmp, stuff->cursor,
165
RT_CURSOR, client, DixUseAccess);
166
if (ret != Success) {
167
client->errorValue = stuff->cursor;
173
dixLookupWindow((WindowPtr *) &tmp, stuff->grab_window, client,
178
ret = CheckGrabValues(client, ¶m);
182
modifiers = (uint32_t *) &stuff[1] + stuff->mask_len;
184
calloc(stuff->num_modifiers, sizeof(xXIGrabModifierInfo));
185
if (!modifiers_failed) {
190
mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
192
for (i = 0; i < stuff->num_modifiers; i++, modifiers++) {
193
uint8_t status = Success;
195
param.modifiers = *modifiers;
196
ret = CheckGrabValues(client, ¶m);
200
switch (stuff->grab_type) {
201
case XIGrabtypeButton:
202
status = GrabButton(client, dev, mod_dev, stuff->detail,
205
case XIGrabtypeKeycode:
206
status = GrabKey(client, dev, mod_dev, stuff->detail,
209
case XIGrabtypeEnter:
210
case XIGrabtypeFocusIn:
211
status = GrabWindow(client, dev, stuff->grab_type, ¶m, &mask);
213
case XIGrabtypeTouchBegin:
214
status = GrabTouch(client, dev, mod_dev, ¶m, &mask);
218
if (status != GrabSuccess) {
219
xXIGrabModifierInfo *info = modifiers_failed + rep.num_modifiers;
221
info->status = status;
222
info->modifiers = *modifiers;
224
swapl(&info->modifiers);
227
rep.length += bytes_to_int32(sizeof(xXIGrabModifierInfo));
231
WriteReplyToClient(client, sizeof(rep), &rep);
232
if (rep.num_modifiers)
233
WriteToClient(client, rep.length * 4, modifiers_failed);
235
free(modifiers_failed);
237
xi2mask_free(&mask.xi2mask);
242
SRepXIPassiveGrabDevice(ClientPtr client, int size,
243
xXIPassiveGrabDeviceReply * rep)
245
swaps(&rep->sequenceNumber);
247
swaps(&rep->num_modifiers);
249
WriteToClient(client, size, rep);
253
SProcXIPassiveUngrabDevice(ClientPtr client)
258
REQUEST(xXIPassiveUngrabDeviceReq);
259
REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq);
261
swaps(&stuff->length);
262
swapl(&stuff->grab_window);
263
swaps(&stuff->deviceid);
264
swapl(&stuff->detail);
265
swaps(&stuff->num_modifiers);
267
REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq,
268
((uint32_t) stuff->num_modifiers) << 2);
269
modifiers = (uint32_t *) &stuff[1];
271
for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
274
return ProcXIPassiveUngrabDevice(client);
278
ProcXIPassiveUngrabDevice(ClientPtr client)
280
DeviceIntPtr dev, mod_dev;
286
REQUEST(xXIPassiveUngrabDeviceReq);
287
REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq,
288
((uint32_t) stuff->num_modifiers) << 2);
290
if (stuff->deviceid == XIAllDevices)
291
dev = inputInfo.all_devices;
292
else if (stuff->deviceid == XIAllMasterDevices)
293
dev = inputInfo.all_master_devices;
295
rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
300
if (stuff->grab_type != XIGrabtypeButton &&
301
stuff->grab_type != XIGrabtypeKeycode &&
302
stuff->grab_type != XIGrabtypeEnter &&
303
stuff->grab_type != XIGrabtypeFocusIn &&
304
stuff->grab_type != XIGrabtypeTouchBegin) {
305
client->errorValue = stuff->grab_type;
309
if ((stuff->grab_type == XIGrabtypeEnter ||
310
stuff->grab_type == XIGrabtypeFocusIn ||
311
stuff->grab_type == XIGrabtypeTouchBegin) && stuff->detail != 0) {
312
client->errorValue = stuff->detail;
316
rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess);
320
mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
322
tempGrab = AllocGrab(NULL);
326
tempGrab->resource = client->clientAsMask;
327
tempGrab->device = dev;
328
tempGrab->window = win;
329
switch (stuff->grab_type) {
330
case XIGrabtypeButton:
331
tempGrab->type = XI_ButtonPress;
333
case XIGrabtypeKeycode:
334
tempGrab->type = XI_KeyPress;
336
case XIGrabtypeEnter:
337
tempGrab->type = XI_Enter;
339
case XIGrabtypeFocusIn:
340
tempGrab->type = XI_FocusIn;
342
case XIGrabtypeTouchBegin:
343
tempGrab->type = XI_TouchBegin;
346
tempGrab->grabtype = XI2;
347
tempGrab->modifierDevice = mod_dev;
348
tempGrab->modifiersDetail.pMask = NULL;
349
tempGrab->detail.exact = stuff->detail;
350
tempGrab->detail.pMask = NULL;
352
modifiers = (uint32_t *) &stuff[1];
354
for (i = 0; i < stuff->num_modifiers; i++, modifiers++) {
355
tempGrab->modifiersDetail.exact = *modifiers;
356
DeletePassiveGrabFromList(tempGrab);