Commit cfcb3da7 authored by Keith Packard's avatar Keith Packard Committed by Peter Hutterer

Make button down state a bitmask. Master buttons track union of slave buttons

Mixing usage where some parts of the code treated this field as a bitmask
and other parts as an array of card8 was wrong, and as the wire protocol
wanted bitmasks, it was less invasive to switch the newer counting code use
booleans.

Master devices track slave buttons by waiting for all slave buttons to be
released before delivering the release event to the client.

This also removes the state merging code in DeepCopyDeviceClasses -- that
code was changing master device state without delivering any events,
violating protocol invariants. The result will be that existing slave
button state which does not match the master will not be visible through the
master device. Fixing this would require that we synthesize events in this
function, which seems like a bad idea. Note that keyboards have the same
issue.
Signed-off-by: Daniel Stone's avatarDaniel Stone <daniel@fooishbar.org>
Signed-off-by: default avatarPeter Hutterer <peter@cs.unisa.edu.au>
parent 3cc5ae6a
......@@ -587,8 +587,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
if (from->button)
{
int i;
DeviceIntPtr sd;
if (!to->button)
{
classes = dixLookupPrivate(&to->devPrivates,
......@@ -603,20 +601,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
classes->button = NULL;
}
to->button->buttonsDown = 0;
memset(to->button->down, 0, MAP_LENGTH);
/* merge button states from all attached devices */
for (sd = inputInfo.devices; sd; sd = sd->next)
{
if (sd->isMaster || sd->u.master != to)
continue;
for (i = 0; i < MAP_LENGTH; i++)
{
to->button->down[i] += sd->button->down[i];
to->button->buttonsDown++;
}
}
#ifdef XKB
if (from->button->xkb_acts)
{
......@@ -923,8 +907,10 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
if (!b)
return DONT_PROCESS;
if (b->down[key]++ > 0)
kptr = &b->down[key >> 3];
if ((*kptr & bit) != 0)
return DONT_PROCESS;
*kptr |= bit;
if (device->valuator)
device->valuator->motionHintWindow = NullWindow;
b->buttonsDown++;
......@@ -938,10 +924,25 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
if (!b)
return DONT_PROCESS;
if (b->down[key] == 0)
return DONT_PROCESS;
if (--b->down[key] > 0)
kptr = &b->down[key>>3];
if (!(*kptr & bit))
return DONT_PROCESS;
if (device->isMaster) {
DeviceIntPtr sd;
/*
* Leave the button down if any slave has the
* button still down. Note that this depends on the
* event being delivered through the slave first
*/
for (sd = inputInfo.devices; sd; sd = sd->next) {
if (sd->isMaster || sd->u.master != device)
continue;
if ((sd->button->down[key>>3] & bit) != 0)
return DONT_PROCESS;
}
}
*kptr &= ~bit;
if (device->valuator)
device->valuator->motionHintWindow = NullWindow;
if (b->buttonsDown >= 1 && !--b->buttonsDown)
......
......@@ -1153,7 +1153,7 @@ InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons,
butc->buttonsDown = 0;
butc->state = 0;
butc->motionMask = 0;
bzero((char *)butc->down, MAP_LENGTH);
bzero((char *)butc->down, sizeof(butc->down));
#ifdef XKB
butc->xkb_acts= NULL;
#endif
......
......@@ -186,7 +186,7 @@ typedef struct _ButtonClassRec {
CARD8 buttonsDown; /* number of buttons currently down */
unsigned short state;
Mask motionMask;
CARD8 down[MAP_LENGTH];
CARD8 down[DOWN_LENGTH];
CARD8 map[MAP_LENGTH];
#ifdef XKB
union _XkbAction *xkb_acts;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment