From 8e0a6529303a52acc10905dd47c72a0d60979676 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 10 Apr 2008 08:25:36 +0930 Subject: [PATCH] dix: When floating, set sprite to NULL before calling InitializeSprite. InitializeSprite won't create a new one if it already exists, with the result of overwriting the master's sprite. This master sprite is then assigned to the floating slave, and freed when the slave is reattached later. Setting the sprite to NULL forces InitializeSprite to alloc a new one, and this one can be freed without further repercussions. --- dix/devices.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/dix/devices.c b/dix/devices.c index c4cde2660..df194de17 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -2506,7 +2506,7 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) return Success; /* free the existing sprite. */ - if (!dev->u.master && dev->spriteInfo->sprite) + if (!dev->u.master && dev->spriteInfo->paired == dev) xfree(dev->spriteInfo->sprite); oldmaster = dev->u.master; @@ -2515,15 +2515,22 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) /* If device is set to floating, we need to create a sprite for it, * otherwise things go bad. However, we don't want to render the cursor, * so we reset spriteOwner. + * Sprite has to be forced to NULL first, otherwise InitializeSprite won't + * alloc new memory but overwrite the previous one. */ if (!master) { - /* current root window */ - InitializeSprite(dev, dev->spriteInfo->sprite->spriteTrace[0]); + WindowPtr currentRoot = dev->spriteInfo->sprite->spriteTrace[0]; + dev->spriteInfo->sprite = NULL; + InitializeSprite(dev, currentRoot); dev->spriteInfo->spriteOwner = FALSE; - + dev->spriteInfo->paired = dev; } else + { dev->spriteInfo->sprite = master->spriteInfo->sprite; + dev->spriteInfo->paired = master; + dev->spriteInfo->spriteOwner = FALSE; + } /* If we were connected to master device before, this MD may need to * change back to it's original classes.