xserver: Branch 'mpx' - 4 commits

Peter Hutterer whot at kemper.freedesktop.org
Thu May 22 07:21:08 PDT 2008


 dix/devices.c   |    9 ++
 dix/getevents.c |  227 ++++++++++++++++++++++++++++++++++++--------------------
 mi/mipointer.c  |   49 ++----------
 3 files changed, 169 insertions(+), 116 deletions(-)

New commits:
commit 7f85acdf70c67c567de688439e25081be5a7d5df
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu May 22 23:27:15 2008 +0930

    dix: fill valuators with the correct values depending on the device mode (GPE)
    
    valuators[] is passed from the DDX. Depending on the device mode, update it
    with either absolute values or relative values. The deviceValuator event sent
    to the client will then contain the respective values.

diff --git a/dix/getevents.c b/dix/getevents.c
index 15e7f3b..fafb632 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -827,19 +827,23 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         master->lasty = pDev->lasty;
     }
 
-    /* update the contents of the valuators based on the mode of the InputDevice */
-    if(1) { /*TODO Absolute mode */
-        /* Update the valuators with the true value sent to the client
-         * (only absolute mode on the InputDevice) */
+    /* update the valuators based on the mode of the InputDevice */
+    if(pDev->valuator->mode == Absolute) {
+        /* Update the valuators with the true value sent to the client*/
         if (first_valuator == 0 && num_valuators >= 1)
-            pDev->valuator->axisVal[0] = x;
+            valuators[0] = x;
         if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
-            pDev->valuator->axisVal[1] = y;
+            valuators[1] = y;
     } else {/* Relative mode */
         /* If driver reported in absolute, calculate the relative valuator
          * values as a delta from the old absolute values of the valuator
          * values. If relative report, keep it as-is.*/
-        /*TODO*/
+        if (flags & POINTER_ABSOLUTE) {
+            int i;
+            for (i = first_valuator; i < num_valuators; i++)
+                valuators[i] = valuators[i] - pDev->valuator->axisVal[i];
+
+        }
     }
     /* Save the last calculated device axis value in the device
      * valuator for next event */
commit 1a3f351c50cba66f71a73239318174b09fd9b63b
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu May 22 23:25:20 2008 +0930

    dix: when floating a device, create a new cursor sprite.
    
    This is essentially necessary to allow calls to miPointerGetSprite etc. to
    work for floating slave devices.

diff --git a/dix/devices.c b/dix/devices.c
index 5606543..1b71a42 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -2415,6 +2415,7 @@ PairDevices(ClientPtr client, DeviceIntPtr ptr, DeviceIntPtr kbd)
 int
 AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
 {
+    ScreenPtr screen;
     DeviceIntPtr oldmaster;
     if (!dev || dev->isMaster)
         return BadDevice;
@@ -2428,7 +2429,11 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
 
     /* free the existing sprite. */
     if (!dev->u.master && dev->spriteInfo->paired == dev)
+    {
+        screen = miPointerGetScreen(dev);
+        screen->DeviceCursorCleanup(dev, screen);
         xfree(dev->spriteInfo->sprite);
+    }
 
     oldmaster = dev->u.master;
     dev->u.master = master;
@@ -2442,10 +2447,14 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
     if (!master)
     {
         WindowPtr currentRoot = dev->spriteInfo->sprite->spriteTrace[0];
+        /* we need to init a fake sprite */
+        screen = currentRoot->drawable.pScreen;
+        screen->DeviceCursorInitialize(dev, screen);
         dev->spriteInfo->sprite = NULL;
         InitializeSprite(dev, currentRoot);
         dev->spriteInfo->spriteOwner = FALSE;
         dev->spriteInfo->paired = dev;
+
     } else
     {
         dev->spriteInfo->sprite = master->spriteInfo->sprite;
commit e0fbe404a436aef24624a3a15e8405a9ca38aadb
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu May 22 23:24:29 2008 +0930

    mi: handle sprite even for floating slave devices.
    
    We still don't render it, but we accept all the other calls to update it's
    internal state.

diff --git a/mi/mipointer.c b/mi/mipointer.c
index e49b3df..28f3b4e 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -50,7 +50,7 @@ _X_EXPORT DevPrivateKey miPointerScreenKey = &miPointerScreenKey;
 static DevPrivateKey miPointerPrivKey = &miPointerPrivKey;
 
 #define MIPOINTER(dev) \
-    ((DevHasCursor((dev))) ? \
+    ((DevHasCursor((dev)) || (!dev->isMaster && !dev->u.master)) ? \
         (miPointerPtr)dixLookupPrivate(&(dev)->devPrivates, miPointerPrivKey): \
         (miPointerPtr)dixLookupPrivate(&(dev)->u.master->devPrivates, miPointerPrivKey))
 
@@ -193,9 +193,6 @@ miPointerDisplayCursor (pDev, pScreen, pCursor)
 {
     miPointerPtr pPointer;
     
-    if (!pDev->isMaster && !pDev->u.master)
-        return FALSE;
-
     /* return for keyboards */
     if ((pDev->isMaster && !DevHasCursor(pDev)) ||
         (!pDev->isMaster && pDev->u.master && !DevHasCursor(pDev->u.master)))
@@ -217,9 +214,6 @@ miPointerConstrainCursor (pDev, pScreen, pBox)
 {
     miPointerPtr pPointer;
 
-    if (!pDev->isMaster && !pDev->u.master)
-        return;
-    
     pPointer = MIPOINTER(pDev);
 
     pPointer->limits = *pBox;
@@ -313,13 +307,13 @@ miPointerDeviceCleanup(pDev, pScreen)
     DeviceIntPtr pDev;
     ScreenPtr pScreen;
 {
-    if (DevHasCursor(pDev))
-    {
-        SetupScreen(pScreen);
-        (*pScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen);
-        xfree(dixLookupPrivate(&pDev->devPrivates, miPointerPrivKey));
-        dixSetPrivate(&pDev->devPrivates, miPointerPrivKey, NULL);
-    }
+    if (!pDev->isMaster && pDev->u.master)
+        return;
+
+    SetupScreen(pScreen);
+    (*pScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen);
+    xfree(dixLookupPrivate(&pDev->devPrivates, miPointerPrivKey));
+    dixSetPrivate(&pDev->devPrivates, miPointerPrivKey, NULL);
 }
 
 
@@ -334,8 +328,6 @@ miPointerWarpCursor (pDev, pScreen, x, y)
     miPointerPtr pPointer;
     BOOL changedScreen = FALSE;
 
-    if (!pDev->isMaster && !pDev->u.master)
-        return;
     pPointer = MIPOINTER(pDev);
     SetupScreen (pScreen);
 
@@ -388,7 +380,7 @@ miPointerUpdateSprite (DeviceIntPtr pDev)
     int			x, y, devx, devy;
     miPointerPtr        pPointer;
 
-    if (!pDev || !pDev->coreEvents || (!pDev->isMaster && !pDev->u.master))
+    if (!pDev || !pDev->coreEvents)
         return;
 
     pPointer = MIPOINTER(pDev);
@@ -477,10 +469,7 @@ miPointerSetScreen(DeviceIntPtr pDev, int screen_no, int x, int y)
 {
 	miPointerScreenPtr pScreenPriv;
 	ScreenPtr pScreen;
-        miPointerPtr pPointer; 
-        
-        if (!pDev->isMaster && !pDev->u.master)
-            return;
+        miPointerPtr pPointer;
 
         pPointer = MIPOINTER(pDev);
 
@@ -502,10 +491,8 @@ miPointerCurrentScreen ()
 _X_EXPORT ScreenPtr
 miPointerGetScreen(DeviceIntPtr pDev)
 {
-    if (!pDev || (!pDev->isMaster && !pDev->u.master))
-        return NULL;
-
-    return MIPOINTER(pDev)->pScreen;
+    miPointerPtr pPointer = MIPOINTER(pDev);
+    return (pPointer) ? pPointer->pScreen : NULL;
 }
 
 /* Move the pointer to x, y on the current screen, update the sprite, and
@@ -525,9 +512,6 @@ miPointerMoved (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y,
     miPointerPtr pPointer;
     SetupScreen(pScreen);
 
-    if (!pDev->isMaster && !pDev->u.master) 
-        return;
-
     pPointer = MIPOINTER(pDev);
 
     /* Hack: We mustn't call into ->MoveCursor for anything but the
@@ -556,9 +540,6 @@ miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y, unsigned long time)
     ScreenPtr		newScreen;
 
     miPointerPtr        pPointer; 
-    
-    if (!pDev->isMaster && !pDev->u.master)
-        return;
 
     pPointer = MIPOINTER(pDev);
     pScreen = pPointer->pScreen;
@@ -613,12 +594,6 @@ miPointerPosition (int *x, int *y)
 _X_EXPORT void
 miPointerGetPosition(DeviceIntPtr pDev, int *x, int *y)
 {
-    if (!pDev->isMaster && !pDev->u.master)
-    {
-        ErrorF("[mi] miPointerGetPosition called for floating device.\n");
-        return;
-    }
-
     *x = MIPOINTER(pDev)->x;
     *y = MIPOINTER(pDev)->y;
 }
commit 0f15875a271889ae3cc4997ad15f787ea28b3a08
Author: Magnus Vigerlöf <Magnus.Vigerlof at ipbo.se>
Date:   Sat May 17 19:24:00 2008 +0200

    Make all conversion handling in GPE.
    
    This isn't quite finished yet, but at least it gives us the ability to use a
    tablet as a normal mouse - with all the scaling in place.
    
    Signed-off-by: Peter Hutterer <peter at cs.unisa.edu.au>

diff --git a/dix/getevents.c b/dix/getevents.c
index 0879434..15e7f3b 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -156,6 +156,55 @@ CreateClassesChangedEvent(EventList* event,
 }
 
 /**
+ * Rescale the coord between the two axis ranges.
+ */
+static int
+rescaleValuatorAxis(int coord, int fmin, int fmax,
+                    int tmin, int tmax, int smax)
+{
+    if(fmin >= fmax) {
+        fmin = 0;
+        fmax = smax;
+    }
+    if(tmin >= tmax) {
+        tmin = 0;
+        tmax = smax;
+    }
+    if(fmin == tmin && fmax == tmax)
+        return coord;
+
+    return (int)(((float)(coord - fmin)) * (tmax - tmin + 1) /
+                 (fmax - fmin + 1)) + tmin;
+}
+
+/**
+ * Update all coordinates when changing to a different SD
+ * to ensure that relative reporting will work as expected
+ * without loss of precision.
+ */
+static void
+updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
+{
+    ScreenPtr scr = miPointerGetScreen(pDev);
+
+    /* lastx/y is in screen coords and the actual position
+     * of the pointer */
+    pDev->lastx = master->lastx;
+    pDev->lasty = master->lasty;
+    /* the valuator axis is in device coords and holds the
+     * position of the pointer, but in device coords. */
+    if(pDev->valuator->numAxes > 0)
+        pDev->valuator->axisVal[0] = rescaleValuatorAxis(pDev->lastx, 0, scr->width,
+                                            pDev->valuator->axes[0].min_value,
+                                            pDev->valuator->axes[0].max_value, scr->width);
+    if(pDev->valuator->numAxes > 1)
+        pDev->valuator->axisVal[1] = rescaleValuatorAxis(pDev->lasty, 0, scr->height,
+                                            pDev->valuator->axes[1].min_value,
+                                            pDev->valuator->axes[1].max_value, scr->height);
+    /*TODO calculate the other axis as well based on info from the old slave-device */
+}
+
+/**
  * Allocate the motion history buffer.
  */
 _X_EXPORT void
@@ -395,25 +444,23 @@ clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators,
  * Fills events with valuator events for pDev, as given by the other
  * parameters.
  *
- * Note that we mis-use the sequence number to store the absolute bit.
- *
  * FIXME: Need to fix ValuatorClassRec to store all the valuators as
  *        last posted, not just x and y; otherwise relative non-x/y
  *        valuators, though a very narrow use case, will be broken.
  */
 static EventList *
-getValuatorEvents(EventList *events, DeviceIntPtr pDev, int absolute,
+getValuatorEvents(EventList *events, DeviceIntPtr pDev,
         int first_valuator, int num_valuators, int *valuators) {
     deviceValuator *xv;
-    int i = 0, final_valuator = first_valuator + num_valuators;
+    int i;
 
-    for (i = first_valuator; i < final_valuator; i += 6, events++) {
+    for (i = 0; i < num_valuators; i += 6, events++) {
         xv = (deviceValuator*)events->event;
         xv->type = DeviceValuator;
-        xv->first_valuator = i;
-        xv->num_valuators = ((final_valuator - i) > 6) ? 6 : (final_valuator - i);
+        xv->first_valuator = first_valuator + i;
+        xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
         xv->deviceid = pDev->id;
-        switch (final_valuator - i) {
+        switch (num_valuators - i) {
         case 6:
             xv->valuator5 = valuators[i + 5];
         case 5:
@@ -425,13 +472,11 @@ getValuatorEvents(EventList *events, DeviceIntPtr pDev, int absolute,
         case 2:
             xv->valuator1 = valuators[i + 1];
         case 1:
-            xv->valuator0 = valuators[i];
+            xv->valuator0 = valuators[i + 0];
         }
 
-        if (i + 6 < final_valuator)
+        if (i + 6 < num_valuators)
             xv->deviceid |= MORE_EVENTS;
-
-        xv->sequenceNumber = (absolute) ? Absolute : Relative;
     }
 
     return events;
@@ -576,8 +621,8 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
     if (num_valuators) {
         kbp->deviceid |= MORE_EVENTS;
         clipValuators(pDev, first_valuator, num_valuators, valuators);
-        events = getValuatorEvents(events, pDev, FALSE /* relative */,
-                                   first_valuator, num_valuators, valuators);
+        events = getValuatorEvents(events, pDev, first_valuator,
+                                   num_valuators, valuators);
     }
 
     return numEvents;
@@ -674,44 +719,28 @@ _X_EXPORT int
 GetPointerEvents(EventList *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;
     CARD32 ms = 0;
     deviceKeyButtonPointer *kbp = NULL;
     DeviceIntPtr master;
-    int x = 0, y = 0;
+    int x, y, cx, cy;
+    ScreenPtr scr = miPointerGetScreen(pDev);
 
     /* Sanity checks. */
     if (type != MotionNotify && type != ButtonPress && type != ButtonRelease)
         return 0;
-
-    if ((type == ButtonPress || type == ButtonRelease) && !pDev->button)
+    if (type != MotionNotify && !pDev->button)
         return 0;
-
     /* FIXME: I guess it should, in theory, be possible to post button events
      *        from devices without valuators. */
-    if (!pDev->valuator)
+    /* This method require at least valuator 0&1 defined on the InputDevice */
+    if (!pDev->valuator || pDev->valuator->numAxes < 2)
         return 0;
-
     if (type == MotionNotify && num_valuators <= 0)
         return 0;
 
     ms = GetTimeInMillis();
 
-    num_events = 1;
-
-    master = pDev->u.master;
-    if (master && master->u.lastSlave != pDev)
-    {
-        CreateClassesChangedEvent(events, master, pDev);
-
-        pDev->lastx = master->lastx;
-        pDev->lasty = master->lasty;
-        master->u.lastSlave = pDev;
-
-        num_events++;
-        events++;
-    }
-
     /* Do we need to send a DeviceValuator event? */
     if (num_valuators) {
         if ((((num_valuators - 1) / 6) + 1) > MAX_VALUATOR_EVENTS)
@@ -719,28 +748,34 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         num_events += ((num_valuators - 1) / 6) + 1;
     }
 
-    final_valuator = num_valuators + first_valuator;
-
     /* You fail. */
-    if (first_valuator < 0 || final_valuator > pDev->valuator->numAxes)
+    if (first_valuator < 0 ||
+        (num_valuators + first_valuator) > pDev->valuator->numAxes)
         return 0;
 
+    master = pDev->u.master;
+    if (master && master->u.lastSlave != pDev)
+    {
+        CreateClassesChangedEvent(events, master, pDev);
+        updateSlaveDeviceCoords(master, pDev);
+        master->u.lastSlave = pDev;
+        num_events++;
+        events++;
+    }
+
     /* Set x and y based on whether this is absolute or relative, and
      * accelerate if we need to. */
+    x = pDev->valuator->axisVal[0];
+    y = pDev->valuator->axisVal[1];
     if (flags & POINTER_ABSOLUTE) {
-        if (num_valuators >= 1 && first_valuator == 0) {
+        if (num_valuators >= 1 && first_valuator == 0)
             x = valuators[0];
-        }
-        else {
-            x = pDev->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 {
-            y = pDev->lasty;
-        }
+
+        /* Clip both x and y to the defined limits (usually co-ord space limit). */
+        clipAxis(pDev, 0, &x);
+        clipAxis(pDev, 1, &y);
     }
     else {
         if (flags & POINTER_ACCELERATE)
@@ -748,34 +783,69 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
                               valuators);
 
         if (first_valuator == 0 && num_valuators >= 1)
-            x = pDev->lastx + valuators[0];
-        else
-            x = pDev->lastx;
-
+            x += valuators[0];
         if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
-            y = pDev->lasty + valuators[1 - first_valuator];
-        else
-            y = pDev->lasty;
+            y += valuators[1 - first_valuator];
+
+        /* if not core -> clip both x and y to the defined limits (usually
+         * co-ord space limit). */
+        if(!pDev->coreEvents) {
+            clipAxis(pDev, 0, &x);
+            clipAxis(pDev, 1, &y);
+        }
     }
 
-    /* Clip both x and y to the defined limits (usually co-ord space limit). */
-    clipAxis(pDev, 0, &x);
-    clipAxis(pDev, 1, &y);
+    /* scale x&y to screen */
+    pDev->lastx = cx = rescaleValuatorAxis(x, pDev->valuator->axes[0].min_value,
+                                           pDev->valuator->axes[0].max_value,
+                                           0, scr->width, scr->width);
+    pDev->lasty = cy = rescaleValuatorAxis(y, pDev->valuator->axes[1].min_value,
+                                           pDev->valuator->axes[1].max_value,
+                                           0, scr->height, scr->height);
 
     /* 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);
+    miPointerSetPosition(pDev, &pDev->lastx, &pDev->lasty, ms);
+
+    scr = miPointerGetScreen(pDev);
+    if(cx != pDev->lastx)
+        x = rescaleValuatorAxis(pDev->lastx, 0, scr->width,
+                                pDev->valuator->axes[0].min_value,
+                                pDev->valuator->axes[0].max_value,
+                                scr->width);
+    if(cy != pDev->lasty)
+        y = rescaleValuatorAxis(pDev->lasty, 0, scr->height,
+                                pDev->valuator->axes[1].min_value,
+                                pDev->valuator->axes[1].max_value,
+                                scr->height);
+
     updateMotionHistory(pDev, ms, first_valuator, num_valuators, valuators);
 
-    pDev->lastx = x;
-    pDev->lasty = y;
-    if (master)
-    {
-        master->lastx = x;
-        master->lasty = y;
+    if (master) {
+        master->lastx = pDev->lastx;
+        master->lasty = pDev->lasty;
     }
 
+    /* update the contents of the valuators based on the mode of the InputDevice */
+    if(1) { /*TODO Absolute mode */
+        /* Update the valuators with the true value sent to the client
+         * (only absolute mode on the InputDevice) */
+        if (first_valuator == 0 && num_valuators >= 1)
+            pDev->valuator->axisVal[0] = x;
+        if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
+            pDev->valuator->axisVal[1] = y;
+    } else {/* Relative mode */
+        /* If driver reported in absolute, calculate the relative valuator
+         * values as a delta from the old absolute values of the valuator
+         * values. If relative report, keep it as-is.*/
+        /*TODO*/
+    }
+    /* Save the last calculated device axis value in the device
+     * valuator for next event */
+    pDev->valuator->axisVal[0] = x;
+    pDev->valuator->axisVal[1] = y;
+
     kbp = (deviceKeyButtonPointer *) events->event;
     kbp->time = ms;
     kbp->deviceid = pDev->id;
@@ -791,15 +861,15 @@ GetPointerEvents(EventList *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->lastx;
+    kbp->root_y = pDev->lasty;
 
     events++;
     if (num_valuators) {
         kbp->deviceid |= MORE_EVENTS;
         clipValuators(pDev, first_valuator, num_valuators, valuators);
-        events = getValuatorEvents(events, pDev, (flags & POINTER_ABSOLUTE),
-                first_valuator, num_valuators, valuators);
+        events = getValuatorEvents(events, pDev, first_valuator,
+                                   num_valuators, valuators);
     }
 
     return num_events;
@@ -824,10 +894,8 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
     /* Sanity checks. */
     if (type != ProximityIn && type != ProximityOut)
         return 0;
-
     if (!pDev->valuator)
         return 0;
-
     /* Do we need to send a DeviceValuator event? */
     if ((pDev->valuator->mode & 1) == Relative)
         num_valuators = 0;
@@ -847,11 +915,8 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
     if (master && master->u.lastSlave != pDev)
     {
         CreateClassesChangedEvent(events, master, pDev);
-
-        pDev->lastx = master->lastx;
-        pDev->lasty = master->lasty;
+        updateSlaveDeviceCoords(master, pDev);
         master->u.lastSlave = pDev;
-
         num_events++;
         events++;
     }
@@ -866,8 +931,8 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
         kbp->deviceid |= MORE_EVENTS;
         events++;
         clipValuators(pDev, first_valuator, num_valuators, valuators);
-        events = getValuatorEvents(events, pDev, False /* relative */,
-                                   first_valuator, num_valuators, valuators);
+        events = getValuatorEvents(events, pDev, first_valuator,
+                                   num_valuators, valuators);
     }
 
     return num_events;


More information about the xorg-commit mailing list