When a touch begin is pointer emulated, the initial motion and button press events should not have the first button set in the button mask. The button mask represents the state of the buttons *before* the event.
Signed-off-by: Chase Douglas <[email protected]> --- .../recordings/intellimouse/device.prop | 24 ++++ .../recordings/intellimouse/move_right.record | 2 + test/integration/xi2.cpp | 132 ++++++++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 test/integration/recordings/intellimouse/device.prop create mode 100644 test/integration/recordings/intellimouse/move_right.record diff --git a/test/integration/recordings/intellimouse/device.prop b/test/integration/recordings/intellimouse/device.prop new file mode 100644 index 0000000..9fa8b75 --- /dev/null +++ b/test/integration/recordings/intellimouse/device.prop @@ -0,0 +1,24 @@ +N: Microsoft Microsoft IntelliMouse® Optical (Virtual Test Device) +I: 0003 045e 0029 0100 +P: 00 00 00 00 00 00 00 00 +B: 00 17 00 00 00 00 00 00 00 +B: 01 00 00 00 00 00 00 00 00 +B: 01 00 00 00 00 00 00 00 00 +B: 01 00 00 00 00 00 00 00 00 +B: 01 00 00 00 00 00 00 00 00 +B: 01 00 00 1f 00 00 00 00 00 +B: 01 00 00 00 00 00 00 00 00 +B: 01 00 00 00 00 00 00 00 00 +B: 01 00 00 00 00 00 00 00 00 +B: 01 00 00 00 00 00 00 00 00 +B: 01 00 00 00 00 00 00 00 00 +B: 01 00 00 00 00 00 00 00 00 +B: 01 00 00 00 00 00 00 00 00 +B: 02 03 01 00 00 00 00 00 00 +B: 03 00 00 00 00 00 00 00 00 +B: 04 10 00 00 00 00 00 00 00 +B: 05 00 00 00 00 00 00 00 00 +B: 11 00 00 00 00 00 00 00 00 +B: 12 00 00 00 00 00 00 00 00 +B: 15 00 00 00 00 00 00 00 00 +B: 15 00 00 00 00 00 00 00 00 diff --git a/test/integration/recordings/intellimouse/move_right.record b/test/integration/recordings/intellimouse/move_right.record new file mode 100644 index 0000000..944ce4a --- /dev/null +++ b/test/integration/recordings/intellimouse/move_right.record @@ -0,0 +1,2 @@ +E: 1327542640.244087 0002 0000 1 +E: 1327542640.244088 0000 0000 0 diff --git a/test/integration/xi2.cpp b/test/integration/xi2.cpp index 1cbbe05..f2af071 100644 --- a/test/integration/xi2.cpp +++ b/test/integration/xi2.cpp @@ -1,4 +1,6 @@ +#include <list> #include <stdexcept> +#include <sstream> #include <xorg/gtest/xorg-gtest.h> @@ -353,4 +355,134 @@ TEST_P(XInput2Test, DisableDeviceEndTouches) XI_TouchEnd)); } +namespace { + +/** + * Helper function for TouchEmulatedButtonState test + */ +void CheckButtonState(::Display* display, int xi2_opcode, + std::list<std::pair<int, bool> >& expect) +{ + for (std::list<std::pair<int, bool> >::iterator it = expect.begin(); + it != expect.end(); + ++it) { + ASSERT_TRUE(WaitForEventOfType(display, GenericEvent, xi2_opcode, + it->first)); + + XEvent event; + ASSERT_EQ(Success, XNextEvent(display, &event)); + + XGenericEventCookie *xcookie = &event.xcookie; + ASSERT_TRUE(XGetEventData(display, xcookie)); + + XIDeviceEvent *device_event = + reinterpret_cast<XIDeviceEvent*>(xcookie->data); + + std::stringstream msg; + msg << "Failed for "; + switch (it->first) { + case XI_Motion: + msg << "XI_Motion "; + break; + case XI_ButtonPress: + msg << "XI_ButtonPress "; + break; + case XI_ButtonRelease: + msg << "XI_ButtonRelease "; + break; + } + msg << "event"; + + EXPECT_EQ(it->second, + static_cast<bool>(XIMaskIsSet(device_event->buttons.mask, 1))) + << msg.str(); + + XFreeEventData(display, xcookie); + } +} + +} + +/** + * The button state should represent the logical state of the buttons before the + * event. Thus, a button press should not have any button state under normal + * circumstances. This holds for touch events emulated as motion and button + * events as well. + */ +TEST_P(XInput2Test, TouchEmulatedButtonState) +{ + XIEventMask mask; + mask.deviceid = XIAllDevices; + mask.mask_len = XIMaskLen(XI_HierarchyChanged); + mask.mask = reinterpret_cast<unsigned char*>(calloc(mask.mask_len, 1)); + XISetMask(mask.mask, XI_HierarchyChanged); + + ASSERT_EQ(Success, + XISelectEvents(Display(), DefaultRootWindow(Display()), &mask, + 1)); + + mask.deviceid = XIAllMasterDevices; + XIClearMask(mask.mask, XI_HierarchyChanged); + XISetMask(mask.mask, XI_ButtonPress); + XISetMask(mask.mask, XI_ButtonRelease); + XISetMask(mask.mask, XI_Motion); + + ASSERT_EQ(Success, + XISelectEvents(Display(), DefaultRootWindow(Display()), &mask, + 1)); + + free(mask.mask); + + XFlush(Display()); + + std::auto_ptr<xorg::testing::evemu::Device> touchscreen; + std::auto_ptr<xorg::testing::evemu::Device> mouse; + try { + touchscreen = std::auto_ptr<xorg::testing::evemu::Device>( + new xorg::testing::evemu::Device( + TEST_ROOT_DIR "recordings/ntrig_dell_xt2/device.prop")); + mouse = std::auto_ptr<xorg::testing::evemu::Device>( + new xorg::testing::evemu::Device( + TEST_ROOT_DIR "recordings/intellimouse/device.prop")); + } catch (std::runtime_error &error) { + std::cerr << "Failed to create evemu device, skipping test.\n"; + return; + } + + ASSERT_TRUE(WaitForDevice(Display(), + "N-Trig MultiTouch (Virtual Test Device)")); + ASSERT_TRUE( + WaitForDevice(Display(), + "Microsoft Microsoft IntelliMouse® Optical (Virtual Test Device)")); + + std::list<std::pair<int, bool> > expect; + + SCOPED_TRACE("Testing touch begin"); + touchscreen->Play( + TEST_ROOT_DIR "recordings/ntrig_dell_xt2/touch_1_begin.record"); + expect.push_back(std::make_pair(XI_Motion, false)); + expect.push_back(std::make_pair(XI_ButtonPress, false)); + CheckButtonState(Display(), xi2_opcode_, expect); + expect.clear(); + + SCOPED_TRACE("Testing mouse motion while touch is active"); + mouse->Play(TEST_ROOT_DIR "recordings/intellimouse/move_right.record"); + expect.push_back(std::make_pair(XI_Motion, true)); + CheckButtonState(Display(), xi2_opcode_, expect); + expect.clear(); + + SCOPED_TRACE("Testing touch end"); + touchscreen->Play( + TEST_ROOT_DIR "recordings/ntrig_dell_xt2/touch_1_end.record"); + expect.push_back(std::make_pair(XI_ButtonRelease, true)); + CheckButtonState(Display(), xi2_opcode_, expect); + expect.clear(); + + SCOPED_TRACE("Testing mouse motion after touch has ended"); + mouse->Play(TEST_ROOT_DIR "recordings/intellimouse/move_right.record"); + expect.push_back(std::make_pair(XI_Motion, false)); + CheckButtonState(Display(), xi2_opcode_, expect); + expect.clear(); +} + INSTANTIATE_TEST_CASE_P(, XInput2Test, ::testing::Range(0, 3)); -- 1.7.10.4 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
