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>
This commit is contained in:
Daniel Stone 2011-12-14 15:45:19 +10:00 committed by Peter Hutterer
parent f3df3ad668
commit d2af968cb6

View File

@ -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;