Not really needed at this point, but will be once touch support is added.
Since grabs are now expected to be allocated/freed with AllocGrab and
FreeGrab, CopyGrab must increase the refcount and duplicate the modifier
masks. Until the callers are switched to use FreeGrab, this introduces
memleaks.

Signed-off-by: Peter Hutterer <[email protected]>
---
 dix/events.c       |    4 ++--
 dix/grabs.c        |   34 ++++++++++++++++++++++++++++++++++
 include/dixgrabs.h |    1 +
 3 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/dix/events.c b/dix/events.c
index 0269ebe..51856ae 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1510,7 +1510,7 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
        grabinfo->grabTime = time;
     if (grab->cursor)
        grab->cursor->refcnt++;
-    grabinfo->activeGrab = *grab;
+    CopyGrab(&grabinfo->activeGrab, grab);
     grabinfo->grab = &grabinfo->activeGrab;
     grabinfo->fromPassiveGrab = isPassive;
     grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
@@ -1587,7 +1587,7 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, 
TimeStamp time, Bool pass
        grabinfo->grabTime = syncEvents.time;
     else
        grabinfo->grabTime = time;
-    grabinfo->activeGrab = *grab;
+    CopyGrab(&grabinfo->activeGrab, grab);
     grabinfo->grab = &grabinfo->activeGrab;
     grabinfo->fromPassiveGrab = passive;
     grabinfo->implicitGrab = passive & ImplicitGrabMask;
diff --git a/dix/grabs.c b/dix/grabs.c
index 3b07186..a1d56c5 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -246,6 +246,40 @@ FreeGrab(GrabPtr pGrab)
     free(pGrab);
 }
 
+Bool
+CopyGrab(GrabPtr dst, const GrabPtr src)
+{
+    Mask *mdetails_mask = NULL;
+    Mask *details_mask = NULL;
+
+    if (src->cursor)
+        src->cursor->refcnt++;
+
+    if (src->modifiersDetail.pMask) {
+        int len = MasksPerDetailMask * sizeof(Mask);
+        mdetails_mask = malloc(len);
+        if (!mdetails_mask)
+            return FALSE;
+        memcpy(mdetails_mask, src->modifiersDetail.pMask, len);
+    }
+
+    if (src->detail.pMask) {
+        int len = MasksPerDetailMask * sizeof(Mask);
+        details_mask = malloc(len);
+        if (!details_mask) {
+            free(mdetails_mask);
+            return FALSE;
+        }
+        memcpy(details_mask, src->detail.pMask, len);
+    }
+
+    *dst = *src;
+    dst->modifiersDetail.pMask = mdetails_mask;
+    dst->detail.pMask = details_mask;
+
+    return TRUE;
+}
+
 int
 DeletePassiveGrab(pointer value, XID id)
 {
diff --git a/include/dixgrabs.h b/include/dixgrabs.h
index 2ed8a54..65ff45d 100644
--- a/include/dixgrabs.h
+++ b/include/dixgrabs.h
@@ -33,6 +33,7 @@ extern void UngrabAllDevices(Bool kill_client);
 
 extern GrabPtr AllocGrab(void);
 extern void FreeGrab(GrabPtr grab);
+extern Bool CopyGrab(GrabPtr dst, const GrabPtr src);
 
 extern GrabPtr CreateGrab(
        int /* client */,
-- 
1.7.7

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to