xserver: Branch 'mpx' - 4 commits

Peter Hutterer whot at kemper.freedesktop.org
Thu Nov 15 18:38:24 PST 2007


 Xi/exevents.c |  118 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 dix/devices.c |   68 +++++++++++++++++++--------------
 2 files changed, 148 insertions(+), 38 deletions(-)

New commits:
commit be3321c2e9fad228a9ee5fef47680a47bc9e39a4
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Fri Nov 16 12:12:41 2007 +1030

    dix: Free both current classes and original classes when closing an MD.

diff --git a/dix/devices.c b/dix/devices.c
index bc3313c..7512529 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -817,10 +817,12 @@ CloseDevice(DeviceIntPtr dev)
     xfree(dev->name);
 
     if (dev->isMaster)
+    {
         classes = (ClassesPtr)dev->devPrivates[MasterDevClassesPrivIdx].ptr;
-    else
-        classes = (ClassesPtr)&dev->key;
+        FreeAllDeviceClasses(classes);
+    }
 
+    classes = (ClassesPtr)&dev->key;
     FreeAllDeviceClasses(classes);
 
 #ifdef XKB
commit 3c39dd19ec2a53b8854279e3b03131098031473a
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Fri Nov 16 12:12:14 2007 +1030

    Xi: Deep-copy full list of FeedbackClasses.
    
    All feedback classes are linked lists and the whole list has to be duplicated,
    not just the first entry.
    
    Xkb stuff still missing.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 1cef825..d72f00a 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -205,6 +205,106 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
     }
 }
 
+/**
+ * Copies the feedback classes from device "from" into device "to". Classes
+ * are duplicated (not just flipping the pointers). All feedback classes are
+ * linked lists, the full list is duplicated.
+ *
+ * XXX: some XKB stuff is still missing.
+ */
+static void
+DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
+{
+    if (from->kbdfeed)
+    {
+        KbdFeedbackPtr *k, it;
+        k = &to->kbdfeed;
+        for(it = from->kbdfeed; it; it = it->next)
+        {
+            *k = xcalloc(1, sizeof(KbdFeedbackClassRec));
+            (*k)->BellProc = it->BellProc;
+            (*k)->CtrlProc = it->CtrlProc;
+            (*k)->ctrl     = it->ctrl;
+            /* XXX: xkb_sli needs to be copied */
+
+            k = &(*k)->next;
+        }
+    }
+
+    if (from->ptrfeed)
+    {
+        PtrFeedbackPtr *p, it;
+        p = &to->ptrfeed;
+        for (it = from->ptrfeed; it; it = it->next)
+        {
+            *p = xcalloc(1, sizeof(PtrFeedbackClassRec));
+            (*p)->CtrlProc = it->CtrlProc;
+            (*p)->ctrl     = it->ctrl;
+            /* XXX: xkb_sli needs to be copied */
+
+            p = &(*p)->next;
+        }
+    }
+
+    if (from->intfeed)
+    {
+        IntegerFeedbackPtr *i, it;
+        i = &to->intfeed;
+        for (it = from->intfeed; it; it = it->next)
+        {
+            *i = xcalloc(1, sizeof(IntegerFeedbackClassRec));
+            (*i)->CtrlProc = it->CtrlProc;
+            (*i)->ctrl     = it->ctrl;
+
+            i = &(*i)->next;
+        }
+    }
+
+    if (from->stringfeed)
+    {
+        StringFeedbackPtr *s, it;
+        s = &to->stringfeed;
+        for (it = from->stringfeed; it; it = it->next)
+        {
+            *s = xcalloc(1, sizeof(StringFeedbackClassRec));
+            (*s)->CtrlProc = it->CtrlProc;
+            (*s)->ctrl     = it->ctrl;
+
+            s = &(*s)->next;
+        }
+    }
+
+    if (from->bell)
+    {
+        BellFeedbackPtr *b, it;
+        b = &to->bell;
+        for (it = from->bell; it; it = it->next)
+        {
+            *b = xcalloc(1, sizeof(BellFeedbackClassRec));
+            (*b)->BellProc = it->BellProc;
+            (*b)->CtrlProc = it->CtrlProc;
+            (*b)->ctrl     = it->ctrl;
+
+            b = &(*b)->next;
+        }
+    }
+
+    if (from->leds)
+    {
+        LedFeedbackPtr *l, it;
+        l = &to->leds;
+        for (it = from->leds; it; it = it->next)
+        {
+            *l = xcalloc(1, sizeof(LedFeedbackClassRec));
+            (*l)->CtrlProc = it->CtrlProc;
+            (*l)->ctrl     = it->ctrl;
+            /* XXX: xkb_sli needs to be copied */
+
+            l = &(*l)->next;
+        }
+    }
+}
+
 _X_EXPORT void
 DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
 {
@@ -256,26 +356,24 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
     ALLOC_COPY_CLASS_IF(focus, FocusClassRec);
     ALLOC_COPY_CLASS_IF(proximity, ProximityClassRec);
     ALLOC_COPY_CLASS_IF(absolute, AbsoluteClassRec);
+
     ALLOC_COPY_CLASS_IF(kbdfeed, KbdFeedbackClassRec);
 #ifdef XKB
     if (to->kbdfeed)
     {
         to->kbdfeed->xkb_sli = NULL;
         /* XXX: XkbSrvLedInfo needs to be copied*/
+        to->kbdfeed->next = NULL;
     }
 #endif
     ALLOC_COPY_CLASS_IF(ptrfeed, PtrFeedbackClassRec);
-    ALLOC_COPY_CLASS_IF(intfeed, IntegerFeedbackClassRec);
-    ALLOC_COPY_CLASS_IF(stringfeed, StringFeedbackClassRec);
-    ALLOC_COPY_CLASS_IF(bell, BellFeedbackClassRec);
-    ALLOC_COPY_CLASS_IF(leds, LedFeedbackClassRec);
-#ifdef XKB
-    if (to->leds)
+    if (to->ptrfeed)
     {
-        to->leds->xkb_sli = NULL;
-        /* XXX: XkbSrvLedInfo needs to be copied*/
+        to->ptrfeed->next = NULL;
     }
-#endif
+
+
+    DeepCopyFeedbackClasses(from, to);
 }
 
 static void
@@ -296,7 +394,7 @@ ChangeMasterDeviceClasses(DeviceIntPtr device,
 
     master->public.devicePrivate = device->public.devicePrivate;
 
-    FreeAllDeviceClasses(&master->key);
+    FreeAllDeviceClasses((ClassesPtr)&master->key);
     DeepCopyDeviceClasses(device, master);
 
     /* event is already correct size, see comment in GetPointerEvents */
commit 497862df2fcd67531fbe0f876c20a09884ee74df
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Fri Nov 16 11:20:22 2007 +1030

    dix: explicitly float all attached SDs before closing down devices.
    
    Some drivers flush on shutdown, if our SD is still attached we'd be trying to
    route an event through a non-existing device.

diff --git a/dix/devices.c b/dix/devices.c
index 045f74f..bc3313c 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -859,6 +859,17 @@ CloseDownDevices(void)
 {
     DeviceIntPtr dev, next;
 
+    /* Float all SDs before closing them. Note that at this point resources
+     * (e.g. cursors) have been freed already, so we can't just call
+     * AttachDevice(NULL, dev, NULL). Instead, we have to forcibly set master
+     * to NULL and pretend nothing happened.
+     */
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+        if (!dev->isMaster && dev->u.master)
+            dev->u.master = NULL;
+    }
+
     for (dev = inputInfo.devices; dev; dev = next)
     {
 	next = dev->next;
commit 9de1ebe2a80164507cbe2ef688f284225e0ec808
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Fri Nov 16 10:45:28 2007 +1030

    dix: Fix up class restoring when last SD disconnects.
    
    Old code was fundamentally broken, fixes now are:
    - free the MDs current device classes
    - copy the device classes instead of flipping the pointers
    - check for the old MD, not the new one.

diff --git a/dix/devices.c b/dix/devices.c
index 1792e9e..045f74f 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -2390,6 +2390,7 @@ PairDevices(ClientPtr client, DeviceIntPtr ptr, DeviceIntPtr kbd)
 int
 AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
 {
+    DeviceIntPtr oldmaster;
     if (!dev || dev->isMaster)
         return BadDevice;
 
@@ -2409,6 +2410,7 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
     if (!dev->u.master && dev->spriteInfo->sprite)
         xfree(dev->spriteInfo->sprite);
 
+    oldmaster = dev->u.master;
     dev->u.master = master;
 
     /* If device is set to floating, we need to create a sprite for it,
@@ -2417,52 +2419,49 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
      */
     if (!master)
     {
-        DeviceIntPtr it;
                               /* current root window */
         InitializeSprite(dev, dev->spriteInfo->sprite->spriteTrace[0]);
         dev->spriteInfo->spriteOwner = FALSE;
 
-        /* the master may need to restore the original classes, search for a
-         * device that is still paired with our master. */
+    } else
+        dev->spriteInfo->sprite = master->spriteInfo->sprite;
+
+    /* If we were connected to master device before, this MD may need to
+     * change back to it's original classes.
+     */
+    if (oldmaster)
+    {
+        DeviceIntPtr it;
         for (it = inputInfo.devices; it; it = it->next)
-            if (!it->isMaster && it->u.master == master)
+            if (!it->isMaster && it->u.master == oldmaster)
                 break;
 
-        if (!it)  /* no dev is paired with our master */
+        if (!it)  /* no dev is paired with old master */
         {
             ClassesPtr classes;
             EventList event = { NULL, 0};
             char* classbuf;
+            DeviceIntRec dummy;
 
-            classes = master->devPrivates[MasterDevClassesPrivIdx].ptr;
-            master->key = classes->key;
-            master->valuator = classes->valuator;
-            master->button = classes->button;
-            master->focus = classes->focus;
-            master->proximity = classes->proximity;
-            master->absolute = classes->absolute;
-            master->kbdfeed = classes->kbdfeed;
-            master->ptrfeed = classes->ptrfeed;
-            master->intfeed = classes->intfeed;
-            master->stringfeed = classes->stringfeed;
-            master->bell = classes->bell;
-            master->leds = classes->leds;
+            FreeAllDeviceClasses((ClassesPtr)&oldmaster->key);
+            classes = oldmaster->devPrivates[MasterDevClassesPrivIdx].ptr;
+            memcpy(&dummy.key, classes, sizeof(ClassesRec));
+            DeepCopyDeviceClasses(&dummy, oldmaster);
 
             /* Send event to clients */
-            CreateClassesChangedEvent(&event, master, master);
+            CreateClassesChangedEvent(&event, oldmaster, oldmaster);
             deviceClassesChangedEvent *dcce =
-                        (deviceClassesChangedEvent*)event.event;
-            dcce->deviceid = master->id;
+                (deviceClassesChangedEvent*)event.event;
+            dcce->deviceid = oldmaster->id;
             dcce->num_classes = 0;
             classbuf = (char*)&event.event[1];
-            CopySwapClasses(NullClient, master, &dcce->num_classes, &classbuf);
-            SendEventToAllWindows(master, XI_DeviceClassesChangedMask,
+            CopySwapClasses(NullClient, oldmaster,
+                    &dcce->num_classes, &classbuf);
+            SendEventToAllWindows(oldmaster, XI_DeviceClassesChangedMask,
                     event.event, 1);
             xfree(event.event);
         }
-
-    } else
-        dev->spriteInfo->sprite = master->spriteInfo->sprite;
+    }
 
     return Success;
 }


More information about the xorg-commit mailing list