summaryrefslogtreecommitdiff
path: root/Xi
diff options
context:
space:
mode:
authorJasper St. Pierre <jstpierre@mecheye.net>2012-12-09 19:45:48 -0500
committerPeter Hutterer <peter.hutterer@who-t.net>2012-12-17 15:02:57 +1000
commit6401317bdcf58b2717214ac65c8f47b0c384a7db (patch)
treeb88cbb14c077b020f4694e754733c1959ec66c6f /Xi
parent207e8dee00dd26ff4363edb72058b48b8a76b824 (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.c44
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);