xserver: Branch 'master' - 4 commits

Peter Hutterer whot at kemper.freedesktop.org
Sat May 31 01:16:19 PDT 2008


 Xext/xtest.c    |  310 +++++++++++++++++++-------------------------------------
 dix/devices.c   |    3 
 dix/getevents.c |    3 
 mi/mieq.c       |    6 -
 4 files changed, 116 insertions(+), 206 deletions(-)

New commits:
commit 6cecae0e8651b1fa58b3cd0e0a636db46f56f6a6
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Sat May 31 13:12:53 2008 +0930

    dix: Remove superfluous comment.
    
    This code can handle devices with < 2 valuators now.

diff --git a/dix/getevents.c b/dix/getevents.c
index b5657a8..37bd203 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -893,8 +893,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         return 0;
     /* FIXME: I guess it should, in theory, be possible to post button events
      *        from devices without valuators. */
-    /* This method require at least valuator 0&1 defined on the InputDevice */
-    if (!pDev->valuator || pDev->valuator->numAxes < 2)
+    if (!pDev->valuator)
         return 0;
     if (type == MotionNotify && num_valuators <= 0)
         return 0;
commit 105d28652d1fb80dd8ce8511e2605dccc8812e99
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Fri May 30 15:20:35 2008 +0930

    Xext: use GPE/GKE from XTestFakeInput #16145
    
    This commit fixes two problems:
    1) XTFI used to assemble the event itself, then passed it to the device. It's
    much easier to just pass the variables into GPE/GKE and let the DIX do the
    rest.
    
    2) XTFI would pass the VCP/VCK as default device to event processing. As a
    result, updating LEDs would be updated on the VCK, not on the actual keyboard.
    Instead, we now pass the events through the last-used SD, thus toggling the
    LEDs on the last keyboard that sent through this MD.
    
    Also some cleanup in XTFI to merge validity checks a bit closer together
    rather than having several different sections.
    
    This breaks XTestFakeMotion with Xinerama though.
    
    X.Org Bug 16145 <http://bugs.freedesktop.org/show_bug.cgi?id=16145>

diff --git a/Xext/xtest.c b/Xext/xtest.c
index 9bd26ba..ad70aa8 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -42,6 +42,7 @@
 #include "scrnintstr.h"
 #include "dixevents.h"
 #include "sleepuntil.h"
+#include "mi.h"
 #define _XTEST_SERVER_
 #include <X11/extensions/XTest.h>
 #include <X11/extensions/xteststr.h>
@@ -164,8 +165,13 @@ ProcXTestFakeInput(client)
     WindowPtr root;
     Bool extension = FALSE;
     deviceValuator *dv = NULL;
-    int base;
-    int *values;
+    int valuators[MAX_VALUATORS] = {0};
+    int numValuators = 0;
+    int firstValuator;
+    EventListPtr events;
+    int nevents;
+    int i;
+    int base = 0;
 
     nev = (stuff->length << 2) - sizeof(xReq);
     if ((nev % sizeof(xEvent)) || !nev)
@@ -177,6 +183,18 @@ ProcXTestFakeInput(client)
 
     if (type >= EXTENSION_EVENT_BASE)
     {
+        extension = TRUE;
+
+        /* check device */
+        rc = dixLookupDevice(&dev, stuff->deviceid & 0177, client,
+                DixWriteAccess);
+        if (rc != Success)
+        {
+            client->errorValue = stuff->deviceid & 0177;
+            return rc;
+        }
+
+        /* check type */
         type -= DeviceValuator;
         switch (type) {
             case XI_DeviceKeyPress:
@@ -191,12 +209,31 @@ ProcXTestFakeInput(client)
                 client->errorValue = ev->u.u.type;
                 return BadValue;
         }
+
+        /* check validity */
         if (nev == 1 && type == XI_DeviceMotionNotify)
             return BadLength; /* DevMotion must be followed by DevValuator */
+
         if (type == XI_DeviceMotionNotify)
-            base = ((deviceValuator *)(ev+1))->first_valuator;
-        else
-            base = 0;
+        {
+            firstValuator = ((deviceValuator *)(ev+1))->first_valuator;
+            if (firstValuator > dev->valuator->numAxes)
+            {
+                client->errorValue = ev->u.u.type;
+                return BadValue;
+            }
+        } else
+            firstValuator = 0;
+
+        if (nev == 1 && type == XI_DeviceMotionNotify && !dev->valuator)
+        {
+            client->errorValue = dv->first_valuator;
+            return BadValue;
+        }
+
+
+        /* check validity of valuator events */
+        base = firstValuator;
         for (n = 1; n < nev; n++)
         {
             dv = (deviceValuator *)(ev + n);
@@ -210,17 +247,32 @@ ProcXTestFakeInput(client)
                 client->errorValue = dv->first_valuator;
                 return BadValue;
             }
-            if (!dv->num_valuators || dv->num_valuators > 6)
+            switch(dv->num_valuators)
+            {
+                case 6: valuators[base + 5] = dv->valuator5;
+                case 5: valuators[base + 4] = dv->valuator4;
+                case 4: valuators[base + 3] = dv->valuator3;
+                case 3: valuators[base + 2] = dv->valuator2;
+                case 2: valuators[base + 1] = dv->valuator1;
+                case 1: valuators[base] = dv->valuator0;
+                        break;
+                default:
+                        client->errorValue = dv->num_valuators;
+                        return BadValue;
+            }
+
+            base += dv->num_valuators;
+            numValuators += dv->num_valuators;
+
+            if (firstValuator + numValuators > dev->valuator->numAxes)
             {
                 client->errorValue = dv->num_valuators;
                 return BadValue;
             }
-            base += dv->num_valuators;
         }
         type = type - XI_DeviceKeyPress + KeyPress;
-        extension = TRUE;
-    }
-    else
+
+    } else
     {
         if (nev != 1)
             return BadLength;
@@ -228,34 +280,26 @@ ProcXTestFakeInput(client)
         {
             case KeyPress:
             case KeyRelease:
-            case MotionNotify:
+                dev = PickKeyboard(client);
+                break;
             case ButtonPress:
             case ButtonRelease:
+                dev = PickPointer(client);
+                break;
+            case MotionNotify:
+                dev = PickPointer(client);
+                valuators[0] = ev->u.keyButtonPointer.rootX;
+                valuators[1] = ev->u.keyButtonPointer.rootY;
+                numValuators = 2;
+                firstValuator = 0;
                 break;
             default:
                 client->errorValue = ev->u.u.type;
                 return BadValue;
         }
 
-        ev->u.u.type += (DeviceValuator - 1);
-        if (ev->u.u.type == DeviceMotionNotify)
-        {
-            /* fake up valuator */
-            xEvent *ne = xalloc(2 * sizeof(xEvent));
-            if (ne) {
-                memcpy(ne, ev, sizeof(xEvent));
-                memcpy(&ne[1], ev, sizeof(xEvent));
-                ev = ne;
-
-                dv = (deviceValuator*)(ne + 1);
-                dv->type = DeviceValuator;
-                dv->first_valuator = 0;
-                dv->num_valuators = 2;
-                dv->valuator0 = ev->u.keyButtonPointer.rootX;
-                dv->valuator1 = ev->u.keyButtonPointer.rootY;
-                nev = 2;
-            }
-        }
+        if (dev->u.lastSlave)
+            dev = dev->u.lastSlave;
     }
 
     /* If the event has a time set, wait for it to pass */
@@ -288,37 +332,10 @@ ProcXTestFakeInput(client)
         return Success;
     }
 
-    if (extension)
-    {
-        rc = dixLookupDevice(&dev, stuff->deviceid & 0177, client,
-                DixWriteAccess);
-        if (rc != Success)
-        {
-            client->errorValue = stuff->deviceid & 0177;
-            return rc;
-        }
-        if (nev > 1)
-        {
-            dv = (deviceValuator *)(ev + 1);
-            if (!dev->valuator || dv->first_valuator >= dev->valuator->numAxes)
-            {
-                client->errorValue = dv->first_valuator;
-                return BadValue;
-            }
-            if (dv->first_valuator + dv->num_valuators >
-                    dev->valuator->numAxes)
-            {
-                client->errorValue = dv->num_valuators;
-                return BadValue;
-            }
-        }
-    }
     switch (type)
     {
         case KeyPress:
         case KeyRelease:
-            if (!extension)
-                dev = PickKeyboard(client);
             if (ev->u.u.detail < dev->key->curKeySyms.minKeyCode ||
                     ev->u.u.detail > dev->key->curKeySyms.maxKeyCode)
             {
@@ -327,66 +344,13 @@ ProcXTestFakeInput(client)
             }
             break;
         case MotionNotify:
-            if (extension)
-            {
-                if (ev->u.u.detail != xFalse && ev->u.u.detail != xTrue)
-                {
-                    client->errorValue = ev->u.u.detail;
-                    return BadValue;
-                }
-                /* detail is True for relative coordinates */
-                if (ev->u.u.detail == xTrue && dev->valuator->mode == Absolute)
-                {
-                    values = dev->valuator->axisVal + dv->first_valuator;
-                    for (n = 1; n < nev; n++)
-                    {
-                        dv = (deviceValuator *)(ev + n);
-                        switch (dv->num_valuators)
-                        {
-                            case 6:
-                                dv->valuator5 += values[5];
-                            case 5:
-                                dv->valuator4 += values[4];
-                            case 4:
-                                dv->valuator3 += values[3];
-                            case 3:
-                                dv->valuator2 += values[2];
-                            case 2:
-                                dv->valuator1 += values[1];
-                            case 1:
-                                dv->valuator0 += values[0];
-                        }
-                        values += 6;
-                    }
-                }
-
-                /* For XI events, the actual event is mostly unset. Since we
-                 * want to update the sprite nontheless, we need to fake up
-                 * sane values for the event. */
-
-                ev->u.keyButtonPointer.root = None;
-                dv = (deviceValuator*)(ev + 1);
-                if (dv->num_valuators && dv->first_valuator == 0)
-                    ev->u.keyButtonPointer.rootX = dv->valuator0;
-                else
-                    ev->u.keyButtonPointer.rootX = 0;
-
-                /* XXX: AFAIK, XI requires always sending _all_ valuators,
-                 * i.e. you can't just send vals 3 - 7. (whot) */
-                if (dv->num_valuators > 1 && dv->first_valuator == 0)
-                    ev->u.keyButtonPointer.rootY = dv->valuator1;
-                else
-                    ev->u.keyButtonPointer.rootY = 0;
-            }
-
-            if (!dev)
-                dev = PickPointer(client);
-            if (ev->u.keyButtonPointer.root == None)
+            /* broken lib, XI events have root uninitialized */
+            if (extension || ev->u.keyButtonPointer.root == None)
                 root = GetCurrentRootWindow(dev);
             else
             {
-                rc = dixLookupWindow(&root, ev->u.keyButtonPointer.root, client,
-                        DixGetAttrAccess);
+                rc = dixLookupWindow(&root, ev->u.keyButtonPointer.root,
+                                     client, DixGetAttrAccess);
                 if (rc != Success)
                     return rc;
                 if (root->parent)
@@ -395,91 +359,23 @@ ProcXTestFakeInput(client)
                     return BadValue;
                 }
             }
-            if (ev->u.u.detail == xTrue)
-            {
-                int x, y;
-                if (!extension || !dev->valuator->mode == Absolute)
-                {
-                    /* if Absolute, rootX already has the final coords. */
-                    GetSpritePosition(dev, &x, &y);
-                    ev->u.keyButtonPointer.rootX += x;
-                    ev->u.keyButtonPointer.rootY += y;
-                }
-            }
-            else if (ev->u.u.detail != xFalse)
+            if (ev->u.u.detail != xTrue && ev->u.u.detail != xFalse)
             {
                 client->errorValue = ev->u.u.detail;
                 return BadValue;
             }
 
-#ifdef PANORAMIX
-            if (!noPanoramiXExtension) {
-                ScreenPtr pScreen = root->drawable.pScreen;
-                BoxRec    box;
-                int       i;
-                int       x = ev->u.keyButtonPointer.rootX + panoramiXdataPtr[0].x;
-                int       y = ev->u.keyButtonPointer.rootY + panoramiXdataPtr[0].y;
-                if (!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
-                            x, y, &box)) {
-                    FOR_NSCREENS(i) {
-                        if (i == pScreen->myNum) continue;
-                        if (POINT_IN_REGION(pScreen,
-                                    &XineramaScreenRegions[i],
-                                    x, y, &box)) {
-                            root = WindowTable[i];
-                            x   -= panoramiXdataPtr[i].x;
-                            y   -= panoramiXdataPtr[i].y;
-                            ev->u.keyButtonPointer.rootX = x;
-                            ev->u.keyButtonPointer.rootY = y;
-                            break;
-                        }
-                    }
-                }
-            }
-#endif
+            /* FIXME: Xinerama! */
 
-            if (ev->u.keyButtonPointer.rootX < 0)
-                ev->u.keyButtonPointer.rootX = 0;
-            else if (ev->u.keyButtonPointer.rootX >= root->drawable.width)
-                ev->u.keyButtonPointer.rootX = root->drawable.width - 1;
-            if (ev->u.keyButtonPointer.rootY < 0)
-                ev->u.keyButtonPointer.rootY = 0;
-            else if (ev->u.keyButtonPointer.rootY >= root->drawable.height)
-                ev->u.keyButtonPointer.rootY = root->drawable.height - 1;
-
-#ifdef PANORAMIX
-            if ((!noPanoramiXExtension
-                        && root->drawable.pScreen->myNum
-                        != XineramaGetCursorScreen(dev))
-                    || (noPanoramiXExtension && root != GetCurrentRootWindow(dev)))
-
-#else
-                if (root != GetCurrentRootWindow(dev))
-#endif
-                {
-                    NewCurrentScreen(dev, root->drawable.pScreen,
-                            ev->u.keyButtonPointer.rootX,
-                            ev->u.keyButtonPointer.rootY);
-                    return client->noClientException;
-                }
-            /* Only update sprite for MDs and floating SDs */
-            if (dev->isMaster || (!dev->isMaster && !dev->u.master))
-            {
-                (*root->drawable.pScreen->SetCursorPosition)
-                    (dev, root->drawable.pScreen,
-                     ev->u.keyButtonPointer.rootX,
-                     ev->u.keyButtonPointer.rootY, FALSE);
-            }
-            dev->last.valuators[0] = ev->u.keyButtonPointer.rootX;
-            dev->last.valuators[1] = ev->u.keyButtonPointer.rootY;
             break;
         case ButtonPress:
         case ButtonRelease:
             if (!extension)
+            {
                 dev = PickPointer(client);
-
-            ev->u.keyButtonPointer.rootX = dev->last.valuators[0];
-            ev->u.keyButtonPointer.rootY = dev->last.valuators[1];
+                if (dev->u.lastSlave)
+                    dev = dev->u.lastSlave;
+            }
             if (!ev->u.u.detail || ev->u.u.detail > dev->button->numButtons)
             {
                 client->errorValue = ev->u.u.detail;
@@ -489,19 +385,31 @@ ProcXTestFakeInput(client)
     }
     if (screenIsSaved == SCREEN_SAVER_ON)
         dixSaveScreens(serverClient, SCREEN_SAVER_OFF, ScreenSaverReset);
-    ev->u.keyButtonPointer.time = currentTime.milliseconds;
-
-    if (!dev->isMaster && dev->u.master)
-    {   /* duplicate and route through master */
-        xEvent *master_event = NULL;
-        CopyGetMasterEvent(dev->u.master, ev, &master_event, nev);
-        (*dev->public.processInputProc)(ev, dev, nev);
-        (*dev->public.processInputProc)(master_event, dev->u.master, nev);
-        xfree(master_event);
-    } else
-        (*dev->public.processInputProc)(ev, dev, nev);
-    if (!extension && type == MotionNotify)
-        xfree(ev);
+
+    GetEventList(&events);
+    switch(type) {
+        case MotionNotify:
+            nevents = GetPointerEvents(events, dev, type, 0,
+                            (ev->u.u.detail == xFalse) ?  POINTER_ABSOLUTE : 0,
+                            firstValuator, numValuators, valuators);
+            break;
+        case ButtonPress:
+        case ButtonRelease:
+            nevents = GetPointerEvents(events, dev, type, ev->u.u.detail,
+                                       POINTER_ABSOLUTE, firstValuator,
+                                       numValuators, valuators);
+            break;
+        case KeyPress:
+        case KeyRelease:
+            nevents = GetKeyboardEvents(events, dev, type, ev->u.u.detail);
+            break;
+    }
+
+    OsBlockSignals();
+    for (i = 0; i < nevents; i++)
+        mieqEnqueue(dev, events->event);
+    OsReleaseSignals();
+
     return client->noClientException;
 }
 
commit 341a61b608873c77b1a17fe7d145ed3ad716e5a3
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Sat May 31 12:01:47 2008 +0930

    mi: reduce noisyness. DebugF is enough if device ID can't be changed.
    
    Also - printing out the event type is actually helpful.

diff --git a/mi/mieq.c b/mi/mieq.c
index 830bab8..a1f9cc6 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -254,9 +254,11 @@ ChangeDeviceID(DeviceIntPtr dev, xEvent* event)
         {
             // do nothing or drink a beer. your choice.
         } else
-            ErrorF("[mi] Unknown generic event, cannot change id.\n");
+            DebugF("[mi] Unknown generic event (%d/%d), cannot change id.\n",
+                    ((xGenericEvent*)ev)->extension,
+                    ((xGenericEvent*)ev)->evtype);
     } else
-        ErrorF("[mi] Unknown event type, cannot change id.\n");
+        DebugF("[mi] Unknown event type (%d), cannot change id.\n", type);
 }
 
 /**
commit 62c1a32976d571f3ced1812b8b96ed5a8e658b4a
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Sat May 31 10:24:37 2008 +0930

    dix: null out dummyDev, otherwise Xephyr dereferences random pointers.
    
    SendEventToAllWindow eventually causes a IsInterferingGrab(), which attempts
    to dereference dev->deviceGrab.grab.

diff --git a/dix/devices.c b/dix/devices.c
index 60d48b2..08520eb 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -376,7 +376,8 @@ ActivateDevice(DeviceIntPtr dev)
     ev.time = currentTime.milliseconds;
     ev.devchange = DeviceAdded;
     ev.deviceid = dev->id;
-    dummyDev.id = 0;
+
+    memset(&dummyDev, 0, sizeof(DeviceIntRec));
     SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
                           (xEvent *) &ev, 1);
 


More information about the xorg-commit mailing list