summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 */,