diff options
author | Jasper St. Pierre <jstpierre@mecheye.net> | 2012-12-09 19:45:48 -0500 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2012-12-17 15:02:57 +1000 |
commit | 6401317bdcf58b2717214ac65c8f47b0c384a7db (patch) | |
tree | b88cbb14c077b020f4694e754733c1959ec66c6f /Xi | |
parent | 207e8dee00dd26ff4363edb72058b48b8a76b824 (diff) |
barriers: Send an XI_BarrierLeave event when a barrier is destroyed
This ensures that we always complete an event sequence.
Signed-off-by: Jasper St. Pierre <jstpierre@mecheye.net>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'Xi')
-rw-r--r-- | Xi/xibarriers.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c index b62a18ee5..2e7f2cc9d 100644 --- a/Xi/xibarriers.c +++ b/Xi/xibarriers.c @@ -539,8 +539,52 @@ static int BarrierFreeBarrier(void *data, XID id) { struct PointerBarrierClient *c; + Time ms = GetTimeInMillis(); c = container_of(data, struct PointerBarrierClient, barrier); + + /* FIXME: this is really broken for multidevice */ + if (c->hit) { + DeviceIntPtr dev = NULL; + ScreenPtr screen = c->screen; + BarrierEvent ev = { + .header = ET_Internal, + .type = ET_BarrierLeave, + .length = sizeof (BarrierEvent), + .time = ms, + /* .deviceid */ + .sourceid = 0, + .barrierid = c->id, + .window = c->window->drawable.id, + .root = screen->root->drawable.id, + .dx = 0, + .dy = 0, + /* .root_x */ + /* .root_y */ + .dt = ms - c->last_timestamp, + .event_id = c->barrier_event_id, + .flags = XIBarrierPointerReleased, + }; + + for (dev = inputInfo.devices; dev; dev = dev->next) { + int root_x, root_y; + + if (dev->type != MASTER_POINTER) + continue; + + if (!barrier_blocks_device(c, dev)) + continue; + + ev.deviceid = dev->id; + + GetSpritePosition(dev, &root_x, &root_y); + ev.root_x = root_x; + ev.root_y = root_y; + + mieqEnqueue(dev, (InternalEvent *) &ev); + } + } + xorg_list_del(&c->entry); free(c); |