aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/Xi/exevents.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/Xi/exevents.c')
-rw-r--r--xorg-server/Xi/exevents.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c
index 4c1aeb4da..58fe49363 100644
--- a/xorg-server/Xi/exevents.c
+++ b/xorg-server/Xi/exevents.c
@@ -1648,6 +1648,49 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev)
UpdateDeviceState(dev, &ev->device_event);
}
+static void
+ProcessBarrierEvent(InternalEvent *e, DeviceIntPtr dev)
+{
+ Mask filter;
+ WindowPtr pWin;
+ BarrierEvent *be = &e->barrier_event;
+ xEvent *ev;
+ int rc;
+ GrabPtr grab = dev->deviceGrab.grab;
+
+ if (!IsMaster(dev))
+ return;
+
+ if (dixLookupWindow(&pWin, be->window, serverClient, DixReadAccess) != Success)
+ return;
+
+ if (grab)
+ be->flags |= XIBarrierDeviceIsGrabbed;
+
+ rc = EventToXI2(e, &ev);
+ if (rc != Success) {
+ ErrorF("[Xi] event conversion from %s failed with code %d\n", __func__, rc);
+ return;
+ }
+
+ /* A client has a grab, deliver to this client if the grab_window is the
+ barrier window.
+
+ Otherwise, deliver normally to the client.
+ */
+ if (grab &&
+ CLIENT_ID(be->barrierid) == CLIENT_ID(grab->resource) &&
+ grab->window->drawable.id == be->window) {
+ DeliverGrabbedEvent(e, dev, FALSE);
+ } else {
+ filter = GetEventFilter(dev, ev);
+
+ DeliverEventsToWindow(dev, pWin, ev, 1,
+ filter, NullGrab);
+ }
+ free(ev);
+}
+
/**
* Process DeviceEvents and DeviceChangedEvents.
*/
@@ -1797,6 +1840,10 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
case ET_TouchEnd:
ProcessTouchEvent(ev, device);
break;
+ case ET_BarrierHit:
+ case ET_BarrierLeave:
+ ProcessBarrierEvent(ev, device);
+ break;
default:
ProcessDeviceEvent(ev, device);
break;