dix: allocate temporary grabs on the heap

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@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
This commit is contained in:
Peter Hutterer 2011-11-04 10:47:27 +10:00
parent b0e9e2e326
commit b601ea769f
5 changed files with 180 additions and 138 deletions

View File

@ -2024,20 +2024,25 @@ CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type,
dev->valuator->motionHintWindow = pWin; dev->valuator->motionHintWindow = pWin;
else if ((type == DeviceButtonPress) && (!grab) && else if ((type == DeviceButtonPress) && (!grab) &&
(deliveryMask & DeviceButtonGrabMask)) { (deliveryMask & DeviceButtonGrabMask)) {
GrabRec tempGrab; GrabPtr tempGrab;
tempGrab.device = dev; tempGrab = AllocGrab();
tempGrab.resource = client->clientAsMask; if (!tempGrab)
tempGrab.window = pWin; return;
tempGrab.ownerEvents =
tempGrab->device = dev;
tempGrab->resource = client->clientAsMask;
tempGrab->window = pWin;
tempGrab->ownerEvents =
(deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE; (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE;
tempGrab.eventMask = deliveryMask; tempGrab->eventMask = deliveryMask;
tempGrab.keyboardMode = GrabModeAsync; tempGrab->keyboardMode = GrabModeAsync;
tempGrab.pointerMode = GrabModeAsync; tempGrab->pointerMode = GrabModeAsync;
tempGrab.confineTo = NullWindow; tempGrab->confineTo = NullWindow;
tempGrab.cursor = NullCursor; tempGrab->cursor = NullCursor;
tempGrab.next = NULL; tempGrab->next = NULL;
(*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE); (*dev->deviceGrab.ActivateGrab) (dev, tempGrab, currentTime, TRUE);
FreeGrab(tempGrab);
} }
} }

View File

@ -96,7 +96,7 @@ ProcXUngrabDeviceButton(ClientPtr client)
DeviceIntPtr dev; DeviceIntPtr dev;
DeviceIntPtr mdev; DeviceIntPtr mdev;
WindowPtr pWin; WindowPtr pWin;
GrabRec temporaryGrab; GrabPtr temporaryGrab;
int rc; int rc;
REQUEST(xUngrabDeviceButtonReq); REQUEST(xUngrabDeviceButtonReq);
@ -126,17 +126,23 @@ ProcXUngrabDeviceButton(ClientPtr client)
(stuff->modifiers & ~AllModifiersMask)) (stuff->modifiers & ~AllModifiersMask))
return BadValue; return BadValue;
temporaryGrab.resource = client->clientAsMask; temporaryGrab = AllocGrab();
temporaryGrab.device = dev; if (!temporaryGrab)
temporaryGrab.window = pWin; return BadAlloc;
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); 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; return Success;
} }

View File

@ -98,7 +98,7 @@ ProcXUngrabDeviceKey(ClientPtr client)
DeviceIntPtr dev; DeviceIntPtr dev;
DeviceIntPtr mdev; DeviceIntPtr mdev;
WindowPtr pWin; WindowPtr pWin;
GrabRec temporaryGrab; GrabPtr temporaryGrab;
int rc; int rc;
REQUEST(xUngrabDeviceKeyReq); REQUEST(xUngrabDeviceKeyReq);
@ -133,17 +133,22 @@ ProcXUngrabDeviceKey(ClientPtr client)
(stuff->modifiers & ~AllModifiersMask)) (stuff->modifiers & ~AllModifiersMask))
return BadValue; return BadValue;
temporaryGrab.resource = client->clientAsMask; temporaryGrab = AllocGrab();
temporaryGrab.device = dev; if (!temporaryGrab)
temporaryGrab.window = pWin; return BadAlloc;
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); 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; return Success;
} }

View File

@ -253,7 +253,7 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
{ {
DeviceIntPtr dev, mod_dev; DeviceIntPtr dev, mod_dev;
WindowPtr win; WindowPtr win;
GrabRec tempGrab; GrabPtr tempGrab;
uint32_t* modifiers; uint32_t* modifiers;
int i, rc; int i, rc;
@ -293,29 +293,36 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD); mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
tempGrab.resource = client->clientAsMask;
tempGrab.device = dev; tempGrab = AllocGrab();
tempGrab.window = win; if (!tempGrab)
return BadAlloc;
tempGrab->resource = client->clientAsMask;
tempGrab->device = dev;
tempGrab->window = win;
switch(stuff->grab_type) switch(stuff->grab_type)
{ {
case XIGrabtypeButton: tempGrab.type = XI_ButtonPress; break; case XIGrabtypeButton: tempGrab->type = XI_ButtonPress; break;
case XIGrabtypeKeycode: tempGrab.type = XI_KeyPress; break; case XIGrabtypeKeycode: tempGrab->type = XI_KeyPress; break;
case XIGrabtypeEnter: tempGrab.type = XI_Enter; break; case XIGrabtypeEnter: tempGrab->type = XI_Enter; break;
case XIGrabtypeFocusIn: tempGrab.type = XI_FocusIn; break; case XIGrabtypeFocusIn: tempGrab->type = XI_FocusIn; break;
} }
tempGrab.grabtype = GRABTYPE_XI2; tempGrab->grabtype = GRABTYPE_XI2;
tempGrab.modifierDevice = mod_dev; tempGrab->modifierDevice = mod_dev;
tempGrab.modifiersDetail.pMask = NULL; tempGrab->modifiersDetail.pMask = NULL;
tempGrab.detail.exact = stuff->detail; tempGrab->detail.exact = stuff->detail;
tempGrab.detail.pMask = NULL; tempGrab->detail.pMask = NULL;
modifiers = (uint32_t*)&stuff[1]; modifiers = (uint32_t*)&stuff[1];
for (i = 0; i < stuff->num_modifiers; i++, modifiers++) for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
{ {
tempGrab.modifiersDetail.exact = *modifiers; tempGrab->modifiersDetail.exact = *modifiers;
DeletePassiveGrabFromList(&tempGrab); DeletePassiveGrabFromList(tempGrab);
} }
FreeGrab(tempGrab);
return Success; return Success;
} }

View File

@ -1976,7 +1976,7 @@ static BOOL
ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win, ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
xEvent *event, Mask deliveryMask) xEvent *event, Mask deliveryMask)
{ {
GrabRec tempGrab; GrabPtr tempGrab;
OtherInputMasks *inputMasks; OtherInputMasks *inputMasks;
CARD8 type = event->u.u.type; CARD8 type = event->u.u.type;
GrabType grabtype; GrabType grabtype;
@ -1990,30 +1990,33 @@ ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
else else
return FALSE; return FALSE;
memset(&tempGrab, 0, sizeof(GrabRec)); tempGrab = AllocGrab();
tempGrab.next = NULL; if (!tempGrab)
tempGrab.device = dev; return FALSE;
tempGrab.resource = client->clientAsMask; tempGrab->next = NULL;
tempGrab.window = win; tempGrab->device = dev;
tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE; tempGrab->resource = client->clientAsMask;
tempGrab.eventMask = deliveryMask; tempGrab->window = win;
tempGrab.keyboardMode = GrabModeAsync; tempGrab->ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
tempGrab.pointerMode = GrabModeAsync; tempGrab->eventMask = deliveryMask;
tempGrab.confineTo = NullWindow; tempGrab->keyboardMode = GrabModeAsync;
tempGrab.cursor = NullCursor; tempGrab->pointerMode = GrabModeAsync;
tempGrab.type = type; tempGrab->confineTo = NullWindow;
tempGrab.grabtype = grabtype; tempGrab->cursor = NullCursor;
tempGrab->type = type;
tempGrab->grabtype = grabtype;
/* get the XI and XI2 device mask */ /* get the XI and XI2 device mask */
inputMasks = wOtherInputMasks(win); inputMasks = wOtherInputMasks(win);
tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[dev->id]: 0; tempGrab->deviceMask = (inputMasks) ? inputMasks->inputEvents[dev->id]: 0;
if (inputMasks) if (inputMasks)
memcpy(tempGrab.xi2mask, inputMasks->xi2mask, memcpy(tempGrab->xi2mask, inputMasks->xi2mask,
sizeof(tempGrab.xi2mask)); sizeof(tempGrab->xi2mask));
(*dev->deviceGrab.ActivateGrab)(dev, &tempGrab, (*dev->deviceGrab.ActivateGrab)(dev, tempGrab,
currentTime, TRUE | ImplicitGrabMask); currentTime, TRUE | ImplicitGrabMask);
FreeGrab(tempGrab);
return TRUE; return TRUE;
} }
@ -3657,7 +3660,7 @@ CheckPassiveGrabsOnWindow(
{ {
SpritePtr pSprite = device->spriteInfo->sprite; SpritePtr pSprite = device->spriteInfo->sprite;
GrabPtr grab = wPassiveGrabs(pWin); GrabPtr grab = wPassiveGrabs(pWin);
GrabRec tempGrab; GrabPtr tempGrab;
GrabInfoPtr grabinfo; GrabInfoPtr grabinfo;
#define CORE_MATCH 0x1 #define CORE_MATCH 0x1
#define XI_MATCH 0x2 #define XI_MATCH 0x2
@ -3666,27 +3669,30 @@ CheckPassiveGrabsOnWindow(
if (!grab) if (!grab)
return NULL; return NULL;
tempGrab = AllocGrab();
/* Fill out the grab details, but leave the type for later before /* Fill out the grab details, but leave the type for later before
* comparing */ * comparing */
switch (event->any.type) switch (event->any.type)
{ {
case ET_KeyPress: case ET_KeyPress:
case ET_KeyRelease: case ET_KeyRelease:
tempGrab.detail.exact = event->device_event.detail.key; tempGrab->detail.exact = event->device_event.detail.key;
break; break;
case ET_ButtonPress: case ET_ButtonPress:
case ET_ButtonRelease: case ET_ButtonRelease:
tempGrab.detail.exact = event->device_event.detail.button; tempGrab->detail.exact = event->device_event.detail.button;
break; break;
default: default:
tempGrab.detail.exact = 0; tempGrab->detail.exact = 0;
break; break;
} }
tempGrab.window = pWin; tempGrab->window = pWin;
tempGrab.device = device; tempGrab->device = device;
tempGrab.detail.pMask = NULL; tempGrab->detail.pMask = NULL;
tempGrab.modifiersDetail.pMask = NULL; tempGrab->modifiersDetail.pMask = NULL;
tempGrab.next = NULL; tempGrab->next = NULL;
for (; grab; grab = grab->next) for (; grab; grab = grab->next)
{ {
DeviceIntPtr gdev; DeviceIntPtr gdev;
@ -3711,29 +3717,29 @@ CheckPassiveGrabsOnWindow(
if (gdev && gdev->key) if (gdev && gdev->key)
xkbi= gdev->key->xkbInfo; xkbi= gdev->key->xkbInfo;
tempGrab.modifierDevice = grab->modifierDevice; tempGrab->modifierDevice = grab->modifierDevice;
tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0; tempGrab->modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0;
/* Check for XI2 and XI grabs first */ /* Check for XI2 and XI grabs first */
tempGrab.type = GetXI2Type(event); tempGrab->type = GetXI2Type(event);
tempGrab.grabtype = GRABTYPE_XI2; tempGrab->grabtype = GRABTYPE_XI2;
if (GrabMatchesSecond(&tempGrab, grab, FALSE)) if (GrabMatchesSecond(tempGrab, grab, FALSE))
match = XI2_MATCH; match = XI2_MATCH;
if (!match) if (!match)
{ {
tempGrab.grabtype = GRABTYPE_XI; tempGrab->grabtype = GRABTYPE_XI;
if ((tempGrab.type = GetXIType(event)) && if ((tempGrab->type = GetXIType(event)) &&
(GrabMatchesSecond(&tempGrab, grab, FALSE))) (GrabMatchesSecond(tempGrab, grab, FALSE)))
match = XI_MATCH; match = XI_MATCH;
} }
/* Check for a core grab (ignore the device when comparing) */ /* Check for a core grab (ignore the device when comparing) */
if (!match && checkCore) if (!match && checkCore)
{ {
tempGrab.grabtype = GRABTYPE_CORE; tempGrab->grabtype = GRABTYPE_CORE;
if ((tempGrab.type = GetCoreType(event)) && if ((tempGrab->type = GetCoreType(event)) &&
(GrabMatchesSecond(&tempGrab, grab, TRUE))) (GrabMatchesSecond(tempGrab, grab, TRUE)))
match = CORE_MATCH; match = CORE_MATCH;
} }
@ -3761,7 +3767,7 @@ CheckPassiveGrabsOnWindow(
Since XGrabDeviceButton requires to specify the Since XGrabDeviceButton requires to specify the
modifierDevice explicitly, we don't override this choice. modifierDevice explicitly, we don't override this choice.
*/ */
if (tempGrab.type < GenericEvent) if (tempGrab->type < GenericEvent)
{ {
grab->device = device; grab->device = device;
grab->modifierDevice = GetMaster(device, MASTER_KEYBOARD); grab->modifierDevice = GetMaster(device, MASTER_KEYBOARD);
@ -3800,7 +3806,7 @@ CheckPassiveGrabsOnWindow(
if (match & (XI_MATCH | CORE_MATCH)) if (match & (XI_MATCH | CORE_MATCH))
{ {
event->device_event.corestate &= 0x1f00; event->device_event.corestate &= 0x1f00;
event->device_event.corestate |= tempGrab.modifiersDetail.exact & event->device_event.corestate |= tempGrab->modifiersDetail.exact &
(~0x1f00); (~0x1f00);
} }
@ -3861,6 +3867,7 @@ CheckPassiveGrabsOnWindow(
break; break;
} }
FreeGrab(tempGrab);
return grab; return grab;
#undef CORE_MATCH #undef CORE_MATCH
#undef XI_MATCH #undef XI_MATCH
@ -5078,29 +5085,30 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
*status = GrabFrozen; *status = GrabFrozen;
else else
{ {
GrabRec tempGrab; GrabPtr tempGrab;
/* Otherwise segfaults happen on grabbed MPX devices */ tempGrab = AllocGrab();
memset(&tempGrab, 0, sizeof(GrabRec));
tempGrab.next = NULL; tempGrab->next = NULL;
tempGrab.window = pWin; tempGrab->window = pWin;
tempGrab.resource = client->clientAsMask; tempGrab->resource = client->clientAsMask;
tempGrab.ownerEvents = ownerEvents; tempGrab->ownerEvents = ownerEvents;
tempGrab.keyboardMode = keyboard_mode; tempGrab->keyboardMode = keyboard_mode;
tempGrab.pointerMode = pointer_mode; tempGrab->pointerMode = pointer_mode;
if (grabtype == GRABTYPE_CORE) if (grabtype == GRABTYPE_CORE)
tempGrab.eventMask = mask->core; tempGrab->eventMask = mask->core;
else if (grabtype == GRABTYPE_XI) else if (grabtype == GRABTYPE_XI)
tempGrab.eventMask = mask->xi; tempGrab->eventMask = mask->xi;
else else
memcpy(tempGrab.xi2mask, mask->xi2mask, sizeof(tempGrab.xi2mask)); memcpy(tempGrab->xi2mask, mask->xi2mask, sizeof(tempGrab->xi2mask));
tempGrab.device = dev; tempGrab->device = dev;
tempGrab.cursor = cursor; tempGrab->cursor = cursor;
tempGrab.confineTo = confineTo; tempGrab->confineTo = confineTo;
tempGrab.grabtype = grabtype; tempGrab->grabtype = grabtype;
(*grabInfo->ActivateGrab)(dev, &tempGrab, time, FALSE); (*grabInfo->ActivateGrab)(dev, tempGrab, time, FALSE);
*status = GrabSuccess; *status = GrabSuccess;
FreeGrab(tempGrab);
} }
return Success; return Success;
} }
@ -5419,7 +5427,7 @@ ProcUngrabKey(ClientPtr client)
{ {
REQUEST(xUngrabKeyReq); REQUEST(xUngrabKeyReq);
WindowPtr pWin; WindowPtr pWin;
GrabRec tempGrab; GrabPtr tempGrab;
DeviceIntPtr keybd = PickKeyboard(client); DeviceIntPtr keybd = PickKeyboard(client);
int rc; int rc;
@ -5441,21 +5449,27 @@ ProcUngrabKey(ClientPtr client)
client->errorValue = stuff->modifiers; client->errorValue = stuff->modifiers;
return BadValue; return BadValue;
} }
tempGrab.resource = client->clientAsMask; tempGrab = AllocGrab();
tempGrab.device = keybd; if (!tempGrab)
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 BadAlloc;
return Success; 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))
rc = BadAlloc;
FreeGrab(tempGrab);
return rc;
} }
/** /**
@ -5619,7 +5633,7 @@ ProcUngrabButton(ClientPtr client)
{ {
REQUEST(xUngrabButtonReq); REQUEST(xUngrabButtonReq);
WindowPtr pWin; WindowPtr pWin;
GrabRec tempGrab; GrabPtr tempGrab;
int rc; int rc;
DeviceIntPtr ptr; DeviceIntPtr ptr;
@ -5636,21 +5650,26 @@ ProcUngrabButton(ClientPtr client)
ptr = PickPointer(client); ptr = PickPointer(client);
tempGrab.resource = client->clientAsMask; tempGrab = AllocGrab();
tempGrab.device = ptr; if (!tempGrab)
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 BadAlloc;
return Success; 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))
rc = BadAlloc;
FreeGrab(tempGrab);
return rc;
} }
/** /**