1037
1037
ActivateEarlyAccept(DeviceIntPtr dev, TouchPointInfoPtr ti)
1040
1039
ClientPtr client;
1043
rc = dixLookupClient(&client, ti->listeners[0].listener, serverClient,
1045
if (rc != Success) {
1046
ErrorF("[Xi] Failed to lookup early accepting client.\n");
1041
GrabPtr grab = ti->listeners[0].grab;
1043
BUG_RETURN(ti->listeners[0].type != LISTENER_GRAB &&
1044
ti->listeners[0].type != LISTENER_POINTER_GRAB);
1047
client = rClient(grab);
1050
1049
if (TouchAcceptReject(client, dev, XIAcceptTouch, ti->client_id,
1051
ti->listeners[0].window->drawable.id, &error) !=
1050
ti->listeners[0].window->drawable.id, &error) != Success)
1053
1051
ErrorF("[Xi] Failed to accept touch grab after early acceptance.\n");
1057
* Generate and deliver a TouchEnd event.
1059
* @param dev The device to deliver the event for.
1060
* @param ti The touch point record to deliver the event for.
1061
* @param flags Internal event flags. The called does not need to provide
1062
* TOUCH_CLIENT_ID and TOUCH_POINTER_EMULATED, this function will ensure
1063
* they are set appropriately.
1064
* @param resource The client resource to deliver to, or 0 for all clients.
1067
EmitTouchEnd(DeviceIntPtr dev, TouchPointInfoPtr ti, int flags, XID resource)
1069
InternalEvent event;
1071
flags |= TOUCH_CLIENT_ID;
1072
if (ti->emulate_pointer)
1073
flags |= TOUCH_POINTER_EMULATED;
1074
TouchDeliverDeviceClassesChangedEvent(ti, GetTimeInMillis(), resource);
1075
GetDixTouchEnd(&event, dev, ti, flags);
1076
DeliverTouchEvents(dev, ti, &event, resource);
1080
1055
* Find the oldest touch that still has a pointer emulation client.
1082
1057
* Pointer emulation can only be performed for the oldest touch. Otherwise, the
1126
1101
TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
1127
1102
TouchOwnershipEvent *ev)
1104
TouchListener *listener = &ti->listeners[0]; /* new owner */
1105
int accepted_early = listener->state == LISTENER_EARLY_ACCEPT;
1129
1107
/* Deliver the ownership */
1130
if (ti->listeners[0].state == LISTENER_AWAITING_OWNER ||
1131
ti->listeners[0].state == LISTENER_EARLY_ACCEPT)
1108
if (listener->state == LISTENER_AWAITING_OWNER || accepted_early)
1132
1109
DeliverTouchEvents(dev, ti, (InternalEvent *) ev,
1133
ti->listeners[0].listener);
1134
else if (ti->listeners[0].state == LISTENER_AWAITING_BEGIN) {
1110
listener->listener);
1111
else if (listener->state == LISTENER_AWAITING_BEGIN) {
1135
1112
/* We can't punt to a pointer listener unless all older pointer
1136
1113
* emulated touches have been seen already. */
1137
if ((ti->listeners[0].type == LISTENER_POINTER_GRAB ||
1138
ti->listeners[0].type == LISTENER_POINTER_REGULAR) &&
1114
if ((listener->type == LISTENER_POINTER_GRAB ||
1115
listener->type == LISTENER_POINTER_REGULAR) &&
1139
1116
ti != FindOldestPointerEmulatedTouch(dev))
1142
TouchEventHistoryReplay(ti, dev, ti->listeners[0].listener);
1145
/* If we've just removed the last grab and the touch has physically
1146
* ended, send a TouchEnd event too and finalise the touch. */
1147
if (ti->num_listeners == 1 && ti->num_grabs == 0 && ti->pending_finish) {
1148
EmitTouchEnd(dev, ti, 0, 0);
1149
TouchEndTouch(dev, ti);
1153
if (ti->listeners[0].state == LISTENER_EARLY_ACCEPT)
1119
TouchEventHistoryReplay(ti, dev, listener->listener);
1122
/* New owner has Begin/Update but not end. If touch is pending_finish,
1123
* emulate the TouchEnd now */
1124
if (ti->pending_finish) {
1125
TouchEmitTouchEnd(dev, ti, 0, 0);
1127
/* If the last owner is not a touch grab, finalise the touch, we
1128
won't get more correspondence on this.
1130
if (ti->num_listeners == 1 &&
1131
(ti->num_grabs == 0 ||
1132
listener->grab->grabtype != XI2 ||
1133
!xi2mask_isset(listener->grab->xi2mask, dev, XI_TouchBegin))) {
1134
TouchEndTouch(dev, ti);
1154
1140
ActivateEarlyAccept(dev, ti);
1194
1180
for (i = 0; i < ti->num_listeners; i++) {
1195
1181
if (ti->listeners[i].listener == resource) {
1196
1182
if (ti->listeners[i].state != LISTENER_HAS_END)
1197
EmitTouchEnd(sourcedev, ti, TOUCH_REJECT, resource);
1183
TouchEmitTouchEnd(sourcedev, ti, TOUCH_REJECT, resource);
1237
1223
else if (ev->reason == XIAcceptTouch) {
1240
/* Go through the motions of ending the touch if the listener has
1227
/* For pointer-emulated listeners that ungrabbed the active grab,
1228
* the state was forced to LISTENER_HAS_END. Still go
1229
* through the motions of ending the touch if the listener has
1241
1230
* already seen the end. This ensures that the touch record is ended in
1243
1233
if (ti->listeners[0].state == LISTENER_HAS_END)
1244
EmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[0].listener);
1234
TouchEmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[0].listener);
1246
1236
/* The touch owner has accepted the touch. Send TouchEnd events to
1247
1237
* everyone else, and truncate the list of listeners. */
1248
1238
for (i = 1; i < ti->num_listeners; i++)
1249
EmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[i].listener);
1239
TouchEmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[i].listener);
1251
1241
while (ti->num_listeners > 1)
1252
1242
TouchRemoveListener(ti, ti->listeners[1].listener);
1384
1374
/* We don't deliver pointer events to non-owners */
1385
1375
if (!TouchResourceIsOwner(ti, listener->listener))
1388
1378
nevents = TouchConvertToPointerEvent(ev, &motion, &button);
1389
1379
BUG_RETURN_VAL(nevents == 0, BadValue);
1417
1407
if (!deliveries)
1418
DeliverOneGrabbedEvent(ptrev, dev, grab->grabtype);
1408
deliveries = DeliverOneGrabbedEvent(ptrev, dev, grab->grabtype);
1420
1410
/* We must accept the touch sequence once a pointer listener has
1421
1411
* received one event past ButtonPress. */
1423
1413
!(ev->device_event.flags & TOUCH_CLIENT_ID))
1424
1414
TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch);
1426
if (ev->any.type == ET_TouchEnd &&
1427
!(ev->device_event.flags & TOUCH_CLIENT_ID) &&
1416
if (deliveries && ev->any.type == ET_TouchEnd &&
1428
1417
!dev->button->buttonsDown &&
1429
1418
dev->deviceGrab.fromPassiveGrab && GrabIsPointerGrab(grab)) {
1430
1419
(*dev->deviceGrab.DeactivateGrab) (dev);
1453
1445
* event selection. Thus, we update the last listener in the array.
1455
1447
l = &ti->listeners[ti->num_listeners - 1];
1456
l->listener = devgrab->resource;
1448
l->listener = g->resource;
1458
1450
//l->resource_type = RT_NONE;
1460
1452
if (devgrab->grabtype != XI2 || devgrab->type != XI_TouchBegin)
1612
1604
* called after event type mutation. Touch end events are always processed
1613
1605
* in order to end touch records. */
1614
1606
/* FIXME: check this */
1615
if ((type == ET_TouchBegin && !TouchBuildSprite(dev, ti, ev)) ||
1607
if ((type == ET_TouchBegin &&
1608
!(ev->device_event.flags & TOUCH_REPLAYING) &&
1609
!TouchBuildSprite(dev, ti, ev)) ||
1616
1610
(type != ET_TouchEnd && ti->sprite.spriteTraceGood == 0))
1620
1614
/* WARNING: the event type may change to TouchUpdate in
1621
1615
* DeliverTouchEvents if a TouchEnd was delivered to a grabbing
1623
DeliverTouchEvents(dev, ti, (InternalEvent *) ev, 0);
1617
DeliverTouchEvents(dev, ti, ev, ev->device_event.resource);
1624
1618
if (ev->any.type == ET_TouchEnd)
1625
1619
TouchEndTouch(dev, ti);
1848
1842
listener->type == LISTENER_POINTER_GRAB) {
1849
1843
rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
1850
1844
grab, xi2mask);
1845
if (rc == Success) {
1846
listener->state = LISTENER_IS_OWNER;
1847
/* async grabs cannot replay, so automatically accept this touch */
1848
if (dev->deviceGrab.grab &&
1849
dev->deviceGrab.fromPassiveGrab &&
1850
dev->deviceGrab.grab->pointerMode == GrabModeAsync)
1851
ActivateEarlyAccept(dev, ti);
1865
1867
if (has_ownershipmask)
1866
1868
TouchSendOwnershipEvent(dev, ti, 0, listener->listener);
1868
if (!has_ownershipmask || listener->type == LISTENER_REGULAR)
1870
if (listener->type == LISTENER_REGULAR)
1869
1871
state = LISTENER_HAS_ACCEPTED;
1871
1873
state = LISTENER_IS_OWNER;
1886
1888
if (listener->type == LISTENER_POINTER_REGULAR ||
1887
1889
listener->type == LISTENER_POINTER_GRAB) {
1888
rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
1890
/* Note: If the active grab was ungrabbed, we already changed the
1891
* state to LISTENER_HAS_END but still get here. So we mustn't
1892
* actually send the event.
1893
* This is part two of the hack in DeactivatePointerGrab
1895
if (listener->state != LISTENER_HAS_END) {
1896
rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
1891
if (ti->num_listeners > 1) {
1892
ev->any.type = ET_TouchUpdate;
1893
ev->device_event.flags |= TOUCH_PENDING_END;
1894
if (!(ev->device_event.flags & TOUCH_CLIENT_ID))
1895
ti->pending_finish = TRUE;
1899
/* Once we send a TouchEnd to a legacy listener, we're already well
1900
* past the accepting/rejecting stage (can only happen on
1901
* GrabModeSync + replay. This listener now gets the end event,
1902
* and we can continue.
1905
listener->state = LISTENER_HAS_END;
1918
1927
rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
1920
1929
if ((ti->num_listeners > 1 ||
1921
listener->state != LISTENER_HAS_ACCEPTED) &&
1930
(ti->num_grabs > 0 && listener->state != LISTENER_HAS_ACCEPTED)) &&
1922
1931
(ev->device_event.flags & (TOUCH_ACCEPT | TOUCH_REJECT)) == 0) {
1923
1932
ev->any.type = ET_TouchUpdate;
1924
1933
ev->device_event.flags |= TOUCH_PENDING_END;