.../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