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