diff options
author | Daniel Stone <daniel@fooishbar.org> | 2011-12-14 15:45:19 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2011-12-21 12:38:35 +1000 |
commit | d2af968cb65873780a6e61342d5d3c23b9654e2a (patch) | |
tree | bcfb8b871b938054e7ff56d8e7bdc211f53a3d87 /Xi/xiselectev.c | |
parent | f3df3ad668fcd417ffb5afa3bea79a73a348bc1a (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.c | 43 |
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; |