[PATCH] dix: Add scaling of X and Y on the reported pointer-events

Magnus Vigerlöf Magnus.Vigerlof at home.se
Thu Dec 27 08:24:42 PST 2007


Add back the support for scaling the reported X and Y axis
when reporting Motion- and Button-events. The two axis will
only be scaled if there is a max-value that is not -1.

Relative motion reports will use the last coordinates from
the InputDevice if it translates into the same position as
the core pointer to preseve the subpixel motion.
---
We're getting more and more people who would like to see this
scaling back, so if the following patch (or something like it)
could be applied it would be very much appreciated.

Comments about the previous patch (which doesn't include min-
values in the calculation) can be found here:
http://lists.freedesktop.org/archives/xorg/2007-December/031199.html

Cheers
 Magnus

 dix/getevents.c |   59 ++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/dix/getevents.c b/dix/getevents.c
index 6e840d4..1cb2595 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -528,6 +528,7 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
     DeviceIntPtr cp = inputInfo.pointer;
     int x = 0, y = 0;
     Bool coreOnly = (pDev == inputInfo.pointer);
+    ScreenPtr scr = miPointerGetScreen(pDev);
 
     /* Sanity checks. */
     if (type != MotionNotify && type != ButtonPress && type != ButtonRelease)
@@ -593,15 +594,35 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
                               valuators);
 
         if (pDev->coreEvents) {
-            if (first_valuator == 0 && num_valuators >= 1)
-                x = cp->valuator->lastx + valuators[0];
+            /* Get and convert the core pointer coordinate space into
+             * device coordinates. Use the device coords if it translates
+             * into the same position as the core to preserve relative sub-
+             * pixel movements from the device. */
+            int min = pDev->valuator->axes[0].min_value;
+            int max = pDev->valuator->axes[0].max_value;
+            if(max > 0) {
+                x = pDev->valuator->lastx;
+                if((int)((float)(x-min)*scr->width/(max-min+1)) != cp->valuator->lastx)
+                    x = (int)((float)(cp->valuator->lastx)*(max-min+1)/scr->width)+min;
+            }
             else
                 x = cp->valuator->lastx;
 
-            if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
-                y = cp->valuator->lasty + valuators[1 - first_valuator];
+            min = pDev->valuator->axes[1].min_value;
+            max = pDev->valuator->axes[1].max_value;
+            if(max > 0) {
+                y = pDev->valuator->lasty;
+                if((int)((float)(y-min)*scr->height/(max-min+1)) != cp->valuator->lasty)
+                    y = (int)((float)(cp->valuator->lasty)*(max-min+1)/scr->height)+min;
+            }
             else
                 y = cp->valuator->lasty;
+
+            /* Add relative movement */
+            if (first_valuator == 0 && num_valuators >= 1)
+                x += valuators[0];
+            if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
+                y += valuators[1 - first_valuator];
         }
         else {
             if (first_valuator == 0 && num_valuators >= 1)
@@ -620,11 +641,6 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
     clipAxis(pDev, 0, &x);
     clipAxis(pDev, 1, &y);
 
-    /* This takes care of crossing screens for us, as well as clipping
-     * to the current screen.  Right now, we only have one history buffer,
-     * so we don't set this for both the device and core.*/
-    miPointerSetPosition(pDev, &x, &y, ms);
-
     /* Drop x and y back into the valuators list, if they were originally
      * present. */
     if (first_valuator == 0 && num_valuators >= 1)
@@ -634,12 +650,29 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
 
     updateMotionHistory(pDev, ms, first_valuator, num_valuators, valuators);
 
+    pDev->valuator->lastx = x;
+    pDev->valuator->lasty = y;
+    /* Convert the dev coord back to screen coord if we're
+     * sending core events */
+    if (pDev->coreEvents) {
+        AxisInfoPtr ax = pDev->valuator->axes;
+        if(ax[0].max_value > 0)
+            x = (int)((float)(x-ax[0].min_value)*scr->width/
+                  (ax[0].max_value-ax[0].min_value+1));
+        if(ax[1].max_value > 0)
+            y = (int)((float)(y-ax[1].min_value)*scr->height/
+                  (ax[1].max_value-ax[1].min_value+1));
+    }
+
+    /* This takes care of crossing screens for us, as well as clipping
+     * to the current screen.  Right now, we only have one history buffer,
+     * so we don't set this for both the device and core.*/
+    miPointerSetPosition(pDev, &x, &y, ms);
+
     if (pDev->coreEvents) {
         cp->valuator->lastx = x;
         cp->valuator->lasty = y;
     }
-    pDev->valuator->lastx = x;
-    pDev->valuator->lasty = y;
 
     /* for some reason inputInfo.pointer does not have coreEvents set */
     if (coreOnly || pDev->coreEvents) {
@@ -677,8 +710,8 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
             kbp->detail = pDev->button->map[buttons];
         }
 
-        kbp->root_x = x;
-        kbp->root_y = y;
+        kbp->root_x = pDev->valuator->lastx;
+        kbp->root_y = pDev->valuator->lasty;
 
         events++;
         if (num_valuators) {
-- 
1.5.2.5




More information about the xorg mailing list