summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter@cs.unisa.edu.au>2007-11-16 10:45:28 +1030
committerPeter Hutterer <peter@cs.unisa.edu.au>2007-11-16 10:45:28 +1030
commit9de1ebe2a80164507cbe2ef688f284225e0ec808 (patch)
treeb54f07f8b9c852052476ec1c94bbbfa055baffff
parent83926cb8bef6288b89e801c5e60b3f40e923e16e (diff)
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.
-rw-r--r--dix/devices.c51
1 files changed, 25 insertions, 26 deletions
diff --git a/dix/devices.c b/dix/devices.c
index 1792e9e3f..045f74f0c 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;
}