diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2013-02-22 17:31:34 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2013-02-22 17:31:34 +1000 |
commit | 51cd9dd2f55f24cbff6b270fcc479a6542bd9ea5 (patch) | |
tree | 49fd1e0484903f9a4a3fef039e5760ae42c70be1 | |
parent | 14dbc8cb7eb672ebe7cfb34c63859edadc43164a (diff) |
server/grab: add test case for the touch grab race condition in #56578touch-grab-race-condition-56578
https://bugs.freedesktop.org/show_bug.cgi?id=56578
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r-- | tests/server/grab.cpp | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/tests/server/grab.cpp b/tests/server/grab.cpp index 6c2d23a..605305d 100644 --- a/tests/server/grab.cpp +++ b/tests/server/grab.cpp @@ -536,6 +536,83 @@ TEST_F(TouchGrabTest, TouchGrabPassedToCoreGrab) } } +TEST_F(TouchGrabTest, TouchGrabPassedToPassivePassedToRegular) +{ + XORG_TESTCASE("Client 1: register for touch grabs with ownership on root window.\n" + "Client 2: register for sync passive core pointer grab on root window.\n" + "Client 3: register for core pointer events on root window.\n" + "Touch begin/end, repeat\n" + "Client 1: reject touch\n" + "Client 2: ReplayPointer\n" + "Client 3: consume events.\n" + "Repeat\n" + "https://bugs.freedesktop.org/show_bug.cgi?id=56578"); + + ::Display *dpy1 = Display(); + ::Display *dpy2 = XOpenDisplay(server.GetDisplayString().c_str()); + ::Display *dpy3 = XOpenDisplay(server.GetDisplayString().c_str()); + + XSynchronize(dpy1, True); + XSynchronize(dpy2, True); + XSynchronize(dpy3, True); + + Window root = DefaultRootWindow(dpy1); + Window win = CreateWindow(dpy2, None); + + XIEventMask mask; + mask.deviceid = VIRTUAL_CORE_POINTER_ID; + mask.mask_len = XIMaskLen(XI_TouchOwnership); + mask.mask = new unsigned char[mask.mask_len](); + XISetMask(mask.mask, XI_TouchBegin); + XISetMask(mask.mask, XI_TouchUpdate); + XISetMask(mask.mask, XI_TouchOwnership); + XISetMask(mask.mask, XI_TouchEnd); + + XIGrabModifiers mods = {}; + mods.modifiers = XIAnyModifier; + ASSERT_EQ(Success, XIGrabTouchBegin(dpy1, VIRTUAL_CORE_POINTER_ID, + root, False, &mask, 1, &mods)); + delete[] mask.mask; + + XGrabButton(dpy2, AnyButton, XIAnyModifier, win, False, + ButtonPressMask|ButtonReleaseMask, + GrabModeSync, GrabModeAsync, None, None); + + XSelectInput(dpy3, win, ButtonPressMask|ButtonReleaseMask); + + for (int i = 0; i < 2; i++) { + dev->Play(RECORDINGS_DIR "tablets/N-Trig-MultiTouch.touch_1_begin.events"); + dev->Play(RECORDINGS_DIR "tablets/N-Trig-MultiTouch.touch_1_update.events"); + dev->Play(RECORDINGS_DIR "tablets/N-Trig-MultiTouch.touch_1_end.events"); + } + + for (int i = 0; i < 2; i++) { + ASSERT_EVENT(XIDeviceEvent, tbegin, dpy1, GenericEvent, xi2_opcode, XI_TouchBegin); + ASSERT_EVENT(XIDeviceEvent, towner, dpy1, GenericEvent, xi2_opcode, XI_TouchOwnership); + ASSERT_EVENT(XIDeviceEvent, tupdate, dpy1, GenericEvent, xi2_opcode, XI_TouchUpdate); + ASSERT_EVENT(XIDeviceEvent, tend, dpy1, GenericEvent, xi2_opcode, XI_TouchEnd); + XIAllowTouchEvents(dpy1, tbegin->deviceid, tbegin->detail, root, XIRejectTouch); + + /* FIXME: this is the stuck bit here. on the second loop, we don't + get this event because dev->touch->touches[1] is stuck in + active|pending_finish with a POINTER_GRAB and a POINTER_REGULAR + listener, both AWAITING_BEGIN. + */ + ASSERT_EVENT(XEvent, grab_press, dpy2, ButtonPress); + XAllowEvents(dpy2, ReplayPointer, CurrentTime); + + ASSERT_EVENT(XEvent, press, dpy3, ButtonPress); + ASSERT_EVENT(XEvent, release, dpy3, ButtonRelease); + + Window r, c; + int rx, ry, wx, wy; + unsigned int state; + + XQueryPointer(dpy2, root, &r, &c, &rx, &ry, &wx, &wy, &state); + ASSERT_FALSE(state & Button1Mask); + } +} + class TouchGrabTestMultipleModes : public TouchGrabTest, public ::testing::WithParamInterface<int> { |