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.
This commit is contained in:
parent
83926cb8be
commit
9de1ebe2a8
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user