summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2011-11-04 10:44:31 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2011-12-09 14:56:23 +1000
commitb0e9e2e32616d09c30a02b9d0ae9db0b13e150d1 (patch)
treeed56b40166201c019ab02924fc8c0596f59a0f84
parent347f377f3b3f8c9d230d6309ec8ae92aa86d78b7 (diff)
dix: add CopyGrab() function
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@who-t.net> Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
-rw-r--r--dix/events.c4
-rw-r--r--dix/grabs.c34
-rw-r--r--include/dixgrabs.h1
3 files changed, 37 insertions, 2 deletions
diff --git a/dix/events.c b/dix/events.c
index 3c21a964c..c1c296d22 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1509,7 +1509,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;
@@ -1586,7 +1586,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 3b07186ea..a1d56c5ed 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 2ed8a54b4..65ff45d1d 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 */,