xserver: Branch 'mpx' - 15 commits

Peter Hutterer whot at kemper.freedesktop.org
Mon Apr 14 22:41:31 PDT 2008


 Xi/exevents.c    |  292 ++++++++++++++++++++++++++++++++++++++++++++++---------
 dix/devices.c    |   37 +++++-
 dix/events.c     |    2 
 include/xkbsrv.h |    8 +
 xkb/xkbLEDs.c    |   43 +++++++-
 5 files changed, 323 insertions(+), 59 deletions(-)

New commits:
commit 51c8fd69ec9292f5e18cdc7f60e1716fbd6ae61a
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Tue Apr 15 15:09:40 2008 +0930

    dix: free the unused device classes when closing a device.
    
    This also requires to NULL-ify all pointers while we're actually using them,
    otherwise we'd try to free them twice.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 4dd9fce..f412508 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -519,7 +519,8 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
                 to->key = xcalloc(1, sizeof(KeyClassRec));
                 if (!to->key)
                     FatalError("[Xi] no memory for class shift.\n");
-            }
+            } else
+                classes->key = NULL;
         }
 
         oldModKeyMap    = to->key->modifierKeyMap;
@@ -562,6 +563,8 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
             classes = dixLookupPrivate(&to->devPrivates,
                                        UnusedClassesPrivateKey);
             to->valuator = classes->valuator;
+            if (to->valuator)
+                classes->valuator = NULL;
         }
 
         to->valuator = xrealloc(to->valuator, sizeof(ValuatorClassRec) +
@@ -600,7 +603,8 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
                 to->button = xcalloc(1, sizeof(ButtonClassRec));
                 if (!to->button)
                     FatalError("[Xi] no memory for class shift.\n");
-            }
+            } else
+                classes->button = NULL;
         }
 
         to->button->buttonsDown = 0;
@@ -650,7 +654,9 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
                 to->focus = xcalloc(1, sizeof(FocusClassRec));
                 if (!to->focus)
                     FatalError("[Xi] no memory for class shift.\n");
-            }
+            } else
+                classes->focus = NULL;
+
             oldTrace = to->focus->trace;
             memcpy(to->focus, from->focus, sizeof(FocusClassRec));
             to->focus->trace = xrealloc(oldTrace,
@@ -680,7 +686,8 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
                 to->proximity = xcalloc(1, sizeof(ProximityClassRec));
                 if (!to->proximity)
                     FatalError("[Xi] no memory for class shift.\n");
-            }
+            } else
+                classes->proximity = NULL;
         }
         memcpy(to->proximity, from->proximity, sizeof(ProximityClassRec));
     } else if (to->proximity)
@@ -703,7 +710,8 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
                 to->absolute = xcalloc(1, sizeof(AbsoluteClassRec));
                 if (!to->absolute)
                     FatalError("[Xi] no memory for class shift.\n");
-            }
+            } else
+                classes->absolute = NULL;
         }
         memcpy(to->absolute, from->absolute, sizeof(AbsoluteClassRec));
     } else if (to->absolute)
@@ -713,7 +721,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
         classes->absolute = to->absolute;
         to->absolute      = NULL;
     }
-
 }
 
 /**
diff --git a/dix/devices.c b/dix/devices.c
index d445916..fe70e78 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -775,6 +775,13 @@ CloseDevice(DeviceIntPtr dev)
     classes = (ClassesPtr)&dev->key;
     FreeAllDeviceClasses(classes);
 
+    if (dev->isMaster)
+    {
+        classes = dixLookupPrivate(&dev->devPrivates, UnusedClassesPrivateKey);
+        FreeAllDeviceClasses(classes);
+    }
+
+
 #ifdef XKB
     while (dev->xkb_interest)
 	XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource);
commit 48d33ab9b672b3b3ca308000cdbd573d1e368ff9
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Tue Apr 15 14:29:53 2008 +0930

    dix: float attached devices _before_ disabling the master.
    
    It also helps if we're actually providing the correct argument to
    AttachDevice...

diff --git a/dix/devices.c b/dix/devices.c
index 266a66c..d445916 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -301,6 +301,16 @@ DisableDevice(DeviceIntPtr dev)
     if (*prev != dev)
 	return FALSE;
 
+    /* float attached devices */
+    if (dev->isMaster)
+    {
+        for (other = inputInfo.devices; other; other = other->next)
+        {
+            if (other->u.master == dev)
+                AttachDevice(NULL, other, NULL);
+        }
+    }
+
     if (dev->isMaster && dev->spriteInfo->sprite)
     {
         for (other = inputInfo.devices; other; other = other->next)
@@ -320,16 +330,6 @@ DisableDevice(DeviceIntPtr dev)
     dev->next = inputInfo.off_devices;
     inputInfo.off_devices = dev;
 
-    /* float attached devices */
-    if (dev->isMaster)
-    {
-        for (other = inputInfo.devices; other; other = other->next)
-        {
-            if (other->u.master == dev)
-                AttachDevice(NULL, dev, NULL);
-        }
-    }
-
     ev.type = DevicePresenceNotify;
     ev.time = currentTime.milliseconds;
     ev.devchange = DeviceDisabled;
commit 4cf9c5909d926ec322ed1c7df47f95bd872bb607
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Tue Apr 15 13:56:11 2008 +0930

    Xi: fix up button count.
    
    Some leftover code from the previously used alloc/free device classes left us
    with a incorrect button count. So a button release didn't come through if
    a different pointer was moved after the button press.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 4417e6c..4dd9fce 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -603,6 +603,8 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
             }
         }
 
+        to->button->buttonsDown = 0;
+        memset(to->button->down, 0, MAP_LENGTH);
         /* merge button states from all attached devices */
         for (sd = inputInfo.devices; sd; sd = sd->next)
         {
@@ -612,6 +614,7 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
             for (i = 0; i < MAP_LENGTH; i++)
             {
                 to->button->down[i] += sd->button->down[i];
+                to->button->buttonsDown++;
             }
         }
 #ifdef XKB
commit 1a9d7205cd5640eb65f019336097d86301942ea7
Merge: 90f491c... 6866e84...
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Mon Apr 14 16:25:58 2008 +0930

    Merge whot at wombat:~/potoroo/xserver into mpx

commit 6866e84e3c607d00d88eab2249c2619d6707c1a4
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Sun Apr 13 19:57:51 2008 +0930

    Xi: store feedback classes in devProviates system as well.
    
    This is a follow-up to cb48d880856fd196ab8e8de5eb1f14944a1b4fff.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index d99f609..4417e6c 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -253,9 +253,19 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
 static void
 DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
 {
+    ClassesPtr classes;
+
     if (from->kbdfeed)
     {
         KbdFeedbackPtr *k, it;
+
+        if (!to->kbdfeed)
+        {
+            classes = dixLookupPrivate(&to->devPrivates,
+                                       UnusedClassesPrivateKey);
+            to->kbdfeed = classes->kbdfeed;
+        }
+
         k = &to->kbdfeed;
         for(it = from->kbdfeed; it; it = it->next)
         {
@@ -281,12 +291,22 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
         }
     } else if (to->kbdfeed && !from->kbdfeed)
     {
-        FreeFeedbackClass(KbdFeedbackClass, (pointer)&to->kbdfeed);
+        ClassesPtr classes;
+        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+        classes->kbdfeed = to->kbdfeed;
+        to->kbdfeed      = NULL;
     }
 
     if (from->ptrfeed)
     {
         PtrFeedbackPtr *p, it;
+        if (!to->ptrfeed)
+        {
+            classes = dixLookupPrivate(&to->devPrivates,
+                                       UnusedClassesPrivateKey);
+            to->ptrfeed = classes->ptrfeed;
+        }
+
         p = &to->ptrfeed;
         for (it = from->ptrfeed; it; it = it->next)
         {
@@ -306,12 +326,23 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
         }
     } else if (to->ptrfeed && !from->ptrfeed)
     {
-        FreeFeedbackClass(PtrFeedbackClass, (pointer)&to->ptrfeed);
+        ClassesPtr classes;
+        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+        classes->ptrfeed = to->ptrfeed;
+        to->ptrfeed      = NULL;
     }
 
     if (from->intfeed)
     {
         IntegerFeedbackPtr *i, it;
+
+        if (!to->intfeed)
+        {
+            classes = dixLookupPrivate(&to->devPrivates,
+                                       UnusedClassesPrivateKey);
+            to->intfeed = classes->intfeed;
+        }
+
         i = &to->intfeed;
         for (it = from->intfeed; it; it = it->next)
         {
@@ -331,12 +362,23 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
         }
     } else if (to->intfeed && !from->intfeed)
     {
-        FreeFeedbackClass(IntegerFeedbackClass, (pointer)&to->intfeed);
+        ClassesPtr classes;
+        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+        classes->intfeed = to->intfeed;
+        to->intfeed      = NULL;
     }
 
     if (from->stringfeed)
     {
         StringFeedbackPtr *s, it;
+
+        if (!to->stringfeed)
+        {
+            classes = dixLookupPrivate(&to->devPrivates,
+                                       UnusedClassesPrivateKey);
+            to->stringfeed = classes->stringfeed;
+        }
+
         s = &to->stringfeed;
         for (it = from->stringfeed; it; it = it->next)
         {
@@ -356,12 +398,23 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
         }
     } else if (to->stringfeed && !from->stringfeed)
     {
-        FreeFeedbackClass(StringFeedbackClass, (pointer)&to->stringfeed);
+        ClassesPtr classes;
+        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+        classes->stringfeed = to->stringfeed;
+        to->stringfeed      = NULL;
     }
 
     if (from->bell)
     {
         BellFeedbackPtr *b, it;
+
+        if (!to->bell)
+        {
+            classes = dixLookupPrivate(&to->devPrivates,
+                                       UnusedClassesPrivateKey);
+            to->bell = classes->bell;
+        }
+
         b = &to->bell;
         for (it = from->bell; it; it = it->next)
         {
@@ -382,12 +435,23 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
         }
     } else if (to->bell && !from->bell)
     {
-        FreeFeedbackClass(BellFeedbackClass, (pointer)&to->bell);
+        ClassesPtr classes;
+        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+        classes->bell = to->bell;
+        to->bell      = NULL;
     }
 
     if (from->leds)
     {
         LedFeedbackPtr *l, it;
+
+        if (!to->leds)
+        {
+            classes = dixLookupPrivate(&to->devPrivates,
+                                       UnusedClassesPrivateKey);
+            to->leds = classes->leds;
+        }
+
         l = &to->leds;
         for (it = from->leds; it; it = it->next)
         {
@@ -412,7 +476,10 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
         }
     } else if (to->leds && !from->leds)
     {
-        FreeFeedbackClass(LedFeedbackClass, (pointer)&to->leds);
+        ClassesPtr classes;
+        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+        classes->leds = to->leds;
+        to->leds      = NULL;
     }
 }
 
commit cb48d880856fd196ab8e8de5eb1f14944a1b4fff
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Sun Apr 13 19:48:28 2008 +0930

    Xi: store unused classes in devPrivates.
    
    Rather than freeing/allocing classes each time the device capabilities need to
    swap, store them in the devPrivates system.
    When a class is unused, it is pushed into the devPrivates, and later recovered
    when needed again. This saves us a lot of memory allocations/frees, admittedly
    on the cost of some memory.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 2a7afa9..d99f609 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -96,6 +96,9 @@ Bool ShouldFreeInputMasks(WindowPtr /* pWin */ ,
 static Bool MakeInputMasks(WindowPtr	/* pWin */
     );
 
+/* Used to sture classes currently not in use by an MD */
+extern DevPrivateKey UnusedClassesPrivateKey;
+
 
 void
 RegisterOtherDevice(DeviceIntPtr device)
@@ -416,28 +419,22 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
 /**
  * Copies the CONTENT of the classes of device from into the classes in device
  * to. From and to are identical after finishing.
+ *
+ * If to does not have classes from currenly has, the classes are stored in
+ * to's devPrivates system. Later, we recover it again from there if needed.
+ * Saves a few memory allocations.
  */
 
 _X_EXPORT void
 DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
 {
+    ClassesPtr classes;
+
     /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the
      * kbdfeed to be set up properly, so let's do the feedback classes first.
      */
     DeepCopyFeedbackClasses(from, to);
 
-#define ALLOC_COPY_CLASS_IF(field, type) \
-    if (from->field)\
-    { \
-        if (!to->field) \
-        { \
-            to->field = xcalloc(1, sizeof(type)); \
-            if (!to->field) \
-            FatalError("[Xi] no memory for class shift.\n"); \
-        } \
-        memcpy(to->field, from->field, sizeof(type)); \
-    }
-
     if (from->key)
     {
         KeyCode             *oldModKeyMap;
@@ -445,15 +442,19 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
 #ifdef XKB
         struct _XkbSrvInfo  *oldXkbInfo;
 #endif
-
         if (!to->key)
         {
-            to->key = xcalloc(1, sizeof(KeyClassRec));
+            classes = dixLookupPrivate(&to->devPrivates,
+                                       UnusedClassesPrivateKey);
+            to->key = classes->key;
             if (!to->key)
-                FatalError("[Xi] no memory for class shift.\n");
+            {
+                to->key = xcalloc(1, sizeof(KeyClassRec));
+                if (!to->key)
+                    FatalError("[Xi] no memory for class shift.\n");
+            }
         }
 
-
         oldModKeyMap    = to->key->modifierKeyMap;
         oldMap          = to->key->curKeySyms.map;
 #ifdef XKB
@@ -480,14 +481,22 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
         CopyKeyClass(from, to);
     } else if (to->key && !from->key)
     {
-        FreeDeviceClass(KeyClass, (pointer)&to->key);
+        ClassesPtr classes;
+        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+        classes->key = to->key;
+        to->key      = NULL;
     }
 
     if (from->valuator)
     {
         ValuatorClassPtr v;
-        if (to->valuator)
-            xfree(to->valuator->motion);
+        if (!to->valuator)
+        {
+            classes = dixLookupPrivate(&to->devPrivates,
+                                       UnusedClassesPrivateKey);
+            to->valuator = classes->valuator;
+        }
+
         to->valuator = xrealloc(to->valuator, sizeof(ValuatorClassRec) +
                 from->valuator->numAxes * sizeof(AxisInfo) +
                 from->valuator->numAxes * sizeof(unsigned int));
@@ -504,14 +513,28 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
         v->axisVal = (int*)(v->axes + from->valuator->numAxes);
     } else if (to->valuator && !from->valuator)
     {
-        FreeDeviceClass(ValuatorClass, (pointer)&to->valuator);
+        ClassesPtr classes;
+        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+        classes->valuator = to->valuator;
+        to->valuator      = NULL;
     }
 
-    ALLOC_COPY_CLASS_IF(button, ButtonClassRec);
-    if (to->button)
+    if (from->button)
     {
         int i;
         DeviceIntPtr sd;
+        if (!to->button)
+        {
+            classes = dixLookupPrivate(&to->devPrivates,
+                                       UnusedClassesPrivateKey);
+            to->button = classes->button;
+            if (!to->button)
+            {
+                to->button = xcalloc(1, sizeof(ButtonClassRec));
+                if (!to->button)
+                    FatalError("[Xi] no memory for class shift.\n");
+            }
+        }
 
         /* merge button states from all attached devices */
         for (sd = inputInfo.devices; sd; sd = sd->next)
@@ -530,7 +553,10 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
 #endif
     } else if (to->button && !from->button)
     {
-        FreeDeviceClass(ButtonClass, (pointer)&to->button);
+        ClassesPtr classes;
+        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+        classes->button = to->button;
+        to->button      = NULL;
     }
 
 
@@ -544,29 +570,78 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
     {
         if (!to->focus)
         {
-            to->focus = xcalloc(1, sizeof(FocusClassRec));
+            WindowPtr *oldTrace;
+
+            classes = dixLookupPrivate(&to->devPrivates,
+                                       UnusedClassesPrivateKey);
+            to->focus = classes->focus;
             if (!to->focus)
-                FatalError("[Xi] no memory for class shift.\n");
+            {
+                to->focus = xcalloc(1, sizeof(FocusClassRec));
+                if (!to->focus)
+                    FatalError("[Xi] no memory for class shift.\n");
+            }
+            oldTrace = to->focus->trace;
+            memcpy(to->focus, from->focus, sizeof(FocusClassRec));
+            to->focus->trace = xrealloc(oldTrace,
+                                  to->focus->traceSize * sizeof(WindowPtr));
+            if (!to->focus->trace && to->focus->traceSize)
+                FatalError("[Xi] no memory for trace.\n");
             memcpy(to->focus->trace, from->focus->trace,
                     from->focus->traceSize * sizeof(WindowPtr));
         }
     } else if (to->focus)
     {
-        /* properly freeing the class would also free the sprite trace, which
-         * is still in use by the SD. just xfree the struct. */
-        xfree(to->focus);
+        ClassesPtr classes;
+        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+        classes->focus = to->focus;
+        to->focus      = NULL;
     }
 
-    ALLOC_COPY_CLASS_IF(proximity, ProximityClassRec);
-    if (to->proximity && !from->proximity)
+    if (from->proximity)
+    {
+        if (!to->proximity)
+        {
+            classes = dixLookupPrivate(&to->devPrivates,
+                                       UnusedClassesPrivateKey);
+            to->proximity = classes->proximity;
+            if (!to->proximity)
+            {
+                to->proximity = xcalloc(1, sizeof(ProximityClassRec));
+                if (!to->proximity)
+                    FatalError("[Xi] no memory for class shift.\n");
+            }
+        }
+        memcpy(to->proximity, from->proximity, sizeof(ProximityClassRec));
+    } else if (to->proximity)
     {
-        FreeDeviceClass(ProximityClass, (pointer)&to->proximity);
+        ClassesPtr classes;
+        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+        classes->proximity = to->proximity;
+        to->proximity      = NULL;
     }
-    ALLOC_COPY_CLASS_IF(absolute, AbsoluteClassRec);
-    if (to->absolute && !from->absolute)
+
+    if (from->absolute)
+    {
+        if (!to->absolute)
+        {
+            classes = dixLookupPrivate(&to->devPrivates,
+                                       UnusedClassesPrivateKey);
+            to->absolute = classes->absolute;
+            if (!to->absolute)
+            {
+                to->absolute = xcalloc(1, sizeof(AbsoluteClassRec));
+                if (!to->absolute)
+                    FatalError("[Xi] no memory for class shift.\n");
+            }
+        }
+        memcpy(to->absolute, from->absolute, sizeof(AbsoluteClassRec));
+    } else if (to->absolute)
     {
-        xfree(to->absolute);
-        to->absolute = NULL;
+        ClassesPtr classes;
+        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+        classes->absolute = to->absolute;
+        to->absolute      = NULL;
     }
 
 }
diff --git a/dix/devices.c b/dix/devices.c
index a78a125..266a66c 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -89,6 +89,8 @@ SOFTWARE.
 /* The client that is allowed to change pointer-keyboard pairings. */
 static ClientPtr pairingClient = NULL;
 DevPrivateKey CoreDevicePrivateKey = &CoreDevicePrivateKey;
+/* Used to sture classes currently not in use by an MD */
+DevPrivateKey UnusedClassesPrivateKey = &UnusedClassesPrivateKey;
 
 /**
  * Create a new input device and init it to sane values. The device is added
@@ -2550,6 +2552,7 @@ AllocMasterDevice(ClientPtr client, char* name, DeviceIntPtr* ptr, DeviceIntPtr*
 {
     DeviceIntPtr pointer;
     DeviceIntPtr keyboard;
+    ClassesPtr classes;
     *ptr = *keybd = NULL;
 
     pointer = AddInputDevice(client, CorePointerProc, TRUE);
@@ -2602,6 +2605,13 @@ AllocMasterDevice(ClientPtr client, char* name, DeviceIntPtr* ptr, DeviceIntPtr*
     keyboard->u.lastSlave = NULL;
     keyboard->isMaster = TRUE;
 
+
+    /* The ClassesRec stores the device classes currently not used. */
+    classes = xcalloc(1, sizeof(ClassesRec));
+    dixSetPrivate(&pointer->devPrivates, UnusedClassesPrivateKey, classes);
+    classes = xcalloc(1, sizeof(ClassesRec));
+    dixSetPrivate(&keyboard->devPrivates, UnusedClassesPrivateKey, classes);
+
     *ptr = pointer;
     *keybd = keyboard;
 
commit fde3c836628b6cdec3e5d107d6b1b99bc8b86912
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Sun Apr 13 17:08:51 2008 +0930

    Xi: copy the KeySyms.map over from the source.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index aee78c6..2a7afa9 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -462,6 +462,15 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
 
         memcpy(to->key, from->key, sizeof(KeyClassRec));
 
+        if (!oldMap) /* newly created key struct */
+        {
+            int bytes = (to->key->curKeySyms.maxKeyCode -
+                         to->key->curKeySyms.minKeyCode + 1) *
+                         to->key->curKeySyms.mapWidth;
+            oldMap = (KeySym *)xcalloc(sizeof(KeySym), bytes);
+            memcpy(oldMap, from->key->curKeySyms.map, bytes);
+        }
+
         to->key->modifierKeyMap = oldModKeyMap;
         to->key->curKeySyms.map = oldMap;
 #ifdef XKB
commit 3c4c9938f31755c5a59995fdcfa138c99db76bbf
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Sun Apr 13 16:52:14 2008 +0930

    Xi: Fix pointer handling in KeyClassRec copy.
    
    We don't free the class anymore, so just store the previous pointers, do the
    memcpy from the SD and then restore the pointers.
    Plugs a memleak too, before xkbInfo was never freed.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index cf0e898..aee78c6 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -438,13 +438,36 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
         memcpy(to->field, from->field, sizeof(type)); \
     }
 
-    ALLOC_COPY_CLASS_IF(key, KeyClassRec);
-    if (to->key && from->key)
+    if (from->key)
     {
+        KeyCode             *oldModKeyMap;
+        KeySym              *oldMap;
 #ifdef XKB
-        to->key->xkbInfo = NULL;
+        struct _XkbSrvInfo  *oldXkbInfo;
 #endif
-        to->key->curKeySyms.map = NULL;
+
+        if (!to->key)
+        {
+            to->key = xcalloc(1, sizeof(KeyClassRec));
+            if (!to->key)
+                FatalError("[Xi] no memory for class shift.\n");
+        }
+
+
+        oldModKeyMap    = to->key->modifierKeyMap;
+        oldMap          = to->key->curKeySyms.map;
+#ifdef XKB
+        oldXkbInfo      = to->key->xkbInfo;
+#endif
+
+        memcpy(to->key, from->key, sizeof(KeyClassRec));
+
+        to->key->modifierKeyMap = oldModKeyMap;
+        to->key->curKeySyms.map = oldMap;
+#ifdef XKB
+        to->key->xkbInfo        = oldXkbInfo;
+#endif
+
         CopyKeyClass(from, to);
     } else if (to->key && !from->key)
     {
commit 755f9e5d7898056cf3bead69ce25a10e23995582
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Sun Apr 13 16:49:25 2008 +0930

    dix: Ignore focus for passive grabs if the event is a pointer event.

diff --git a/dix/events.c b/dix/events.c
index 1b62db0..e25ec30 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3546,7 +3546,7 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
 {
     int i;
     WindowPtr pWin = NULL;
-    FocusClassPtr focus = device->focus;
+    FocusClassPtr focus = IsPointerEvent(xE) ? NULL : device->focus;
     xEvent core;
     BOOL sendCore = (device->isMaster && device->coreEvents);
 
commit 6faf5b97b92953c331d6540ceb18fd0a77197fea
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Sun Apr 13 15:42:33 2008 +0930

    Xi: fix up modifierKeyMap copying.
    
    Setting it to NULL isn't correct either. The correct behaviour is to realloc
    it to the size necessary (or newly alloc it/free it).  Otherwise we have a
    memleak.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 6fa08d1..cf0e898 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -176,11 +176,16 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
 
         if (dk->maxKeysPerModifier)
         {
-            mk->modifierKeyMap = xcalloc(8, dk->maxKeysPerModifier);
+            mk->modifierKeyMap = xrealloc(mk->modifierKeyMap,
+                                          8 * dk->maxKeysPerModifier);
             if (!mk->modifierKeyMap)
                 FatalError("[Xi] no memory for class shift.\n");
             memcpy(mk->modifierKeyMap, dk->modifierKeyMap,
                     (8 * dk->maxKeysPerModifier));
+        } else
+        {
+            xfree(mk->modifierKeyMap);
+            mk->modifierKeyMap = NULL;
         }
 
         mk->maxKeysPerModifier = dk->maxKeysPerModifier;
@@ -439,7 +444,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
 #ifdef XKB
         to->key->xkbInfo = NULL;
 #endif
-        to->key->modifierKeyMap = NULL;
         to->key->curKeySyms.map = NULL;
         CopyKeyClass(from, to);
     } else if (to->key && !from->key)
commit 3106ba1116e3b9d893f66a93e4a91cc61e23226a
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Sun Apr 13 11:48:06 2008 +0930

    xkb: two fixes to avoid server crashes.
    
    - map can be NULL in some cases, so don't try to dereference it.
    - don't default to inputInfo.keyboard
    
    This is firefighting, I presume something in the class copy may have gone
    wrong to get a NULL map in the first instance?

diff --git a/xkb/xkbLEDs.c b/xkb/xkbLEDs.c
index d7ada57..1ea3e11 100644
--- a/xkb/xkbLEDs.c
+++ b/xkb/xkbLEDs.c
@@ -447,7 +447,7 @@ XkbIndicatorMapPtr	map;
 XkbDescPtr		xkb;
 
     if ((sli->flags&XkbSLI_HasOwnState)==0)
-	dev= inputInfo.keyboard;
+        return;
 
     sli->usesBase&=	 ~which;
     sli->usesLatched&=	 ~which;
@@ -462,7 +462,7 @@ XkbDescPtr		xkb;
 	if (which&bit) {
 	    CARD8		what;
 
-	    if (!XkbIM_InUse(map)) 
+	    if (!map || !XkbIM_InUse(map))
 		continue;
 	    sli->mapsPresent|= bit;
 
commit 415c6df0da1197d487456b4c48e2e28e7ded8b8e
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Sun Apr 13 11:46:44 2008 +0930

    Xi: copy feedback classes first, in some cases xkb relies on kbdfeed.
    
    XkbInitIndicatorMap (in XkbInitDevice) calls XkbFindSrvLedInfo. This accesses
    the devices kbdfeed struct, which is all nice and dandy if it is NULL. When
    copying the device classes however, kbdfeed may not be NULL and thus
    XkbFindSrvLedInfo goes on its merry way to do whatever it does.
    
    By copying kbdfeed first, we avoid XkbFSLI to reference the "old" kbdfeed
    struct of the previous SD.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 1d4dc51..6fa08d1 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -416,6 +416,11 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
 _X_EXPORT void
 DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
 {
+    /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the
+     * kbdfeed to be set up properly, so let's do the feedback classes first.
+     */
+    DeepCopyFeedbackClasses(from, to);
+
 #define ALLOC_COPY_CLASS_IF(field, type) \
     if (from->field)\
     { \
@@ -528,7 +533,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
         to->absolute = NULL;
     }
 
-    DeepCopyFeedbackClasses(from, to);
 }
 
 /**
commit 961f6660902163e99727c2dcc1a039f32b083859
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Sun Apr 13 09:31:16 2008 +0930

    Xi: modifierKeyMap needs to be set to NULL when copying classes.
    
    Otherwise we have a double reference to the same memory area.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 815eb7c..1d4dc51 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -434,6 +434,7 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
 #ifdef XKB
         to->key->xkbInfo = NULL;
 #endif
+        to->key->modifierKeyMap = NULL;
         to->key->curKeySyms.map = NULL;
         CopyKeyClass(from, to);
     } else if (to->key && !from->key)
commit bf6679cba40a936d46008c886d204ed521a4971a
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Sun Apr 13 08:28:07 2008 +0930

    Xi: copy the XkbSrvLedInfo too when copying device classes.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index a93fef4..815eb7c 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -263,7 +263,11 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
             (*k)->BellProc = it->BellProc;
             (*k)->CtrlProc = it->CtrlProc;
             (*k)->ctrl     = it->ctrl;
-            /* XXX: xkb_sli needs to be copied */
+#ifdef XKB
+            if ((*k)->xkb_sli)
+                XkbFreeSrvLedInfo((*k)->xkb_sli);
+            (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL);
+#endif
 
             k = &(*k)->next;
         }
@@ -289,7 +293,6 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
             }
             (*p)->CtrlProc = it->CtrlProc;
             (*p)->ctrl     = it->ctrl;
-            /* XXX: xkb_sli needs to be copied */
 
             p = &(*p)->next;
         }
@@ -391,7 +394,11 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
             }
             (*l)->CtrlProc = it->CtrlProc;
             (*l)->ctrl     = it->ctrl;
-            /* XXX: xkb_sli needs to be copied */
+#ifdef XKB
+            if ((*l)->xkb_sli)
+                XkbFreeSrvLedInfo((*l)->xkb_sli);
+            (*l)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, NULL, *l);
+#endif
 
             l = &(*l)->next;
         }
commit 4219e94c2f7d431be433eceddfe79760a1ee31a1
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Sun Apr 13 08:27:31 2008 +0930

    xkb: Add XkbCopySrvLedInfo, deep-copies a XkbSrvLedInfoRec.

diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index fef341a..7db9eef 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -576,6 +576,14 @@ extern XkbSrvLedInfoPtr XkbAllocSrvLedInfo(
     unsigned int		/* needed_parts */
 );
 
+extern XkbSrvLedInfoPtr XkbCopySrvLedInfo(
+    DeviceIntPtr		/* dev */,
+    XkbSrvLedInfoPtr		/* src */,
+    KbdFeedbackPtr		/* kf */,
+    LedFeedbackPtr		/* lf */
+);
+
+
 extern XkbSrvLedInfoPtr XkbFindSrvLedInfo(
     DeviceIntPtr		/* dev */,
     unsigned int		/* class */,
diff --git a/xkb/xkbLEDs.c b/xkb/xkbLEDs.c
index 55ce12a..d7ada57 100644
--- a/xkb/xkbLEDs.c
+++ b/xkb/xkbLEDs.c
@@ -615,6 +615,45 @@ XkbFreeSrvLedInfo(XkbSrvLedInfoPtr sli)
     return;
 }
 
+/*
+ * XkbSrvLedInfoPtr
+ * XkbCopySrvLedInfo(dev,src,kf,lf)
+ *
+ * Takes the given XkbSrvLedInfoPtr and duplicates it. A deep copy is made,
+ * thus the new copy behaves like the original one and can be freed with
+ * XkbFreeSrvLedInfo.
+ */
+XkbSrvLedInfoPtr
+XkbCopySrvLedInfo(	DeviceIntPtr		from,
+			XkbSrvLedInfoPtr	src,
+			KbdFeedbackPtr		kf,
+			LedFeedbackPtr		lf)
+{
+    XkbSrvLedInfoPtr sli_new;
+
+    if (!src)
+	goto finish;
+
+    sli_new = _XkbTypedCalloc(1, XkbSrvLedInfoRec);
+    if (!sli_new)
+	goto finish;
+
+    memcpy(src, sli_new, sizeof(XkbSrvLedInfoRec));
+    if (sli_new->class == KbdFeedbackClass)
+	sli_new->fb.kf = kf;
+    else
+	sli_new->fb.lf = lf;
+
+    if (sli_new->flags & XkbSLI_IsDefault) {
+	sli_new->names= _XkbTypedCalloc(XkbNumIndicators,Atom);
+	sli_new->maps= _XkbTypedCalloc(XkbNumIndicators,XkbIndicatorMapRec);
+    } /* else sli_new->names/maps is pointing to
+	dev->key->xkbInfo->desc->names->indicators;
+	dev->key->xkbInfo->desc->names->indicators; */
+
+finish:
+    return sli_new;
+}
 
 /***====================================================================***/
 


More information about the xorg-commit mailing list