diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2009-02-23 15:58:07 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2009-03-20 15:17:55 +1000 |
commit | 8b6a370058ad5a20e0a0e49ec9443daf03775de8 (patch) | |
tree | 9c681008defdd3226fbd50cd7c44aff392298ccf /Xi/xiselectev.c | |
parent | 38bba0c1b75b84e8bbdfa7975cf701a9414a3afd (diff) |
Add XI2 masks and XISelectEvent() request handling.
XI2 event masks are simply stored in the OtherEventMasks as a separate field.
This replaces the XiSelectEvent code.
Diffstat (limited to 'Xi/xiselectev.c')
-rw-r--r-- | Xi/xiselectev.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c new file mode 100644 index 000000000..87811dc2d --- /dev/null +++ b/Xi/xiselectev.c @@ -0,0 +1,121 @@ +/* + * Copyright 2008 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 + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + + +#include "dixstruct.h" +#include "windowstr.h" +#include "exglobals.h" +#include "exevents.h" +#include <X11/extensions/XI2proto.h> + +#include "xiselectev.h" + +int +SProcXISelectEvent(ClientPtr client) +{ + char n; + int i; + xXIDeviceEventMask* evmask; + uint16_t *evtype; + + REQUEST(xXISelectEventsReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xXISelectEventsReq); + swapl(&stuff->window, n); + swaps(&stuff->num_masks, n); + + evmask = (xXIDeviceEventMask*)&stuff[1]; + for (i = 0; i < stuff->num_masks; i++) + { + swaps(&evmask->deviceid, n); + swaps(&evmask->mask_len, n); + evmask = (xXIDeviceEventMask*)(((char*)evtype) + evmask->mask_len * 4); + } + + return (ProcXISelectEvent(client)); +} + +int +ProcXISelectEvent(ClientPtr client) +{ + int rc, num_masks, i; + WindowPtr win; + DeviceIntPtr dev; + xXIDeviceEventMask *evmask; + int *types = NULL; + + REQUEST(xXISelectEventsReq); + REQUEST_AT_LEAST_SIZE(xXISelectEventsReq); + + rc = dixLookupWindow(&win, stuff->window, client, DixReceiveAccess); + if (rc != Success) + return rc; + + /* check request validity */ + evmask = (xXIDeviceEventMask*)&stuff[1]; + num_masks = stuff->num_masks; + while(num_masks--) + { + if (evmask->deviceid != AllDevices && evmask->deviceid != AllMasterDevices) + rc = dixLookupDevice(&dev, evmask->deviceid, client, DixReadAccess); + else { + /* XXX: XACE here? */ + } + if (rc != Success) + return rc; + + + if ((evmask->mask_len * 4) > XI_LASTEVENT) + { + unsigned char *bits = (unsigned char*)&evmask[1]; + for (i = XI_LASTEVENT; i < evmask->mask_len * 4; i++) + { + if (BitIsOn(bits, i)) + return BadValue; + } + } + + evmask = (xXIDeviceEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4); + } + + /* Set masks on window */ + evmask = (xXIDeviceEventMask*)&stuff[1]; + num_masks = stuff->num_masks; + while(num_masks--) + { + dixLookupDevice(&dev, evmask->deviceid, client, DixReadAccess); + XISetEventMask(dev, win, client, evmask->mask_len * 4, (unsigned char*)&evmask[1]); + evmask = (xXIDeviceEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4); + } + + RecalculateDeliverableEvents(win); + + xfree(types); + return Success; +} |