xserver: Branch 'master' - 6 commits

Keith Packard keithp at kemper.freedesktop.org
Thu Aug 12 22:59:38 PDT 2010


 Xi/exevents.c                  |    6 ++
 dix/devices.c                  |    8 ---
 dix/getevents.c                |   10 ++--
 hw/xfree86/common/xf86Xinput.c |    3 -
 hw/xfree86/parser/Input.c      |    7 ++-
 hw/xfree86/parser/InputClass.c |    6 +-
 include/input.h                |    6 ++
 xkb/xkbActions.c               |   93 ++++++++++++++++++++++++++---------------
 8 files changed, 89 insertions(+), 50 deletions(-)

New commits:
commit 0af322858e86665ee43f065741318e69c2755510
Author: Keith Packard <keithp at keithp.com>
Date:   Thu Aug 12 22:56:36 2010 -0700

    Silence GCC warning about uninitialized lastSlave variable
    
    Not an actual bug, but gcc can't tell that this variable cannot be
    used without being initialized
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index 59c7fc5..8c75301 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1358,7 +1358,7 @@ InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, int nu
     ScreenPtr           pScreen;
     EventListPtr        events;
     int                 nevents, i;
-    DeviceIntPtr        ptr, mpointer, lastSlave;
+    DeviceIntPtr        ptr, mpointer, lastSlave = NULL;
     Bool                saveWait;
 
     if (IsMaster(dev)) {
commit b5cf9c5090d15a50b105470900823f2d398d4bd2
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Thu Aug 12 00:09:01 2010 -0700

    Stop checking or calling PtrCtrlProcs
    
    None of them do anything useful now that pointer acceleration is
    entirely handled in the server.   (Does not completely nuke yet,
    since that would be an API/ABI break.)
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/devices.c b/dix/devices.c
index ac5806a..2e65a04 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -2111,9 +2111,6 @@ ProcChangePointerControl(ClientPtr client)
     REQUEST(xChangePointerControlReq);
     REQUEST_SIZE_MATCH(xChangePointerControlReq);
 
-    if (!mouse->ptrfeed->CtrlProc)
-        return BadDevice;
-
     ctrl = mouse->ptrfeed->ctrl;
     if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) {
 	client->errorValue = stuff->doAccel;
@@ -2161,7 +2158,7 @@ ProcChangePointerControl(ClientPtr client)
 
     for (dev = inputInfo.devices; dev; dev = dev->next) {
         if ((dev == mouse || (!IsMaster(dev) && dev->u.master == mouse)) &&
-            dev->ptrfeed && dev->ptrfeed->CtrlProc) {
+            dev->ptrfeed) {
 	    rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess);
 	    if (rc != Success)
 		return rc;
@@ -2170,9 +2167,8 @@ ProcChangePointerControl(ClientPtr client)
 
     for (dev = inputInfo.devices; dev; dev = dev->next) {
         if ((dev == mouse || (!IsMaster(dev) && dev->u.master == mouse)) &&
-            dev->ptrfeed && dev->ptrfeed->CtrlProc) {
+            dev->ptrfeed) {
             dev->ptrfeed->ctrl = ctrl;
-            (*dev->ptrfeed->CtrlProc)(dev, &mouse->ptrfeed->ctrl);
         }
     }
 
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 76d2d00..bd77fe6 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -264,9 +264,6 @@ ApplyAccelerationSettings(DeviceIntPtr dev){
         if (i >= 0)
             dev->ptrfeed->ctrl.threshold = i;
 
-        /* mostly a no-op anyway */
-        (*dev->ptrfeed->CtrlProc)(dev, &dev->ptrfeed->ctrl);
-
         xf86Msg(X_CONFIG, "%s: (accel) acceleration factor: %.3f\n",
                             local->name, ((float)dev->ptrfeed->ctrl.num)/
                                          ((float)dev->ptrfeed->ctrl.den));
commit bce12f2956f23c0ee53f7f6485dba631293a0931
Author: Jesse Adkins <jesserayadkins at gmail.com>
Date:   Wed Aug 4 23:39:14 2010 -0700

    xfree86: parser: Never use constant strings for driver names (fixes #17438)
    
    When the parser sees the "keyboard" driver, it automatically (and
     silently) replaces it with the constant string "kbd".
    Everybody else uses malloc'd memory for the driver name, so input
     device closure assumes it can use free.
    Free val.str, so this crash doesn't turn into a memory leak. Whew.
    
    Signed-off-by: Jesse Adkins <jesserayadkins at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/parser/Input.c b/hw/xfree86/parser/Input.c
index 50869d4..faff0f4 100644
--- a/hw/xfree86/parser/Input.c
+++ b/hw/xfree86/parser/Input.c
@@ -59,6 +59,7 @@
 #include <xorg-config.h>
 #endif
 
+#include "os.h"
 #include "xf86Parser.h"
 #include "xf86tokens.h"
 #include "Configint.h"
@@ -102,8 +103,10 @@ xf86parseInputSection (void)
 		case DRIVER:
 			if (xf86getSubToken (&(ptr->inp_comment)) != STRING)
 				Error (QUOTE_MSG, "Driver");
-                        if (strcmp(val.str, "keyboard") == 0)
-                            ptr->inp_driver = "kbd";
+                        if (strcmp(val.str, "keyboard") == 0) {
+                            ptr->inp_driver = strdup("kbd");
+                            free(val.str);
+                        }
                         else
 			    ptr->inp_driver = val.str;
 			break;
diff --git a/hw/xfree86/parser/InputClass.c b/hw/xfree86/parser/InputClass.c
index ce611d9..9f88e7e 100644
--- a/hw/xfree86/parser/InputClass.c
+++ b/hw/xfree86/parser/InputClass.c
@@ -111,8 +111,10 @@ xf86parseInputClassSection(void)
         case DRIVER:
             if (xf86getSubToken(&(ptr->comment)) != STRING)
                 Error(QUOTE_MSG, "Driver");
-            if (strcmp(val.str, "keyboard") == 0)
-                ptr->driver = "kbd";
+            if (strcmp(val.str, "keyboard") == 0) {
+                ptr->driver = strdup("kbd");
+                free(val.str);
+            }
             else
                 ptr->driver = val.str;
             break;
commit 619ca32202cd22f2a408586cbc906b8bbaeb9358
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jul 28 15:08:27 2010 +1000

    Xi: reset the unused classes pointer after copying
    
    After copying the unused_classes into the device, reset the original
    pointer. Otherwise we have two pointers pointing to the same field and both
    get freed on device removal.
    
    Some classes already have this behaviour since 51c8fd69.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index e990aeb..e19e207 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -223,6 +223,7 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
         {
             classes = to->unused_classes;
             to->intfeed = classes->intfeed;
+            classes->intfeed = NULL;
         }
 
         i = &to->intfeed;
@@ -258,6 +259,7 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
         {
             classes = to->unused_classes;
             to->stringfeed = classes->stringfeed;
+            classes->stringfeed = NULL;
         }
 
         s = &to->stringfeed;
@@ -293,6 +295,7 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
         {
             classes = to->unused_classes;
             to->bell = classes->bell;
+            classes->bell = NULL;
         }
 
         b = &to->bell;
@@ -329,6 +332,7 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
         {
             classes = to->unused_classes;
             to->leds = classes->leds;
+            classes->leds = NULL;
         }
 
         l = &to->leds;
@@ -379,6 +383,7 @@ DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to)
             to->kbdfeed = classes->kbdfeed;
             if (!to->kbdfeed)
                 InitKeyboardDeviceStruct(to, NULL, NULL, NULL);
+            classes->kbdfeed = NULL;
         }
 
         k = &to->kbdfeed;
@@ -506,6 +511,7 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
         {
             classes = to->unused_classes;
             to->ptrfeed = classes->ptrfeed;
+            classes->ptrfeed = NULL;
         }
 
         p = &to->ptrfeed;
commit 1a172f3297369a72865232c382abfc14281102a4
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jul 23 13:24:34 2010 +1000

    xkb: if the button isn't down, don't fake an event.
    
    If the button we're about to fake isn't down (or up), don't fake a release
    (or press) event for it. Behaviour is the same as before, this just saves
    a few cycles.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index c36dba0..59c7fc5 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1410,6 +1410,7 @@ void
 XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
 {
     DeviceIntPtr        ptr;
+    int                 down;
 
     /* If dev is a slave device, and the SD is attached, do nothing. If we'd
      * post through the attached master pointer we'd get duplicate events.
@@ -1427,6 +1428,10 @@ XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
     else
         return;
 
+    down = button_is_down(ptr, button, BUTTON_PROCESSED);
+    if (press == down)
+        return;
+
     InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease,
                            button, 0, 0, NULL);
 }
commit 651c36e95ec0ac60d3fb98966df4218712ae78c2
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jul 23 11:46:30 2010 +1000

    xkb: post-fix PointerKeys button events with a DeviceChangedEvent.
    
    commit 14327858391ebe929b806efb53ad79e789361883
        xkb: release XTEST pointer buttons on physical releases. (#28808)
    revealed a bug with the XTEST/PointerKeys interaction.
    
    Events resulting from PointerKeys are injected into the event processing
    stream, not appended to the event queue. The events generated for the fake
    button press include a DeviceChangedEvent (DCE), a raw button event and the
    button event itself. The DCE causes the master to switch classes to the
    attached XTEST pointer device.
    
    Once the fake button is processed, normal event processing continues with
    events in the EQ. The master still contains the XTEST classes, causing some
    events to be dropped if e.g. the number of valuators of the event in the
    queue exceeds the XTEST device's number of valuators.
    
    Example: the EQ contains the following events, processed one-by-one, left to
    right.
    
    [DCE (dev)][Btn down][Btn up][Motion][Motion][...]
                      ^ XkbFakeDeviceButton injects [DCE (XTEST)][Btn up]
    
    Thus the event sequence processed looks like this:
    
    [DCE (dev)][Btn down][Btn up][DCE (XTEST)][Btn up][Motion][Motion][...]
    
    The first DCE causes the master to switch to the device. The button up event
    injects a DCE to the XTEST device, causing the following Motion events to be
    processed with the master still being on XTEST classes.
    
    This patch post-fixes the injected event sequence with a DCE to restore the
    classes of the original slave device, resulting in an event sequence like
    this:
    [DCE (dev)][Btn down][Btn up][DCE (XTEST)][Btn up][DCE (dev)][Motion][Motion]
    
    Note that this is a simplified description. The event sequence injected by
    the PointerKeys code is injected for the master device only and the matching
    slave device that caused the injection has already finished processing on
    the slave. Furthermore, the injection happens as part of the the XKB layer,
    before the unwrapping of the processInputProc takes us into the DIX where
    the DCE is actually handled.
    
    Bug reproducible with a device that reports more than 2 valuators. Simply
    cause button releases on the device and wait for a "too many valuators"
    warning message.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Acked-by: Daniel Stone <daniel at fooishbar.org>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/getevents.c b/dix/getevents.c
index a9b6e82..20bcf7e 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -652,8 +652,8 @@ clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators,
  *        events if a DCCE was generated.
  * @return The updated @events pointer.
  */
-static EventListPtr
-updateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_events)
+EventListPtr
+UpdateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_events)
 {
     DeviceIntPtr master;
 
@@ -929,7 +929,7 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
 
     num_events = 1;
 
-    events = updateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT, &num_events);
+    events = UpdateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT, &num_events);
 
     /* Handle core repeating, via press/release/press/release. */
     if (type == KeyPress && key_is_down(pDev, key_code, KEY_POSTED)) {
@@ -1091,7 +1091,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         (type == MotionNotify && num_valuators <= 0))
         return 0;
 
-    events = updateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
+    events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
 
     raw = (RawDeviceEvent*)events->event;
     events++;
@@ -1206,7 +1206,7 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
         (num_valuators + first_valuator) > pDev->valuator->numAxes)
         return 0;
 
-    events = updateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
+    events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
 
     event = (DeviceEvent *) events->event;
     init_event(pDev, event, GetTimeInMillis());
diff --git a/include/input.h b/include/input.h
index 55b1537..ffb1c33 100644
--- a/include/input.h
+++ b/include/input.h
@@ -439,6 +439,12 @@ extern void CreateClassesChangedEvent(EventListPtr event,
                                       DeviceIntPtr master,
                                       DeviceIntPtr slave,
                                       int type);
+extern EventListPtr UpdateFromMaster(
+    EventListPtr events,
+    DeviceIntPtr pDev,
+    int type,
+    int *num_events);
+
 extern _X_EXPORT int GetPointerEvents(
     EventListPtr events,
     DeviceIntPtr pDev,
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index eea3d4a..c36dba0 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1332,35 +1332,53 @@ xkbStateNotify	sn;
     return;
 }
 
+/*
+ * The event is injected into the event processing, not the EQ. Thus,
+ * ensure that we restore the master after the event sequence to the
+ * original set of classes. Otherwise, the master remains on the XTEST
+ * classes and drops events that don't fit into the XTEST layout (e.g.
+ * events with more than 2 valuators).
+ *
+ * FIXME: EQ injection in the processing stage is not designed for, so this
+ * is a rather awkward hack. The event list returned by GetPointerEvents()
+ * and friends is always prefixed with a DCE if the last _posted_ device was
+ * different. For normal events, this sequence then resets the master during
+ * the processing stage. Since we inject the PointerKey events in the
+ * processing stage though, we need to manually reset to restore the
+ * previous order, because the events already in the EQ must be sent for the
+ * right device.
+ * So we post-fix the event list we get from GPE with a DCE back to the
+ * previous slave device.
+ *
+ * First one on drinking island wins!
+ */
 static void
-XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
+InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, int num_valuators, int *valuators)
 {
+    ScreenPtr           pScreen;
     EventListPtr        events;
     int                 nevents, i;
-    DeviceIntPtr        ptr;
-    ScreenPtr           pScreen;
+    DeviceIntPtr        ptr, mpointer, lastSlave;
     Bool                saveWait;
-    int                 gpe_flags = 0;
 
-    if (IsMaster(dev))
-        ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
-    else if (!dev->u.master)
+    if (IsMaster(dev)) {
+        mpointer = GetMaster(dev, MASTER_POINTER);
+        lastSlave = mpointer->u.lastSlave;
+        ptr = GetXTestDevice(mpointer);
+    } else if (!dev->u.master)
         ptr = dev;
     else
         return;
 
-    if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
-        gpe_flags = POINTER_ABSOLUTE;
-    else
-        gpe_flags = POINTER_RELATIVE;
 
-    events = InitEventList(GetMaximumEventsNum());
+    events = InitEventList(GetMaximumEventsNum() + 1);
     OsBlockSignals();
     pScreen = miPointerGetScreen(ptr);
     saveWait = miPointerSetWaitForUpdate(pScreen, FALSE);
-    nevents = GetPointerEvents(events, ptr,
-                               MotionNotify, 0,
-                               gpe_flags, 0, 2, (int[]){x, y});
+    nevents = GetPointerEvents(events, ptr, type, button, flags, 0,
+                               num_valuators, valuators);
+    if (IsMaster(dev) && (lastSlave && lastSlave != ptr))
+        UpdateFromMaster(&events[nevents], lastSlave, DEVCHANGE_POINTER_EVENT, &nevents);
     miPointerSetWaitForUpdate(pScreen, saveWait);
     OsReleaseSignals();
 
@@ -1368,13 +1386,29 @@ XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
         mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
 
     FreeEventList(events, GetMaximumEventsNum());
+
+}
+
+static void
+XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
+{
+    int                 gpe_flags = 0;
+
+    /* ignore attached SDs */
+    if (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) != NULL)
+        return;
+
+    if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
+        gpe_flags = POINTER_ABSOLUTE;
+    else
+        gpe_flags = POINTER_RELATIVE;
+
+    InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, 2, (int[]){x, y});
 }
 
 void
 XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
 {
-    EventListPtr        events;
-    int                 nevents, i;
     DeviceIntPtr        ptr;
 
     /* If dev is a slave device, and the SD is attached, do nothing. If we'd
@@ -1385,24 +1419,14 @@ XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
      * if dev is a floating slave, post through the device itself.
      */
 
-    if (IsMaster(dev))
-        ptr = GetXTestDevice(GetMaster(dev, MASTER_POINTER));
-    else if (!dev->u.master)
+    if (IsMaster(dev)) {
+        DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER);
+        ptr = GetXTestDevice(mpointer);
+    } else if (!dev->u.master)
         ptr = dev;
     else
         return;
 
-    events = InitEventList(GetMaximumEventsNum());
-    OsBlockSignals();
-    nevents = GetPointerEvents(events, ptr,
-                               press ? ButtonPress : ButtonRelease, button,
-                               0 /* flags */, 0 /* first */,
-                               0 /* num_val */, NULL);
-    OsReleaseSignals();
-
-
-    for (i = 0; i < nevents; i++)
-        mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
-
-    FreeEventList(events, GetMaximumEventsNum());
+    InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease,
+                           button, 0, 0, NULL);
 }


More information about the xorg-commit mailing list