xserver: Branch 'master' - 4 commits

Keith Packard keithp at kemper.freedesktop.org
Wed Oct 19 17:29:15 PDT 2011


 dix/getevents.c                        |   32 +++++++++++++++++++++--------
 dix/inpututils.c                       |   36 +++++++++++++++++++++++++++++++++
 hw/xfree86/common/xf86Events.c         |    9 +++-----
 hw/xfree86/os-support/linux/lnx_init.c |   14 +++++-------
 include/input.h                        |    4 +++
 test/input.c                           |   15 ++++++++++++-
 6 files changed, 87 insertions(+), 23 deletions(-)

New commits:
commit 15bbdc103b34b6b374815698946e6c409421a644
Merge: a5266dc... 323869f...
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Oct 19 17:26:50 2011 -0700

    Merge remote-tracking branch 'whot/for-keith'

commit 323869f3298cbbfe864af9404a8aed1bf7995d79
Author: Tomáš Trnka <tomastrnka at gmx.com>
Date:   Tue Oct 11 09:11:18 2011 +0200

    Fix drain_console unregistration
    
    Bug introduced by 9dca441670d261a9a9fb6108960ed48f3d58fb7f
    xfree86: add a hook to replace the new console handler.
    
    console_handler was not being set, making the server eat up CPU spinning
    in WaitForSomething selecting consoleFd over and over again, every time
    trying to unregister drain_console without success due to
    console_handler being NULL.
    
    Let's just fix the unregistration in xf86SetConsoleHandler() and use that.
    
    But wait, there could be a catch: If some driver replaced the handler using
    xf86SetConsoleHandler(), the unregistration in xf86CloseConsole will unregister
    that one. I don't understand Xorg well enough to know whether this poses a
    problem (could mess up driver deinit somehow or something like that). As it is,
    xf86SetConsoleHandler() doesn't offer any way to prevent this (i.e. check which
    handler is currently registered).
    
    I had been using it for two days on my machine that previously hit 100% CPU
    several times a day. That has now gone away without any new problems appearing.
    
    Signed-off-by: Tomas Trnka <tomastrnka at gmx.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/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index c4a4db9..41ffabd 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -601,16 +601,15 @@ xf86AddGeneralHandler(int fd, InputHandlerProc proc, pointer data)
 InputHandlerProc
 xf86SetConsoleHandler(InputHandlerProc proc, pointer data)
 {
-    static InputHandlerProc handler = NULL;
-    InputHandlerProc old_handler = handler;
+    static IHPtr handler = NULL;
+    IHPtr old_handler = handler;
 
     if (old_handler)
         xf86RemoveGeneralHandler(old_handler);
 
-    xf86AddGeneralHandler(xf86Info.consoleFd, proc, data);
-    handler = proc;
+    handler = xf86AddGeneralHandler(xf86Info.consoleFd, proc, data);
 
-    return old_handler;
+    return (old_handler) ? old_handler->ihproc : NULL;
 }
 
 static void
diff --git a/hw/xfree86/os-support/linux/lnx_init.c b/hw/xfree86/os-support/linux/lnx_init.c
index 9c91740..f18271f 100644
--- a/hw/xfree86/os-support/linux/lnx_init.c
+++ b/hw/xfree86/os-support/linux/lnx_init.c
@@ -45,15 +45,12 @@ static char vtname[11];
 static struct termios tty_attr; /* tty state to restore */
 static int tty_mode; /* kbd mode to restore */
 
-static void *console_handler;
-
 static void
 drain_console(int fd, void *closure)
 {
     errno = 0;
     if (tcflush(fd, TCIOFLUSH) == -1 && errno == EIO) {
-	xf86RemoveGeneralHandler(console_handler);
-	console_handler = NULL;
+        xf86SetConsoleHandler(NULL, NULL);
     }
 }
 
@@ -257,10 +254,11 @@ xf86CloseConsole(void)
         return;
     }
 
-    if (console_handler) {
-	xf86RemoveGeneralHandler(console_handler);
-	console_handler = NULL;
-    };
+    /*
+     * unregister the drain_console handler
+     * - what to do if someone else changed it in the meantime?
+     */
+    xf86SetConsoleHandler(NULL, NULL);
 
     /* Back to text mode ... */
     SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT));
commit 2cb63180fa9b54f763e7e92e433943e3e73741f3
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Oct 5 12:08:31 2011 +1000

    dix: mark motion events as emulated if we're scrolling from button press
    
    The protocol requires that the emulated event is marked as such. So if a
    driver with smooth scrolling axis sends legacy button events, the motion
    event must be marked as emulated.
    
    Pass the real type to emulate_scroll_button_events and create the events
    accordingly. For real button press or relase events, only that event must be
    generated since a release event will follow or a press event has already
    occured, respectively. (This fixes a bug where we'd get two release events
    for each legacy button event)
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/dix/getevents.c b/dix/getevents.c
index 874189f..7be39dc 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1228,6 +1228,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
  *
  * @param events The pointer to the event list to fill the events
  * @param dev The device to generate the events for
+ * @param type The real type of the event
  * @param axis The axis number to generate events for
  * @param mask State before this event in absolute coords
  * @param[in,out] last Last scroll state posted in absolute coords (modified
@@ -1239,6 +1240,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
 static int
 emulate_scroll_button_events(InternalEvent *events,
                              DeviceIntPtr dev,
+                             int type,
                              int axis,
                              const ValuatorMask *mask,
                              ValuatorMask *last,
@@ -1251,6 +1253,7 @@ emulate_scroll_button_events(InternalEvent *events,
     int num_events = 0;
     double total;
     int b;
+    int flags = 0;
 
     if (dev->valuator->axes[axis].scroll.type == SCROLL_TYPE_NONE)
         return 0;
@@ -1261,6 +1264,9 @@ emulate_scroll_button_events(InternalEvent *events,
     ax = &dev->valuator->axes[axis];
     incr = ax->scroll.increment;
 
+    if (type != ButtonPress && type != ButtonRelease)
+        flags |= POINTER_EMULATED;
+
     if (!valuator_mask_isset(last, axis))
         valuator_mask_set_double(last, axis, 0);
 
@@ -1288,14 +1294,20 @@ emulate_scroll_button_events(InternalEvent *events,
          */
         if (num_events + 4 < max_events)
         {
-            nev_tmp = fill_pointer_events(events, dev, ButtonPress, b, ms,
-                                          POINTER_EMULATED, NULL);
-            events += nev_tmp;
-            num_events += nev_tmp;
-            nev_tmp = fill_pointer_events(events, dev, ButtonRelease, b, ms,
-                                          POINTER_EMULATED, NULL);
-            events += nev_tmp;
-            num_events += nev_tmp;
+            if (type != ButtonRelease)
+            {
+                nev_tmp = fill_pointer_events(events, dev, ButtonPress, b, ms,
+                                              flags, NULL);
+                events += nev_tmp;
+                num_events += nev_tmp;
+            }
+            if (type != ButtonPress)
+            {
+                nev_tmp = fill_pointer_events(events, dev, ButtonRelease, b, ms,
+                                              flags, NULL);
+                events += nev_tmp;
+                num_events += nev_tmp;
+            }
         }
     }
 
@@ -1340,6 +1352,7 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
     ValuatorMask mask;
     ValuatorMask scroll;
     int i;
+    int realtype = type;
 
     /* refuse events from disabled devices */
     if (!pDev->enabled)
@@ -1392,6 +1405,7 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
             valuator_mask_set_double(&mask, axis, val);
             type = MotionNotify;
             buttons = 0;
+            flags |= POINTER_EMULATED;
         }
     }
 
@@ -1411,7 +1425,7 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
 
         valuator_mask_set_double(&scroll, i, pDev->last.valuators[i]);
 
-        nev_tmp = emulate_scroll_button_events(events, pDev, i, &scroll,
+        nev_tmp = emulate_scroll_button_events(events, pDev, realtype, i, &scroll,
                                                pDev->last.scroll, ms,
                                                GetMaximumEventsNum() - num_events);
         events += nev_tmp;
commit 82c60232c07f50774ccc0198950f64c9338057a5
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Sep 30 10:59:47 2011 +1000

    dix: add valuator_mask_fetch_double()
    
    Using this call simplifies callers that don't know if the mask bit is set.
    
    Before:
      if (valuator_mask_isset(mask, valnum))
        value = valuator_mask_get_double(mask, valnum));
      else
        value = someothervalue;
    
    Now:
     if (!valuator_mask_fetch_double(mask, valnum, &value))
        value = someothervalue;
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/dix/inpututils.c b/dix/inpututils.c
index eeae2a7..c27894b 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -539,6 +539,42 @@ valuator_mask_get(const ValuatorMask *mask, int valuator)
 }
 
 /**
+ * Set value to the requested valuator. If the mask bit is set for this
+ * valuator, value contains the requested valuator value and TRUE is
+ * returned.
+ * If the mask bit is not set for this valuator, value is unchanged and
+ * FALSE is returned.
+ */
+Bool
+valuator_mask_fetch_double(const ValuatorMask *mask, int valuator, double *value)
+{
+    if (valuator_mask_isset(mask, valuator))
+    {
+        *value = valuator_mask_get_double(mask, valuator);
+        return TRUE;
+    } else
+        return FALSE;
+}
+
+/**
+ * Set value to the requested valuator. If the mask bit is set for this
+ * valuator, value contains the requested valuator value and TRUE is
+ * returned.
+ * If the mask bit is not set for this valuator, value is unchanged and
+ * FALSE is returned.
+ */
+Bool
+valuator_mask_fetch(const ValuatorMask *mask, int valuator, int *value)
+{
+    if (valuator_mask_isset(mask, valuator))
+    {
+        *value = valuator_mask_get(mask, valuator);
+        return TRUE;
+    } else
+        return FALSE;
+}
+
+/**
  * Remove the valuator from the mask.
  */
 void
diff --git a/include/input.h b/include/input.h
index b7de5ca..a1930bb 100644
--- a/include/input.h
+++ b/include/input.h
@@ -597,6 +597,10 @@ extern _X_EXPORT void valuator_mask_copy(ValuatorMask *dest,
 extern _X_EXPORT int valuator_mask_get(const ValuatorMask *mask, int valnum);
 extern _X_EXPORT double valuator_mask_get_double(const ValuatorMask *mask,
                                                  int valnum);
+extern _X_EXPORT Bool valuator_mask_fetch(const ValuatorMask *mask,
+                                          int valnum, int *val);
+extern _X_EXPORT Bool valuator_mask_fetch_double(const ValuatorMask *mask,
+                                                 int valnum, double *val);
 
 /* InputOption handling interface */
 extern _X_EXPORT InputOption* input_option_new(InputOption *list, const char *key, const char *value);
diff --git a/test/input.c b/test/input.c
index afc4d4d..5fb9a90 100644
--- a/test/input.c
+++ b/test/input.c
@@ -1199,14 +1199,19 @@ static void dix_input_valuator_masks(void)
     assert(valuator_mask_num_valuators(mask) == num_vals);
     for (i = 0; i < nvaluators; i++)
     {
+        double val;
         if (i < first_val || i >= first_val + num_vals)
+        {
             assert(!valuator_mask_isset(mask, i));
-        else
+            assert(!valuator_mask_fetch_double(mask, i, &val));
+        } else
         {
             assert(valuator_mask_isset(mask, i));
             assert(valuator_mask_get(mask, i) == val_ranged[i - first_val]);
             assert(valuator_mask_get_double(mask, i) ==
                     val_ranged[i - first_val]);
+            assert(valuator_mask_fetch_double(mask, i, &val));
+            assert(val_ranged[i - first_val] == val);
         }
     }
 
@@ -1218,10 +1223,18 @@ static void dix_input_valuator_masks(void)
 
     for (i = 0; i < nvaluators; i++)
     {
+        double a, b;
         assert(valuator_mask_isset(mask, i) == valuator_mask_isset(copy, i));
+
+        if (!valuator_mask_isset(mask, i))
+            continue;
+
         assert(valuator_mask_get(mask, i) == valuator_mask_get(copy, i));
         assert(valuator_mask_get_double(mask, i) ==
                 valuator_mask_get_double(copy, i));
+        assert(valuator_mask_fetch_double(mask, i, &a));
+        assert(valuator_mask_fetch_double(copy, i, &b));
+        assert(a == b);
     }
 
     valuator_mask_free(&mask);


More information about the xorg-commit mailing list