summaryrefslogtreecommitdiff
path: root/tests/server/grab.cpp
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2012-10-22 13:36:35 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2012-10-25 16:32:16 +1000
commit5032a54287d286bb4080bb9832c01cf3a6b7011c (patch)
treef7b4805188cbc4a298cfb2329382639e9f77f234 /tests/server/grab.cpp
parent1b811912990849c3933286609fa6c8c588893cdc (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.cpp151
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);