[PATCH] server: Add more tests for pointer barriers

Jasper St. Pierre jstpierre at mecheye.net
Tue Nov 20 11:22:12 PST 2012


From: "Jasper St. Pierre" <jstpierre at mecheye.net>

This time, ensure that our device implementation works correctly.
---
 tests/server/Makefile.am           |   1 +
 tests/server/barriers-devices.cpp  | 138 +++++++++++++++++++++++++++++++++++++
 tests/server/barriers-validity.cpp |  18 +++++
 3 files changed, 157 insertions(+)
 create mode 100644 tests/server/barriers-devices.cpp

diff --git a/tests/server/Makefile.am b/tests/server/Makefile.am
index b82e861..f684018 100644
--- a/tests/server/Makefile.am
+++ b/tests/server/Makefile.am
@@ -13,5 +13,6 @@ server_SOURCES = \
                  barriers-common.h \
                  barriers-validity.cpp \
                  barriers-directions.cpp \
+                 barriers-devices.cpp	\
                  $(common_sources)
 server_LDADD = $(GTEST_LDADDS) $(XTEST_LIBS) $(XFIXES_LIBS) $(XSCREENSAVER_LIBS)
diff --git a/tests/server/barriers-devices.cpp b/tests/server/barriers-devices.cpp
new file mode 100644
index 0000000..55ebc3a
--- /dev/null
+++ b/tests/server/barriers-devices.cpp
@@ -0,0 +1,138 @@
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <xorg/gtest/xorg-gtest.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/Xfixes.h>
+#include <X11/extensions/XInput2.h>
+
+#include "barriers-common.h"
+#include "helpers.h"
+
+using namespace xorg::testing::evemu;
+
+/* BarrierTest doesn't give us anything useful, so don't
+ * bother using it. */
+class BarrierDevices : public XITServerInputTest {
+public:
+    std::auto_ptr<xorg::testing::evemu::Device> dev1;
+    std::auto_ptr<xorg::testing::evemu::Device> dev2;
+
+    int master_id_1;
+    int master_id_2;
+
+    virtual void SetUp() {
+        dev1 = std::auto_ptr<Device>(new Device(RECORDINGS_DIR "mice/PIXART-USB-OPTICAL-MOUSE-HWHEEL.desc"));
+        dev2 = std::auto_ptr<Device>(new Device(RECORDINGS_DIR "mice/PIXART-USB-OPTICAL-MOUSE-HWHEEL.desc"));
+        XITServerInputTest::SetUp();
+        ConfigureDevices();
+    }
+
+    void ConfigureDevices() {
+        ::Display *dpy = Display();
+        int device_id_2;
+
+        XIAnyHierarchyChangeInfo change;
+        change.add = (XIAddMasterInfo) {
+            .type = XIAddMaster,
+            .name = (char *) "New Master",
+            .send_core = False,
+            .enable = True
+        };
+
+        master_id_1 = VIRTUAL_CORE_POINTER_ID;
+
+        ASSERT_EQ(XIChangeHierarchy(dpy, &change, 1), Success) << "Couldn't add the new master device.";
+        ASSERT_TRUE(xorg::testing::XServer::WaitForDevice(dpy, "New Master pointer")) << "Didn't get the new master pointer device.";
+        ASSERT_TRUE(FindInputDeviceByName(dpy, "New Master pointer", &master_id_2)) << "Failed to find the new master pointer.";
+        ASSERT_TRUE(FindInputDeviceByName(dpy, "--device2--", &device_id_2)) << "Failed to find device2.";
+
+        change.attach = (XIAttachSlaveInfo) {
+            .type = XIAttachSlave,
+            .deviceid = device_id_2,
+            .new_master = master_id_2,
+        };
+        ASSERT_EQ(XIChangeHierarchy(dpy, &change, 1), Success) << "Couldn't attach device2 to the new master pointer.";
+    }
+
+    virtual void SetUpConfigAndLog() {
+        config.AddDefaultScreenWithDriver();
+        config.AddInputSection("evdev", "--device1--",
+                               "Option \"CorePointer\" \"on\""
+                               "Option \"AccelerationProfile\" \"-1\""
+                               "Option \"Device\" \"" + dev1->GetDeviceNode() + "\"");
+
+        config.AddInputSection("evdev", "--device2--",
+                               "Option \"CorePointer\" \"on\""
+                               "Option \"AccelerationProfile\" \"-1\""
+                               "Option \"Device\" \"" + dev2->GetDeviceNode() + "\"");
+
+        config.AddInputSection("kbd", "kbd-device",
+                               "Option \"CoreKeyboard\" \"on\"\n");
+        config.WriteConfig();
+    }
+};
+
+static Bool
+QueryPointerPosition(Display *dpy, int device_id,
+                     double *root_x, double *root_y)
+{
+    Window root, child;
+    double win_x, win_y;
+    XIButtonState buttons;
+    XIModifierState mods;
+    XIGroupState group;
+
+    return XIQueryPointer (dpy, device_id,
+                           DefaultRootWindow (dpy),
+                           &root, &child,
+                           root_x, root_y,
+                           &win_x, &win_y,
+                           &buttons, &mods, &group);
+ }
+
+#define ASSERT_PTR_POS(dev, x, y)                       \
+    QueryPointerPosition(dpy, dev, &root_x, &root_y);   \
+    ASSERT_EQ(x, root_x);                               \
+    ASSERT_EQ(y, root_y);
+
+TEST_F(BarrierDevices, BarrierBlocksCorrectDevices)
+{
+    XORG_TESTCASE("Set up a vertical pointer barrier that\n"
+                  "should block motion only on the VCP device.\n"
+                  "Ensure that it blocks motion on the VCP only.\n");
+
+    ::Display *dpy = Display();
+    Window root = DefaultRootWindow(dpy);
+    PointerBarrier barrier;
+    double root_x, root_y;
+
+    /* Do some basic warps. */
+    XIWarpPointer(dpy, master_id_1, None, root, 0, 0, 0, 0, 30, 30);
+    ASSERT_PTR_POS(master_id_1, 30, 30);
+
+    XIWarpPointer(dpy, master_id_2, None, root, 0, 0, 0, 0, 30, 30);
+    ASSERT_PTR_POS(master_id_2, 30, 30);
+
+    barrier = XFixesCreatePointerBarrier(dpy, root, 50, 0, 50, 50, 0, 1, &master_id_1);
+    /* Ensure the barrier is created before we play events. */
+    XSync(dpy, False);
+
+    /* Make sure that the VCP is blocked when going across
+     * the barrier, but the other device is not. */
+    dev1->PlayOne(EV_REL, REL_X, 100, True);
+    ASSERT_PTR_POS(master_id_1, 49, 30);
+
+    dev2->PlayOne(EV_REL, REL_X, 100, True);
+    ASSERT_PTR_POS(master_id_2, 130, 30);
+
+    /* Assume that if all the other warp and directions tests
+     * passed and were all correct than this holds true for the
+     * multi-device case as well. If this is not the case, we can
+     * always add more fanciness later. */
+
+    XFixesDestroyPointerBarrier (dpy, barrier);
+}
diff --git a/tests/server/barriers-validity.cpp b/tests/server/barriers-validity.cpp
index 31763e4..b931195 100644
--- a/tests/server/barriers-validity.cpp
+++ b/tests/server/barriers-validity.cpp
@@ -7,6 +7,7 @@
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
 #include <X11/extensions/Xfixes.h>
+#include <X11/extensions/XInput.h>
 #include <X11/extensions/XInput2.h>
 
 #include "barriers-common.h"
@@ -47,6 +48,23 @@ TEST_F(BarrierSimpleTest, DestroyInvalidBarrier)
     ASSERT_ERROR(error, xfixes_error_base + BadBarrier);
 }
 
+TEST_F(BarrierSimpleTest, InvalidDeviceCausesBadDevice)
+{
+    XORG_TESTCASE("Ensure that passing a garbage device ID\n"
+                  "to XFixesCreatePointerBarrier returns with\n"
+                  "a BadDevice error\n");
+
+    ::Display *dpy = Display();
+    Window root = DefaultRootWindow(dpy);
+    int garbage_id = 0x00FACADE;
+    const XErrorEvent *error;
+
+    SetErrorTrap(dpy);
+    XFixesCreatePointerBarrier(dpy, root, 20, 20, 20, 40, 0, 1, &garbage_id);
+    error = ReleaseErrorTrap(dpy);
+    ASSERT_ERROR(error, xi_error_base + XI_BadDevice);
+}
+
 #define VALID_DIRECTIONS                                        \
     ::testing::Values(0L,                                       \
                       BarrierPositiveX,                         \
-- 
1.8.0



More information about the xorg-devel mailing list