[PATCH 08/12] dix: add CopyGrab() function

Peter Hutterer peter.hutterer at who-t.net
Mon Nov 7 13:39:12 PST 2011


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 <peter.hutterer at who-t.net>
---
 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



More information about the xorg-devel mailing list