summaryrefslogtreecommitdiff
path: root/Xi/xiselectev.c
diff options
context:
space:
mode:
authorDaniel Stone <daniel@fooishbar.org>2011-12-14 15:45:19 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2011-12-21 12:38:35 +1000
commitd2af968cb65873780a6e61342d5d3c23b9654e2a (patch)
treebcfb8b871b938054e7ff56d8e7bdc211f53a3d87 /Xi/xiselectev.c
parentf3df3ad668fcd417ffb5afa3bea79a73a348bc1a (diff)
Xi: allow selecting for touch events
Selecting for any of XI_TouchBegin/Update/End/Ownership requires the three bits for begin/update/end to be set. Only one client at a time may select for XI_TouchBegin event Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
Diffstat (limited to 'Xi/xiselectev.c')
-rw-r--r--Xi/xiselectev.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c
index 815a34fc7..1b6c47a87 100644
--- a/Xi/xiselectev.c
+++ b/Xi/xiselectev.c
@@ -155,6 +155,49 @@ ProcXISelectEvents(ClientPtr client)
}
}
+ if (evmask->mask_len >= 1)
+ {
+ unsigned char *bits = (unsigned char*)&evmask[1];
+
+ /* All three touch events must be selected at once */
+ if ((BitIsOn(bits, XI_TouchBegin) ||
+ BitIsOn(bits, XI_TouchUpdate) ||
+ BitIsOn(bits, XI_TouchOwnership) ||
+ BitIsOn(bits, XI_TouchEnd)) &&
+ (!BitIsOn(bits, XI_TouchBegin) ||
+ !BitIsOn(bits, XI_TouchUpdate) ||
+ !BitIsOn(bits, XI_TouchEnd)))
+ {
+ client->errorValue = XI_TouchBegin;
+ return BadValue;
+ }
+
+ /* Only one client per window may select for touch events on the
+ * same devices, including master devices.
+ * XXX: This breaks if a device goes from floating to attached. */
+ if (BitIsOn(bits, XI_TouchBegin))
+ {
+ OtherInputMasks *inputMasks = wOtherInputMasks(win);
+ InputClients *iclient = NULL;
+ if (inputMasks)
+ iclient = inputMasks->inputClients;
+ for (; iclient; iclient = iclient->next)
+ {
+ DeviceIntPtr dummy;
+
+ if (CLIENT_ID(iclient->resource) == client->index)
+ continue;
+
+ dixLookupDevice(&dummy, evmask->deviceid, serverClient, DixReadAccess);
+ if (!dummy)
+ return BadImplementation; /* this shouldn't happen */
+
+ if (xi2mask_isset(iclient->xi2mask, dummy, XI_TouchBegin))
+ return BadAccess;
+ }
+ }
+ }
+
if (XICheckInvalidMaskBits(client, (unsigned char*)&evmask[1],
evmask->mask_len * 4) != Success)
return BadValue;