GitLab will be down for maintenance this Sunday 13th June, from approx 7-11am UTC. This is for a PostgreSQL migration. See the tracker issue for more informations.

Commit bc41226f authored by Matt Dew's avatar Matt Dew
Browse files

Merge branch 'server-1.14-touch-fixes' of...

Merge branch 'server-1.14-touch-fixes' of git://people.freedesktop.org/~whot/xserver into server-1.14-branch
parents 4ebd618b 2cd62dc0
......@@ -531,15 +531,16 @@ CreateSaverWindow(ScreenPtr pScreen)
mask |= CWBorderPixmap;
}
if (pAttr->pCursor) {
CursorPtr cursor;
if (!pWin->optional)
if (!MakeWindowOptional(pWin)) {
FreeResource(pWin->drawable.id, RT_NONE);
return FALSE;
}
pAttr->pCursor->refcnt++;
cursor = RefCursor(pAttr->pCursor);
if (pWin->optional->cursor)
FreeCursor(pWin->optional->cursor, (Cursor) 0);
pWin->optional->cursor = pAttr->pCursor;
pWin->optional->cursor = cursor;
pWin->cursorIsNone = FALSE;
CheckWindowOptionalNeed(pWin);
mask |= CWCursor;
......@@ -1065,8 +1066,7 @@ ScreenSaverSetAttributes(ClientPtr client)
client->errorValue = cursorID;
goto PatchUp;
}
pCursor->refcnt++;
pAttr->pCursor = pCursor;
pAttr->pCursor = RefCursor(pCursor);
pAttr->mask &= ~CWCursor;
}
break;
......
......@@ -1036,46 +1036,21 @@ DeliverOneTouchEvent(ClientPtr client, DeviceIntPtr dev, TouchPointInfoPtr ti,
static void
ActivateEarlyAccept(DeviceIntPtr dev, TouchPointInfoPtr ti)
{
int rc;
ClientPtr client;
XID error;
GrabPtr grab = ti->listeners[0].grab;
rc = dixLookupClient(&client, ti->listeners[0].listener, serverClient,
DixSendAccess);
if (rc != Success) {
ErrorF("[Xi] Failed to lookup early accepting client.\n");
return;
}
BUG_RETURN(ti->listeners[0].type != LISTENER_GRAB &&
ti->listeners[0].type != LISTENER_POINTER_GRAB);
BUG_RETURN(!grab);
client = rClient(grab);
if (TouchAcceptReject(client, dev, XIAcceptTouch, ti->client_id,
ti->listeners[0].window->drawable.id, &error) !=
Success)
ti->listeners[0].window->drawable.id, &error) != Success)
ErrorF("[Xi] Failed to accept touch grab after early acceptance.\n");
}
/**
* Generate and deliver a TouchEnd event.
*
* @param dev The device to deliver the event for.
* @param ti The touch point record to deliver the event for.
* @param flags Internal event flags. The called does not need to provide
* TOUCH_CLIENT_ID and TOUCH_POINTER_EMULATED, this function will ensure
* they are set appropriately.
* @param resource The client resource to deliver to, or 0 for all clients.
*/
static void
EmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resource)
{
InternalEvent event;
flags |= TOUCH_CLIENT_ID;
if (ti->emulate_pointer)
flags |= TOUCH_POINTER_EMULATED;
TouchDeliverDeviceClassesChangedEvent(ti, GetTimeInMillis(), resource);
GetDixTouchEnd(&event, dev, ti, flags);
DeliverTouchEvents(dev, ti, &event, resource);
}
/**
* Find the oldest touch that still has a pointer emulation client.
*
......@@ -1126,31 +1101,42 @@ static void
TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
TouchOwnershipEvent *ev)
{
TouchListener *listener = &ti->listeners[0]; /* new owner */
int accepted_early = listener->state == LISTENER_EARLY_ACCEPT;
/* Deliver the ownership */
if (ti->listeners[0].state == LISTENER_AWAITING_OWNER ||
ti->listeners[0].state == LISTENER_EARLY_ACCEPT)
if (listener->state == LISTENER_AWAITING_OWNER || accepted_early)
DeliverTouchEvents(dev, ti, (InternalEvent *) ev,
ti->listeners[0].listener);
else if (ti->listeners[0].state == LISTENER_AWAITING_BEGIN) {
listener->listener);
else if (listener->state == LISTENER_AWAITING_BEGIN) {
/* We can't punt to a pointer listener unless all older pointer
* emulated touches have been seen already. */
if ((ti->listeners[0].type == LISTENER_POINTER_GRAB ||
ti->listeners[0].type == LISTENER_POINTER_REGULAR) &&
if ((listener->type == LISTENER_POINTER_GRAB ||
listener->type == LISTENER_POINTER_REGULAR) &&
ti != FindOldestPointerEmulatedTouch(dev))
return;
TouchEventHistoryReplay(ti, dev, ti->listeners[0].listener);
TouchEventHistoryReplay(ti, dev, listener->listener);
}
/* If we've just removed the last grab and the touch has physically
* ended, send a TouchEnd event too and finalise the touch. */
if (ti->num_listeners == 1 && ti->num_grabs == 0 && ti->pending_finish) {
EmitTouchEnd(dev, ti, 0, 0);
TouchEndTouch(dev, ti);
return;
/* New owner has Begin/Update but not end. If touch is pending_finish,
* emulate the TouchEnd now */
if (ti->pending_finish) {
TouchEmitTouchEnd(dev, ti, 0, 0);
/* If the last owner is not a touch grab, finalise the touch, we
won't get more correspondence on this.
*/
if (ti->num_listeners == 1 &&
(ti->num_grabs == 0 ||
listener->grab->grabtype != XI2 ||
!xi2mask_isset(listener->grab->xi2mask, dev, XI_TouchBegin))) {
TouchEndTouch(dev, ti);
return;
}
}
if (ti->listeners[0].state == LISTENER_EARLY_ACCEPT)
if (accepted_early)
ActivateEarlyAccept(dev, ti);
}
......@@ -1194,7 +1180,7 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource,
for (i = 0; i < ti->num_listeners; i++) {
if (ti->listeners[i].listener == resource) {
if (ti->listeners[i].state != LISTENER_HAS_END)
EmitTouchEnd(sourcedev, ti, TOUCH_REJECT, resource);
TouchEmitTouchEnd(sourcedev, ti, TOUCH_REJECT, resource);
break;
}
}
......@@ -1237,16 +1223,20 @@ ProcessTouchOwnershipEvent(TouchOwnershipEvent *ev,
else if (ev->reason == XIAcceptTouch) {
int i;
/* Go through the motions of ending the touch if the listener has
/* For pointer-emulated listeners that ungrabbed the active grab,
* the state was forced to LISTENER_HAS_END. Still go
* through the motions of ending the touch if the listener has
* already seen the end. This ensures that the touch record is ended in
* the server. */
* the server.
*/
if (ti->listeners[0].state == LISTENER_HAS_END)
EmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[0].listener);
TouchEmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[0].listener);
/* The touch owner has accepted the touch. Send TouchEnd events to
* everyone else, and truncate the list of listeners. */
for (i = 1; i < ti->num_listeners; i++)
EmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[i].listener);
TouchEmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[i].listener);
while (ti->num_listeners > 1)
TouchRemoveListener(ti, ti->listeners[1].listener);
......@@ -1383,7 +1373,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
/* We don't deliver pointer events to non-owners */
if (!TouchResourceIsOwner(ti, listener->listener))
return Success;
return !Success;
nevents = TouchConvertToPointerEvent(ev, &motion, &button);
BUG_RETURN_VAL(nevents == 0, BadValue);
......@@ -1405,7 +1395,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
/* 'grab' is the passive grab, but if the grab isn't active,
* don't deliver */
if (!dev->deviceGrab.grab)
return Success;
return !Success;
if (grab->ownerEvents) {
WindowPtr focus = NullWindow;
......@@ -1415,7 +1405,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
}
if (!deliveries)
DeliverOneGrabbedEvent(ptrev, dev, grab->grabtype);
deliveries = DeliverOneGrabbedEvent(ptrev, dev, grab->grabtype);
/* We must accept the touch sequence once a pointer listener has
* received one event past ButtonPress. */
......@@ -1423,8 +1413,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
!(ev->device_event.flags & TOUCH_CLIENT_ID))
TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch);
if (ev->any.type == ET_TouchEnd &&
!(ev->device_event.flags & TOUCH_CLIENT_ID) &&
if (deliveries && ev->any.type == ET_TouchEnd &&
!dev->button->buttonsDown &&
dev->deviceGrab.fromPassiveGrab && GrabIsPointerGrab(grab)) {
(*dev->deviceGrab.DeactivateGrab) (dev);
......@@ -1443,8 +1432,11 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
*/
if (!devgrab && dev->deviceGrab.grab && dev->deviceGrab.implicitGrab) {
TouchListener *l;
GrabPtr g;
devgrab = dev->deviceGrab.grab;
g = AllocGrab(devgrab);
BUG_WARN(!g);
*dev->deviceGrab.sync.event = ev->device_event;
......@@ -1453,8 +1445,8 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
* event selection. Thus, we update the last listener in the array.
*/
l = &ti->listeners[ti->num_listeners - 1];
l->listener = devgrab->resource;
l->grab = devgrab;
l->listener = g->resource;
l->grab = g;
//l->resource_type = RT_NONE;
if (devgrab->grabtype != XI2 || devgrab->type != XI_TouchBegin)
......@@ -1545,7 +1537,7 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
touchid = ev->device_event.touchid;
if (type == ET_TouchBegin) {
if (type == ET_TouchBegin && !(ev->device_event.flags & TOUCH_REPLAYING)) {
ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
emulate_pointer);
}
......@@ -1612,7 +1604,9 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
* called after event type mutation. Touch end events are always processed
* in order to end touch records. */
/* FIXME: check this */
if ((type == ET_TouchBegin && !TouchBuildSprite(dev, ti, ev)) ||
if ((type == ET_TouchBegin &&
!(ev->device_event.flags & TOUCH_REPLAYING) &&
!TouchBuildSprite(dev, ti, ev)) ||
(type != ET_TouchEnd && ti->sprite.spriteTraceGood == 0))
return;
......@@ -1620,7 +1614,7 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
/* WARNING: the event type may change to TouchUpdate in
* DeliverTouchEvents if a TouchEnd was delivered to a grabbing
* owner */
DeliverTouchEvents(dev, ti, (InternalEvent *) ev, 0);
DeliverTouchEvents(dev, ti, ev, ev->device_event.resource);
if (ev->any.type == ET_TouchEnd)
TouchEndTouch(dev, ti);
......@@ -1848,6 +1842,14 @@ DeliverTouchBeginEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
listener->type == LISTENER_POINTER_GRAB) {
rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
grab, xi2mask);
if (rc == Success) {
listener->state = LISTENER_IS_OWNER;
/* async grabs cannot replay, so automatically accept this touch */
if (dev->deviceGrab.grab &&
dev->deviceGrab.fromPassiveGrab &&
dev->deviceGrab.grab->pointerMode == GrabModeAsync)
ActivateEarlyAccept(dev, ti);
}
goto out;
}
......@@ -1865,7 +1867,7 @@ DeliverTouchBeginEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
if (has_ownershipmask)
TouchSendOwnershipEvent(dev, ti, 0, listener->listener);
if (!has_ownershipmask || listener->type == LISTENER_REGULAR)
if (listener->type == LISTENER_REGULAR)
state = LISTENER_HAS_ACCEPTED;
else
state = LISTENER_IS_OWNER;
......@@ -1885,16 +1887,23 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
if (listener->type == LISTENER_POINTER_REGULAR ||
listener->type == LISTENER_POINTER_GRAB) {
rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
grab, xi2mask);
if (ti->num_listeners > 1) {
ev->any.type = ET_TouchUpdate;
ev->device_event.flags |= TOUCH_PENDING_END;
if (!(ev->device_event.flags & TOUCH_CLIENT_ID))
ti->pending_finish = TRUE;
/* Note: If the active grab was ungrabbed, we already changed the
* state to LISTENER_HAS_END but still get here. So we mustn't
* actually send the event.
* This is part two of the hack in DeactivatePointerGrab
*/
if (listener->state != LISTENER_HAS_END) {
rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
grab, xi2mask);
/* Once we send a TouchEnd to a legacy listener, we're already well
* past the accepting/rejecting stage (can only happen on
* GrabModeSync + replay. This listener now gets the end event,
* and we can continue.
*/
if (rc == Success)
listener->state = LISTENER_HAS_END;
}
goto out;
}
......@@ -1918,7 +1927,7 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
if ((ti->num_listeners > 1 ||
listener->state != LISTENER_HAS_ACCEPTED) &&
(ti->num_grabs > 0 && listener->state != LISTENER_HAS_ACCEPTED)) &&
(ev->device_event.flags & (TOUCH_ACCEPT | TOUCH_REJECT)) == 0) {
ev->any.type = ET_TouchUpdate;
ev->device_event.flags |= TOUCH_PENDING_END;
......@@ -2849,7 +2858,7 @@ CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type,
(deliveryMask & DeviceButtonGrabMask)) {
GrabPtr tempGrab;
tempGrab = AllocGrab();
tempGrab = AllocGrab(NULL);
if (!tempGrab)
return;
......
......@@ -127,7 +127,7 @@ ProcXUngrabDeviceButton(ClientPtr client)
(stuff->modifiers & ~AllModifiersMask))
return BadValue;
temporaryGrab = AllocGrab();
temporaryGrab = AllocGrab(NULL);
if (!temporaryGrab)
return BadAlloc;
......
......@@ -134,7 +134,7 @@ ProcXUngrabDeviceKey(ClientPtr client)
(stuff->modifiers & ~AllModifiersMask))
return BadValue;
temporaryGrab = AllocGrab();
temporaryGrab = AllocGrab(NULL);
if (!temporaryGrab)
return BadAlloc;
......
......@@ -307,7 +307,7 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
tempGrab = AllocGrab();
tempGrab = AllocGrab(NULL);
if (!tempGrab)
return BadAlloc;
......
......@@ -114,9 +114,13 @@ FreeCursor(pointer value, XID cid)
ScreenPtr pscr;
DeviceIntPtr pDev = NULL; /* unused anyway */
if (--pCurs->refcnt != 0)
UnrefCursor(pCurs);
if (CursorRefCount(pCurs) != 0)
return Success;
BUG_WARN(CursorRefCount(pCurs) < 0);
for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
pscr = screenInfo.screens[nscr];
(void) (*pscr->UnrealizeCursor) (pDev, pscr, pCurs);
......@@ -127,6 +131,29 @@ FreeCursor(pointer value, XID cid)
return Success;
}
CursorPtr
RefCursor(CursorPtr cursor)
{
if (cursor)
cursor->refcnt++;
return cursor;
}
CursorPtr
UnrefCursor(CursorPtr cursor)
{
if (cursor)
cursor->refcnt--;
return cursor;
}
int
CursorRefCount(const CursorPtr cursor)
{
return cursor ? cursor->refcnt : 0;
}
/*
* We check for empty cursors so that we won't have to display them
*/
......
......@@ -281,7 +281,6 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
dev->deviceGrab.grabTime = currentTime;
dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
dev->deviceGrab.activeGrab = AllocGrab();
dev->deviceGrab.sync.event = calloc(1, sizeof(DeviceEvent));
XkbSetExtension(dev, ProcessKeyboardEvent);
......@@ -977,7 +976,8 @@ CloseDevice(DeviceIntPtr dev)
}
}
FreeGrab(dev->deviceGrab.activeGrab);
if (dev->deviceGrab.grab)
FreeGrab(dev->deviceGrab.grab);
free(dev->deviceGrab.sync.event);
free(dev->config_info); /* Allocated in xf86ActivateDevice. */
free(dev->last.scroll);
......
......@@ -3398,6 +3398,7 @@ CloseDownClient(ClientPtr client)
clientinfo.setup = (xConnSetup *) NULL;
CallCallbacks((&ClientStateCallback), (pointer) &clientinfo);
}
TouchListenerGone(client->clientAsMask);
FreeClientResources(client);
/* Disable client ID tracking. This must be done after
* ClientStateCallback. */
......
......@@ -931,8 +931,7 @@ ChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor)
(*pScreen->DisplayCursor) (pDev, pScreen, cursor);
FreeCursor(pSprite->current, (Cursor) 0);
pSprite->current = cursor;
pSprite->current->refcnt++;
pSprite->current = RefCursor(cursor);
}
}
......@@ -1424,21 +1423,24 @@ UpdateTouchesForGrab(DeviceIntPtr mouse)
for (i = 0; i < mouse->touch->num_touches; i++) {
TouchPointInfoPtr ti = mouse->touch->touches + i;
TouchListener *listener = &ti->listeners[0];
GrabPtr grab = mouse->deviceGrab.grab;
if (ti->active &&
CLIENT_BITS(ti->listeners[0].listener) == grab->resource) {
ti->listeners[0].listener = grab->resource;
ti->listeners[0].level = grab->grabtype;
ti->listeners[0].state = LISTENER_IS_OWNER;
ti->listeners[0].window = grab->window;
CLIENT_BITS(listener->listener) == grab->resource) {
listener->listener = grab->resource;
listener->level = grab->grabtype;
listener->state = LISTENER_IS_OWNER;
listener->window = grab->window;
if (grab->grabtype == CORE || grab->grabtype == XI ||
!xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin))
ti->listeners[0].type = LISTENER_POINTER_GRAB;
listener->type = LISTENER_POINTER_GRAB;
else
ti->listeners[0].type = LISTENER_GRAB;
ti->listeners[0].grab = grab;
listener->type = LISTENER_GRAB;
if (listener->grab)
FreeGrab(listener->grab);
listener->grab = AllocGrab(grab);
}
}
}
......@@ -1463,6 +1465,7 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
TimeStamp time, Bool autoGrab)
{
GrabInfoPtr grabinfo = &mouse->deviceGrab;
GrabPtr oldgrab = grabinfo->grab;
WindowPtr oldWin = (grabinfo->grab) ?
grabinfo->grab->window : mouse->spriteInfo->sprite->win;
Bool isPassive = autoGrab & ~ImplicitGrabMask;
......@@ -1485,16 +1488,15 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
grabinfo->grabTime = syncEvents.time;
else
grabinfo->grabTime = time;
if (grab->cursor)
grab->cursor->refcnt++;
CopyGrab(grabinfo->activeGrab, grab);
grabinfo->grab = grabinfo->activeGrab;
grabinfo->grab = AllocGrab(grab);
grabinfo->fromPassiveGrab = isPassive;
grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
PostNewCursor(mouse);
UpdateTouchesForGrab(mouse);
CheckGrabForSyncs(mouse, (Bool) grab->pointerMode,
(Bool) grab->keyboardMode);
if (oldgrab)
FreeGrab(oldgrab);
}
/**
......@@ -1518,13 +1520,20 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
for (i = 0; !wasPassive && mouse->touch && i < mouse->touch->num_touches; i++) {
TouchPointInfoPtr ti = mouse->touch->touches + i;
if (ti->active && TouchResourceIsOwner(ti, grab_resource)) {
int mode = XIRejectTouch;
/* Rejecting will generate a TouchEnd, but we must not
emulate a ButtonRelease here. So pretend the listener
already has the end event */
if (grab->grabtype == CORE || grab->grabtype == XI ||
!xi2mask_isset(mouse->deviceGrab.grab->xi2mask, mouse, XI_TouchBegin))
!xi2mask_isset(mouse->deviceGrab.grab->xi2mask, mouse, XI_TouchBegin)) {
mode = XIAcceptTouch;
/* NOTE: we set the state here, but
* ProcessTouchOwnershipEvent() will still call
* TouchEmitTouchEnd for this listener. The other half of
* this hack is in DeliverTouchEndEvent */
ti->listeners[0].state = LISTENER_HAS_END;
TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch);
}
TouchListenerAcceptReject(mouse, ti, 0, mode);
}
}
......@@ -1544,13 +1553,13 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
if (grab->confineTo)
ConfineCursorToWindow(mouse, GetCurrentRootWindow(mouse), FALSE, FALSE);
PostNewCursor(mouse);
if (grab->cursor)
FreeCursor(grab->cursor, (Cursor) 0);
if (!wasImplicit && grab->grabtype == XI2)
ReattachToOldMaster(mouse);
ComputeFreezes();
FreeGrab(grab);
}
/**
......@@ -1563,6 +1572,7 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time,
Bool passive)
{
GrabInfoPtr grabinfo = &keybd->deviceGrab;
GrabPtr oldgrab = grabinfo->grab;
WindowPtr oldWin;
/* slave devices need to float for the duration of the grab. */
......@@ -1588,12 +1598,13 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time,
grabinfo->grabTime = syncEvents.time;
else
grabinfo->grabTime = time;
CopyGrab(grabinfo->activeGrab, grab);
grabinfo->grab = grabinfo->activeGrab;
grabinfo->grab = AllocGrab(grab);
grabinfo->fromPassiveGrab = passive;
grabinfo->implicitGrab = passive & ImplicitGrabMask;
CheckGrabForSyncs(keybd, (Bool) grab->keyboardMode,
(Bool) grab->pointerMode);
if (oldgrab)
FreeGrab(oldgrab);
}
/**
......@@ -1635,6 +1646,8 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd)
ReattachToOldMaster(keybd);
ComputeFreezes();
FreeGrab(grab);
}
void
......@@ -1739,6 +1752,16 @@ AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
}
break;
}
/* We've unfrozen the grab. If the grab was a touch grab, we're now the
* owner and expected to accept/reject it. Reject == ReplayPointer which
* we've handled in ComputeFreezes() (during DeactivateGrab) above,
* anything else is accept.
*/
if (newState != NOT_GRABBED /* Replay */ &&
IsTouchEvent((InternalEvent*)grabinfo->sync.event)) {
TouchAcceptAndEnd(thisDev, grabinfo->sync.event->touchid);
}
}
/**
......@@ -1971,7 +1994,7 @@ ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
else
return FALSE;
tempGrab = AllocGrab();
tempGrab = AllocGrab(NULL);
if (!tempGrab)
return FALSE;
tempGrab->next = NULL;
......@@ -3191,11 +3214,10 @@ InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin)
pSprite->pEnqueueScreen = screenInfo.screens[0];
pSprite->pDequeueScreen = pSprite->pEnqueueScreen;
}
if (pCursor)
pCursor->refcnt++;
pCursor = RefCursor(pCursor);
if (pSprite->current)
FreeCursor(pSprite->current, None);
pSprite->current = pCursor;
pSprite->current = RefCursor(pCursor);
if (pScreen) {
(*pScreen->RealizeCursor) (pDev, pScreen, pSprite->current);
......@@ -3274,9 +3296,7 @@ UpdateSpriteForScreen(DeviceIntPtr pDev, ScreenPtr pScreen)
pSprite->hotLimits.x2 = pScreen->width;
pSprite->hotLimits.y2 = pScreen->height;
pSprite->win = win;