[RFC] xserver: Reintroduction of scaling of x&y axis in dix:getevents (xf86PostMotionEvent)

Magnus Vigerlöf Magnus.Vigerlof at home.se
Tue Mar 13 14:48:17 PDT 2007


Hi,

I've rewrote my initial patch that added the calls for scaling the x&y axis
when reporting a motionevent with xf86PostMotionEvent (and others).

The patch below adds two function pointers to DeviceIntRec that will hold
the functions for conversion. These function pointers can be set when the
device is configured (DEVICE_INIT). If not set no scaling will take place
(as it is today).

The parameters for the scaling functions has been simplified from the
previous interface (same interface for both functions though):
* void convert(DeviceIntPtr pDev, int x, int y, int *convx, int *convy);

When the scaling is made is the same as in the old xf86PostMotionEvent. A
reverse conversion of the current core coordinates if relative movement is
reported is made before extension events are generated. And before the
pointer is moved and core event generated the coordinates are converted
back into coordinates that fits the screen.


A quick check of the current input drivers indicates that around half of
them need to use some kind of scaling and with that a small patch. Would
the bugzilla be the best place to add all these patches?

The patch contains some cleanup as well, that you might or might not want
to have that in one and the same patch. Would appreciate if you think this
would be ok or not.

Would this kind of change be within ABI_XINPUT_VERSION 1.0? Or is there
some other kind of version stepping that needs to be done?

Comments/thoughts/... ?

 BR
  Magnus

---
commit c2725e19f9daf0d2b37cb141e73cfa91fc5a7791
Author: Magnus Vigerlöf <wigge at pipe.(none)>
Date:   Tue Mar 13 21:44:43 2007 +0100

    Second try of restoring the scaling of x&y for input devices.

diff --git a/dix/getevents.c b/dix/getevents.c
index 935112d..30a67d7 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -481,13 +481,14 @@ _X_EXPORT int
 GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
                  int flags, int first_valuator, int num_valuators,
                  int *valuators) {
-    int num_events = 0, final_valuator = 0;
+    int num_events = 1, final_valuator = 0;
     CARD32 ms = 0;
     deviceKeyButtonPointer *kbp = NULL;
     /* Thanks to a broken lib, we _always_ have to chase DeviceMotionNotifies
      * with DeviceValuators. */
     Bool sendValuators = (type == MotionNotify || flags & POINTER_ABSOLUTE);
     DeviceIntPtr cp = inputInfo.pointer;
+    DeviceIntPtr srcp = (pDev->coreEvents)?cp:pDev;
     int x = 0, y = 0;
     Bool coreOnly = (pDev == inputInfo.pointer);
 
@@ -498,14 +499,11 @@ GetPointerEvents(xEvent *events, DeviceI
     if ((type == ButtonPress || type == ButtonRelease) && !pDev->button)
         return 0;
 
+    if (type == MotionNotify && num_valuators <= 0)
+        return 0;
+
     if (!coreOnly && pDev->coreEvents)
         num_events = 2;
-    else
-        num_events = 1;
-
-    if (type == MotionNotify && num_valuators <= 0) {
-        return 0;
-    }
 
     /* Do we need to send a DeviceValuator event? */
     if (!coreOnly && sendValuators) {
@@ -525,64 +523,40 @@ GetPointerEvents(xEvent *events, DeviceI
     /* Set x and y based on whether this is absolute or relative, and
      * accelerate if we need to. */
     if (flags & POINTER_ABSOLUTE) {
-        if (num_valuators >= 1 && first_valuator == 0) {
+        if (num_valuators >= 1 && first_valuator == 0)
             x = valuators[0];
-        }
-        else {
-            if (pDev->coreEvents)
-                x = cp->valuator->lastx;
-            else
-                x = pDev->valuator->lastx;
-        }
+        else
+            x = srcp->valuator->lastx;
 
-        if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) {
+        if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
             y = valuators[1 - first_valuator];
-        }
-        else {
-            if (pDev->coreEvents)
-                y = cp->valuator->lasty;
-            else
-                y = pDev->valuator->lasty;
-        }
+        else
+            x = srcp->valuator->lasty;
     }
     else {
         if (flags & POINTER_ACCELERATE)
             acceleratePointer(pDev, first_valuator, num_valuators,
                               valuators);
 
-        if (pDev->coreEvents) {
-            if (first_valuator == 0 && num_valuators >= 1)
-                x = cp->valuator->lastx + valuators[0];
-            else
-                x = cp->valuator->lastx;
-
-            if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
-                y = cp->valuator->lasty + valuators[1 - first_valuator];
-            else
-                y = cp->valuator->lasty;
-        }
+        /* Convert the core coordinates to the device coordinate space */
+        if(!coreOnly && pDev->reverse_conversion_proc)
+            (*pDev->reverse_conversion_proc)(pDev, cp->valuator->lastx,
+                                             cp->valuator->lasty, &x, &y);
         else {
-            if (first_valuator == 0 && num_valuators >= 1)
-                x = pDev->valuator->lastx + valuators[0];
-            else
-                x = pDev->valuator->lastx;
-
-            if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
-                y = pDev->valuator->lasty + valuators[1 - first_valuator];
-            else
-                y = pDev->valuator->lasty;
+            x = srcp->valuator->lastx;
+            y = srcp->valuator->lasty;
         }
+
+        if (first_valuator == 0 && num_valuators >= 1)
+            x += valuators[0];
+        if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
+            y += valuators[1 - first_valuator];
     }
 
     /* Clip both x and y to the defined limits (usually co-ord space limit). */
     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)
@@ -592,10 +566,6 @@ GetPointerEvents(xEvent *events, DeviceI
 
     updateMotionHistory(pDev, ms, first_valuator, num_valuators, valuators);
 
-    if (pDev->coreEvents) {
-        cp->valuator->lastx = x;
-        cp->valuator->lasty = y;
-    }
     pDev->valuator->lastx = x;
     pDev->valuator->lasty = y;
 
@@ -628,8 +598,23 @@ GetPointerEvents(xEvent *events, DeviceI
         }
     }
 
+    /* Convert the coordinates back to the core coordinate space for
+     * updating the pointer on the screen and to generate the core event */
+    if(!coreOnly && pDev->conversion_proc)
+        (*pDev->conversion_proc)(pDev, pDev->valuator->lastx,
+                                       pDev->valuator->lasty, &x, &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);
+
     /* for some reason inputInfo.pointer does not have coreEvents set */
     if (coreOnly || pDev->coreEvents) {
+        if (pDev->coreEvents) {
+            cp->valuator->lastx = x;
+            cp->valuator->lasty = y;
+        }
         events->u.u.type = type;
         events->u.keyButtonPointer.time = ms;
         events->u.keyButtonPointer.rootX = x;
diff --git a/include/inputstr.h b/include/inputstr.h
index ada94e6..2b04d5c 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -329,6 +329,10 @@ #endif
     DevUnion		*devPrivates;
     int			nPrivates;
     DeviceUnwrapProc    unwrapProc;
+    void (*conversion_proc)(struct _DeviceIntRec *dDev,
+			int x, int y, int *convx, int *convy);
+    void (*reverse_conversion_proc)(struct _DeviceIntRec *dDev,
+			int x, int y, int *convx, int *convy);
 } DeviceIntRec;
 
 typedef struct {



More information about the xorg mailing list