xigrabdev.c revision 6747b715
16747b715Smrg/*
26747b715Smrg * Copyright © 2009 Red Hat, Inc.
36747b715Smrg *
46747b715Smrg * Permission is hereby granted, free of charge, to any person obtaining a
56747b715Smrg * copy of this software and associated documentation files (the "Software"),
66747b715Smrg * to deal in the Software without restriction, including without limitation
76747b715Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
86747b715Smrg * and/or sell copies of the Software, and to permit persons to whom the
96747b715Smrg * Software is furnished to do so, subject to the following conditions:
106747b715Smrg *
116747b715Smrg * The above copyright notice and this permission notice (including the next
126747b715Smrg * paragraph) shall be included in all copies or substantial portions of the
136747b715Smrg * Software.
146747b715Smrg *
156747b715Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
166747b715Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
176747b715Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
186747b715Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
196747b715Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
206747b715Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
216747b715Smrg * DEALINGS IN THE SOFTWARE.
226747b715Smrg *
236747b715Smrg * Author: Peter Hutterer
246747b715Smrg */
256747b715Smrg
266747b715Smrg/***********************************************************************
276747b715Smrg *
286747b715Smrg * Request to grab or ungrab input device.
296747b715Smrg *
306747b715Smrg */
316747b715Smrg
326747b715Smrg#ifdef HAVE_DIX_CONFIG_H
336747b715Smrg#include <dix-config.h>
346747b715Smrg#endif
356747b715Smrg
366747b715Smrg#include "inputstr.h"	/* DeviceIntPtr      */
376747b715Smrg#include "windowstr.h"	/* window structure  */
386747b715Smrg#include <X11/extensions/XI2.h>
396747b715Smrg#include <X11/extensions/XI2proto.h>
406747b715Smrg
416747b715Smrg#include "exglobals.h" /* BadDevice */
426747b715Smrg#include "exevents.h"
436747b715Smrg#include "xigrabdev.h"
446747b715Smrg
456747b715Smrgint
466747b715SmrgSProcXIGrabDevice(ClientPtr client)
476747b715Smrg{
486747b715Smrg    char n;
496747b715Smrg
506747b715Smrg    REQUEST(xXIGrabDeviceReq);
516747b715Smrg
526747b715Smrg    swaps(&stuff->length, n);
536747b715Smrg    swaps(&stuff->deviceid, n);
546747b715Smrg    swapl(&stuff->grab_window, n);
556747b715Smrg    swapl(&stuff->cursor, n);
566747b715Smrg    swapl(&stuff->time, n);
576747b715Smrg    swaps(&stuff->mask_len, n);
586747b715Smrg
596747b715Smrg    return ProcXIGrabDevice(client);
606747b715Smrg}
616747b715Smrg
626747b715Smrgint
636747b715SmrgProcXIGrabDevice(ClientPtr client)
646747b715Smrg{
656747b715Smrg    DeviceIntPtr dev;
666747b715Smrg    xXIGrabDeviceReply rep;
676747b715Smrg    int ret = Success;
686747b715Smrg    uint8_t status;
696747b715Smrg    GrabMask mask;
706747b715Smrg    int mask_len;
716747b715Smrg
726747b715Smrg    REQUEST(xXIGrabDeviceReq);
736747b715Smrg    REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq);
746747b715Smrg
756747b715Smrg    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
766747b715Smrg    if (ret != Success)
776747b715Smrg	return ret;
786747b715Smrg
796747b715Smrg    if (!IsMaster(dev))
806747b715Smrg        stuff->paired_device_mode = GrabModeAsync;
816747b715Smrg
826747b715Smrg    if (XICheckInvalidMaskBits((unsigned char*)&stuff[1],
836747b715Smrg                               stuff->mask_len * 4) != Success)
846747b715Smrg        return BadValue;
856747b715Smrg
866747b715Smrg    mask_len = min(sizeof(mask.xi2mask[stuff->deviceid]), stuff->mask_len * 4);
876747b715Smrg    memset(mask.xi2mask, 0, sizeof(mask.xi2mask));
886747b715Smrg    memcpy(mask.xi2mask, (char*)&stuff[1], mask_len);
896747b715Smrg
906747b715Smrg    ret = GrabDevice(client, dev, stuff->grab_mode,
916747b715Smrg                     stuff->paired_device_mode,
926747b715Smrg                     stuff->grab_window,
936747b715Smrg                     stuff->owner_events,
946747b715Smrg                     stuff->time,
956747b715Smrg                     &mask,
966747b715Smrg                     GRABTYPE_XI2,
976747b715Smrg                     stuff->cursor,
986747b715Smrg                     None /* confineTo */,
996747b715Smrg                     &status);
1006747b715Smrg
1016747b715Smrg    if (ret != Success)
1026747b715Smrg        return ret;
1036747b715Smrg
1046747b715Smrg    rep.repType = X_Reply;
1056747b715Smrg    rep.RepType = X_XIGrabDevice;
1066747b715Smrg    rep.length = 0;
1076747b715Smrg    rep.sequenceNumber = client->sequence;
1086747b715Smrg    rep.status = status;
1096747b715Smrg
1106747b715Smrg
1116747b715Smrg    WriteReplyToClient(client, sizeof(rep), &rep);
1126747b715Smrg    return ret;
1136747b715Smrg}
1146747b715Smrg
1156747b715Smrgint
1166747b715SmrgSProcXIUngrabDevice(ClientPtr client)
1176747b715Smrg{
1186747b715Smrg    char n;
1196747b715Smrg
1206747b715Smrg    REQUEST(xXIUngrabDeviceReq);
1216747b715Smrg
1226747b715Smrg    swaps(&stuff->length, n);
1236747b715Smrg    swaps(&stuff->deviceid, n);
1246747b715Smrg    swapl(&stuff->time, n);
1256747b715Smrg
1266747b715Smrg    return ProcXIUngrabDevice(client);
1276747b715Smrg}
1286747b715Smrg
1296747b715Smrgint
1306747b715SmrgProcXIUngrabDevice(ClientPtr client)
1316747b715Smrg{
1326747b715Smrg    DeviceIntPtr dev;
1336747b715Smrg    GrabPtr grab;
1346747b715Smrg    int ret = Success;
1356747b715Smrg    TimeStamp time;
1366747b715Smrg
1376747b715Smrg    REQUEST(xXIUngrabDeviceReq);
1386747b715Smrg
1396747b715Smrg    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
1406747b715Smrg    if (ret != Success)
1416747b715Smrg	return ret;
1426747b715Smrg
1436747b715Smrg    grab = dev->deviceGrab.grab;
1446747b715Smrg
1456747b715Smrg    time = ClientTimeToServerTime(stuff->time);
1466747b715Smrg    if ((CompareTimeStamps(time, currentTime) != LATER) &&
1476747b715Smrg	(CompareTimeStamps(time, dev->deviceGrab.grabTime) != EARLIER) &&
1486747b715Smrg	(grab) && SameClient(grab, client) && grab->grabtype == GRABTYPE_XI2)
1496747b715Smrg	(*dev->deviceGrab.DeactivateGrab) (dev);
1506747b715Smrg
1516747b715Smrg    return Success;
1526747b715Smrg}
1536747b715Smrg
1546747b715Smrgvoid SRepXIGrabDevice(ClientPtr client, int size, xXIGrabDeviceReply * rep)
1556747b715Smrg{
1566747b715Smrg    char n;
1576747b715Smrg
1586747b715Smrg    swaps(&rep->sequenceNumber, n);
1596747b715Smrg    swapl(&rep->length, n);
1606747b715Smrg    WriteToClient(client, size, (char *)rep);
1616747b715Smrg}
162