xserver: Branch 'master' - 2 commits

Peter Hutterer whot at kemper.freedesktop.org
Thu Apr 23 22:31:36 PDT 2009


 Xext/xtest.c    |   15 +++++++-
 Xi/chdevhier.c  |   98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 dix/devices.c   |   64 ++++++++++++++++++++++++++++++++++++
 include/input.h |    4 ++
 mi/mieq.c       |    2 -
 5 files changed, 177 insertions(+), 6 deletions(-)

New commits:
commit 932d6bcbb68194c5bdfeb336f700dc8b31529223
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Apr 24 15:28:45 2009 +1000

    mi: remove superfluous check.
    
    mieqProcessInputEvents doesn't process events from MDs anymore, so we don't
    need to check for pDev->isMaster.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/mi/mieq.c b/mi/mieq.c
index 0846602..3daf91e 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -427,7 +427,7 @@ mieqProcessInputEvents(void)
         mieqProcessDeviceEvent(dev, event, screen);
 
         /* Update the sprite now. Next event may be from different device. */
-        if (event->u.any.type == ET_Motion && (master || dev->isMaster))
+        if (event->u.any.type == ET_Motion && master)
             miPointerUpdateSprite(dev);
 
 #ifdef XQUARTZ
commit fab563bf8f6b63906ce9d5a568c467425843265b
Author: Benjamin Close <Benjamin.Close at clearchain.com>
Date:   Fri Mar 27 16:44:15 2009 +1030

    input: propagate XTst events through virtual slave devices.
    
    A XTest virtual slave device pair (kbd/ptr) exists for every master
    device pair. This is so XTest events are correctly propogated via slave
    devices up to Master devices and the classes are correctly changed along
    the way. We add the XTest slave device pair to the Virtual Core pointer
    and provide a simple way of creating the devices.
    
    A XTest Slave Device is identified by the XTstDevicePrivateKey property
    being set in the devices devProperties
    
    XI events are still propagated through the matching device, in the hope the
    client knows what it is doing.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xext/xtest.c b/Xext/xtest.c
index ab88231..d21eedc 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -54,6 +54,7 @@
 
 extern int DeviceValuator;
 extern int DeviceMotionNotify;
+extern DevPrivateKey XTstDevicePrivateKey;
 
 #ifdef PANORAMIX
 #include "panoramiX.h"
@@ -160,6 +161,7 @@ ProcXTestFakeInput(ClientPtr client)
     int i;
     int base = 0;
     int flags = 0;
+    DeviceIntPtr xtstdevice;
 
     nev = (stuff->length << 2) - sizeof(xReq);
     if ((nev % sizeof(xEvent)) || !nev)
@@ -268,6 +270,8 @@ ProcXTestFakeInput(ClientPtr client)
 
     } else
     {
+        DeviceIntPtr it;
+
         if (nev != 1)
             return BadLength;
         switch (type)
@@ -294,8 +298,14 @@ ProcXTestFakeInput(ClientPtr client)
                 return BadValue;
         }
 
-        if (dev->u.lastSlave)
-            dev = dev->u.lastSlave;
+        /* When faking core events through XTest, we always fake through the
+         * virtual test device.
+         */
+        for(it = inputInfo.devices; it ; it = it->next )
+            if( !it->isMaster && it->u.master == dev &&
+                    dixLookupPrivate(&it->devPrivates, XTstDevicePrivateKey ))
+                break;
+        dev= it;
     }
 
     /* If the event has a time set, wait for it to pass */
@@ -403,6 +413,7 @@ ProcXTestFakeInput(ClientPtr client)
     for (i = 0; i < nevents; i++)
         mieqProcessDeviceEvent(dev, (events+i)->event, NULL);
 
+    miPointerUpdateSprite(dev);
     return client->noClientException;
 }
 
diff --git a/Xi/chdevhier.c b/Xi/chdevhier.c
index 5c8b369..6c70bd9 100644
--- a/Xi/chdevhier.c
+++ b/Xi/chdevhier.c
@@ -52,6 +52,8 @@
 
 #include "chdevhier.h"
 
+extern DevPrivateKey XTstDevicePrivateKey;
+
 
 /***********************************************************************
  *
@@ -74,7 +76,7 @@ int SProcXChangeDeviceHierarchy(ClientPtr client)
 int
 ProcXChangeDeviceHierarchy(ClientPtr client)
 {
-    DeviceIntPtr ptr, keybd;
+    DeviceIntPtr ptr, keybd, xtstptr, xtstkeybd;
     DeviceIntRec dummyDev;
     xAnyHierarchyChangeInfo *any;
     int required_len = sizeof(xChangeDeviceHierarchyReq);
@@ -118,14 +120,33 @@ ProcXChangeDeviceHierarchy(ClientPtr client)
                     if (!c->sendCore)
                         ptr->coreEvents = keybd->coreEvents =  FALSE;
 
+		    /* Allocate virtual slave devices for xtest events */
+                    rc = AllocXtstDevice(client, name, &xtstptr, &xtstkeybd);
+                    if (rc != Success)
+                    {
+
+                        xfree(name);
+                        goto unwind;
+                    }
+
                     ActivateDevice(ptr);
                     ActivateDevice(keybd);
+                    ActivateDevice(xtstptr);
+                    ActivateDevice(xtstkeybd);
 
                     if (c->enable)
                     {
                         EnableDevice(ptr);
                         EnableDevice(keybd);
+                        EnableDevice(xtstptr);
+                        EnableDevice(xtstkeybd);
                     }
+
+                    /* Attach the XTest virtual devices to the newly
+                       created master device */
+                    AttachDevice(NULL, xtstptr, ptr);
+                    AttachDevice(NULL, xtstkeybd, keybd);
+
                     xfree(name);
                     nchanges++;
                 }
@@ -133,6 +154,7 @@ ProcXChangeDeviceHierarchy(ClientPtr client)
             case CH_RemoveMasterDevice:
                 {
                     xRemoveMasterInfo* r = (xRemoveMasterInfo*)any;
+                    DeviceIntPtr xtstdevice;
 
                     if (r->returnMode != AttachToMaster &&
                             r->returnMode != Floating)
@@ -158,7 +180,17 @@ ProcXChangeDeviceHierarchy(ClientPtr client)
                         goto unwind;
                     }
 
-                    /* disable keyboards first */
+                    for(xtstdevice = inputInfo.devices; xtstdevice ; xtstdevice = xtstdevice->next )
+                        if( !xtstdevice->isMaster && xtstdevice->u.master == ptr &&
+                            dixLookupPrivate(&xtstdevice->devPrivates, XTstDevicePrivateKey ))
+                            break;
+
+                    rc = dixLookupDevice(&xtstptr, xtstdevice->id, client,
+                                         DixDestroyAccess);
+                    if (rc != Success)
+                        goto unwind;
+
+                    /* find keyboards to destroy */
                     if (IsPointerDevice(ptr))
                     {
                         rc = dixLookupDevice(&keybd,
@@ -167,6 +199,7 @@ ProcXChangeDeviceHierarchy(ClientPtr client)
                                              DixDestroyAccess);
                         if (rc != Success)
                             goto unwind;
+
                     }
                     else
                     {
@@ -177,8 +210,47 @@ ProcXChangeDeviceHierarchy(ClientPtr client)
                                              DixDestroyAccess);
                         if (rc != Success)
                             goto unwind;
+
                     }
 
+                    /* handle xtst pointer / keyboard slave devices */
+                    if ( IsPointerDevice(xtstptr))
+                    {
+                        /* Search the matching keyboard */
+                        for(xtstdevice = inputInfo.devices; xtstdevice ; xtstdevice = xtstdevice->next )
+                            if( !xtstdevice->isMaster &&
+                                xtstdevice->u.master == keybd &&
+                                IsKeyboardDevice(xtstdevice) &&
+                                dixLookupPrivate(&xtstdevice->devPrivates, XTstDevicePrivateKey ))
+                                break;
+
+                        rc = dixLookupDevice(&xtstkeybd,
+                                             xtstdevice->id,
+                                             client,
+                                             DixDestroyAccess);
+
+                        if (rc != Success)
+                            goto unwind;
+                    }
+                    else
+                    {
+                        xtstkeybd = xtstptr;
+                        /* Search the matching pointer */
+                        for(xtstdevice = inputInfo.devices; xtstdevice ; xtstdevice = xtstdevice->next )
+                            if( !xtstdevice->isMaster &&
+                                xtstdevice->u.master == ptr &&
+                                IsPointerDevice(xtstdevice) &&
+                                dixLookupPrivate(&xtstdevice->devPrivates, XTstDevicePrivateKey )
+                              )
+                                break;
+                        rc = dixLookupDevice(&xtstptr,
+                                             xtstdevice->id,
+                                             client,
+                                             DixDestroyAccess);
+
+                        if (rc != Success)
+                            goto unwind;
+                    }
 
                     /* Disabling sends the devices floating, reattach them if
                      * desired. */
@@ -228,9 +300,18 @@ ProcXChangeDeviceHierarchy(ClientPtr client)
                     /* can't disable until we removed pairing */
                     keybd->spriteInfo->paired = NULL;
                     ptr->spriteInfo->paired = NULL;
+                    xtstptr->spriteInfo->paired = NULL;
+                    xtstkeybd->spriteInfo->paired = NULL;
+
+                    /* disable the remove the devices, xtst devices must be done first
+                       else the sprites they rely on will be destroyed  */
+                    DisableDevice(xtstptr);
+                    DisableDevice(xtstkeybd);
                     DisableDevice(keybd);
                     DisableDevice(ptr);
 
+                    RemoveDevice(xtstptr);
+                    RemoveDevice(xtstkeybd);
                     RemoveDevice(keybd);
                     RemoveDevice(ptr);
                     nchanges++;
@@ -238,6 +319,8 @@ ProcXChangeDeviceHierarchy(ClientPtr client)
                 break;
             case CH_ChangeAttachment:
                 {
+                    DeviceIntPtr *xtstdevice;
+
                     xChangeAttachmentInfo* c = (xChangeAttachmentInfo*)any;
 
                     rc = dixLookupDevice(&ptr, c->deviceid, client,
@@ -252,6 +335,17 @@ ProcXChangeDeviceHierarchy(ClientPtr client)
                         goto unwind;
                     }
 
+                    xtstdevice = dixLookupPrivate( &ptr->devPrivates,
+                                                   XTstDevicePrivateKey );
+
+                    /* Don't allow changes to Xtst Devices, these are fixed */
+                    if( xtstdevice )
+                    {
+                        client->errorValue = c->deviceid;
+                        rc = BadDevice;
+                        goto unwind;
+                    }
+
                     if (c->changeMode == Floating)
                         AttachDevice(client, ptr, NULL);
                     else
diff --git a/dix/devices.c b/dix/devices.c
index bbddf3b..afe340b 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -88,9 +88,24 @@ SOFTWARE.
 
 static int CoreDevicePrivateKeyIndex;
 DevPrivateKey CoreDevicePrivateKey = &CoreDevicePrivateKeyIndex;
-/* Used to sture classes currently not in use by an MD */
+/* Used to store classes currently not in use by an MD */
 static int UnusedClassesPrivateKeyIndex;
 DevPrivateKey UnusedClassesPrivateKey = &UnusedClassesPrivateKeyIndex;
+/* Used to store if a device is an XTest Virtual device */
+static int XTstDevicePrivateKeyIndex;
+DevPrivateKey XTstDevicePrivateKey = &XTstDevicePrivateKeyIndex;
+
+/**
+ * vxtstpointer
+ * is the virtual pointer for XTest. It is the first slave
+ * device of the VCP.
+ * vxtstkeyboard
+ * is the virtual keyboard for XTest. It is the first slave
+ * device of the VCK
+ *
+ * Neither of these devices can be deleted.
+ */
+DeviceIntPtr vxtstpointer, vxtstkeyboard;
 
 
 /**
@@ -556,6 +571,25 @@ InitCoreDevices(void)
     if (!EnableDevice(inputInfo.pointer) ||
         !EnableDevice(inputInfo.keyboard))
         FatalError("Failed to enable core devices.");
+
+    /*
+      Allocate an virtual slave device for xtest events, this
+      is a slave device to inputInfo master devices
+     */
+    if(AllocXtstDevice(serverClient, "Virtual core",
+                       &vxtstpointer,
+                       &vxtstkeyboard) != Success)
+        FatalError("Failed to allocate XTst devices");
+
+    if (ActivateDevice(vxtstpointer) != Success ||
+        ActivateDevice(vxtstkeyboard) != Success)
+        FatalError("Failed to activate xtst core devices.");
+    if (!EnableDevice(vxtstpointer) ||
+        !EnableDevice(vxtstkeyboard))
+        FatalError("Failed to enable xtst core devices.");
+
+    AttachDevice(NULL, vxtstpointer, inputInfo.pointer);
+    AttachDevice(NULL, vxtstkeyboard, inputInfo.keyboard);
 }
 
 /**
@@ -2339,3 +2373,31 @@ AllocDevicePair (ClientPtr client, char* name,
 
     return Success;
 }
+
+/**
+ * Allocate a device pair that is initialised as a slave
+ * device with properties that identify the devices as belonging
+ * to XTest subsystem.
+ * This only creates the pair, Activate/Enable Device
+ * still need to be called.
+ */
+int AllocXtstDevice (ClientPtr client, char* name,
+		 DeviceIntPtr* ptr, DeviceIntPtr* keybd)
+{
+    int retval;
+    int len = strlen(name);
+    char *xtstname = xcalloc(len + 6, 1 );
+
+    strncpy( xtstname, name, len);
+    strncat( xtstname, " Xtst", 5 );
+
+    retval = AllocDevicePair( client, xtstname, ptr, keybd, FALSE);
+    if ( retval == Success ){
+	dixSetPrivate(&((*ptr)->devPrivates), XTstDevicePrivateKey, (void *)True );
+	dixSetPrivate(&((*keybd)->devPrivates), XTstDevicePrivateKey,(void *)True);
+    }
+
+    xfree( xtstname );
+
+    return retval;
+}
diff --git a/include/input.h b/include/input.h
index b3bb5d1..56c3d29 100644
--- a/include/input.h
+++ b/include/input.h
@@ -481,6 +481,10 @@ extern int generate_modkeymap(ClientPtr client, DeviceIntPtr dev,
                               KeyCode **modkeymap, int *max_keys_per_mod);
 extern int change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *map,
                          int max_keys_per_mod);
+extern int AllocXtstDevice(ClientPtr client,
+                             char* name,
+                             DeviceIntPtr* ptr,
+                             DeviceIntPtr* keybd);
 
 /* Implemented by the DDX. */
 extern _X_EXPORT int NewInputDeviceRequest(


More information about the xorg-commit mailing list