xserver: Branch 'master' - 2 commits

Peter Hutterer whot at kemper.freedesktop.org
Thu Jun 19 05:37:47 PDT 2008


 Xi/exevents.c      |   41 +++++++++++++++++++++--------------------
 dix/devices.c      |    2 +-
 dix/events.c       |    3 +++
 include/inputstr.h |    2 +-
 4 files changed, 26 insertions(+), 22 deletions(-)

New commits:
commit cfcb3da75e807dec225cc7ea469e04d2db10bf73
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Jun 18 11:37:00 2008 -0700

    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 <daniel at fooishbar.org>
    Signed-off-by: Peter Hutterer <peter at cs.unisa.edu.au>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 4736a12..d59a87d 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 3581cde..91a43f3 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 11fe031..4c7ec2e 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;
commit 3cc5ae6a4f725483612c00fc8bcc2c61607f66a8
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Wed Jun 18 16:14:42 2008 +0930

    dix: don't attempt to send Enter/Leave events if we have a keyboard.
    
    Dereferencing into dev->valuator could crash the server, although it looks
    like I could only reproduce this by having a keyboard send an event after it
    was created and the WM was still replaying. Or so.

diff --git a/dix/events.c b/dix/events.c
index 4e11bda..7bd6825 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -4583,6 +4583,9 @@ DoEnterLeaveEvents(DeviceIntPtr pDev,
         WindowPtr toWin,
         int mode)
 {
+    if (!IsPointerDevice(pDev))
+        return;
+
     if (fromWin == toWin)
 	return;
     if (IsParent(fromWin, toWin))


More information about the xorg-commit mailing list