On 07/11/2012 11:26 PM, Peter Hutterer wrote:
On Mon, Jul 09, 2012 at 05:13:15PM -0700, Chase Douglas wrote:
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]>
---

only comment: the TEST_P should be a TEST_F since you don't use the range.

I purposely leave everything as TEST_P. This way we are sure each test passes no matter what version of Xinput the client speaks. It does mean we triple the run time, but that seems like a worthwhile tradeoff.

With that in mind, do you still think we should switch to TEST_F?

Reviewed-by: Peter Hutterer <[email protected]>

otherwise. also, man am I glad we can have tests for this stuff now...

Cheers,
   Peter


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

Reply via email to