summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Xi/exevents.c41
-rw-r--r--dix/devices.c2
-rw-r--r--include/inputstr.h2
3 files changed, 23 insertions, 22 deletions
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 4736a1284..d59a87d1a 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -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)
diff --git a/dix/devices.c b/dix/devices.c
index 3581cde8f..91a43f342 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -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
diff --git a/include/inputstr.h b/include/inputstr.h
index 11fe031a0..4c7ec2eb9 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -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;