Merge remote-tracking branch 'whot/touch-grab-race-condition-56578-v3'
This commit is contained in:
commit
c76a1b343d
|
@ -531,15 +531,16 @@ CreateSaverWindow(ScreenPtr pScreen)
|
||||||
mask |= CWBorderPixmap;
|
mask |= CWBorderPixmap;
|
||||||
}
|
}
|
||||||
if (pAttr->pCursor) {
|
if (pAttr->pCursor) {
|
||||||
|
CursorPtr cursor;
|
||||||
if (!pWin->optional)
|
if (!pWin->optional)
|
||||||
if (!MakeWindowOptional(pWin)) {
|
if (!MakeWindowOptional(pWin)) {
|
||||||
FreeResource(pWin->drawable.id, RT_NONE);
|
FreeResource(pWin->drawable.id, RT_NONE);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
pAttr->pCursor->refcnt++;
|
cursor = RefCursor(pAttr->pCursor);
|
||||||
if (pWin->optional->cursor)
|
if (pWin->optional->cursor)
|
||||||
FreeCursor(pWin->optional->cursor, (Cursor) 0);
|
FreeCursor(pWin->optional->cursor, (Cursor) 0);
|
||||||
pWin->optional->cursor = pAttr->pCursor;
|
pWin->optional->cursor = cursor;
|
||||||
pWin->cursorIsNone = FALSE;
|
pWin->cursorIsNone = FALSE;
|
||||||
CheckWindowOptionalNeed(pWin);
|
CheckWindowOptionalNeed(pWin);
|
||||||
mask |= CWCursor;
|
mask |= CWCursor;
|
||||||
|
@ -1065,8 +1066,7 @@ ScreenSaverSetAttributes(ClientPtr client)
|
||||||
client->errorValue = cursorID;
|
client->errorValue = cursorID;
|
||||||
goto PatchUp;
|
goto PatchUp;
|
||||||
}
|
}
|
||||||
pCursor->refcnt++;
|
pAttr->pCursor = RefCursor(pCursor);
|
||||||
pAttr->pCursor = pCursor;
|
|
||||||
pAttr->mask &= ~CWCursor;
|
pAttr->mask &= ~CWCursor;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
116
Xi/exevents.c
116
Xi/exevents.c
|
@ -1036,46 +1036,21 @@ DeliverOneTouchEvent(ClientPtr client, DeviceIntPtr dev, TouchPointInfoPtr ti,
|
||||||
static void
|
static void
|
||||||
ActivateEarlyAccept(DeviceIntPtr dev, TouchPointInfoPtr ti)
|
ActivateEarlyAccept(DeviceIntPtr dev, TouchPointInfoPtr ti)
|
||||||
{
|
{
|
||||||
int rc;
|
|
||||||
ClientPtr client;
|
ClientPtr client;
|
||||||
XID error;
|
XID error;
|
||||||
|
GrabPtr grab = ti->listeners[0].grab;
|
||||||
|
|
||||||
rc = dixLookupClient(&client, ti->listeners[0].listener, serverClient,
|
BUG_RETURN(ti->listeners[0].type != LISTENER_GRAB &&
|
||||||
DixSendAccess);
|
ti->listeners[0].type != LISTENER_POINTER_GRAB);
|
||||||
if (rc != Success) {
|
BUG_RETURN(!grab);
|
||||||
ErrorF("[Xi] Failed to lookup early accepting client.\n");
|
|
||||||
return;
|
client = rClient(grab);
|
||||||
}
|
|
||||||
|
|
||||||
if (TouchAcceptReject(client, dev, XIAcceptTouch, ti->client_id,
|
if (TouchAcceptReject(client, dev, XIAcceptTouch, ti->client_id,
|
||||||
ti->listeners[0].window->drawable.id, &error) !=
|
ti->listeners[0].window->drawable.id, &error) != Success)
|
||||||
Success)
|
|
||||||
ErrorF("[Xi] Failed to accept touch grab after early acceptance.\n");
|
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.
|
* Find the oldest touch that still has a pointer emulation client.
|
||||||
*
|
*
|
||||||
|
@ -1127,10 +1102,10 @@ TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
|
||||||
TouchOwnershipEvent *ev)
|
TouchOwnershipEvent *ev)
|
||||||
{
|
{
|
||||||
TouchListener *listener = &ti->listeners[0]; /* new owner */
|
TouchListener *listener = &ti->listeners[0]; /* new owner */
|
||||||
|
int accepted_early = listener->state == LISTENER_EARLY_ACCEPT;
|
||||||
|
|
||||||
/* Deliver the ownership */
|
/* Deliver the ownership */
|
||||||
if (listener->state == LISTENER_AWAITING_OWNER ||
|
if (listener->state == LISTENER_AWAITING_OWNER || accepted_early)
|
||||||
listener->state == LISTENER_EARLY_ACCEPT)
|
|
||||||
DeliverTouchEvents(dev, ti, (InternalEvent *) ev,
|
DeliverTouchEvents(dev, ti, (InternalEvent *) ev,
|
||||||
listener->listener);
|
listener->listener);
|
||||||
else if (listener->state == LISTENER_AWAITING_BEGIN) {
|
else if (listener->state == LISTENER_AWAITING_BEGIN) {
|
||||||
|
@ -1144,15 +1119,24 @@ TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
|
||||||
TouchEventHistoryReplay(ti, dev, listener->listener);
|
TouchEventHistoryReplay(ti, dev, listener->listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we've just removed the last grab and the touch has physically
|
/* New owner has Begin/Update but not end. If touch is pending_finish,
|
||||||
* ended, send a TouchEnd event too and finalise the touch. */
|
* emulate the TouchEnd now */
|
||||||
if (ti->num_listeners == 1 && ti->num_grabs == 0 && ti->pending_finish) {
|
if (ti->pending_finish) {
|
||||||
EmitTouchEnd(dev, ti, 0, 0);
|
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);
|
TouchEndTouch(dev, ti);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (listener->state == LISTENER_EARLY_ACCEPT)
|
if (accepted_early)
|
||||||
ActivateEarlyAccept(dev, ti);
|
ActivateEarlyAccept(dev, ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1196,7 +1180,7 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource,
|
||||||
for (i = 0; i < ti->num_listeners; i++) {
|
for (i = 0; i < ti->num_listeners; i++) {
|
||||||
if (ti->listeners[i].listener == resource) {
|
if (ti->listeners[i].listener == resource) {
|
||||||
if (ti->listeners[i].state != LISTENER_HAS_END)
|
if (ti->listeners[i].state != LISTENER_HAS_END)
|
||||||
EmitTouchEnd(sourcedev, ti, TOUCH_REJECT, resource);
|
TouchEmitTouchEnd(sourcedev, ti, TOUCH_REJECT, resource);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1243,12 +1227,12 @@ ProcessTouchOwnershipEvent(TouchOwnershipEvent *ev,
|
||||||
* already seen the end. This ensures that the touch record is ended in
|
* 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)
|
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
|
/* The touch owner has accepted the touch. Send TouchEnd events to
|
||||||
* everyone else, and truncate the list of listeners. */
|
* everyone else, and truncate the list of listeners. */
|
||||||
for (i = 1; i < ti->num_listeners; i++)
|
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)
|
while (ti->num_listeners > 1)
|
||||||
TouchRemoveListener(ti, ti->listeners[1].listener);
|
TouchRemoveListener(ti, ti->listeners[1].listener);
|
||||||
|
@ -1417,7 +1401,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!deliveries)
|
if (!deliveries)
|
||||||
DeliverOneGrabbedEvent(ptrev, dev, grab->grabtype);
|
deliveries = DeliverOneGrabbedEvent(ptrev, dev, grab->grabtype);
|
||||||
|
|
||||||
/* We must accept the touch sequence once a pointer listener has
|
/* We must accept the touch sequence once a pointer listener has
|
||||||
* received one event past ButtonPress. */
|
* received one event past ButtonPress. */
|
||||||
|
@ -1425,8 +1409,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
|
||||||
!(ev->device_event.flags & TOUCH_CLIENT_ID))
|
!(ev->device_event.flags & TOUCH_CLIENT_ID))
|
||||||
TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch);
|
TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch);
|
||||||
|
|
||||||
if (ev->any.type == ET_TouchEnd &&
|
if (deliveries && ev->any.type == ET_TouchEnd &&
|
||||||
!(ev->device_event.flags & TOUCH_CLIENT_ID) &&
|
|
||||||
!dev->button->buttonsDown &&
|
!dev->button->buttonsDown &&
|
||||||
dev->deviceGrab.fromPassiveGrab && GrabIsPointerGrab(grab)) {
|
dev->deviceGrab.fromPassiveGrab && GrabIsPointerGrab(grab)) {
|
||||||
(*dev->deviceGrab.DeactivateGrab) (dev);
|
(*dev->deviceGrab.DeactivateGrab) (dev);
|
||||||
|
@ -1445,8 +1428,11 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
|
||||||
*/
|
*/
|
||||||
if (!devgrab && dev->deviceGrab.grab && dev->deviceGrab.implicitGrab) {
|
if (!devgrab && dev->deviceGrab.grab && dev->deviceGrab.implicitGrab) {
|
||||||
TouchListener *l;
|
TouchListener *l;
|
||||||
|
GrabPtr g;
|
||||||
|
|
||||||
devgrab = dev->deviceGrab.grab;
|
devgrab = dev->deviceGrab.grab;
|
||||||
|
g = AllocGrab(devgrab);
|
||||||
|
BUG_WARN(!g);
|
||||||
|
|
||||||
*dev->deviceGrab.sync.event = ev->device_event;
|
*dev->deviceGrab.sync.event = ev->device_event;
|
||||||
|
|
||||||
|
@ -1455,8 +1441,8 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
|
||||||
* event selection. Thus, we update the last listener in the array.
|
* event selection. Thus, we update the last listener in the array.
|
||||||
*/
|
*/
|
||||||
l = &ti->listeners[ti->num_listeners - 1];
|
l = &ti->listeners[ti->num_listeners - 1];
|
||||||
l->listener = devgrab->resource;
|
l->listener = g->resource;
|
||||||
l->grab = devgrab;
|
l->grab = g;
|
||||||
//l->resource_type = RT_NONE;
|
//l->resource_type = RT_NONE;
|
||||||
|
|
||||||
if (devgrab->grabtype != XI2 || devgrab->type != XI_TouchBegin)
|
if (devgrab->grabtype != XI2 || devgrab->type != XI_TouchBegin)
|
||||||
|
@ -1547,7 +1533,7 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
|
||||||
|
|
||||||
touchid = ev->device_event.touchid;
|
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,
|
ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
|
||||||
emulate_pointer);
|
emulate_pointer);
|
||||||
}
|
}
|
||||||
|
@ -1614,7 +1600,9 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
|
||||||
* called after event type mutation. Touch end events are always processed
|
* called after event type mutation. Touch end events are always processed
|
||||||
* in order to end touch records. */
|
* in order to end touch records. */
|
||||||
/* FIXME: check this */
|
/* 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))
|
(type != ET_TouchEnd && ti->sprite.spriteTraceGood == 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1622,7 +1610,7 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
|
||||||
/* WARNING: the event type may change to TouchUpdate in
|
/* WARNING: the event type may change to TouchUpdate in
|
||||||
* DeliverTouchEvents if a TouchEnd was delivered to a grabbing
|
* DeliverTouchEvents if a TouchEnd was delivered to a grabbing
|
||||||
* owner */
|
* owner */
|
||||||
DeliverTouchEvents(dev, ti, (InternalEvent *) ev, 0);
|
DeliverTouchEvents(dev, ti, ev, ev->device_event.resource);
|
||||||
if (ev->any.type == ET_TouchEnd)
|
if (ev->any.type == ET_TouchEnd)
|
||||||
TouchEndTouch(dev, ti);
|
TouchEndTouch(dev, ti);
|
||||||
|
|
||||||
|
@ -1850,6 +1838,14 @@ DeliverTouchBeginEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
|
||||||
listener->type == LISTENER_POINTER_GRAB) {
|
listener->type == LISTENER_POINTER_GRAB) {
|
||||||
rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
|
rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
|
||||||
grab, xi2mask);
|
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;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1867,7 +1863,7 @@ DeliverTouchBeginEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
|
||||||
if (has_ownershipmask)
|
if (has_ownershipmask)
|
||||||
TouchSendOwnershipEvent(dev, ti, 0, listener->listener);
|
TouchSendOwnershipEvent(dev, ti, 0, listener->listener);
|
||||||
|
|
||||||
if (!has_ownershipmask || listener->type == LISTENER_REGULAR)
|
if (listener->type == LISTENER_REGULAR)
|
||||||
state = LISTENER_HAS_ACCEPTED;
|
state = LISTENER_HAS_ACCEPTED;
|
||||||
else
|
else
|
||||||
state = LISTENER_IS_OWNER;
|
state = LISTENER_IS_OWNER;
|
||||||
|
@ -1890,13 +1886,13 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
|
||||||
rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
|
rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
|
||||||
grab, xi2mask);
|
grab, xi2mask);
|
||||||
|
|
||||||
if (ti->num_listeners > 1) {
|
/* Once we send a TouchEnd to a legacy listener, we're already well
|
||||||
ev->any.type = ET_TouchUpdate;
|
* past the accepting/rejecting stage (can only happen on
|
||||||
ev->device_event.flags |= TOUCH_PENDING_END;
|
* GrabModeSync + replay. This listener now gets the end event,
|
||||||
if (!(ev->device_event.flags & TOUCH_CLIENT_ID))
|
* and we can continue.
|
||||||
ti->pending_finish = TRUE;
|
*/
|
||||||
}
|
if (rc == Success)
|
||||||
|
listener->state = LISTENER_HAS_END;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1922,7 +1918,7 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
|
||||||
rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
|
rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
|
||||||
|
|
||||||
if ((ti->num_listeners > 1 ||
|
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->device_event.flags & (TOUCH_ACCEPT | TOUCH_REJECT)) == 0) {
|
||||||
ev->any.type = ET_TouchUpdate;
|
ev->any.type = ET_TouchUpdate;
|
||||||
ev->device_event.flags |= TOUCH_PENDING_END;
|
ev->device_event.flags |= TOUCH_PENDING_END;
|
||||||
|
@ -2850,7 +2846,7 @@ CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type,
|
||||||
(deliveryMask & DeviceButtonGrabMask)) {
|
(deliveryMask & DeviceButtonGrabMask)) {
|
||||||
GrabPtr tempGrab;
|
GrabPtr tempGrab;
|
||||||
|
|
||||||
tempGrab = AllocGrab();
|
tempGrab = AllocGrab(NULL);
|
||||||
if (!tempGrab)
|
if (!tempGrab)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ ProcXUngrabDeviceButton(ClientPtr client)
|
||||||
(stuff->modifiers & ~AllModifiersMask))
|
(stuff->modifiers & ~AllModifiersMask))
|
||||||
return BadValue;
|
return BadValue;
|
||||||
|
|
||||||
temporaryGrab = AllocGrab();
|
temporaryGrab = AllocGrab(NULL);
|
||||||
if (!temporaryGrab)
|
if (!temporaryGrab)
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,7 @@ ProcXUngrabDeviceKey(ClientPtr client)
|
||||||
(stuff->modifiers & ~AllModifiersMask))
|
(stuff->modifiers & ~AllModifiersMask))
|
||||||
return BadValue;
|
return BadValue;
|
||||||
|
|
||||||
temporaryGrab = AllocGrab();
|
temporaryGrab = AllocGrab(NULL);
|
||||||
if (!temporaryGrab)
|
if (!temporaryGrab)
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
|
|
||||||
|
|
|
@ -307,7 +307,7 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
|
||||||
|
|
||||||
mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
|
mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
|
||||||
|
|
||||||
tempGrab = AllocGrab();
|
tempGrab = AllocGrab(NULL);
|
||||||
if (!tempGrab)
|
if (!tempGrab)
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
|
|
||||||
|
|
33
dix/cursor.c
33
dix/cursor.c
|
@ -114,9 +114,13 @@ FreeCursor(pointer value, XID cid)
|
||||||
ScreenPtr pscr;
|
ScreenPtr pscr;
|
||||||
DeviceIntPtr pDev = NULL; /* unused anyway */
|
DeviceIntPtr pDev = NULL; /* unused anyway */
|
||||||
|
|
||||||
if (--pCurs->refcnt != 0)
|
|
||||||
|
UnrefCursor(pCurs);
|
||||||
|
if (CursorRefCount(pCurs) != 0)
|
||||||
return Success;
|
return Success;
|
||||||
|
|
||||||
|
BUG_WARN(CursorRefCount(pCurs) < 0);
|
||||||
|
|
||||||
for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
|
for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
|
||||||
pscr = screenInfo.screens[nscr];
|
pscr = screenInfo.screens[nscr];
|
||||||
(void) (*pscr->UnrealizeCursor) (pDev, pscr, pCurs);
|
(void) (*pscr->UnrealizeCursor) (pDev, pscr, pCurs);
|
||||||
|
@ -127,6 +131,33 @@ FreeCursor(pointer value, XID cid)
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CursorPtr
|
||||||
|
RefCursor(CursorPtr cursor)
|
||||||
|
{
|
||||||
|
ErrorF("%s ::::: cursor is %p", __func__, cursor);
|
||||||
|
if (cursor) {
|
||||||
|
xorg_backtrace();
|
||||||
|
cursor->refcnt++;
|
||||||
|
}
|
||||||
|
ErrorF("\n");
|
||||||
|
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
|
* 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.grabTime = currentTime;
|
||||||
dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
|
dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
|
||||||
dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
|
dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
|
||||||
dev->deviceGrab.activeGrab = AllocGrab();
|
|
||||||
dev->deviceGrab.sync.event = calloc(1, sizeof(DeviceEvent));
|
dev->deviceGrab.sync.event = calloc(1, sizeof(DeviceEvent));
|
||||||
|
|
||||||
XkbSetExtension(dev, ProcessKeyboardEvent);
|
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->deviceGrab.sync.event);
|
||||||
free(dev->config_info); /* Allocated in xf86ActivateDevice. */
|
free(dev->config_info); /* Allocated in xf86ActivateDevice. */
|
||||||
free(dev->last.scroll);
|
free(dev->last.scroll);
|
||||||
|
@ -1647,6 +1647,7 @@ InitTouchClassDeviceStruct(DeviceIntPtr device, unsigned int max_touches,
|
||||||
|
|
||||||
BUG_RETURN_VAL(device == NULL, FALSE);
|
BUG_RETURN_VAL(device == NULL, FALSE);
|
||||||
BUG_RETURN_VAL(device->touch != NULL, FALSE);
|
BUG_RETURN_VAL(device->touch != NULL, FALSE);
|
||||||
|
BUG_RETURN_VAL(device->valuator == NULL, FALSE);
|
||||||
|
|
||||||
/* Check the mode is valid, and at least X and Y axes. */
|
/* Check the mode is valid, and at least X and Y axes. */
|
||||||
BUG_RETURN_VAL(mode != XIDirectTouch && mode != XIDependentTouch, FALSE);
|
BUG_RETURN_VAL(mode != XIDirectTouch && mode != XIDependentTouch, FALSE);
|
||||||
|
|
|
@ -3399,6 +3399,7 @@ CloseDownClient(ClientPtr client)
|
||||||
clientinfo.setup = (xConnSetup *) NULL;
|
clientinfo.setup = (xConnSetup *) NULL;
|
||||||
CallCallbacks((&ClientStateCallback), (pointer) &clientinfo);
|
CallCallbacks((&ClientStateCallback), (pointer) &clientinfo);
|
||||||
}
|
}
|
||||||
|
TouchListenerGone(client->clientAsMask);
|
||||||
FreeClientResources(client);
|
FreeClientResources(client);
|
||||||
/* Disable client ID tracking. This must be done after
|
/* Disable client ID tracking. This must be done after
|
||||||
* ClientStateCallback. */
|
* ClientStateCallback. */
|
||||||
|
|
89
dix/events.c
89
dix/events.c
|
@ -931,8 +931,7 @@ ChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor)
|
||||||
|
|
||||||
(*pScreen->DisplayCursor) (pDev, pScreen, cursor);
|
(*pScreen->DisplayCursor) (pDev, pScreen, cursor);
|
||||||
FreeCursor(pSprite->current, (Cursor) 0);
|
FreeCursor(pSprite->current, (Cursor) 0);
|
||||||
pSprite->current = cursor;
|
pSprite->current = RefCursor(cursor);
|
||||||
pSprite->current->refcnt++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1427,21 +1426,23 @@ UpdateTouchesForGrab(DeviceIntPtr mouse)
|
||||||
|
|
||||||
for (i = 0; i < mouse->touch->num_touches; i++) {
|
for (i = 0; i < mouse->touch->num_touches; i++) {
|
||||||
TouchPointInfoPtr ti = mouse->touch->touches + i;
|
TouchPointInfoPtr ti = mouse->touch->touches + i;
|
||||||
|
TouchListener *listener = &ti->listeners[0];
|
||||||
GrabPtr grab = mouse->deviceGrab.grab;
|
GrabPtr grab = mouse->deviceGrab.grab;
|
||||||
|
|
||||||
if (ti->active &&
|
if (ti->active &&
|
||||||
CLIENT_BITS(ti->listeners[0].listener) == grab->resource) {
|
CLIENT_BITS(listener->listener) == grab->resource) {
|
||||||
ti->listeners[0].listener = grab->resource;
|
listener->listener = grab->resource;
|
||||||
ti->listeners[0].level = grab->grabtype;
|
listener->level = grab->grabtype;
|
||||||
ti->listeners[0].state = LISTENER_IS_OWNER;
|
listener->state = LISTENER_IS_OWNER;
|
||||||
ti->listeners[0].window = grab->window;
|
listener->window = grab->window;
|
||||||
|
|
||||||
if (grab->grabtype == CORE || grab->grabtype == XI ||
|
if (grab->grabtype == CORE || grab->grabtype == XI ||
|
||||||
!xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin))
|
!xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin))
|
||||||
ti->listeners[0].type = LISTENER_POINTER_GRAB;
|
listener->type = LISTENER_POINTER_GRAB;
|
||||||
else
|
else
|
||||||
ti->listeners[0].type = LISTENER_GRAB;
|
listener->type = LISTENER_GRAB;
|
||||||
ti->listeners[0].grab = grab;
|
FreeGrab(listener->grab);
|
||||||
|
listener->grab = AllocGrab(grab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1466,6 +1467,7 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
|
||||||
TimeStamp time, Bool autoGrab)
|
TimeStamp time, Bool autoGrab)
|
||||||
{
|
{
|
||||||
GrabInfoPtr grabinfo = &mouse->deviceGrab;
|
GrabInfoPtr grabinfo = &mouse->deviceGrab;
|
||||||
|
GrabPtr oldgrab = grabinfo->grab;
|
||||||
WindowPtr oldWin = (grabinfo->grab) ?
|
WindowPtr oldWin = (grabinfo->grab) ?
|
||||||
grabinfo->grab->window : mouse->spriteInfo->sprite->win;
|
grabinfo->grab->window : mouse->spriteInfo->sprite->win;
|
||||||
Bool isPassive = autoGrab & ~ImplicitGrabMask;
|
Bool isPassive = autoGrab & ~ImplicitGrabMask;
|
||||||
|
@ -1488,16 +1490,15 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
|
||||||
grabinfo->grabTime = syncEvents.time;
|
grabinfo->grabTime = syncEvents.time;
|
||||||
else
|
else
|
||||||
grabinfo->grabTime = time;
|
grabinfo->grabTime = time;
|
||||||
if (grab->cursor)
|
grabinfo->grab = AllocGrab(grab);
|
||||||
grab->cursor->refcnt++;
|
|
||||||
CopyGrab(grabinfo->activeGrab, grab);
|
|
||||||
grabinfo->grab = grabinfo->activeGrab;
|
|
||||||
grabinfo->fromPassiveGrab = isPassive;
|
grabinfo->fromPassiveGrab = isPassive;
|
||||||
grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
|
grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
|
||||||
PostNewCursor(mouse);
|
PostNewCursor(mouse);
|
||||||
UpdateTouchesForGrab(mouse);
|
UpdateTouchesForGrab(mouse);
|
||||||
CheckGrabForSyncs(mouse, (Bool) grab->pointerMode,
|
CheckGrabForSyncs(mouse, (Bool) grab->pointerMode,
|
||||||
(Bool) grab->keyboardMode);
|
(Bool) grab->keyboardMode);
|
||||||
|
if (oldgrab)
|
||||||
|
FreeGrab(oldgrab);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1547,13 +1548,13 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
|
||||||
if (grab->confineTo)
|
if (grab->confineTo)
|
||||||
ConfineCursorToWindow(mouse, GetCurrentRootWindow(mouse), FALSE, FALSE);
|
ConfineCursorToWindow(mouse, GetCurrentRootWindow(mouse), FALSE, FALSE);
|
||||||
PostNewCursor(mouse);
|
PostNewCursor(mouse);
|
||||||
if (grab->cursor)
|
|
||||||
FreeCursor(grab->cursor, (Cursor) 0);
|
|
||||||
|
|
||||||
if (!wasImplicit && grab->grabtype == XI2)
|
if (!wasImplicit && grab->grabtype == XI2)
|
||||||
ReattachToOldMaster(mouse);
|
ReattachToOldMaster(mouse);
|
||||||
|
|
||||||
ComputeFreezes();
|
ComputeFreezes();
|
||||||
|
|
||||||
|
FreeGrab(grab);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1566,6 +1567,7 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time,
|
||||||
Bool passive)
|
Bool passive)
|
||||||
{
|
{
|
||||||
GrabInfoPtr grabinfo = &keybd->deviceGrab;
|
GrabInfoPtr grabinfo = &keybd->deviceGrab;
|
||||||
|
GrabPtr oldgrab = grabinfo->grab;
|
||||||
WindowPtr oldWin;
|
WindowPtr oldWin;
|
||||||
|
|
||||||
/* slave devices need to float for the duration of the grab. */
|
/* slave devices need to float for the duration of the grab. */
|
||||||
|
@ -1591,12 +1593,13 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time,
|
||||||
grabinfo->grabTime = syncEvents.time;
|
grabinfo->grabTime = syncEvents.time;
|
||||||
else
|
else
|
||||||
grabinfo->grabTime = time;
|
grabinfo->grabTime = time;
|
||||||
CopyGrab(grabinfo->activeGrab, grab);
|
grabinfo->grab = AllocGrab(grab);
|
||||||
grabinfo->grab = grabinfo->activeGrab;
|
|
||||||
grabinfo->fromPassiveGrab = passive;
|
grabinfo->fromPassiveGrab = passive;
|
||||||
grabinfo->implicitGrab = passive & ImplicitGrabMask;
|
grabinfo->implicitGrab = passive & ImplicitGrabMask;
|
||||||
CheckGrabForSyncs(keybd, (Bool) grab->keyboardMode,
|
CheckGrabForSyncs(keybd, (Bool) grab->keyboardMode,
|
||||||
(Bool) grab->pointerMode);
|
(Bool) grab->pointerMode);
|
||||||
|
if (oldgrab)
|
||||||
|
FreeGrab(oldgrab);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1638,6 +1641,8 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd)
|
||||||
ReattachToOldMaster(keybd);
|
ReattachToOldMaster(keybd);
|
||||||
|
|
||||||
ComputeFreezes();
|
ComputeFreezes();
|
||||||
|
|
||||||
|
FreeGrab(grab);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1742,6 +1747,16 @@ AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
|
||||||
}
|
}
|
||||||
break;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1974,7 +1989,7 @@ ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
tempGrab = AllocGrab();
|
tempGrab = AllocGrab(NULL);
|
||||||
if (!tempGrab)
|
if (!tempGrab)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
tempGrab->next = NULL;
|
tempGrab->next = NULL;
|
||||||
|
@ -3194,11 +3209,10 @@ InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin)
|
||||||
pSprite->pEnqueueScreen = screenInfo.screens[0];
|
pSprite->pEnqueueScreen = screenInfo.screens[0];
|
||||||
pSprite->pDequeueScreen = pSprite->pEnqueueScreen;
|
pSprite->pDequeueScreen = pSprite->pEnqueueScreen;
|
||||||
}
|
}
|
||||||
if (pCursor)
|
pCursor = RefCursor(pCursor);
|
||||||
pCursor->refcnt++;
|
|
||||||
if (pSprite->current)
|
if (pSprite->current)
|
||||||
FreeCursor(pSprite->current, None);
|
FreeCursor(pSprite->current, None);
|
||||||
pSprite->current = pCursor;
|
pSprite->current = RefCursor(pCursor);
|
||||||
|
|
||||||
if (pScreen) {
|
if (pScreen) {
|
||||||
(*pScreen->RealizeCursor) (pDev, pScreen, pSprite->current);
|
(*pScreen->RealizeCursor) (pDev, pScreen, pSprite->current);
|
||||||
|
@ -3277,9 +3291,7 @@ UpdateSpriteForScreen(DeviceIntPtr pDev, ScreenPtr pScreen)
|
||||||
pSprite->hotLimits.x2 = pScreen->width;
|
pSprite->hotLimits.x2 = pScreen->width;
|
||||||
pSprite->hotLimits.y2 = pScreen->height;
|
pSprite->hotLimits.y2 = pScreen->height;
|
||||||
pSprite->win = win;
|
pSprite->win = win;
|
||||||
pCursor = wCursor(win);
|
pCursor = RefCursor(wCursor(win));
|
||||||
if (pCursor)
|
|
||||||
pCursor->refcnt++;
|
|
||||||
if (pSprite->current)
|
if (pSprite->current)
|
||||||
FreeCursor(pSprite->current, 0);
|
FreeCursor(pSprite->current, 0);
|
||||||
pSprite->current = pCursor;
|
pSprite->current = pCursor;
|
||||||
|
@ -3881,7 +3893,7 @@ CheckPassiveGrabsOnWindow(WindowPtr pWin,
|
||||||
if (!grab)
|
if (!grab)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
tempGrab = AllocGrab();
|
tempGrab = AllocGrab(NULL);
|
||||||
|
|
||||||
/* 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 */
|
||||||
|
@ -4839,7 +4851,6 @@ ProcGrabPointer(ClientPtr client)
|
||||||
GrabPtr grab;
|
GrabPtr grab;
|
||||||
GrabMask mask;
|
GrabMask mask;
|
||||||
WindowPtr confineTo;
|
WindowPtr confineTo;
|
||||||
CursorPtr oldCursor;
|
|
||||||
BYTE status;
|
BYTE status;
|
||||||
|
|
||||||
REQUEST(xGrabPointerReq);
|
REQUEST(xGrabPointerReq);
|
||||||
|
@ -4862,15 +4873,10 @@ ProcGrabPointer(ClientPtr client)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
oldCursor = NullCursor;
|
|
||||||
grab = device->deviceGrab.grab;
|
grab = device->deviceGrab.grab;
|
||||||
|
|
||||||
if (grab) {
|
if (grab && grab->confineTo && !confineTo)
|
||||||
if (grab->confineTo && !confineTo)
|
ConfineCursorToWindow(device, GetCurrentRootWindow(device), FALSE, FALSE);
|
||||||
ConfineCursorToWindow(device, GetCurrentRootWindow(device), FALSE,
|
|
||||||
FALSE);
|
|
||||||
oldCursor = grab->cursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
mask.core = stuff->eventMask;
|
mask.core = stuff->eventMask;
|
||||||
|
|
||||||
|
@ -4880,9 +4886,6 @@ ProcGrabPointer(ClientPtr client)
|
||||||
if (rc != Success)
|
if (rc != Success)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (oldCursor && status == GrabSuccess)
|
|
||||||
FreeCursor(oldCursor, (Cursor) 0);
|
|
||||||
|
|
||||||
rep = (xGrabPointerReply) {
|
rep = (xGrabPointerReply) {
|
||||||
.type = X_Reply,
|
.type = X_Reply,
|
||||||
.status = status,
|
.status = status,
|
||||||
|
@ -4938,9 +4941,7 @@ ProcChangeActivePointerGrab(ClientPtr client)
|
||||||
(CompareTimeStamps(time, device->deviceGrab.grabTime) == EARLIER))
|
(CompareTimeStamps(time, device->deviceGrab.grabTime) == EARLIER))
|
||||||
return Success;
|
return Success;
|
||||||
oldCursor = grab->cursor;
|
oldCursor = grab->cursor;
|
||||||
grab->cursor = newCursor;
|
grab->cursor = RefCursor(newCursor);
|
||||||
if (newCursor)
|
|
||||||
newCursor->refcnt++;
|
|
||||||
PostNewCursor(device);
|
PostNewCursor(device);
|
||||||
if (oldCursor)
|
if (oldCursor)
|
||||||
FreeCursor(oldCursor, (Cursor) 0);
|
FreeCursor(oldCursor, (Cursor) 0);
|
||||||
|
@ -5070,7 +5071,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
|
||||||
else {
|
else {
|
||||||
GrabPtr tempGrab;
|
GrabPtr tempGrab;
|
||||||
|
|
||||||
tempGrab = AllocGrab();
|
tempGrab = AllocGrab(NULL);
|
||||||
|
|
||||||
tempGrab->next = NULL;
|
tempGrab->next = NULL;
|
||||||
tempGrab->window = pWin;
|
tempGrab->window = pWin;
|
||||||
|
@ -5085,7 +5086,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
|
||||||
else
|
else
|
||||||
xi2mask_merge(tempGrab->xi2mask, mask->xi2mask);
|
xi2mask_merge(tempGrab->xi2mask, mask->xi2mask);
|
||||||
tempGrab->device = dev;
|
tempGrab->device = dev;
|
||||||
tempGrab->cursor = cursor;
|
tempGrab->cursor = RefCursor(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);
|
||||||
|
@ -5426,7 +5427,7 @@ ProcUngrabKey(ClientPtr client)
|
||||||
client->errorValue = stuff->modifiers;
|
client->errorValue = stuff->modifiers;
|
||||||
return BadValue;
|
return BadValue;
|
||||||
}
|
}
|
||||||
tempGrab = AllocGrab();
|
tempGrab = AllocGrab(NULL);
|
||||||
if (!tempGrab)
|
if (!tempGrab)
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
tempGrab->resource = client->clientAsMask;
|
tempGrab->resource = client->clientAsMask;
|
||||||
|
@ -5620,7 +5621,7 @@ ProcUngrabButton(ClientPtr client)
|
||||||
|
|
||||||
ptr = PickPointer(client);
|
ptr = PickPointer(client);
|
||||||
|
|
||||||
tempGrab = AllocGrab();
|
tempGrab = AllocGrab(NULL);
|
||||||
if (!tempGrab)
|
if (!tempGrab)
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
tempGrab->resource = client->clientAsMask;
|
tempGrab->resource = client->clientAsMask;
|
||||||
|
|
21
dix/grabs.c
21
dix/grabs.c
|
@ -189,7 +189,7 @@ UngrabAllDevices(Bool kill_client)
|
||||||
}
|
}
|
||||||
|
|
||||||
GrabPtr
|
GrabPtr
|
||||||
AllocGrab(void)
|
AllocGrab(const GrabPtr src)
|
||||||
{
|
{
|
||||||
GrabPtr grab = calloc(1, sizeof(GrabRec));
|
GrabPtr grab = calloc(1, sizeof(GrabRec));
|
||||||
|
|
||||||
|
@ -201,6 +201,12 @@ AllocGrab(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (src && !CopyGrab(grab, src)) {
|
||||||
|
free(grab->xi2mask);
|
||||||
|
free(grab);
|
||||||
|
grab = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return grab;
|
return grab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +219,7 @@ CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice,
|
||||||
{
|
{
|
||||||
GrabPtr grab;
|
GrabPtr grab;
|
||||||
|
|
||||||
grab = AllocGrab();
|
grab = AllocGrab(NULL);
|
||||||
if (!grab)
|
if (!grab)
|
||||||
return (GrabPtr) NULL;
|
return (GrabPtr) NULL;
|
||||||
grab->resource = FakeClientID(client);
|
grab->resource = FakeClientID(client);
|
||||||
|
@ -235,13 +241,11 @@ CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice,
|
||||||
grab->detail.exact = keybut;
|
grab->detail.exact = keybut;
|
||||||
grab->detail.pMask = NULL;
|
grab->detail.pMask = NULL;
|
||||||
grab->confineTo = confineTo;
|
grab->confineTo = confineTo;
|
||||||
grab->cursor = cursor;
|
grab->cursor = RefCursor(cursor);
|
||||||
grab->next = NULL;
|
grab->next = NULL;
|
||||||
|
|
||||||
if (grabtype == XI2)
|
if (grabtype == XI2)
|
||||||
xi2mask_merge(grab->xi2mask, mask->xi2mask);
|
xi2mask_merge(grab->xi2mask, mask->xi2mask);
|
||||||
if (cursor)
|
|
||||||
cursor->refcnt++;
|
|
||||||
return grab;
|
return grab;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -249,8 +253,7 @@ CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice,
|
||||||
void
|
void
|
||||||
FreeGrab(GrabPtr pGrab)
|
FreeGrab(GrabPtr pGrab)
|
||||||
{
|
{
|
||||||
if (pGrab->grabtype == XI2 && pGrab->type == XI_TouchBegin)
|
BUG_RETURN(!pGrab);
|
||||||
TouchListenerGone(pGrab->resource);
|
|
||||||
|
|
||||||
free(pGrab->modifiersDetail.pMask);
|
free(pGrab->modifiersDetail.pMask);
|
||||||
free(pGrab->detail.pMask);
|
free(pGrab->detail.pMask);
|
||||||
|
@ -269,9 +272,6 @@ CopyGrab(GrabPtr dst, const GrabPtr src)
|
||||||
Mask *details_mask = NULL;
|
Mask *details_mask = NULL;
|
||||||
XI2Mask *xi2mask;
|
XI2Mask *xi2mask;
|
||||||
|
|
||||||
if (src->cursor)
|
|
||||||
src->cursor->refcnt++;
|
|
||||||
|
|
||||||
if (src->modifiersDetail.pMask) {
|
if (src->modifiersDetail.pMask) {
|
||||||
int len = MasksPerDetailMask * sizeof(Mask);
|
int len = MasksPerDetailMask * sizeof(Mask);
|
||||||
|
|
||||||
|
@ -309,6 +309,7 @@ CopyGrab(GrabPtr dst, const GrabPtr src)
|
||||||
dst->modifiersDetail.pMask = mdetails_mask;
|
dst->modifiersDetail.pMask = mdetails_mask;
|
||||||
dst->detail.pMask = details_mask;
|
dst->detail.pMask = details_mask;
|
||||||
dst->xi2mask = xi2mask;
|
dst->xi2mask = xi2mask;
|
||||||
|
dst->cursor = RefCursor(src->cursor);
|
||||||
|
|
||||||
xi2mask_merge(dst->xi2mask, src->xi2mask);
|
xi2mask_merge(dst->xi2mask, src->xi2mask);
|
||||||
|
|
||||||
|
|
98
dix/touch.c
98
dix/touch.c
|
@ -263,6 +263,7 @@ void
|
||||||
TouchFreeTouchPoint(DeviceIntPtr device, int index)
|
TouchFreeTouchPoint(DeviceIntPtr device, int index)
|
||||||
{
|
{
|
||||||
TouchPointInfoPtr ti;
|
TouchPointInfoPtr ti;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (!device->touch || index >= device->touch->num_touches)
|
if (!device->touch || index >= device->touch->num_touches)
|
||||||
return;
|
return;
|
||||||
|
@ -271,6 +272,9 @@ TouchFreeTouchPoint(DeviceIntPtr device, int index)
|
||||||
if (ti->active)
|
if (ti->active)
|
||||||
TouchEndTouch(device, ti);
|
TouchEndTouch(device, ti);
|
||||||
|
|
||||||
|
for (i = 0; i < ti->num_listeners; i++)
|
||||||
|
TouchRemoveListener(ti, ti->listeners[0].listener);
|
||||||
|
|
||||||
valuator_mask_free(&ti->valuators);
|
valuator_mask_free(&ti->valuators);
|
||||||
free(ti->sprite.spriteTrace);
|
free(ti->sprite.spriteTrace);
|
||||||
ti->sprite.spriteTrace = NULL;
|
ti->sprite.spriteTrace = NULL;
|
||||||
|
@ -365,6 +369,8 @@ TouchBeginTouch(DeviceIntPtr dev, int sourceid, uint32_t touchid,
|
||||||
void
|
void
|
||||||
TouchEndTouch(DeviceIntPtr dev, TouchPointInfoPtr ti)
|
TouchEndTouch(DeviceIntPtr dev, TouchPointInfoPtr ti)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if (ti->emulate_pointer) {
|
if (ti->emulate_pointer) {
|
||||||
GrabPtr grab;
|
GrabPtr grab;
|
||||||
|
|
||||||
|
@ -376,6 +382,9 @@ TouchEndTouch(DeviceIntPtr dev, TouchPointInfoPtr ti)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ti->num_listeners; i++)
|
||||||
|
TouchRemoveListener(ti, ti->listeners[0].listener);
|
||||||
|
|
||||||
ti->active = FALSE;
|
ti->active = FALSE;
|
||||||
ti->pending_finish = FALSE;
|
ti->pending_finish = FALSE;
|
||||||
ti->sprite.spriteTraceGood = 0;
|
ti->sprite.spriteTraceGood = 0;
|
||||||
|
@ -474,7 +483,21 @@ TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, XID resource)
|
||||||
DeviceEvent *ev = &ti->history[i];
|
DeviceEvent *ev = &ti->history[i];
|
||||||
|
|
||||||
ev->flags |= TOUCH_REPLAYING;
|
ev->flags |= TOUCH_REPLAYING;
|
||||||
DeliverTouchEvents(dev, ti, (InternalEvent *) ev, resource);
|
ev->resource = resource;
|
||||||
|
/* FIXME:
|
||||||
|
We're replaying ti->history which contains the TouchBegin +
|
||||||
|
all TouchUpdates for ti. This needs to be passed on to the next
|
||||||
|
listener. If that is a touch listener, everything is dandy.
|
||||||
|
If the TouchBegin however triggers a sync passive grab, the
|
||||||
|
TouchUpdate events must be sent to EnqueueEvent so the events end
|
||||||
|
up in syncEvents.pending to be forwarded correctly in a
|
||||||
|
subsequent ComputeFreeze().
|
||||||
|
|
||||||
|
However, if we just send them to EnqueueEvent the sync'ing device
|
||||||
|
prevents handling of touch events for ownership listeners who
|
||||||
|
want the events right here, right now.
|
||||||
|
*/
|
||||||
|
dev->public.processInputProc((InternalEvent*)ev, dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -678,15 +701,23 @@ void
|
||||||
TouchAddListener(TouchPointInfoPtr ti, XID resource, int resource_type,
|
TouchAddListener(TouchPointInfoPtr ti, XID resource, int resource_type,
|
||||||
enum InputLevel level, enum TouchListenerType type,
|
enum InputLevel level, enum TouchListenerType type,
|
||||||
enum TouchListenerState state, WindowPtr window,
|
enum TouchListenerState state, WindowPtr window,
|
||||||
GrabPtr grab)
|
const GrabPtr grab)
|
||||||
{
|
{
|
||||||
|
GrabPtr g = NULL;
|
||||||
|
|
||||||
|
/* We need a copy of the grab, not the grab itself since that may be
|
||||||
|
* deleted by a UngrabButton request and leaves us with a dangling
|
||||||
|
* pointer */
|
||||||
|
if (grab)
|
||||||
|
g = AllocGrab(grab);
|
||||||
|
|
||||||
ti->listeners[ti->num_listeners].listener = resource;
|
ti->listeners[ti->num_listeners].listener = resource;
|
||||||
ti->listeners[ti->num_listeners].resource_type = resource_type;
|
ti->listeners[ti->num_listeners].resource_type = resource_type;
|
||||||
ti->listeners[ti->num_listeners].level = level;
|
ti->listeners[ti->num_listeners].level = level;
|
||||||
ti->listeners[ti->num_listeners].state = state;
|
ti->listeners[ti->num_listeners].state = state;
|
||||||
ti->listeners[ti->num_listeners].type = type;
|
ti->listeners[ti->num_listeners].type = type;
|
||||||
ti->listeners[ti->num_listeners].window = window;
|
ti->listeners[ti->num_listeners].window = window;
|
||||||
ti->listeners[ti->num_listeners].grab = grab;
|
ti->listeners[ti->num_listeners].grab = g;
|
||||||
if (grab)
|
if (grab)
|
||||||
ti->num_grabs++;
|
ti->num_grabs++;
|
||||||
ti->num_listeners++;
|
ti->num_listeners++;
|
||||||
|
@ -704,11 +735,15 @@ TouchRemoveListener(TouchPointInfoPtr ti, XID resource)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ti->num_listeners; i++) {
|
for (i = 0; i < ti->num_listeners; i++) {
|
||||||
if (ti->listeners[i].listener == resource) {
|
|
||||||
int j;
|
int j;
|
||||||
|
TouchListener *listener = &ti->listeners[i];
|
||||||
|
|
||||||
if (ti->listeners[i].grab) {
|
if (listener->listener != resource)
|
||||||
ti->listeners[i].grab = NULL;
|
continue;
|
||||||
|
|
||||||
|
if (listener->grab) {
|
||||||
|
FreeGrab(listener->grab);
|
||||||
|
listener->grab = NULL;
|
||||||
ti->num_grabs--;
|
ti->num_grabs--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -717,9 +752,9 @@ TouchRemoveListener(TouchPointInfoPtr ti, XID resource)
|
||||||
ti->num_listeners--;
|
ti->num_listeners--;
|
||||||
ti->listeners[ti->num_listeners].listener = 0;
|
ti->listeners[ti->num_listeners].listener = 0;
|
||||||
ti->listeners[ti->num_listeners].state = LISTENER_AWAITING_BEGIN;
|
ti->listeners[ti->num_listeners].state = LISTENER_AWAITING_BEGIN;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -874,7 +909,7 @@ TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev)
|
||||||
SpritePtr sprite = &ti->sprite;
|
SpritePtr sprite = &ti->sprite;
|
||||||
WindowPtr win;
|
WindowPtr win;
|
||||||
|
|
||||||
if (dev->deviceGrab.grab)
|
if (dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab)
|
||||||
TouchAddActiveGrabListener(dev, ti, ev, dev->deviceGrab.grab);
|
TouchAddActiveGrabListener(dev, ti, ev, dev->deviceGrab.grab);
|
||||||
|
|
||||||
/* We set up an active touch listener for existing touches, but not any
|
/* We set up an active touch listener for existing touches, but not any
|
||||||
|
@ -954,11 +989,11 @@ TouchListenerGone(XID resource)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (j = 0; j < ti->num_listeners; j++) {
|
for (j = 0; j < ti->num_listeners; j++) {
|
||||||
if (ti->listeners[j].listener != resource)
|
if (CLIENT_BITS(ti->listeners[j].listener) != resource)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
nev = GetTouchOwnershipEvents(events, dev, ti, XIRejectTouch,
|
nev = GetTouchOwnershipEvents(events, dev, ti, XIRejectTouch,
|
||||||
resource, 0);
|
ti->listeners[j].listener, 0);
|
||||||
for (k = 0; k < nev; k++)
|
for (k = 0; k < nev; k++)
|
||||||
mieqProcessDeviceEvent(dev, events + k, NULL);
|
mieqProcessDeviceEvent(dev, events + k, NULL);
|
||||||
|
|
||||||
|
@ -1061,3 +1096,46 @@ TouchEndPhysicallyActiveTouches(DeviceIntPtr dev)
|
||||||
|
|
||||||
FreeEventList(eventlist, GetMaximumEventsNum());
|
FreeEventList(eventlist, GetMaximumEventsNum());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TouchEmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resource)
|
||||||
|
{
|
||||||
|
InternalEvent event;
|
||||||
|
|
||||||
|
/* We're not processing a touch end for a frozen device */
|
||||||
|
if (dev->deviceGrab.sync.frozen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (ti->num_grabs == 0)
|
||||||
|
UpdateDeviceState(dev, &event.device_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TouchAcceptAndEnd(DeviceIntPtr dev, int touchid)
|
||||||
|
{
|
||||||
|
TouchPointInfoPtr ti = TouchFindByClientID(dev, touchid);
|
||||||
|
if (!ti)
|
||||||
|
return;
|
||||||
|
|
||||||
|
TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch);
|
||||||
|
if (ti->pending_finish)
|
||||||
|
TouchEmitTouchEnd(dev, ti, 0, 0);
|
||||||
|
if (ti->num_listeners <= 1)
|
||||||
|
TouchEndTouch(dev, ti);
|
||||||
|
}
|
||||||
|
|
15
dix/window.c
15
dix/window.c
|
@ -547,8 +547,7 @@ InitRootWindow(WindowPtr pWin)
|
||||||
(*pScreen->PositionWindow) (pWin, 0, 0);
|
(*pScreen->PositionWindow) (pWin, 0, 0);
|
||||||
|
|
||||||
pWin->cursorIsNone = FALSE;
|
pWin->cursorIsNone = FALSE;
|
||||||
pWin->optional->cursor = rootCursor;
|
pWin->optional->cursor = RefCursor(rootCursor);
|
||||||
rootCursor->refcnt++;
|
|
||||||
|
|
||||||
if (party_like_its_1989) {
|
if (party_like_its_1989) {
|
||||||
MakeRootTile(pWin);
|
MakeRootTile(pWin);
|
||||||
|
@ -1416,8 +1415,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
|
||||||
else if (pWin->parent && pCursor == wCursor(pWin->parent))
|
else if (pWin->parent && pCursor == wCursor(pWin->parent))
|
||||||
checkOptional = TRUE;
|
checkOptional = TRUE;
|
||||||
pOldCursor = pWin->optional->cursor;
|
pOldCursor = pWin->optional->cursor;
|
||||||
pWin->optional->cursor = pCursor;
|
pWin->optional->cursor = RefCursor(pCursor);
|
||||||
pCursor->refcnt++;
|
|
||||||
pWin->cursorIsNone = FALSE;
|
pWin->cursorIsNone = FALSE;
|
||||||
/*
|
/*
|
||||||
* check on any children now matching the new cursor
|
* check on any children now matching the new cursor
|
||||||
|
@ -3323,8 +3321,7 @@ MakeWindowOptional(WindowPtr pWin)
|
||||||
parentOptional = FindWindowWithOptional(pWin)->optional;
|
parentOptional = FindWindowWithOptional(pWin)->optional;
|
||||||
optional->visual = parentOptional->visual;
|
optional->visual = parentOptional->visual;
|
||||||
if (!pWin->cursorIsNone) {
|
if (!pWin->cursorIsNone) {
|
||||||
optional->cursor = parentOptional->cursor;
|
optional->cursor = RefCursor(parentOptional->cursor);
|
||||||
optional->cursor->refcnt++;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
optional->cursor = None;
|
optional->cursor = None;
|
||||||
|
@ -3412,8 +3409,7 @@ ChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor)
|
||||||
if (pCursor && WindowParentHasDeviceCursor(pWin, pDev, pCursor))
|
if (pCursor && WindowParentHasDeviceCursor(pWin, pDev, pCursor))
|
||||||
pNode->cursor = None;
|
pNode->cursor = None;
|
||||||
else {
|
else {
|
||||||
pNode->cursor = pCursor;
|
pNode->cursor = RefCursor(pCursor);
|
||||||
pCursor->refcnt++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pNode = pPrev = NULL;
|
pNode = pPrev = NULL;
|
||||||
|
@ -3421,8 +3417,7 @@ ChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor)
|
||||||
for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
|
for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
|
||||||
if (WindowSeekDeviceCursor(pChild, pDev, &pNode, &pPrev)) {
|
if (WindowSeekDeviceCursor(pChild, pDev, &pNode, &pPrev)) {
|
||||||
if (pNode->cursor == None) { /* inherited from parent */
|
if (pNode->cursor == None) { /* inherited from parent */
|
||||||
pNode->cursor = pOldCursor;
|
pNode->cursor = RefCursor(pOldCursor);
|
||||||
pOldCursor->refcnt++;
|
|
||||||
}
|
}
|
||||||
else if (pNode->cursor == pCursor) {
|
else if (pNode->cursor == pCursor) {
|
||||||
pNode->cursor = None;
|
pNode->cursor = None;
|
||||||
|
|
|
@ -481,7 +481,7 @@ xf86_use_hw_cursor(ScreenPtr screen, CursorPtr cursor)
|
||||||
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
|
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
|
||||||
xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
|
xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
|
||||||
|
|
||||||
++cursor->refcnt;
|
cursor = RefCursor(cursor);
|
||||||
if (xf86_config->cursor)
|
if (xf86_config->cursor)
|
||||||
FreeCursor(xf86_config->cursor, None);
|
FreeCursor(xf86_config->cursor, None);
|
||||||
xf86_config->cursor = cursor;
|
xf86_config->cursor = cursor;
|
||||||
|
@ -500,7 +500,7 @@ xf86_use_hw_cursor_argb(ScreenPtr screen, CursorPtr cursor)
|
||||||
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
|
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
|
||||||
xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
|
xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
|
||||||
|
|
||||||
++cursor->refcnt;
|
cursor = RefCursor(cursor);
|
||||||
if (xf86_config->cursor)
|
if (xf86_config->cursor)
|
||||||
FreeCursor(xf86_config->cursor, None);
|
FreeCursor(xf86_config->cursor, None);
|
||||||
xf86_config->cursor = cursor;
|
xf86_config->cursor = cursor;
|
||||||
|
|
|
@ -271,7 +271,7 @@ xf86CursorRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs)
|
||||||
(xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
|
(xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
|
||||||
xf86CursorScreenKey);
|
xf86CursorScreenKey);
|
||||||
|
|
||||||
if (pCurs->refcnt <= 1)
|
if (CursorRefCount(pCurs) <= 1)
|
||||||
dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
|
dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
@ -285,7 +285,7 @@ xf86CursorUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs)
|
||||||
(xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
|
(xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
|
||||||
xf86CursorScreenKey);
|
xf86CursorScreenKey);
|
||||||
|
|
||||||
if (pCurs->refcnt <= 1) {
|
if (CursorRefCount(pCurs) <= 1) {
|
||||||
free(dixLookupScreenPrivate
|
free(dixLookupScreenPrivate
|
||||||
(&pCurs->devPrivates, CursorScreenKey, pScreen));
|
(&pCurs->devPrivates, CursorScreenKey, pScreen));
|
||||||
dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
|
dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
|
||||||
|
@ -322,37 +322,37 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
|
||||||
/* only update for VCP, otherwise we get cursor jumps when removing a
|
/* only update for VCP, otherwise we get cursor jumps when removing a
|
||||||
sprite. The second cursor is never HW rendered anyway. */
|
sprite. The second cursor is never HW rendered anyway. */
|
||||||
if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer) {
|
if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer) {
|
||||||
pCurs->refcnt++;
|
CursorPtr cursor = RefCursor(pCurs);
|
||||||
if (ScreenPriv->CurrentCursor)
|
if (ScreenPriv->CurrentCursor)
|
||||||
FreeCursor(ScreenPriv->CurrentCursor, None);
|
FreeCursor(ScreenPriv->CurrentCursor, None);
|
||||||
ScreenPriv->CurrentCursor = pCurs;
|
ScreenPriv->CurrentCursor = cursor;
|
||||||
ScreenPriv->x = x;
|
ScreenPriv->x = x;
|
||||||
ScreenPriv->y = y;
|
ScreenPriv->y = y;
|
||||||
ScreenPriv->CursorToRestore = NULL;
|
ScreenPriv->CursorToRestore = NULL;
|
||||||
ScreenPriv->HotX = pCurs->bits->xhot;
|
ScreenPriv->HotX = cursor->bits->xhot;
|
||||||
ScreenPriv->HotY = pCurs->bits->yhot;
|
ScreenPriv->HotY = cursor->bits->yhot;
|
||||||
|
|
||||||
if (!infoPtr->pScrn->vtSema)
|
if (!infoPtr->pScrn->vtSema)
|
||||||
ScreenPriv->SavedCursor = pCurs;
|
ScreenPriv->SavedCursor = cursor;
|
||||||
|
|
||||||
if (infoPtr->pScrn->vtSema && xorg_list_is_empty(&pScreen->pixmap_dirty_list) &&
|
if (infoPtr->pScrn->vtSema && xorg_list_is_empty(&pScreen->pixmap_dirty_list) &&
|
||||||
(ScreenPriv->ForceHWCursorCount ||
|
(ScreenPriv->ForceHWCursorCount ||
|
||||||
((
|
((
|
||||||
#ifdef ARGB_CURSOR
|
#ifdef ARGB_CURSOR
|
||||||
pCurs->bits->argb &&
|
cursor->bits->argb &&
|
||||||
infoPtr->UseHWCursorARGB &&
|
infoPtr->UseHWCursorARGB &&
|
||||||
(*infoPtr->UseHWCursorARGB)(pScreen, pCurs)) ||
|
(*infoPtr->UseHWCursorARGB)(pScreen, cursor)) ||
|
||||||
(pCurs->bits->argb == 0 &&
|
(cursor->bits->argb == 0 &&
|
||||||
#endif
|
#endif
|
||||||
(pCurs->bits->height <= infoPtr->MaxHeight) &&
|
(cursor->bits->height <= infoPtr->MaxHeight) &&
|
||||||
(pCurs->bits->width <= infoPtr->MaxWidth) &&
|
(cursor->bits->width <= infoPtr->MaxWidth) &&
|
||||||
(!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor) (pScreen, pCurs)))))) {
|
(!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor) (pScreen, cursor)))))) {
|
||||||
|
|
||||||
if (ScreenPriv->SWCursor) /* remove the SW cursor */
|
if (ScreenPriv->SWCursor) /* remove the SW cursor */
|
||||||
(*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen,
|
(*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen,
|
||||||
NullCursor, x, y);
|
NullCursor, x, y);
|
||||||
|
|
||||||
xf86SetCursor(pScreen, pCurs, x, y);
|
xf86SetCursor(pScreen, cursor, x, y);
|
||||||
ScreenPriv->SWCursor = FALSE;
|
ScreenPriv->SWCursor = FALSE;
|
||||||
ScreenPriv->isUp = TRUE;
|
ScreenPriv->isUp = TRUE;
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,10 @@ extern _X_EXPORT CursorPtr rootCursor;
|
||||||
extern _X_EXPORT int FreeCursor(pointer /*pCurs */ ,
|
extern _X_EXPORT int FreeCursor(pointer /*pCurs */ ,
|
||||||
XID /*cid */ );
|
XID /*cid */ );
|
||||||
|
|
||||||
|
extern _X_EXPORT CursorPtr RefCursor(CursorPtr /* cursor */);
|
||||||
|
extern _X_EXPORT CursorPtr UnrefCursor(CursorPtr /* cursor */);
|
||||||
|
extern _X_EXPORT int CursorRefCount(const CursorPtr /* cursor */);
|
||||||
|
|
||||||
extern _X_EXPORT int AllocARGBCursor(unsigned char * /*psrcbits */ ,
|
extern _X_EXPORT int AllocARGBCursor(unsigned char * /*psrcbits */ ,
|
||||||
unsigned char * /*pmaskbits */ ,
|
unsigned char * /*pmaskbits */ ,
|
||||||
CARD32 * /*argb */ ,
|
CARD32 * /*argb */ ,
|
||||||
|
|
|
@ -31,7 +31,7 @@ struct _GrabParameters;
|
||||||
extern void PrintDeviceGrabInfo(DeviceIntPtr dev);
|
extern void PrintDeviceGrabInfo(DeviceIntPtr dev);
|
||||||
extern void UngrabAllDevices(Bool kill_client);
|
extern void UngrabAllDevices(Bool kill_client);
|
||||||
|
|
||||||
extern GrabPtr AllocGrab(void);
|
extern GrabPtr AllocGrab(const GrabPtr src);
|
||||||
extern void FreeGrab(GrabPtr grab);
|
extern void FreeGrab(GrabPtr grab);
|
||||||
extern Bool CopyGrab(GrabPtr dst, const GrabPtr src);
|
extern Bool CopyGrab(GrabPtr dst, const GrabPtr src);
|
||||||
|
|
||||||
|
|
|
@ -123,6 +123,7 @@ struct _DeviceEvent {
|
||||||
int corestate; /**< Core key/button state BEFORE the event */
|
int corestate; /**< Core key/button state BEFORE the event */
|
||||||
int key_repeat; /**< Internally-generated key repeat event */
|
int key_repeat; /**< Internally-generated key repeat event */
|
||||||
uint32_t flags; /**< Flags to be copied into the generated event */
|
uint32_t flags; /**< Flags to be copied into the generated event */
|
||||||
|
uint32_t resource; /**< Touch event resource, only for TOUCH_REPLAYING */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -590,6 +590,8 @@ extern int TouchAcceptReject(ClientPtr client, DeviceIntPtr dev, int mode,
|
||||||
extern void TouchEndPhysicallyActiveTouches(DeviceIntPtr dev);
|
extern void TouchEndPhysicallyActiveTouches(DeviceIntPtr dev);
|
||||||
extern void TouchDeliverDeviceClassesChangedEvent(TouchPointInfoPtr ti,
|
extern void TouchDeliverDeviceClassesChangedEvent(TouchPointInfoPtr ti,
|
||||||
Time time, XID resource);
|
Time time, XID resource);
|
||||||
|
extern void TouchEmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resource);
|
||||||
|
extern void TouchAcceptAndEnd(DeviceIntPtr dev, int touchid);
|
||||||
|
|
||||||
/* misc event helpers */
|
/* misc event helpers */
|
||||||
extern Mask GetEventMask(DeviceIntPtr dev, xEvent *ev, InputClientsPtr clients);
|
extern Mask GetEventMask(DeviceIntPtr dev, xEvent *ev, InputClientsPtr clients);
|
||||||
|
|
|
@ -485,7 +485,7 @@ typedef struct _GrabInfoRec {
|
||||||
TimeStamp grabTime;
|
TimeStamp grabTime;
|
||||||
Bool fromPassiveGrab; /* true if from passive grab */
|
Bool fromPassiveGrab; /* true if from passive grab */
|
||||||
Bool implicitGrab; /* implicit from ButtonPress */
|
Bool implicitGrab; /* implicit from ButtonPress */
|
||||||
GrabPtr activeGrab;
|
GrabPtr unused; /* Kept for ABI stability, remove soon */
|
||||||
GrabPtr grab;
|
GrabPtr grab;
|
||||||
CARD8 activatingKey;
|
CARD8 activatingKey;
|
||||||
void (*ActivateGrab) (DeviceIntPtr /*device */ ,
|
void (*ActivateGrab) (DeviceIntPtr /*device */ ,
|
||||||
|
|
|
@ -383,8 +383,7 @@ AnimCursorCreate(CursorPtr *cursors, CARD32 *deltas, int ncursor,
|
||||||
ac->elts = (AnimCurElt *) (ac + 1);
|
ac->elts = (AnimCurElt *) (ac + 1);
|
||||||
|
|
||||||
for (i = 0; i < ncursor; i++) {
|
for (i = 0; i < ncursor; i++) {
|
||||||
cursors[i]->refcnt++;
|
ac->elts[i].pCursor = RefCursor(cursors[i]);
|
||||||
ac->elts[i].pCursor = cursors[i];
|
|
||||||
ac->elts[i].delay = deltas[i];
|
ac->elts[i].delay = deltas[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -613,12 +613,12 @@ ReplaceCursorLookup(pointer value, XID id, pointer closure)
|
||||||
}
|
}
|
||||||
if (pCursor && pCursor != rcl->pNew) {
|
if (pCursor && pCursor != rcl->pNew) {
|
||||||
if ((*rcl->testCursor) (pCursor, rcl->closure)) {
|
if ((*rcl->testCursor) (pCursor, rcl->closure)) {
|
||||||
rcl->pNew->refcnt++;
|
CursorPtr curs = RefCursor(rcl->pNew);
|
||||||
/* either redirect reference or update resource database */
|
/* either redirect reference or update resource database */
|
||||||
if (pCursorRef)
|
if (pCursorRef)
|
||||||
*pCursorRef = rcl->pNew;
|
*pCursorRef = curs;
|
||||||
else
|
else
|
||||||
ChangeResourceValue(id, RT_CURSOR, rcl->pNew);
|
ChangeResourceValue(id, RT_CURSOR, curs);
|
||||||
FreeCursor(pCursor, cursor);
|
FreeCursor(pCursor, cursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user