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]> --- The original bug report is likely against X core, but we don't have a nice suite for X core input events yet. I've at least provided a test here for XI 2.x, which hopefully is validation enough that the bug is fixed. This is meant to be applied on top of Peter's integration-testing branch. Currently, the top commit ID is: 092d98c17999fbf696e4db8f1d85e79052c83be5. test/integration/xi2.cpp | 97 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/test/integration/xi2.cpp b/test/integration/xi2.cpp index 1cbbe05..b9451b2 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,99 @@ TEST_P(XInput2Test, DisableDeviceEndTouches) XI_TouchEnd)); } +/** + * 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, TouchBeginButtonState) +{ + 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> device; + try { + device = std::auto_ptr<xorg::testing::evemu::Device>( + new xorg::testing::evemu::Device( + TEST_ROOT_DIR "recordings/ntrig_dell_xt2/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)")); + + device->Play( + TEST_ROOT_DIR "recordings/ntrig_dell_xt2/touch_1_begin.record"); + device->Play( + TEST_ROOT_DIR "recordings/ntrig_dell_xt2/touch_1_end.record"); + + /* We expect the first button to be unset for the motion and press events, + * but set for the release event. */ + std::list<std::pair<int, bool> > expect; + expect.push_back(std::make_pair(XI_Motion, false)); + expect.push_back(std::make_pair(XI_ButtonPress, false)); + expect.push_back(std::make_pair(XI_ButtonRelease, true)); + + 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); + } +} + 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
