Merge branch 'touch-selection-conflict-fixes' into for-keith
This commit is contained in:
commit
f961c3a3b9
|
@ -36,6 +36,57 @@
|
|||
|
||||
#include "xiselectev.h"
|
||||
|
||||
/**
|
||||
* Ruleset:
|
||||
* - if A has XIAllDevices, B may select on device X
|
||||
* - If A has XIAllDevices, B may select on XIAllMasterDevices
|
||||
* - If A has XIAllMasterDevices, B may select on device X
|
||||
* - If A has XIAllMasterDevices, B may select on XIAllDevices
|
||||
* - if A has device X, B may select on XIAllDevices/XIAllMasterDevices
|
||||
*/
|
||||
static int check_for_touch_selection_conflicts(ClientPtr B, WindowPtr win, int deviceid)
|
||||
{
|
||||
OtherInputMasks *inputMasks = wOtherInputMasks(win);
|
||||
InputClients *A = NULL;
|
||||
|
||||
if (inputMasks)
|
||||
A = inputMasks->inputClients;
|
||||
for (; A; A = A->next) {
|
||||
DeviceIntPtr tmp;
|
||||
|
||||
if (CLIENT_ID(A->resource) == B->index)
|
||||
continue;
|
||||
|
||||
if (deviceid == XIAllDevices)
|
||||
tmp = inputInfo.all_devices;
|
||||
else if (deviceid == XIAllMasterDevices)
|
||||
tmp = inputInfo.all_master_devices;
|
||||
else
|
||||
dixLookupDevice(&tmp, deviceid, serverClient, DixReadAccess);
|
||||
if (!tmp)
|
||||
return BadImplementation; /* this shouldn't happen */
|
||||
|
||||
/* A has XIAllDevices */
|
||||
if (xi2mask_isset_for_device(A->xi2mask, inputInfo.all_devices, XI_TouchBegin)) {
|
||||
if (deviceid == XIAllDevices)
|
||||
return BadAccess;
|
||||
}
|
||||
|
||||
/* A has XIAllMasterDevices */
|
||||
if (xi2mask_isset_for_device(A->xi2mask, inputInfo.all_master_devices, XI_TouchBegin)) {
|
||||
if (deviceid == XIAllMasterDevices)
|
||||
return BadAccess;
|
||||
}
|
||||
|
||||
/* A has this device */
|
||||
if (xi2mask_isset_for_device(A->xi2mask, tmp, XI_TouchBegin))
|
||||
return BadAccess;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check the given mask (in len bytes) for invalid mask bits.
|
||||
* Invalid mask bits are any bits above XI2LastEvent.
|
||||
|
@ -169,30 +220,11 @@ ProcXISelectEvents(ClientPtr client)
|
|||
* 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 tmp;
|
||||
|
||||
if (CLIENT_ID(iclient->resource) == client->index)
|
||||
continue;
|
||||
|
||||
if (evmask->deviceid == XIAllDevices)
|
||||
tmp = inputInfo.all_devices;
|
||||
else if (evmask->deviceid == XIAllMasterDevices)
|
||||
tmp = inputInfo.all_master_devices;
|
||||
else
|
||||
dixLookupDevice(&tmp, evmask->deviceid, serverClient,
|
||||
DixReadAccess);
|
||||
if (!tmp)
|
||||
return BadImplementation; /* this shouldn't happen */
|
||||
|
||||
if (xi2mask_isset(iclient->xi2mask, tmp, XI_TouchBegin))
|
||||
return BadAccess;
|
||||
}
|
||||
rc = check_for_touch_selection_conflicts(client,
|
||||
win,
|
||||
evmask->deviceid);
|
||||
if (rc != Success)
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1015,6 +1015,21 @@ xi2mask_free(XI2Mask **mask)
|
|||
*mask = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the bit for event type is set for this device only.
|
||||
*
|
||||
* @return TRUE if the bit is set, FALSE otherwise
|
||||
*/
|
||||
Bool
|
||||
xi2mask_isset_for_device(XI2Mask *mask, const DeviceIntPtr dev, int event_type)
|
||||
{
|
||||
BUG_WARN(dev->id < 0);
|
||||
BUG_WARN(dev->id >= mask->nmasks);
|
||||
BUG_WARN(bits_to_bytes(event_type + 1) > mask->mask_size);
|
||||
|
||||
return BitIsOn(mask->masks[dev->id], event_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the bit for event type is set for this device, or the
|
||||
* XIAllDevices/XIAllMasterDevices (if applicable) is set.
|
||||
|
@ -1026,15 +1041,12 @@ xi2mask_isset(XI2Mask *mask, const DeviceIntPtr dev, int event_type)
|
|||
{
|
||||
int set = 0;
|
||||
|
||||
BUG_WARN(dev->id < 0);
|
||||
BUG_WARN(dev->id >= mask->nmasks);
|
||||
BUG_WARN(bits_to_bytes(event_type + 1) > mask->mask_size);
|
||||
|
||||
set = ! !BitIsOn(mask->masks[XIAllDevices], event_type);
|
||||
if (!set)
|
||||
set = ! !BitIsOn(mask->masks[dev->id], event_type);
|
||||
if (!set && IsMaster(dev))
|
||||
set = ! !BitIsOn(mask->masks[XIAllMasterDevices], event_type);
|
||||
if (xi2mask_isset_for_device(mask, inputInfo.all_devices, event_type))
|
||||
set = 1;
|
||||
else if (xi2mask_isset_for_device(mask, dev, event_type))
|
||||
set = 1;
|
||||
else if (IsMaster(dev) && xi2mask_isset_for_device(mask, inputInfo.all_master_devices, event_type))
|
||||
set = 1;
|
||||
|
||||
return set;
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ XI2Mask *xi2mask_new(void);
|
|||
XI2Mask *xi2mask_new_with_size(size_t, size_t); /* don't use it */
|
||||
void xi2mask_free(XI2Mask **mask);
|
||||
Bool xi2mask_isset(XI2Mask *mask, const DeviceIntPtr dev, int event_type);
|
||||
Bool xi2mask_isset_for_device(XI2Mask *mask, const DeviceIntPtr dev, int event_type);
|
||||
void xi2mask_set(XI2Mask *mask, int deviceid, int event_type);
|
||||
void xi2mask_zero(XI2Mask *mask, int deviceid);
|
||||
void xi2mask_merge(XI2Mask *dest, const XI2Mask *source);
|
||||
|
|
|
@ -36,8 +36,14 @@ xi2mask_test(void)
|
|||
XI2Mask *xi2mask = NULL, *mergemask = NULL;
|
||||
unsigned char *mask;
|
||||
DeviceIntRec dev;
|
||||
DeviceIntRec all_devices, all_master_devices;
|
||||
int i;
|
||||
|
||||
all_devices.id = XIAllDevices;
|
||||
inputInfo.all_devices = &all_devices;
|
||||
all_master_devices.id = XIAllMasterDevices;
|
||||
inputInfo.all_master_devices = &all_master_devices;
|
||||
|
||||
/* size >= nmasks * 2 for the test cases below */
|
||||
xi2mask = xi2mask_new_with_size(MAXDEVICES + 2, (MAXDEVICES + 2) * 2);
|
||||
assert(xi2mask);
|
||||
|
|
Loading…
Reference in New Issue