dix: fix cursor refcounting
authorPeter Hutterer <peter.hutterer@who-t.net>
Fri, 3 May 2013 05:07:58 +0000 (15:07 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Wed, 15 May 2013 09:16:59 +0000 (19:16 +1000)
The cursor is referenced during CopyGrab(), thus doesn't need to be handled
manually anymore. It does need to be refcounted for temp grabs though.

The oldGrab handling in ProcGrabPointer is a leftover from the cursor in the
grab being refcounted, but the grab itself being a static struct in the
DeviceIntRec. Now that all grabs are copied, this lead to a double-free of
the cursor (Reproduced in Thunderbird, dragging an email twice (or more
often) causes a crash).

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
dix/events.c

index 7464db5..8124ca9 100644 (file)
@@ -1491,9 +1491,6 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
         grabinfo->grabTime = syncEvents.time;
     else
         grabinfo->grabTime = time;
-    if (grab->cursor)
-        grab->cursor->refcnt++;
-    BUG_WARN(grabinfo->grab != NULL);
     grabinfo->grab = AllocGrab(grab);
     grabinfo->fromPassiveGrab = isPassive;
     grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
@@ -1552,8 +1549,6 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
     if (grab->confineTo)
         ConfineCursorToWindow(mouse, GetCurrentRootWindow(mouse), FALSE, FALSE);
     PostNewCursor(mouse);
-    if (grab->cursor)
-        FreeCursor(grab->cursor, (Cursor) 0);
 
     if (!wasImplicit && grab->grabtype == XI2)
         ReattachToOldMaster(mouse);
@@ -4860,7 +4855,6 @@ ProcGrabPointer(ClientPtr client)
     GrabPtr grab;
     GrabMask mask;
     WindowPtr confineTo;
-    CursorPtr oldCursor;
     BYTE status;
 
     REQUEST(xGrabPointerReq);
@@ -4883,15 +4877,10 @@ ProcGrabPointer(ClientPtr client)
             return rc;
     }
 
-    oldCursor = NullCursor;
     grab = device->deviceGrab.grab;
 
-    if (grab) {
-        if (grab->confineTo && !confineTo)
-            ConfineCursorToWindow(device, GetCurrentRootWindow(device), FALSE,
-                                  FALSE);
-        oldCursor = grab->cursor;
-    }
+    if (grab && grab->confineTo && !confineTo)
+        ConfineCursorToWindow(device, GetCurrentRootWindow(device), FALSE, FALSE);
 
     mask.core = stuff->eventMask;
 
@@ -4901,9 +4890,6 @@ ProcGrabPointer(ClientPtr client)
     if (rc != Success)
         return rc;
 
-    if (oldCursor && status == GrabSuccess)
-        FreeCursor(oldCursor, (Cursor) 0);
-
     rep = (xGrabPointerReply) {
         .type = X_Reply,
         .status = status,
@@ -5107,6 +5093,8 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
             xi2mask_merge(tempGrab->xi2mask, mask->xi2mask);
         tempGrab->device = dev;
         tempGrab->cursor = cursor;
+        if (cursor)
+            tempGrab->cursor->refcnt++;
         tempGrab->confineTo = confineTo;
         tempGrab->grabtype = grabtype;
         (*grabInfo->ActivateGrab) (dev, tempGrab, time, FALSE);