[PATCH 09/12] dix: allocate temporary grabs on the heap

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


Once grabs start having nested memory locations, we can't just use the
GrabRec on the stack anymore, we need to alloc/copy/free the grabs.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 Xi/exevents.c      |   29 +++++---
 Xi/ungrdevb.c      |   30 +++++---
 Xi/ungrdevk.c      |   29 +++++---
 Xi/xipassivegrab.c |   37 ++++++----
 dix/events.c       |  193 ++++++++++++++++++++++++++++-----------------------
 5 files changed, 180 insertions(+), 138 deletions(-)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 6c19ab3..0876af7 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -2022,20 +2022,25 @@ CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type,
 	dev->valuator->motionHintWindow = pWin;
     else if ((type == DeviceButtonPress) && (!grab) &&
 	     (deliveryMask & DeviceButtonGrabMask)) {
-	GrabRec tempGrab;
+        GrabPtr tempGrab;
 
-	tempGrab.device = dev;
-	tempGrab.resource = client->clientAsMask;
-	tempGrab.window = pWin;
-	tempGrab.ownerEvents =
+        tempGrab = AllocGrab();
+        if (!tempGrab)
+            return;
+
+	tempGrab->device = dev;
+	tempGrab->resource = client->clientAsMask;
+	tempGrab->window = pWin;
+	tempGrab->ownerEvents =
 	    (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE;
-	tempGrab.eventMask = deliveryMask;
-	tempGrab.keyboardMode = GrabModeAsync;
-	tempGrab.pointerMode = GrabModeAsync;
-	tempGrab.confineTo = NullWindow;
-	tempGrab.cursor = NullCursor;
-        tempGrab.next = NULL;
-	(*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE);
+	tempGrab->eventMask = deliveryMask;
+	tempGrab->keyboardMode = GrabModeAsync;
+	tempGrab->pointerMode = GrabModeAsync;
+	tempGrab->confineTo = NullWindow;
+	tempGrab->cursor = NullCursor;
+        tempGrab->next = NULL;
+	(*dev->deviceGrab.ActivateGrab) (dev, tempGrab, currentTime, TRUE);
+        FreeGrab(tempGrab);
     }
 }
 
diff --git a/Xi/ungrdevb.c b/Xi/ungrdevb.c
index 9e9ece4..6280248 100644
--- a/Xi/ungrdevb.c
+++ b/Xi/ungrdevb.c
@@ -96,7 +96,7 @@ ProcXUngrabDeviceButton(ClientPtr client)
     DeviceIntPtr dev;
     DeviceIntPtr mdev;
     WindowPtr pWin;
-    GrabRec temporaryGrab;
+    GrabPtr temporaryGrab;
     int rc;
 
     REQUEST(xUngrabDeviceButtonReq);
@@ -126,17 +126,23 @@ ProcXUngrabDeviceButton(ClientPtr client)
 	(stuff->modifiers & ~AllModifiersMask))
 	return BadValue;
 
-    temporaryGrab.resource = client->clientAsMask;
-    temporaryGrab.device = dev;
-    temporaryGrab.window = pWin;
-    temporaryGrab.type = DeviceButtonPress;
-    temporaryGrab.grabtype = GRABTYPE_XI;
-    temporaryGrab.modifierDevice = mdev;
-    temporaryGrab.modifiersDetail.exact = stuff->modifiers;
-    temporaryGrab.modifiersDetail.pMask = NULL;
-    temporaryGrab.detail.exact = stuff->button;
-    temporaryGrab.detail.pMask = NULL;
+    temporaryGrab = AllocGrab();
+    if (!temporaryGrab)
+        return BadAlloc;
 
-    DeletePassiveGrabFromList(&temporaryGrab);
+    temporaryGrab->resource = client->clientAsMask;
+    temporaryGrab->device = dev;
+    temporaryGrab->window = pWin;
+    temporaryGrab->type = DeviceButtonPress;
+    temporaryGrab->grabtype = GRABTYPE_XI;
+    temporaryGrab->modifierDevice = mdev;
+    temporaryGrab->modifiersDetail.exact = stuff->modifiers;
+    temporaryGrab->modifiersDetail.pMask = NULL;
+    temporaryGrab->detail.exact = stuff->button;
+    temporaryGrab->detail.pMask = NULL;
+
+    DeletePassiveGrabFromList(temporaryGrab);
+
+    FreeGrab(temporaryGrab);
     return Success;
 }
diff --git a/Xi/ungrdevk.c b/Xi/ungrdevk.c
index 526347d..b0d83cb 100644
--- a/Xi/ungrdevk.c
+++ b/Xi/ungrdevk.c
@@ -98,7 +98,7 @@ ProcXUngrabDeviceKey(ClientPtr client)
     DeviceIntPtr dev;
     DeviceIntPtr mdev;
     WindowPtr pWin;
-    GrabRec temporaryGrab;
+    GrabPtr temporaryGrab;
     int rc;
 
     REQUEST(xUngrabDeviceKeyReq);
@@ -133,17 +133,22 @@ ProcXUngrabDeviceKey(ClientPtr client)
 	(stuff->modifiers & ~AllModifiersMask))
 	return BadValue;
 
-    temporaryGrab.resource = client->clientAsMask;
-    temporaryGrab.device = dev;
-    temporaryGrab.window = pWin;
-    temporaryGrab.type = DeviceKeyPress;
-    temporaryGrab.grabtype = GRABTYPE_XI;
-    temporaryGrab.modifierDevice = mdev;
-    temporaryGrab.modifiersDetail.exact = stuff->modifiers;
-    temporaryGrab.modifiersDetail.pMask = NULL;
-    temporaryGrab.detail.exact = stuff->key;
-    temporaryGrab.detail.pMask = NULL;
+    temporaryGrab = AllocGrab();
+    if (!temporaryGrab)
+        return BadAlloc;
 
-    DeletePassiveGrabFromList(&temporaryGrab);
+    temporaryGrab->resource = client->clientAsMask;
+    temporaryGrab->device = dev;
+    temporaryGrab->window = pWin;
+    temporaryGrab->type = DeviceKeyPress;
+    temporaryGrab->grabtype = GRABTYPE_XI;
+    temporaryGrab->modifierDevice = mdev;
+    temporaryGrab->modifiersDetail.exact = stuff->modifiers;
+    temporaryGrab->modifiersDetail.pMask = NULL;
+    temporaryGrab->detail.exact = stuff->key;
+    temporaryGrab->detail.pMask = NULL;
+
+    DeletePassiveGrabFromList(temporaryGrab);
+    FreeGrab(temporaryGrab);
     return Success;
 }
diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index 2f13a95..4fa887a 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -253,7 +253,7 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
 {
     DeviceIntPtr dev, mod_dev;
     WindowPtr win;
-    GrabRec tempGrab;
+    GrabPtr tempGrab;
     uint32_t* modifiers;
     int i, rc;
 
@@ -293,29 +293,36 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
 
     mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
 
-    tempGrab.resource = client->clientAsMask;
-    tempGrab.device = dev;
-    tempGrab.window = win;
+
+    tempGrab = AllocGrab();
+    if (!tempGrab)
+        return BadAlloc;
+
+    tempGrab->resource = client->clientAsMask;
+    tempGrab->device = dev;
+    tempGrab->window = win;
     switch(stuff->grab_type)
     {
-        case XIGrabtypeButton:  tempGrab.type = XI_ButtonPress; break;
-        case XIGrabtypeKeycode:  tempGrab.type = XI_KeyPress;    break;
-        case XIGrabtypeEnter:   tempGrab.type = XI_Enter;       break;
-        case XIGrabtypeFocusIn: tempGrab.type = XI_FocusIn;     break;
+        case XIGrabtypeButton:  tempGrab->type = XI_ButtonPress; break;
+        case XIGrabtypeKeycode:  tempGrab->type = XI_KeyPress;    break;
+        case XIGrabtypeEnter:   tempGrab->type = XI_Enter;       break;
+        case XIGrabtypeFocusIn: tempGrab->type = XI_FocusIn;     break;
     }
-    tempGrab.grabtype = GRABTYPE_XI2;
-    tempGrab.modifierDevice = mod_dev;
-    tempGrab.modifiersDetail.pMask = NULL;
-    tempGrab.detail.exact = stuff->detail;
-    tempGrab.detail.pMask = NULL;
+    tempGrab->grabtype = GRABTYPE_XI2;
+    tempGrab->modifierDevice = mod_dev;
+    tempGrab->modifiersDetail.pMask = NULL;
+    tempGrab->detail.exact = stuff->detail;
+    tempGrab->detail.pMask = NULL;
 
     modifiers = (uint32_t*)&stuff[1];
 
     for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
     {
-        tempGrab.modifiersDetail.exact = *modifiers;
-        DeletePassiveGrabFromList(&tempGrab);
+        tempGrab->modifiersDetail.exact = *modifiers;
+        DeletePassiveGrabFromList(tempGrab);
     }
 
+    FreeGrab(tempGrab);
+
     return Success;
 }
diff --git a/dix/events.c b/dix/events.c
index 51856ae..4bc6aaa 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1977,7 +1977,7 @@ static BOOL
 ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
                      xEvent *event, Mask deliveryMask)
 {
-    GrabRec tempGrab;
+    GrabPtr tempGrab;
     OtherInputMasks *inputMasks;
     CARD8 type = event->u.u.type;
     GrabType grabtype;
@@ -1991,30 +1991,33 @@ ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
     else
         return FALSE;
 
-    memset(&tempGrab, 0, sizeof(GrabRec));
-    tempGrab.next = NULL;
-    tempGrab.device = dev;
-    tempGrab.resource = client->clientAsMask;
-    tempGrab.window = win;
-    tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
-    tempGrab.eventMask = deliveryMask;
-    tempGrab.keyboardMode = GrabModeAsync;
-    tempGrab.pointerMode = GrabModeAsync;
-    tempGrab.confineTo = NullWindow;
-    tempGrab.cursor = NullCursor;
-    tempGrab.type = type;
-    tempGrab.grabtype = grabtype;
+    tempGrab = AllocGrab();
+    if (!tempGrab)
+        return FALSE;
+    tempGrab->next = NULL;
+    tempGrab->device = dev;
+    tempGrab->resource = client->clientAsMask;
+    tempGrab->window = win;
+    tempGrab->ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
+    tempGrab->eventMask = deliveryMask;
+    tempGrab->keyboardMode = GrabModeAsync;
+    tempGrab->pointerMode = GrabModeAsync;
+    tempGrab->confineTo = NullWindow;
+    tempGrab->cursor = NullCursor;
+    tempGrab->type = type;
+    tempGrab->grabtype = grabtype;
 
     /* get the XI and XI2 device mask */
     inputMasks = wOtherInputMasks(win);
-    tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[dev->id]: 0;
+    tempGrab->deviceMask = (inputMasks) ? inputMasks->inputEvents[dev->id]: 0;
 
     if (inputMasks)
-        memcpy(tempGrab.xi2mask, inputMasks->xi2mask,
-               sizeof(tempGrab.xi2mask));
+        memcpy(tempGrab->xi2mask, inputMasks->xi2mask,
+               sizeof(tempGrab->xi2mask));
 
-    (*dev->deviceGrab.ActivateGrab)(dev, &tempGrab,
+    (*dev->deviceGrab.ActivateGrab)(dev, tempGrab,
                                     currentTime, TRUE | ImplicitGrabMask);
+    FreeGrab(tempGrab);
     return TRUE;
 }
 
@@ -3658,7 +3661,7 @@ CheckPassiveGrabsOnWindow(
 {
     SpritePtr pSprite = device->spriteInfo->sprite;
     GrabPtr grab = wPassiveGrabs(pWin);
-    GrabRec tempGrab;
+    GrabPtr tempGrab;
     GrabInfoPtr grabinfo;
 #define CORE_MATCH      0x1
 #define XI_MATCH        0x2
@@ -3667,27 +3670,30 @@ CheckPassiveGrabsOnWindow(
 
     if (!grab)
 	return NULL;
+
+    tempGrab = AllocGrab();
+
     /* Fill out the grab details, but leave the type for later before
      * comparing */
     switch (event->any.type)
     {
         case ET_KeyPress:
         case ET_KeyRelease:
-            tempGrab.detail.exact = event->device_event.detail.key;
+            tempGrab->detail.exact = event->device_event.detail.key;
             break;
         case ET_ButtonPress:
         case ET_ButtonRelease:
-            tempGrab.detail.exact = event->device_event.detail.button;
+            tempGrab->detail.exact = event->device_event.detail.button;
             break;
         default:
-            tempGrab.detail.exact = 0;
+            tempGrab->detail.exact = 0;
             break;
     }
-    tempGrab.window = pWin;
-    tempGrab.device = device;
-    tempGrab.detail.pMask = NULL;
-    tempGrab.modifiersDetail.pMask = NULL;
-    tempGrab.next = NULL;
+    tempGrab->window = pWin;
+    tempGrab->device = device;
+    tempGrab->detail.pMask = NULL;
+    tempGrab->modifiersDetail.pMask = NULL;
+    tempGrab->next = NULL;
     for (; grab; grab = grab->next)
     {
 	DeviceIntPtr	gdev;
@@ -3712,29 +3718,29 @@ CheckPassiveGrabsOnWindow(
 
         if (gdev && gdev->key)
             xkbi= gdev->key->xkbInfo;
-	tempGrab.modifierDevice = grab->modifierDevice;
-        tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0;
+        tempGrab->modifierDevice = grab->modifierDevice;
+        tempGrab->modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0;
 
         /* Check for XI2 and XI grabs first */
-        tempGrab.type = GetXI2Type(event);
-        tempGrab.grabtype = GRABTYPE_XI2;
-        if (GrabMatchesSecond(&tempGrab, grab, FALSE))
+        tempGrab->type = GetXI2Type(event);
+        tempGrab->grabtype = GRABTYPE_XI2;
+        if (GrabMatchesSecond(tempGrab, grab, FALSE))
             match = XI2_MATCH;
 
         if (!match)
         {
-            tempGrab.grabtype = GRABTYPE_XI;
-            if ((tempGrab.type = GetXIType(event)) &&
-                (GrabMatchesSecond(&tempGrab, grab, FALSE)))
+            tempGrab->grabtype = GRABTYPE_XI;
+            if ((tempGrab->type = GetXIType(event)) &&
+                (GrabMatchesSecond(tempGrab, grab, FALSE)))
                 match = XI_MATCH;
         }
 
         /* Check for a core grab (ignore the device when comparing) */
         if (!match && checkCore)
         {
-            tempGrab.grabtype = GRABTYPE_CORE;
-            if ((tempGrab.type = GetCoreType(event)) &&
-                (GrabMatchesSecond(&tempGrab, grab, TRUE)))
+            tempGrab->grabtype = GRABTYPE_CORE;
+            if ((tempGrab->type = GetCoreType(event)) &&
+                (GrabMatchesSecond(tempGrab, grab, TRUE)))
                 match = CORE_MATCH;
         }
 
@@ -3762,7 +3768,7 @@ CheckPassiveGrabsOnWindow(
                Since XGrabDeviceButton requires to specify the
                modifierDevice explicitly, we don't override this choice.
                */
-            if (tempGrab.type < GenericEvent)
+            if (tempGrab->type < GenericEvent)
             {
                 grab->device = device;
                 grab->modifierDevice = GetMaster(device, MASTER_KEYBOARD);
@@ -3801,7 +3807,7 @@ CheckPassiveGrabsOnWindow(
         if (match & (XI_MATCH | CORE_MATCH))
         {
             event->device_event.corestate &= 0x1f00;
-            event->device_event.corestate |= tempGrab.modifiersDetail.exact &
+            event->device_event.corestate |= tempGrab->modifiersDetail.exact &
                                               (~0x1f00);
         }
 
@@ -3862,6 +3868,7 @@ CheckPassiveGrabsOnWindow(
         break;
     }
 
+    FreeGrab(tempGrab);
     return grab;
 #undef CORE_MATCH
 #undef XI_MATCH
@@ -5079,29 +5086,30 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
 	*status = GrabFrozen;
     else
     {
-	GrabRec tempGrab;
+	GrabPtr tempGrab;
 
-        /* Otherwise segfaults happen on grabbed MPX devices */
-        memset(&tempGrab, 0, sizeof(GrabRec));
+        tempGrab = AllocGrab();
 
-        tempGrab.next = NULL;
-	tempGrab.window = pWin;
-	tempGrab.resource = client->clientAsMask;
-	tempGrab.ownerEvents = ownerEvents;
-	tempGrab.keyboardMode = keyboard_mode;
-	tempGrab.pointerMode = pointer_mode;
+	tempGrab->next = NULL;
+	tempGrab->window = pWin;
+	tempGrab->resource = client->clientAsMask;
+	tempGrab->ownerEvents = ownerEvents;
+	tempGrab->keyboardMode = keyboard_mode;
+	tempGrab->pointerMode = pointer_mode;
 	if (grabtype == GRABTYPE_CORE)
-	    tempGrab.eventMask = mask->core;
+	    tempGrab->eventMask = mask->core;
 	else if (grabtype == GRABTYPE_XI)
-	    tempGrab.eventMask = mask->xi;
+	    tempGrab->eventMask = mask->xi;
 	else
-	    memcpy(tempGrab.xi2mask, mask->xi2mask, sizeof(tempGrab.xi2mask));
-	tempGrab.device = dev;
-	tempGrab.cursor = cursor;
-	tempGrab.confineTo = confineTo;
-	tempGrab.grabtype = grabtype;
-	(*grabInfo->ActivateGrab)(dev, &tempGrab, time, FALSE);
+	    memcpy(tempGrab->xi2mask, mask->xi2mask, sizeof(tempGrab->xi2mask));
+	tempGrab->device = dev;
+	tempGrab->cursor = cursor;
+	tempGrab->confineTo = confineTo;
+	tempGrab->grabtype = grabtype;
+	(*grabInfo->ActivateGrab)(dev, tempGrab, time, FALSE);
 	*status = GrabSuccess;
+
+        FreeGrab(tempGrab);
     }
     return Success;
 }
@@ -5422,7 +5430,7 @@ ProcUngrabKey(ClientPtr client)
 {
     REQUEST(xUngrabKeyReq);
     WindowPtr pWin;
-    GrabRec tempGrab;
+    GrabPtr tempGrab;
     DeviceIntPtr keybd = PickKeyboard(client);
     int rc;
 
@@ -5444,21 +5452,27 @@ ProcUngrabKey(ClientPtr client)
 	client->errorValue = stuff->modifiers;
 	return BadValue;
     }
-    tempGrab.resource = client->clientAsMask;
-    tempGrab.device = keybd;
-    tempGrab.window = pWin;
-    tempGrab.modifiersDetail.exact = stuff->modifiers;
-    tempGrab.modifiersDetail.pMask = NULL;
-    tempGrab.modifierDevice = keybd;
-    tempGrab.type = KeyPress;
-    tempGrab.grabtype = GRABTYPE_CORE;
-    tempGrab.detail.exact = stuff->key;
-    tempGrab.detail.pMask = NULL;
-    tempGrab.next = NULL;
+    tempGrab = AllocGrab();
+    if (!tempGrab)
+        return BadAlloc;
+    tempGrab->resource = client->clientAsMask;
+    tempGrab->device = keybd;
+    tempGrab->window = pWin;
+    tempGrab->modifiersDetail.exact = stuff->modifiers;
+    tempGrab->modifiersDetail.pMask = NULL;
+    tempGrab->modifierDevice = keybd;
+    tempGrab->type = KeyPress;
+    tempGrab->grabtype = GRABTYPE_CORE;
+    tempGrab->detail.exact = stuff->key;
+    tempGrab->detail.pMask = NULL;
+    tempGrab->next = NULL;
 
-    if (!DeletePassiveGrabFromList(&tempGrab))
-	return BadAlloc;
-    return Success;
+    if (!DeletePassiveGrabFromList(tempGrab))
+        rc = BadAlloc;
+
+    FreeGrab(tempGrab);
+
+    return rc;
 }
 
 /**
@@ -5622,7 +5636,7 @@ ProcUngrabButton(ClientPtr client)
 {
     REQUEST(xUngrabButtonReq);
     WindowPtr pWin;
-    GrabRec tempGrab;
+    GrabPtr tempGrab;
     int rc;
     DeviceIntPtr ptr;
 
@@ -5639,21 +5653,26 @@ ProcUngrabButton(ClientPtr client)
 
     ptr = PickPointer(client);
 
-    tempGrab.resource = client->clientAsMask;
-    tempGrab.device = ptr;
-    tempGrab.window = pWin;
-    tempGrab.modifiersDetail.exact = stuff->modifiers;
-    tempGrab.modifiersDetail.pMask = NULL;
-    tempGrab.modifierDevice = GetMaster(ptr, MASTER_KEYBOARD);
-    tempGrab.type = ButtonPress;
-    tempGrab.detail.exact = stuff->button;
-    tempGrab.grabtype = GRABTYPE_CORE;
-    tempGrab.detail.pMask = NULL;
-    tempGrab.next = NULL;
+    tempGrab = AllocGrab();
+    if (!tempGrab)
+        return BadAlloc;
+    tempGrab->resource = client->clientAsMask;
+    tempGrab->device = ptr;
+    tempGrab->window = pWin;
+    tempGrab->modifiersDetail.exact = stuff->modifiers;
+    tempGrab->modifiersDetail.pMask = NULL;
+    tempGrab->modifierDevice = GetMaster(ptr, MASTER_KEYBOARD);
+    tempGrab->type = ButtonPress;
+    tempGrab->detail.exact = stuff->button;
+    tempGrab->grabtype = GRABTYPE_CORE;
+    tempGrab->detail.pMask = NULL;
+    tempGrab->next = NULL;
 
-    if (!DeletePassiveGrabFromList(&tempGrab))
-	return BadAlloc;
-    return Success;
+    if (!DeletePassiveGrabFromList(tempGrab))
+        rc = BadAlloc;
+
+    FreeGrab(tempGrab);
+    return rc;
 }
 
 /**
-- 
1.7.7



More information about the xorg-devel mailing list