xserver: Branch 'mpx' - 6 commits

Peter Hutterer whot at kemper.freedesktop.org
Wed Nov 14 22:15:01 PST 2007


 Xi/exevents.c      |   49 +++++----
 dix/devices.c      |  276 ++++++++++++++++++++++++++++++++++-------------------
 include/input.h    |    4 
 include/inputstr.h |   16 +++
 xkb/xkbPrKeyEv.c   |    2 
 5 files changed, 226 insertions(+), 121 deletions(-)

New commits:
commit 070195dbf88eb121e65f802e023aa37ed1f2c2ac
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu Nov 15 16:27:18 2007 +1030

    Xi: fix up sloppy class copying causing segfaults.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 5395011..837afa3 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -220,6 +220,7 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
 #ifdef XKB
         to->key->xkbInfo = NULL;
 #endif
+        to->key->curKeySyms.map = NULL;
         CopyKeyClass(from, to);
     }
 
@@ -233,8 +234,12 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
         if (!v)
             FatalError("[Xi] no memory for class shift.\n");
         memcpy(v, from->valuator, sizeof(ValuatorClassRec));
+        v->motion = NULL;
+
         v->axes = (AxisInfoPtr)&v[1];
         memcpy(v->axes, from->valuator->axes, v->numAxes * sizeof(AxisInfo));
+
+        v->axisVal = (int*)(v->axes + from->valuator->numAxes);
     }
 
     ALLOC_COPY_CLASS_IF(button, ButtonClassRec);
commit 53539688cab990a7df1851d64f3ee4e11920a86b
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu Nov 15 16:23:48 2007 +1030

    dix: SetKeySymMap should alloc the map if dst doesn't have one already.

diff --git a/dix/devices.c b/dix/devices.c
index bf1126f..1792e9e 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1046,10 +1046,9 @@ SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src)
         KeySym *map;
 	int bytes = sizeof(KeySym) * src->mapWidth *
 		    (dst->maxKeyCode - dst->minKeyCode + 1);
-        map = (KeySym *)xalloc(bytes);
+        map = (KeySym *)xcalloc(1, bytes);
 	if (!map)
 	    return FALSE;
-	bzero((char *)map, bytes);
         if (dst->map)
 	{
             for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++)
@@ -1060,6 +1059,15 @@ SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src)
 	}
 	dst->mapWidth = src->mapWidth;
 	dst->map = map;
+    } else if (!dst->map)
+    {
+        KeySym *map;
+	int bytes = sizeof(KeySym) * src->mapWidth *
+		    (dst->maxKeyCode - dst->minKeyCode + 1);
+        map = (KeySym *)xcalloc(1, bytes);
+        if (!map)
+            return FALSE;
+        dst->map = map;
     }
     memmove((char *)&dst->map[rowDif * dst->mapWidth],
 	    (char *)src->map,
commit b40646dc104fb03ea7cc0b27fae573aecaab486e
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu Nov 15 15:43:44 2007 +1030

    dix: Add FreeDeviceClass and FreeFeedbackClass for centralised xfree.
    
    Ensures that we only have one way of freeing a device class to avoid leaks in
    ChangeMasterDeviceClasses and other places.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index f9ea1c9..5395011 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -288,34 +288,7 @@ ChangeMasterDeviceClasses(DeviceIntPtr device,
 
     master->public.devicePrivate = device->public.devicePrivate;
 
-    if (master->key)
-        xfree(master->key->modifierKeyMap);
-#ifdef XKB
-    if (master->key && master->key->xkbInfo)
-        XkbFreeInfo(master->key->xkbInfo);
-#endif
-    xfree(master->key);         master->key = NULL;
-    xfree(master->valuator);    master->valuator = NULL;
-    /* XXX: xkb_acts needs to be freed for master->button */
-    xfree(master->button);      master->button = NULL;
-    xfree(master->focus);       master->focus = NULL;
-    xfree(master->proximity);   master->proximity = NULL;
-    xfree(master->absolute);    master->absolute = NULL;
-#ifdef XKB
-    if (master->kbdfeed && master->kbdfeed->xkb_sli)
-        XkbFreeSrvLedInfo(master->kbdfeed->xkb_sli);
-#endif
-    xfree(master->kbdfeed);     master->kbdfeed = NULL;
-    xfree(master->ptrfeed);     master->ptrfeed = NULL;
-    xfree(master->stringfeed);  master->stringfeed = NULL;
-    xfree(master->bell);        master->bell = NULL;
-#ifdef XKB
-    if (master->leds && master->leds->xkb_sli)
-        XkbFreeSrvLedInfo(master->leds->xkb_sli);
-#endif
-    xfree(master->leds);        master->leds = NULL;
-    xfree(master->intfeed);     master->intfeed = NULL;
-
+    FreeAllDeviceClasses(&master->key);
     DeepCopyDeviceClasses(device, master);
 
     /* event is already correct size, see comment in GetPointerEvents */
diff --git a/dix/devices.c b/dix/devices.c
index 65d1980..bf1126f 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -85,22 +85,6 @@ SOFTWARE.
  * This file handles input device-related stuff.
  */
 
-typedef struct {
-    KeyClassPtr		key;
-    ValuatorClassPtr	valuator;
-    ButtonClassPtr	button;
-    FocusClassPtr	focus;
-    ProximityClassPtr	proximity;
-    AbsoluteClassPtr    absolute;
-    KbdFeedbackPtr	kbdfeed;
-    PtrFeedbackPtr	ptrfeed;
-    IntegerFeedbackPtr	intfeed;
-    StringFeedbackPtr	stringfeed;
-    BellFeedbackPtr	bell;
-    LedFeedbackPtr	leds;
-} ClassesRec, *ClassesPtr;
-
-
 int CoreDevicePrivatesIndex = 0;
 static int CoreDevicePrivatesGeneration = -1;
 int MasterDevClassesPrivIdx = -1;
@@ -638,6 +622,174 @@ InitAndStartDevices(WindowPtr root)
     return Success;
 }
 
+_X_EXPORT void
+FreeAllDeviceClasses(ClassesPtr classes)
+{
+    if (!classes)
+        return;
+
+    FreeDeviceClass(KeyClass, (pointer)&classes->key);
+    FreeDeviceClass(ValuatorClass, (pointer)&classes->valuator);
+    FreeDeviceClass(ButtonClass, (pointer)&classes->button);
+    FreeDeviceClass(FocusClass, (pointer)&classes->focus);
+    FreeDeviceClass(ProximityClass, (pointer)&classes->proximity);
+
+    FreeFeedbackClass(KbdFeedbackClass, (pointer)&classes->kbdfeed);
+    FreeFeedbackClass(PtrFeedbackClass, (pointer)&classes->ptrfeed);
+    FreeFeedbackClass(IntegerFeedbackClass, (pointer)&classes->intfeed);
+    FreeFeedbackClass(StringFeedbackClass, (pointer)&classes->stringfeed);
+    FreeFeedbackClass(BellFeedbackClass, (pointer)&classes->bell);
+    FreeFeedbackClass(LedFeedbackClass, (pointer)&classes->leds);
+
+}
+
+/**
+ * Free the given device class and reset the pointer to NULL.
+ */
+_X_EXPORT void
+FreeDeviceClass(int type, pointer *class)
+{
+    if (!(*class))
+        return;
+
+    switch(type)
+    {
+        case KeyClass:
+            {
+                KeyClassPtr* k = (KeyClassPtr*)class;
+#ifdef XKB
+                if ((*k)->xkbInfo)
+                    XkbFreeInfo((*k)->xkbInfo);
+#endif
+
+                xfree((*k)->curKeySyms.map);
+                xfree((*k)->modifierKeyMap);
+                xfree((*k));
+                break;
+            }
+        case ButtonClass:
+            {
+                ButtonClassPtr *b = (ButtonClassPtr*)class;
+#ifdef XKB
+                if ((*b)->xkb_acts)
+                    xfree((*b)->xkb_acts);
+#endif
+                xfree((*b));
+                break;
+            }
+        case ValuatorClass:
+            {
+                ValuatorClassPtr *v = (ValuatorClassPtr*)class;
+
+                /* Counterpart to 'biggest hack ever' in init. */
+                if ((*v)->motion && (*v)->GetMotionProc == GetMotionHistory)
+                    xfree((*v)->motion);
+                xfree((*v));
+                break;
+            }
+        case FocusClass:
+            {
+                FocusClassPtr *f = (FocusClassPtr*)class;
+                xfree((*f)->trace);
+                xfree((*f));
+                break;
+            }
+        case ProximityClass:
+            {
+                ProximityClassPtr *p = (ProximityClassPtr*)class;
+                xfree((*p));
+                break;
+            }
+
+    }
+    *class = NULL;
+}
+_X_EXPORT void
+FreeFeedbackClass(int type, pointer *class)
+{
+    if (!(*class))
+        return;
+
+    switch(type)
+    {
+        case KbdFeedbackClass:
+            {
+                KbdFeedbackPtr *kbdfeed = (KbdFeedbackPtr*)class;
+                KbdFeedbackPtr k, knext;
+                for (k = (*kbdfeed); k; k = knext) {
+                    knext = k->next;
+#ifdef XKB
+                    if (k->xkb_sli)
+                        XkbFreeSrvLedInfo(k->xkb_sli);
+#endif
+                    xfree(k);
+                }
+                break;
+            }
+        case PtrFeedbackClass:
+            {
+                PtrFeedbackPtr *ptrfeed = (PtrFeedbackPtr*)class;
+                PtrFeedbackPtr p, pnext;
+
+                for (p = (*ptrfeed); p; p = pnext) {
+                    pnext = p->next;
+                    xfree(p);
+                }
+                break;
+            }
+        case IntegerFeedbackClass:
+            {
+                IntegerFeedbackPtr *intfeed = (IntegerFeedbackPtr*)class;
+                IntegerFeedbackPtr i, inext;
+
+                for (i = (*intfeed); i; i = inext) {
+                    inext = i->next;
+                    xfree(i);
+                }
+                break;
+            }
+        case StringFeedbackClass:
+            {
+                StringFeedbackPtr *stringfeed = (StringFeedbackPtr*)class;
+                StringFeedbackPtr s, snext;
+
+                for (s = (*stringfeed); s; s = snext) {
+                    snext = s->next;
+                    xfree(s->ctrl.symbols_supported);
+                    xfree(s->ctrl.symbols_displayed);
+                    xfree(s);
+                }
+                break;
+            }
+        case BellFeedbackClass:
+            {
+                BellFeedbackPtr *bell = (BellFeedbackPtr*)class;
+                BellFeedbackPtr b, bnext;
+
+                for (b = (*bell); b; b = bnext) {
+                    bnext = b->next;
+                    xfree(b);
+                }
+                break;
+            }
+        case LedFeedbackClass:
+            {
+                LedFeedbackPtr *leds = (LedFeedbackPtr*)class;
+                LedFeedbackPtr l, lnext;
+
+                for (l = (*leds); l; l = lnext) {
+                    lnext = l->next;
+#ifdef XKB
+                    if (l->xkb_sli)
+                        XkbFreeSrvLedInfo(l->xkb_sli);
+#endif
+                    xfree(l);
+                }
+                break;
+            }
+    }
+    *class = NULL;
+}
 /**
  * Close down a device and free all resources.
  * Once closed down, the driver will probably not expect you that you'll ever
@@ -648,12 +800,6 @@ InitAndStartDevices(WindowPtr root)
 static void
 CloseDevice(DeviceIntPtr dev)
 {
-    KbdFeedbackPtr k, knext;
-    PtrFeedbackPtr p, pnext;
-    IntegerFeedbackPtr i, inext;
-    StringFeedbackPtr s, snext;
-    BellFeedbackPtr b, bnext;
-    LedFeedbackPtr l, lnext;
     ScreenPtr screen = screenInfo.screens[0];
     ClassesPtr classes;
     int j;
@@ -675,79 +821,7 @@ CloseDevice(DeviceIntPtr dev)
     else
         classes = (ClassesPtr)&dev->key;
 
-    if (classes->key) {
-#ifdef XKB
-	if (classes->key->xkbInfo)
-	    XkbFreeInfo(classes->key->xkbInfo);
-#endif
-	xfree(classes->key->curKeySyms.map);
-	xfree(classes->key->modifierKeyMap);
-	xfree(classes->key);
-    }
-
-    if (classes->valuator) {
-        /* Counterpart to 'biggest hack ever' in init. */
-        if (classes->valuator->motion &&
-            classes->valuator->GetMotionProc == GetMotionHistory)
-            xfree(classes->valuator->motion);
-        xfree(classes->valuator);
-    }
-
-    if (classes->button) {
-#ifdef XKB
-        if (classes->button->xkb_acts)
-            xfree(classes->button->xkb_acts);
-#endif
-        xfree(classes->button);
-    }
-
-    if (classes->focus) {
-	xfree(classes->focus->trace);
-	xfree(classes->focus);
-    }
-
-    if (classes->proximity)
-        xfree(classes->proximity);
-
-    for (k = classes->kbdfeed; k; k = knext) {
-	knext = k->next;
-#ifdef XKB
-	if (k->xkb_sli)
-	    XkbFreeSrvLedInfo(k->xkb_sli);
-#endif
-	xfree(k);
-    }
-
-    for (p = classes->ptrfeed; p; p = pnext) {
-	pnext = p->next;
-	xfree(p);
-    }
-
-    for (i = classes->intfeed; i; i = inext) {
-	inext = i->next;
-	xfree(i);
-    }
-
-    for (s = classes->stringfeed; s; s = snext) {
-	snext = s->next;
-	xfree(s->ctrl.symbols_supported);
-	xfree(s->ctrl.symbols_displayed);
-	xfree(s);
-    }
-
-    for (b = classes->bell; b; b = bnext) {
-	bnext = b->next;
-	xfree(b);
-    }
-
-    for (l = classes->leds; l; l = lnext) {
-	lnext = l->next;
-#ifdef XKB
-	if (l->xkb_sli)
-	    XkbFreeSrvLedInfo(l->xkb_sli);
-#endif
-	xfree(l);
-    }
+    FreeAllDeviceClasses(classes);
 
 #ifdef XKB
     while (dev->xkb_interest)
diff --git a/include/input.h b/include/input.h
index 91ce4ee..9e73dc2 100644
--- a/include/input.h
+++ b/include/input.h
@@ -84,6 +84,7 @@ typedef unsigned long Leds;
 typedef struct _OtherClients *OtherClientsPtr;
 typedef struct _InputClients *InputClientsPtr;
 typedef struct _DeviceIntRec *DeviceIntPtr;
+typedef struct _ClassesRec *ClassesPtr;
 
 typedef struct _EventList {
     xEvent* event;
@@ -484,6 +485,9 @@ extern int AllocMasterDevice(char* name,
                              DeviceIntPtr* keybd);
 extern void DeepCopyDeviceClasses(DeviceIntPtr from,
                                   DeviceIntPtr to);
+extern void FreeDeviceClass(int type, pointer* class);
+extern void FreeFeedbackClass(int type, pointer* class);
+extern void FreeAllDeviceClasses(ClassesPtr classes);
 
 /* Window/device based access control */
 extern Bool ACRegisterClient(ClientPtr client);
diff --git a/include/inputstr.h b/include/inputstr.h
index 507e7b0..0589097 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -283,6 +283,22 @@ typedef struct _LedFeedbackClassRec {
 } LedFeedbackClassRec;
 
 
+typedef struct _ClassesRec {
+    KeyClassPtr		key;
+    ValuatorClassPtr	valuator;
+    ButtonClassPtr	button;
+    FocusClassPtr	focus;
+    ProximityClassPtr	proximity;
+    AbsoluteClassPtr    absolute;
+    KbdFeedbackPtr	kbdfeed;
+    PtrFeedbackPtr	ptrfeed;
+    IntegerFeedbackPtr	intfeed;
+    StringFeedbackPtr	stringfeed;
+    BellFeedbackPtr	bell;
+    LedFeedbackPtr	leds;
+} ClassesRec;
+
+
 /**
  * Sprite information for a device.
  */
commit 18833d648fd7e1a5e962b93636bbbb38aca9c454
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu Nov 15 12:13:59 2007 +1030

    Xi: reset xkb-stuff to NULL after copying (DeepCopyDeviceClasses)
    
    Having two devices point to the same xkb stuff causes SIGABRTs.
    
    Also, don't init a MD's xkbInfo unless the SD has an xkbInfo.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 158f523..f9ea1c9 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -178,9 +178,9 @@ CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
             mk->modifierKeyCount[i] = dk->modifierKeyCount[i];
 
 #ifdef XKB
-        if (!mk->xkbInfo || !mk->xkbInfo->desc)
-            XkbInitDevice(master);
         if (!noXkbExtension && dk->xkbInfo && dk->xkbInfo->desc) {
+            if (!mk->xkbInfo || !mk->xkbInfo->desc)
+                XkbInitDevice(master);
             if (!XkbCopyKeymap(dk->xkbInfo->desc, mk->xkbInfo->desc, True))
                 FatalError("Couldn't pivot keymap from device to core!\n");
         }
@@ -238,18 +238,36 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
     }
 
     ALLOC_COPY_CLASS_IF(button, ButtonClassRec);
+#ifdef XKB
+    if (to->button)
+    {
+        to->button->xkb_acts = NULL;
         /* XXX: XkbAction needs to be copied */
+    }
+#endif
     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*/
+    }
+#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);
-        /* XXX: XkbSrvLedInfo needs to be copied. */
+#ifdef XKB
+    if (to->leds)
+    {
+        to->leds->xkb_sli = NULL;
+        /* XXX: XkbSrvLedInfo needs to be copied*/
+    }
+#endif
 }
 
 static void
commit 1635832c1635374033686d3a943b77adbd60bb98
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu Nov 15 11:35:07 2007 +1030

    Revert "xkb: disable xkb key repeats (temporarily)"
    
    This reverts commit 2b1d946392ce28b96941341778b2b526aa0fb126.

diff --git a/xkb/xkbPrKeyEv.c b/xkb/xkbPrKeyEv.c
index 147df3e..f007f75 100644
--- a/xkb/xkbPrKeyEv.c
+++ b/xkb/xkbPrKeyEv.c
@@ -76,7 +76,6 @@ int             xiEvent;
     if ((behavior.type&XkbKB_Permanent)==0) {
 	switch (behavior.type) {
 	    case XkbKB_Default:
-#if 0
 		if (( xE->u.u.type == KeyPress || 
                             xE->u.u.type == DeviceKeyPress) && 
 		    (keyc->down[key>>3] & (1<<(key&7)))) {
@@ -113,7 +112,6 @@ int             xiEvent;
 		    XkbLastRepeatEvent= NULL;
 		    return;
 		}
-#endif
 		break;
 	    case XkbKB_Lock:
 		if ( xE->u.u.type == KeyRelease || 
commit b05246696d14bd35aa53b49302707b51206c72a6
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu Nov 15 11:31:43 2007 +1030

    Xi: free XkbSrvLedInfos as well when freeing an MD's device classes.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 1bf6c51..158f523 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -278,14 +278,23 @@ ChangeMasterDeviceClasses(DeviceIntPtr device,
 #endif
     xfree(master->key);         master->key = NULL;
     xfree(master->valuator);    master->valuator = NULL;
+    /* XXX: xkb_acts needs to be freed for master->button */
     xfree(master->button);      master->button = NULL;
     xfree(master->focus);       master->focus = NULL;
     xfree(master->proximity);   master->proximity = NULL;
     xfree(master->absolute);    master->absolute = NULL;
+#ifdef XKB
+    if (master->kbdfeed && master->kbdfeed->xkb_sli)
+        XkbFreeSrvLedInfo(master->kbdfeed->xkb_sli);
+#endif
     xfree(master->kbdfeed);     master->kbdfeed = NULL;
     xfree(master->ptrfeed);     master->ptrfeed = NULL;
     xfree(master->stringfeed);  master->stringfeed = NULL;
     xfree(master->bell);        master->bell = NULL;
+#ifdef XKB
+    if (master->leds && master->leds->xkb_sli)
+        XkbFreeSrvLedInfo(master->leds->xkb_sli);
+#endif
     xfree(master->leds);        master->leds = NULL;
     xfree(master->intfeed);     master->intfeed = NULL;
 


More information about the xorg-commit mailing list