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
|
int
|
||||||
AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
|
AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
|
||||||
{
|
{
|
||||||
|
DeviceIntPtr oldmaster;
|
||||||
if (!dev || dev->isMaster)
|
if (!dev || dev->isMaster)
|
||||||
return BadDevice;
|
return BadDevice;
|
||||||
|
|
||||||
|
@ -2409,6 +2410,7 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
|
||||||
if (!dev->u.master && dev->spriteInfo->sprite)
|
if (!dev->u.master && dev->spriteInfo->sprite)
|
||||||
xfree(dev->spriteInfo->sprite);
|
xfree(dev->spriteInfo->sprite);
|
||||||
|
|
||||||
|
oldmaster = dev->u.master;
|
||||||
dev->u.master = master;
|
dev->u.master = master;
|
||||||
|
|
||||||
/* If device is set to floating, we need to create a sprite for it,
|
/* 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)
|
if (!master)
|
||||||
{
|
{
|
||||||
DeviceIntPtr it;
|
|
||||||
/* current root window */
|
/* current root window */
|
||||||
InitializeSprite(dev, dev->spriteInfo->sprite->spriteTrace[0]);
|
InitializeSprite(dev, dev->spriteInfo->sprite->spriteTrace[0]);
|
||||||
dev->spriteInfo->spriteOwner = FALSE;
|
dev->spriteInfo->spriteOwner = FALSE;
|
||||||
|
|
||||||
/* the master may need to restore the original classes, search for a
|
} else
|
||||||
* device that is still paired with our master. */
|
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)
|
for (it = inputInfo.devices; it; it = it->next)
|
||||||
if (!it->isMaster && it->u.master == master)
|
if (!it->isMaster && it->u.master == oldmaster)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!it) /* no dev is paired with our master */
|
if (!it) /* no dev is paired with old master */
|
||||||
{
|
{
|
||||||
ClassesPtr classes;
|
ClassesPtr classes;
|
||||||
EventList event = { NULL, 0};
|
EventList event = { NULL, 0};
|
||||||
char* classbuf;
|
char* classbuf;
|
||||||
|
DeviceIntRec dummy;
|
||||||
|
|
||||||
classes = master->devPrivates[MasterDevClassesPrivIdx].ptr;
|
FreeAllDeviceClasses((ClassesPtr)&oldmaster->key);
|
||||||
master->key = classes->key;
|
classes = oldmaster->devPrivates[MasterDevClassesPrivIdx].ptr;
|
||||||
master->valuator = classes->valuator;
|
memcpy(&dummy.key, classes, sizeof(ClassesRec));
|
||||||
master->button = classes->button;
|
DeepCopyDeviceClasses(&dummy, oldmaster);
|
||||||
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;
|
|
||||||
|
|
||||||
/* Send event to clients */
|
/* Send event to clients */
|
||||||
CreateClassesChangedEvent(&event, master, master);
|
CreateClassesChangedEvent(&event, oldmaster, oldmaster);
|
||||||
deviceClassesChangedEvent *dcce =
|
deviceClassesChangedEvent *dcce =
|
||||||
(deviceClassesChangedEvent*)event.event;
|
(deviceClassesChangedEvent*)event.event;
|
||||||
dcce->deviceid = master->id;
|
dcce->deviceid = oldmaster->id;
|
||||||
dcce->num_classes = 0;
|
dcce->num_classes = 0;
|
||||||
classbuf = (char*)&event.event[1];
|
classbuf = (char*)&event.event[1];
|
||||||
CopySwapClasses(NullClient, master, &dcce->num_classes, &classbuf);
|
CopySwapClasses(NullClient, oldmaster,
|
||||||
SendEventToAllWindows(master, XI_DeviceClassesChangedMask,
|
&dcce->num_classes, &classbuf);
|
||||||
|
SendEventToAllWindows(oldmaster, XI_DeviceClassesChangedMask,
|
||||||
event.event, 1);
|
event.event, 1);
|
||||||
xfree(event.event);
|
xfree(event.event);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else
|
|
||||||
dev->spriteInfo->sprite = master->spriteInfo->sprite;
|
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue