diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2012-10-22 13:36:35 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2012-10-25 16:32:16 +1000 |
commit | 5032a54287d286bb4080bb9832c01cf3a6b7011c (patch) | |
tree | f7b4805188cbc4a298cfb2329382639e9f77f234 /tests/server/grab.cpp | |
parent | 1b811912990849c3933286609fa6c8c588893cdc (diff) |
server/grab: add tests for touch passive grab pointer emulation
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'tests/server/grab.cpp')
-rw-r--r-- | tests/server/grab.cpp | 151 |
1 files changed, 146 insertions, 5 deletions
diff --git a/tests/server/grab.cpp b/tests/server/grab.cpp index 48f9a75..514bf02 100644 --- a/tests/server/grab.cpp +++ b/tests/server/grab.cpp @@ -158,8 +158,7 @@ TEST_F(PointerGrabTest, GrabDisabledDevices) #if HAVE_XI22 class TouchGrabTest : public InputDriverTest, - public DeviceInterface, - public ::testing::WithParamInterface<int> { + public DeviceInterface { public: /** * Initializes a standard mouse device. @@ -194,7 +193,12 @@ public: }; -TEST_P(TouchGrabTest, ActiveAndPassiveGrab) +class TouchGrabTestMultipleModes : public TouchGrabTest, + public ::testing::WithParamInterface<int> +{ +}; + +TEST_P(TouchGrabTestMultipleModes, ActiveAndPassiveGrab) { int mode = GetParam(); std::string strmode = (mode == XIAcceptTouch) ? "XIAcceptTouch" : "XIRejectTouch"; @@ -269,9 +273,146 @@ TEST_P(TouchGrabTest, ActiveAndPassiveGrab) delete[] mask.mask; } -INSTANTIATE_TEST_CASE_P(, TouchGrabTest, ::testing::Values(XIAcceptTouch, XIRejectTouch)); +INSTANTIATE_TEST_CASE_P(, TouchGrabTestMultipleModes, ::testing::Values(XIAcceptTouch, XIRejectTouch)); -#endif +class TouchGrabTestMultipleTaps : public TouchGrabTest, + public ::testing::WithParamInterface<int> { }; + +TEST_P(TouchGrabTestMultipleTaps, PassiveGrabPointerEmulationMultipleTouchesFastSuccession) +{ + SCOPED_TRACE("\nTESTCASE: a client selecting for core events on the \n" + "root window must not receive ButtonPress and Release events \n" + "if a passive button grabbing client has GrabModeAsync.\n" + "This test exceeds num_touches on the device.\n"); + + ::Display *dpy1 = Display(); + + XIEventMask mask; + mask.deviceid = XIAllDevices; + mask.mask_len = XIMaskLen(XI_ButtonRelease); + mask.mask = new unsigned char[mask.mask_len](); + XISetMask(mask.mask, XI_ButtonPress); + + XIGrabModifiers mods; + mods.modifiers = XIAnyModifier; + XIGrabButton(dpy1, 2 /* VCP */, 1, DefaultRootWindow(dpy1), + None, GrabModeAsync, GrabModeAsync, False, &mask, 1, &mods); + delete[] mask.mask; + + ::Display *dpy2 = XOpenDisplay(server.GetDisplayString().c_str()); + ASSERT_TRUE(dpy2); + Window root = DefaultRootWindow(dpy2); + + int major = 2, minor = 0; + ASSERT_EQ(XIQueryVersion(dpy2, &major, &minor), Success); + + XSelectInput(dpy2, root, PointerMotionMask | ButtonPressMask | ButtonReleaseMask); + XSync(dpy2, False); + ASSERT_FALSE(XPending(dpy2)); + + int repeats = GetParam(); + + /* for this test to succeed, the server mustn't start processing until + the last touch event physically ends, so no usleep here*/ + for (int i = 0; i < repeats; i++) { + dev->Play(RECORDINGS_DIR "tablets/N-Trig-MultiTouch.touch_1_begin.events"); + dev->Play(RECORDINGS_DIR "tablets/N-Trig-MultiTouch.touch_1_end.events"); + } + + XSync(dpy1, False); + XSync(dpy2, False); + + ASSERT_TRUE(XPending(dpy1)); + ASSERT_EQ(XPending(dpy1), repeats); // ButtonPress event + while (XPending(dpy1)) { + XEvent ev; + XNextEvent(dpy1, &ev); + ASSERT_EQ(ev.type, GenericEvent); + ASSERT_EQ(ev.xcookie.extension, xi2_opcode); + ASSERT_EQ(ev.xcookie.evtype, XI_ButtonPress); + } + + while (XPending(dpy2)) { + XEvent ev; + XNextEvent(dpy2, &ev); + ASSERT_EQ(ev.type, MotionNotify); + } +} + +TEST_P(TouchGrabTestMultipleTaps, PassiveGrabPointerRelease) +{ + SCOPED_TRACE("\nTESTCASE: if a client has a async passive button grab on the " + "root window,\na client with a touch selection on the next window " + "down must not get touch events.\n" + "This test exceeds num_touches on the device.\n"); + + ::Display *dpy1 = Display(); + + XIEventMask mask; + mask.deviceid = XIAllDevices; + mask.mask_len = XIMaskLen(XI_ButtonRelease); + mask.mask = new unsigned char[mask.mask_len](); + XISetMask(mask.mask, XI_ButtonPress); + + XIGrabModifiers mods; + mods.modifiers = XIAnyModifier; + XIGrabButton(dpy1, 2 /* VCP */, 1, DefaultRootWindow(dpy1), + None, GrabModeAsync, GrabModeAsync, False, &mask, 1, &mods); + delete[] mask.mask; + + ::Display *dpy2 = XOpenDisplay(server.GetDisplayString().c_str()); + ASSERT_TRUE(dpy2); + Window root = DefaultRootWindow(dpy2); + + int major = 2, minor = 2; + ASSERT_EQ(XIQueryVersion(dpy2, &major, &minor), Success); + + mask.deviceid = XIAllMasterDevices; + mask.mask_len = XIMaskLen(XI_TouchEnd); + mask.mask = new unsigned char[mask.mask_len](); + XISetMask(mask.mask, XI_TouchBegin); + XISetMask(mask.mask, XI_TouchUpdate); + XISetMask(mask.mask, XI_TouchEnd); + + XISelectEvents(dpy2, root, &mask, 1); + delete[] mask.mask; + + XSync(dpy2, False); + ASSERT_FALSE(XPending(dpy2)); + + int repeats = GetParam(); + + /* for this test to succeed, the server mustn't start processing until + the last touch event physically ends, so no usleep here*/ + for (int i = 0; i < repeats; i++) { + dev->Play(RECORDINGS_DIR "tablets/N-Trig-MultiTouch.touch_1_begin.events"); + dev->Play(RECORDINGS_DIR "tablets/N-Trig-MultiTouch.touch_1_end.events"); + } + + XSync(dpy1, False); + XSync(dpy2, False); + + ASSERT_TRUE(XPending(dpy1)); + ASSERT_EQ(XPending(dpy1), repeats); // ButtonPress event + while (XPending(dpy1)) { + XEvent ev; + XNextEvent(dpy1, &ev); + ASSERT_EQ(ev.type, GenericEvent); + ASSERT_EQ(ev.xcookie.extension, xi2_opcode); + ASSERT_EQ(ev.xcookie.evtype, XI_ButtonPress); + } + + if (XPending(dpy2)) { + XEvent ev; + XPeekEvent(dpy2, &ev); + ASSERT_FALSE(XPending(dpy2)) << "Event type " << ev.type << " (extension " << + ev.xcookie.extension << " evtype " << ev.xcookie.evtype << ")"; + } +} + +INSTANTIATE_TEST_CASE_P(, TouchGrabTestMultipleTaps, ::testing::Range(1, 11)); /* device num_touches is 5 */ + +#endif /* HAVE_XI22 */ int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); |