123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- /*
- * Copyright © 2009 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Author: Peter Hutterer
- */
- /***********************************************************************
- *
- * Request to grab or ungrab input device.
- *
- */
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #include "inputstr.h" /* DeviceIntPtr */
- #include "windowstr.h" /* window structure */
- #include <X11/extensions/XI2.h>
- #include <X11/extensions/XI2proto.h>
- #include "swaprep.h"
- #include "exglobals.h" /* BadDevice */
- #include "exevents.h"
- #include "xipassivegrab.h"
- #include "dixgrabs.h"
- #include "misc.h"
- #include "inpututils.h"
- int
- SProcXIPassiveGrabDevice(ClientPtr client)
- {
- int i;
- uint32_t *mods;
- REQUEST(xXIPassiveGrabDeviceReq);
- REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
- swaps(&stuff->length);
- swaps(&stuff->deviceid);
- swapl(&stuff->grab_window);
- swapl(&stuff->cursor);
- swapl(&stuff->time);
- swapl(&stuff->detail);
- swaps(&stuff->mask_len);
- swaps(&stuff->num_modifiers);
- REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
- ((uint32_t) stuff->mask_len + stuff->num_modifiers) *4);
- mods = (uint32_t *) &stuff[1] + stuff->mask_len;
- for (i = 0; i < stuff->num_modifiers; i++, mods++) {
- swapl(mods);
- }
- return ProcXIPassiveGrabDevice(client);
- }
- int
- ProcXIPassiveGrabDevice(ClientPtr client)
- {
- DeviceIntPtr dev, mod_dev;
- xXIPassiveGrabDeviceReply rep = {
- .repType = X_Reply,
- .RepType = X_XIPassiveGrabDevice,
- .sequenceNumber = client->sequence,
- .length = 0,
- .num_modifiers = 0
- };
- int i, ret = Success;
- uint32_t *modifiers;
- xXIGrabModifierInfo *modifiers_failed;
- GrabMask mask = { 0 };
- GrabParameters param;
- void *tmp;
- int mask_len;
- REQUEST(xXIPassiveGrabDeviceReq);
- REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
- ((uint32_t) stuff->mask_len + stuff->num_modifiers) * 4);
- if (stuff->deviceid == XIAllDevices)
- dev = inputInfo.all_devices;
- else if (stuff->deviceid == XIAllMasterDevices)
- dev = inputInfo.all_master_devices;
- else {
- ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
- if (ret != Success) {
- client->errorValue = stuff->deviceid;
- return ret;
- }
- }
- if (stuff->grab_type != XIGrabtypeButton &&
- stuff->grab_type != XIGrabtypeKeycode &&
- stuff->grab_type != XIGrabtypeEnter &&
- stuff->grab_type != XIGrabtypeFocusIn &&
- stuff->grab_type != XIGrabtypeTouchBegin) {
- client->errorValue = stuff->grab_type;
- return BadValue;
- }
- if ((stuff->grab_type == XIGrabtypeEnter ||
- stuff->grab_type == XIGrabtypeFocusIn ||
- stuff->grab_type == XIGrabtypeTouchBegin) && stuff->detail != 0) {
- client->errorValue = stuff->detail;
- return BadValue;
- }
- if (stuff->grab_type == XIGrabtypeTouchBegin &&
- (stuff->grab_mode != XIGrabModeTouch ||
- stuff->paired_device_mode != GrabModeAsync)) {
- client->errorValue = stuff->grab_mode;
- return BadValue;
- }
- if (XICheckInvalidMaskBits(client, (unsigned char *) &stuff[1],
- stuff->mask_len * 4) != Success)
- return BadValue;
- mask.xi2mask = xi2mask_new();
- if (!mask.xi2mask)
- return BadAlloc;
- mask_len = min(xi2mask_mask_size(mask.xi2mask), stuff->mask_len * 4);
- xi2mask_set_one_mask(mask.xi2mask, stuff->deviceid,
- (unsigned char *) &stuff[1], mask_len * 4);
- memset(¶m, 0, sizeof(param));
- param.grabtype = XI2;
- param.ownerEvents = stuff->owner_events;
- param.grabWindow = stuff->grab_window;
- param.cursor = stuff->cursor;
- if (IsKeyboardDevice(dev)) {
- param.this_device_mode = stuff->grab_mode;
- param.other_devices_mode = stuff->paired_device_mode;
- }
- else {
- param.this_device_mode = stuff->paired_device_mode;
- param.other_devices_mode = stuff->grab_mode;
- }
- if (stuff->cursor != None) {
- ret = dixLookupResourceByType(&tmp, stuff->cursor,
- RT_CURSOR, client, DixUseAccess);
- if (ret != Success) {
- client->errorValue = stuff->cursor;
- goto out;
- }
- }
- ret =
- dixLookupWindow((WindowPtr *) &tmp, stuff->grab_window, client,
- DixSetAttrAccess);
- if (ret != Success)
- goto out;
- ret = CheckGrabValues(client, ¶m);
- if (ret != Success)
- goto out;
- modifiers = (uint32_t *) &stuff[1] + stuff->mask_len;
- modifiers_failed =
- calloc(stuff->num_modifiers, sizeof(xXIGrabModifierInfo));
- if (!modifiers_failed) {
- ret = BadAlloc;
- goto out;
- }
- mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
- for (i = 0; i < stuff->num_modifiers; i++, modifiers++) {
- uint8_t status = Success;
- param.modifiers = *modifiers;
- ret = CheckGrabValues(client, ¶m);
- if (ret != Success)
- goto out;
- switch (stuff->grab_type) {
- case XIGrabtypeButton:
- status = GrabButton(client, dev, mod_dev, stuff->detail,
- ¶m, XI2, &mask);
- break;
- case XIGrabtypeKeycode:
- status = GrabKey(client, dev, mod_dev, stuff->detail,
- ¶m, XI2, &mask);
- break;
- case XIGrabtypeEnter:
- case XIGrabtypeFocusIn:
- status = GrabWindow(client, dev, stuff->grab_type, ¶m, &mask);
- break;
- case XIGrabtypeTouchBegin:
- status = GrabTouch(client, dev, mod_dev, ¶m, &mask);
- break;
- }
- if (status != GrabSuccess) {
- xXIGrabModifierInfo *info = modifiers_failed + rep.num_modifiers;
- info->status = status;
- info->modifiers = *modifiers;
- if (client->swapped)
- swapl(&info->modifiers);
- rep.num_modifiers++;
- rep.length += bytes_to_int32(sizeof(xXIGrabModifierInfo));
- }
- }
- WriteReplyToClient(client, sizeof(rep), &rep);
- if (rep.num_modifiers)
- WriteToClient(client, rep.length * 4, modifiers_failed);
- free(modifiers_failed);
- out:
- xi2mask_free(&mask.xi2mask);
- return ret;
- }
- void
- SRepXIPassiveGrabDevice(ClientPtr client, int size,
- xXIPassiveGrabDeviceReply * rep)
- {
- swaps(&rep->sequenceNumber);
- swapl(&rep->length);
- swaps(&rep->num_modifiers);
- WriteToClient(client, size, rep);
- }
- int
- SProcXIPassiveUngrabDevice(ClientPtr client)
- {
- int i;
- uint32_t *modifiers;
- REQUEST(xXIPassiveUngrabDeviceReq);
- REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq);
- swaps(&stuff->length);
- swapl(&stuff->grab_window);
- swaps(&stuff->deviceid);
- swapl(&stuff->detail);
- swaps(&stuff->num_modifiers);
- REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq,
- ((uint32_t) stuff->num_modifiers) << 2);
- modifiers = (uint32_t *) &stuff[1];
- for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
- swapl(modifiers);
- return ProcXIPassiveUngrabDevice(client);
- }
- int
- ProcXIPassiveUngrabDevice(ClientPtr client)
- {
- DeviceIntPtr dev, mod_dev;
- WindowPtr win;
- GrabPtr tempGrab;
- uint32_t *modifiers;
- int i, rc;
- REQUEST(xXIPassiveUngrabDeviceReq);
- REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq,
- ((uint32_t) stuff->num_modifiers) << 2);
- if (stuff->deviceid == XIAllDevices)
- dev = inputInfo.all_devices;
- else if (stuff->deviceid == XIAllMasterDevices)
- dev = inputInfo.all_master_devices;
- else {
- rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
- if (rc != Success)
- return rc;
- }
- if (stuff->grab_type != XIGrabtypeButton &&
- stuff->grab_type != XIGrabtypeKeycode &&
- stuff->grab_type != XIGrabtypeEnter &&
- stuff->grab_type != XIGrabtypeFocusIn &&
- stuff->grab_type != XIGrabtypeTouchBegin) {
- client->errorValue = stuff->grab_type;
- return BadValue;
- }
- if ((stuff->grab_type == XIGrabtypeEnter ||
- stuff->grab_type == XIGrabtypeFocusIn ||
- stuff->grab_type == XIGrabtypeTouchBegin) && stuff->detail != 0) {
- client->errorValue = stuff->detail;
- return BadValue;
- }
- rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess);
- if (rc != Success)
- return rc;
- mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
- tempGrab = AllocGrab(NULL);
- if (!tempGrab)
- return BadAlloc;
- tempGrab->resource = client->clientAsMask;
- tempGrab->device = dev;
- tempGrab->window = win;
- switch (stuff->grab_type) {
- case XIGrabtypeButton:
- tempGrab->type = XI_ButtonPress;
- break;
- case XIGrabtypeKeycode:
- tempGrab->type = XI_KeyPress;
- break;
- case XIGrabtypeEnter:
- tempGrab->type = XI_Enter;
- break;
- case XIGrabtypeFocusIn:
- tempGrab->type = XI_FocusIn;
- break;
- case XIGrabtypeTouchBegin:
- tempGrab->type = XI_TouchBegin;
- break;
- }
- tempGrab->grabtype = XI2;
- tempGrab->modifierDevice = mod_dev;
- tempGrab->modifiersDetail.pMask = NULL;
- tempGrab->detail.exact = stuff->detail;
- tempGrab->detail.pMask = NULL;
- modifiers = (uint32_t *) &stuff[1];
- for (i = 0; i < stuff->num_modifiers; i++, modifiers++) {
- tempGrab->modifiersDetail.exact = *modifiers;
- DeletePassiveGrabFromList(tempGrab);
- }
- FreeGrab(tempGrab);
- return Success;
- }
|