diff options
author | Jasper St. Pierre <jstpierre@mecheye.net> | 2012-10-29 23:16:30 -0400 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2012-11-02 10:44:53 +1000 |
commit | a2b6c0cbb57fd25cde5a1334f347c3d258560858 (patch) | |
tree | 4e4579928cac2553fed3de5e84dca34d78057d49 | |
parent | 10dd3b107ed3c0c896e1c19ef0f0240e03818917 (diff) |
server: Add tests for pointer barriers
Signed-off-by: Jasper St. Pierre <jstpierre@mecheye.net>
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | tests/common/Makefile.am | 1 | ||||
-rw-r--r-- | tests/server/.gitignore | 1 | ||||
-rw-r--r-- | tests/server/Makefile.am | 5 | ||||
-rw-r--r-- | tests/server/barriers-common.h | 54 | ||||
-rw-r--r-- | tests/server/barriers-directions.cpp | 421 | ||||
-rw-r--r-- | tests/server/barriers-validity.cpp | 163 |
7 files changed, 646 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac index e7a3628..f9459a7 100644 --- a/configure.ac +++ b/configure.ac @@ -49,7 +49,8 @@ PKG_CHECK_MODULES(EVEMU, [evemu >= 1.0.10]) PKG_CHECK_MODULES(XI22, [inputproto >= 2.2] [xi >= 1.6], AC_DEFINE(HAVE_XI22, 1, [XI 2.2 available]), [noop=noop]) -PKG_CHECK_MODULES(XTEST, [xtst]); +PKG_CHECK_MODULES(XTEST, [xtst]) +PKG_CHECK_MODULES(XFIXES, [xfixes]) PKG_CHECK_MODULES(XORGGTEST, [xorg-gtest >= 0.6.0]) PKG_CHECK_MODULES(WACOM, xorg-wacom) diff --git a/tests/common/Makefile.am b/tests/common/Makefile.am index d0eda52..0164918 100644 --- a/tests/common/Makefile.am +++ b/tests/common/Makefile.am @@ -4,6 +4,7 @@ noinst_LIBRARIES = $(XORG_GTEST_BUILD_LIBS) AM_CPPFLAGS = \ $(XI_CFLAGS) \ + $(XFIXES_CFLAGS) \ $(XRANDR_CFLAGS) \ $(WACOM_CFLAGS) \ $(GTEST_CPPFLAGS) \ diff --git a/tests/server/.gitignore b/tests/server/.gitignore index 4eb1c20..f7d8d2e 100644 --- a/tests/server/.gitignore +++ b/tests/server/.gitignore @@ -4,3 +4,4 @@ xigrabbutton xtest multihead misc +barriers diff --git a/tests/server/Makefile.am b/tests/server/Makefile.am index 23c8b17..e5060ba 100644 --- a/tests/server/Makefile.am +++ b/tests/server/Makefile.am @@ -1,6 +1,6 @@ include $(top_srcdir)/tests/common/Makefile.am -noinst_PROGRAMS = grab touch xtest multihead misc +noinst_PROGRAMS = grab touch xtest multihead misc barriers TESTS=$(noinst_PROGRAMS) grab_SOURCES = grab.cpp xigrabbutton.cpp $(common_sources) @@ -17,3 +17,6 @@ multihead_LDADD = $(GTEST_LDADDS) misc_SOURCES = misc.cpp $(common_sources) misc_LDADD = $(GTEST_LDADDS) + +barriers_SOURCES = barrires-common.h barriers-validity.cpp barriers-directions.cpp $(common_sources) +barriers_LDADD = $(GTEST_LDADDS) $(XFIXES_LIBS) diff --git a/tests/server/barriers-common.h b/tests/server/barriers-common.h new file mode 100644 index 0000000..1c9e590 --- /dev/null +++ b/tests/server/barriers-common.h @@ -0,0 +1,54 @@ +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#ifndef _BARRIERS_COMMON_H_ +#define _BARRIERS_COMMON_H_ + +#include <xorg/gtest/xorg-gtest.h> + +#include "xit-server-input-test.h" +#include "device-interface.h" + +class BarrierTest : public XITServerInputTest, + public DeviceInterface { +public: + int xfixes_opcode; + int xfixes_event_base; + int xfixes_error_base; + + /** + * Initializes a standard mouse device. + */ + virtual void SetUp() { + SetDevice("mice/PIXART-USB-OPTICAL-MOUSE-HWHEEL.desc"); + XITServerInputTest::SetUp(); + + if (!XQueryExtension (Display(), XFIXES_NAME, + &xfixes_opcode, + &xfixes_event_base, + &xfixes_error_base)) { + ADD_FAILURE () << "Need XFixes.\n"; + } + } + + /** + * Sets up an xorg.conf for a single evdev CoreKeyboard device based on + * the evemu device. The input from GetParam() is used as XkbLayout. + */ + virtual void SetUpConfigAndLog() { + config.AddDefaultScreenWithDriver(); + config.AddInputSection("evdev", "--device--", + "Option \"CorePointer\" \"on\"\n" + /* Disable pointer acceleration to allow for accurate + * pointer positions with EV_REL events... */ + "Option \"AccelerationProfile\" \"-1\"" + "Option \"Device\" \"" + dev->GetDeviceNode() + "\""); + /* add default keyboard device to avoid server adding our device again */ + config.AddInputSection("kbd", "kbd-device", + "Option \"CoreKeyboard\" \"on\"\n"); + config.WriteConfig(); + } +}; + +#endif diff --git a/tests/server/barriers-directions.cpp b/tests/server/barriers-directions.cpp new file mode 100644 index 0000000..0db58a9 --- /dev/null +++ b/tests/server/barriers-directions.cpp @@ -0,0 +1,421 @@ +#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" + +class BarrierConstrained : public BarrierTest {}; + +/* Helper because XIQueryPointer and friends + * are terrible... */ +static Bool +QueryPointerPosition(Display *dpy, double *root_x, double *root_y) +{ + Window root, child; + double win_x, win_y; + XIButtonState buttons; + XIModifierState mods; + XIGroupState group; + + return XIQueryPointer (dpy, VIRTUAL_CORE_POINTER_ID, + DefaultRootWindow (dpy), + &root, &child, + root_x, root_y, + &win_x, &win_y, + &buttons, &mods, &group); + } + +#define ASSERT_PTR_POS(x, y) \ + QueryPointerPosition(dpy, &root_x, &root_y); \ + ASSERT_EQ(x, root_x); \ + ASSERT_EQ(y, root_y); + +/* Doing this parameterized would require a lot of fancy logic + * that would make it super fancy. For now, just do it manually. + */ + +TEST_F(BarrierConstrained, VerticalBarrierNoDirectionBlocksMotion) +{ + XORG_TESTCASE("Set up a vertical pointer barrier.\n" + "Ensure that mouse movement is blocked in both directions,\n" + " horizontally, when crossing the barrer and that warping\n" + " across the barrier is not blocked."); + + ::Display *dpy = Display(); + Window root = DefaultRootWindow(dpy); + PointerBarrier barrier; + double root_x, root_y; + + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 30); + + ASSERT_PTR_POS(30, 30); + + /* Barrier allows motion in neither direction */ + barrier = XFixesCreatePointerBarrier(dpy, root, 20, 20, 20, 40, 0, 0, NULL); + + /* Warp the pointer to before the barrier. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 10, 30); + ASSERT_PTR_POS(10, 30); + + /* Ensure that absolute warping works fine. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 50, 30); + ASSERT_PTR_POS(50, 30); + + /* This should be blocked. */ + dev->PlayOne(EV_REL, REL_X, -100, True); + ASSERT_PTR_POS(20, 30); + + /* Warp the pointer to before the barrier. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 10, 30); + ASSERT_PTR_POS(10, 30); + + /* This should be blocked. */ + dev->PlayOne(EV_REL, REL_X, 100, True); + ASSERT_PTR_POS(19, 30); + + XFixesDestroyPointerBarrier (dpy, barrier); +} + +TEST_F(BarrierConstrained, VerticalBarrierPositiveXBlocksMotion) +{ + XORG_TESTCASE("Set up a vertical pointer barrier. Ensure that mouse" + " movement is blocked in the positive X direction when" + " crossing the barrer and that warping across the barrier is" + " not blocked."); + + ::Display *dpy = Display(); + Window root = DefaultRootWindow(dpy); + PointerBarrier barrier; + double root_x, root_y; + + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 30); + + ASSERT_PTR_POS(30, 30); + + /* Barrier allows motion in positive X */ + barrier = XFixesCreatePointerBarrier(dpy, root, 20, 20, 20, 40, + BarrierPositiveX, 0, NULL); + + /* Warp the pointer to before the barrier. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 10, 30); + ASSERT_PTR_POS(10, 30); + + /* Ensure that absolute warping works fine. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 50, 30); + ASSERT_PTR_POS(50, 30); + + /* This should be blocked. */ + dev->PlayOne(EV_REL, REL_X, -100, True); + ASSERT_PTR_POS(20, 30); + + /* Warp the pointer to before the barrier. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 10, 30); + ASSERT_PTR_POS(10, 30); + + /* This shouldn't be blocked. */ + dev->PlayOne(EV_REL, REL_X, 100, True); + ASSERT_PTR_POS(110, 30); + + XFixesDestroyPointerBarrier (dpy, barrier); +} + +TEST_F(BarrierConstrained, VerticalBarrierNegativeXBlocksMotion) +{ + XORG_TESTCASE("Set up a vertical pointer barrier. Ensure that mouse" + " movement is blocked in the negative X direction when" + " crossing the barrer and that warping across the barrier is" + " not blocked."); + + ::Display *dpy = Display(); + Window root = DefaultRootWindow(dpy); + PointerBarrier barrier; + double root_x, root_y; + + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 30); + + ASSERT_PTR_POS(30, 30); + + /* Barrier allows motion in negative X */ + barrier = XFixesCreatePointerBarrier(dpy, root, 20, 20, 20, 40, + BarrierNegativeX, 0, NULL); + + /* Warp the pointer to before the barrier. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 10, 30); + ASSERT_PTR_POS(10, 30); + + /* Ensure that absolute warping works fine. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 50, 30); + ASSERT_PTR_POS(50, 30); + + /* This shouldn't be blocked. */ + dev->PlayOne(EV_REL, REL_X, -100, True); + ASSERT_PTR_POS(0, 30); + + /* Warp the pointer to before the barrier. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 10, 30); + ASSERT_PTR_POS(10, 30); + + /* This should be blocked. */ + dev->PlayOne(EV_REL, REL_X, 100, True); + ASSERT_PTR_POS(19, 30); + + XFixesDestroyPointerBarrier (dpy, barrier); +} + +TEST_F(BarrierConstrained, VerticalBarrierBothDirectionsXBlocksNoMotion) +{ + XORG_TESTCASE("Set up a vertical pointer barrier. Ensure that mouse" + " movement is not blocked in either direction, horizontally, when" + " crossing the barrer and that warping across the barrier is" + " not blocked."); + + ::Display *dpy = Display(); + Window root = DefaultRootWindow(dpy); + PointerBarrier barrier; + double root_x, root_y; + + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 30); + + ASSERT_PTR_POS(30, 30); + + /* Barrier allows motion in negative X */ + barrier = XFixesCreatePointerBarrier(dpy, root, 20, 20, 20, 40, + BarrierPositiveX | BarrierNegativeX, + 0, NULL); + + /* Warp the pointer to before the barrier. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 10, 30); + ASSERT_PTR_POS(10, 30); + + /* Ensure that absolute warping works fine. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 50, 30); + ASSERT_PTR_POS(50, 30); + + /* This shouldn't be blocked. */ + dev->PlayOne(EV_REL, REL_X, -100, True); + ASSERT_PTR_POS(0, 30); + + /* Warp the pointer to before the barrier. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 10, 30); + ASSERT_PTR_POS(10, 30); + + /* This shouldn't be blocked. */ + dev->PlayOne(EV_REL, REL_X, 100, True); + ASSERT_PTR_POS(110, 30); + + XFixesDestroyPointerBarrier (dpy, barrier); +} + + + +TEST_F(BarrierConstrained, HorizontalBarrierNoDirectionBlocksMotion) +{ + XORG_TESTCASE("Set up a horizontal pointer barrier. Ensure that mouse" + " movement is blocked in both directions, vertically, when" + " crossing the barrer and that warping across the barrier is" + " not blocked."); + + ::Display *dpy = Display(); + Window root = DefaultRootWindow(dpy); + PointerBarrier barrier; + double root_x, root_y; + + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 30); + + ASSERT_PTR_POS(30, 30); + + /* Barrier allows motion in neither direction */ + barrier = XFixesCreatePointerBarrier(dpy, root, 20, 20, 40, 20, 0, 0, NULL); + + /* Warp the pointer to before the barrier. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 10); + ASSERT_PTR_POS(30, 10); + + /* Ensure that absolute warping works fine. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 50); + ASSERT_PTR_POS(30, 50); + + /* This should be blocked. */ + dev->PlayOne(EV_REL, REL_Y, -100, True); + ASSERT_PTR_POS(30, 20); + + /* Warp the pointer to before the barrier. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 10); + ASSERT_PTR_POS(30, 10); + + /* This should be blocked. */ + dev->PlayOne(EV_REL, REL_Y, 100, True); + ASSERT_PTR_POS(30, 19); + + XFixesDestroyPointerBarrier (dpy, barrier); +} + +TEST_F(BarrierConstrained, HoritzontalBarrierPositiveYBlocksMotion) +{ + XORG_TESTCASE("Set up a horizontal pointer barrier. Ensure that mouse" + " movement is blocked in the positive Y direction when" + " crossing the barrer and that warping across the barrier is" + " not blocked."); + + ::Display *dpy = Display(); + Window root = DefaultRootWindow(dpy); + PointerBarrier barrier; + double root_x, root_y; + + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 30); + + ASSERT_PTR_POS(30, 30); + + /* Barrier allows motion in positive Y */ + barrier = XFixesCreatePointerBarrier(dpy, root, 20, 20, 40, 20, + BarrierPositiveY, 0, NULL); + + /* Warp the pointer to before the barrier. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 10); + ASSERT_PTR_POS(30, 10); + + /* Ensure that absolute warping works fine. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 50); + ASSERT_PTR_POS(30, 50); + + /* This should be blocked. */ + dev->PlayOne(EV_REL, REL_Y, -100, True); + ASSERT_PTR_POS(30, 20); + + /* Warp the pointer to before the barrier. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 10); + ASSERT_PTR_POS(30, 10); + + /* This shouldn't be blocked. */ + dev->PlayOne(EV_REL, REL_Y, 100, True); + ASSERT_PTR_POS(30, 110); + + XFixesDestroyPointerBarrier (dpy, barrier); +} + +TEST_F(BarrierConstrained, HoritzontalBarrierNegativeYBlocksMotion) +{ + XORG_TESTCASE("Set up a horizontal pointer barrier. Ensure that mouse" + " movement is blocked in the negative Y direction when" + " crossing the barrer and that warping across the barrier is" + " not blocked."); + + ::Display *dpy = Display(); + Window root = DefaultRootWindow(dpy); + PointerBarrier barrier; + double root_x, root_y; + + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 30); + + ASSERT_PTR_POS(30, 30); + + /* Barrier allows motion in negative Y */ + barrier = XFixesCreatePointerBarrier(dpy, root, 20, 20, 40, 20, + BarrierNegativeY, 0, NULL); + + /* Warp the pointer to before the barrier. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 10); + ASSERT_PTR_POS(30, 10); + + /* Ensure that absolute warping works fine. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 50); + ASSERT_PTR_POS(30, 50); + + /* This shouldn't be blocked. */ + dev->PlayOne(EV_REL, REL_Y, -100, True); + ASSERT_PTR_POS(30, 0); + + /* Warp the pointer to before the barrier. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 10); + ASSERT_PTR_POS(30, 10); + + /* This should be blocked. */ + dev->PlayOne(EV_REL, REL_Y, 100, True); + ASSERT_PTR_POS(30, 19); + + XFixesDestroyPointerBarrier (dpy, barrier); +} + +TEST_F(BarrierConstrained, HorizontalBarrierBothDirectionsYBlocksNoMotion) +{ + XORG_TESTCASE("Set up a horizontal pointer barrier. Ensure that mouse" + " movement is not blocked in either direction, vertically, when" + " crossing the barrer and that warping across the barrier is" + " not blocked."); + + ::Display *dpy = Display(); + Window root = DefaultRootWindow(dpy); + PointerBarrier barrier; + double root_x, root_y; + + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 30); + + ASSERT_PTR_POS(30, 30); + + /* Barrier allows motion in negative X */ + barrier = XFixesCreatePointerBarrier(dpy, root, 20, 20, 40, 20, + BarrierPositiveY | BarrierNegativeY, + 0, NULL); + + /* Warp the pointer to before the barrier. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 10); + ASSERT_PTR_POS(30, 10); + + /* Ensure that absolute warping works fine. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 50); + ASSERT_PTR_POS(30, 50); + + /* This shouldn't be blocked. */ + dev->PlayOne(EV_REL, REL_Y, -100, True); + ASSERT_PTR_POS(30, 0); + + /* Warp the pointer to before the barrier. */ + XIWarpPointer(dpy, VIRTUAL_CORE_POINTER_ID, + None, root, 0, 0, 0, 0, 30, 10); + ASSERT_PTR_POS(30, 10); + + /* This shouldn't be blocked. */ + dev->PlayOne(EV_REL, REL_Y, 100, True); + ASSERT_PTR_POS(30, 110); + + XFixesDestroyPointerBarrier (dpy, barrier); +} diff --git a/tests/server/barriers-validity.cpp b/tests/server/barriers-validity.cpp new file mode 100644 index 0000000..8aa9343 --- /dev/null +++ b/tests/server/barriers-validity.cpp @@ -0,0 +1,163 @@ +#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" + +class BarrierSimpleTest : public BarrierTest {}; + +TEST_F(BarrierSimpleTest, CreateAndDestroyBarrier) +{ + XORG_TESTCASE("Create a valid pointer barrier.\n" + "Ensure PointerBarrier XID is valid.\n" + "Delete pointer barrier\n" + "Ensure no error is generated\n"); + + ::Display *dpy = Display(); + Window root = DefaultRootWindow(dpy); + PointerBarrier barrier; + + XSync(dpy, False); + + barrier = XFixesCreatePointerBarrier(dpy, root, 20, 20, 20, 40, + BarrierPositiveX, 0, NULL); + ASSERT_NE((PointerBarrier)None, barrier) << "Failed to create barrier."; + + SetErrorTrap(dpy); + XFixesDestroyPointerBarrier(dpy, barrier); + ASSERT_NO_ERROR(ReleaseErrorTrap(dpy)); +} + +TEST_F(BarrierSimpleTest, DestroyInvalidBarrier) +{ + XORG_TESTCASE("Delete invalid pointer barrier\n" + "Ensure error is generated\n"); + + SetErrorTrap(Display()); + XFixesDestroyPointerBarrier(Display(), -1); + XErrorEvent *error = ReleaseErrorTrap(Display()); + ASSERT_ERROR(error, xfixes_error_base + BadBarrier); +} + +#define VALID_DIRECTIONS \ + ::testing::Values(0L, \ + BarrierPositiveX, \ + BarrierPositiveY, \ + BarrierNegativeX, \ + BarrierNegativeY, \ + BarrierPositiveX | BarrierNegativeX, \ + BarrierPositiveY | BarrierNegativeX) + +#define INVALID_DIRECTIONS \ + ::testing::Values(BarrierPositiveX | BarrierPositiveY, \ + BarrierNegativeX | BarrierNegativeY, \ + BarrierPositiveX | BarrierNegativeY, \ + BarrierNegativeX | BarrierPositiveY, \ + BarrierPositiveX | BarrierNegativeX | BarrierPositiveY, \ + BarrierPositiveX | BarrierNegativeX | BarrierNegativeY, \ + BarrierPositiveX | BarrierPositiveY | BarrierNegativeY, \ + BarrierNegativeX | BarrierPositiveY | BarrierNegativeY, \ + BarrierPositiveX | BarrierNegativeX | BarrierPositiveY | BarrierNegativeY) + + +class BarrierZeroLength : public BarrierTest, + public ::testing::WithParamInterface<long int> {}; +TEST_P(BarrierZeroLength, InvalidZeroLengthBarrier) +{ + XORG_TESTCASE("Create a pointer barrier with zero length.\n" + "Ensure server returns BadValue."); + + ::Display *dpy = Display(); + Window root = DefaultRootWindow(dpy); + int directions = GetParam(); + + XSync(dpy, False); + + SetErrorTrap(dpy); + XFixesCreatePointerBarrier(dpy, root, 20, 20, 20, 20, directions, 0, NULL); + XErrorEvent *error = ReleaseErrorTrap(dpy); + ASSERT_ERROR(error, BadValue); +} + +INSTANTIATE_TEST_CASE_P(, BarrierZeroLength, VALID_DIRECTIONS); + +class BarrierNonZeroArea : public BarrierTest, + public ::testing::WithParamInterface<long int> {}; +TEST_P(BarrierNonZeroArea, InvalidNonZeroAreaBarrier) +{ + XORG_TESTCASE("Create pointer barrier with non-zero area.\n" + "Ensure server returns BadValue\n"); + + ::Display *dpy = Display(); + Window root = DefaultRootWindow(dpy); + int directions = GetParam(); + + XSync(dpy, False); + + SetErrorTrap(dpy); + XFixesCreatePointerBarrier(dpy, root, 20, 20, 40, 40, directions, 0, NULL); + XErrorEvent *error = ReleaseErrorTrap(dpy); + ASSERT_ERROR(error, BadValue); +} +INSTANTIATE_TEST_CASE_P(, BarrierNonZeroArea, VALID_DIRECTIONS); + +static void +BarrierPosForDirections(int directions, int *x1, int *y1, int *x2, int *y2) +{ + *x1 = 20; + *y1 = 20; + + if (directions & BarrierPositiveY) { + *x2 = 40; + *y2 = 20; + } else { + *x2 = 20; + *y2 = 40; + } +} + +class BarrierConflictingDirections : public BarrierTest, + public ::testing::WithParamInterface<long int> {}; +TEST_P(BarrierConflictingDirections, InvalidConflictingDirectionsBarrier) +{ + XORG_TESTCASE("Create a barrier with conflicting directions, such\n" + "as (PositiveX | NegativeY), and ensure that these\n" + "cases are handled properly."); + + ::Display *dpy = Display(); + Window root = DefaultRootWindow(dpy); + + int directions = GetParam(); + int x1, y1, x2, y2; + BarrierPosForDirections(directions, &x1, &y1, &x2, &y2); + + XSync(dpy, False); + + SetErrorTrap(dpy); + XFixesCreatePointerBarrier(dpy, root, x1, y1, x2, y2, directions, 0, NULL); + XErrorEvent *error = ReleaseErrorTrap(dpy); + + /* Nonsensical directions are ignored -- they don't + * raise a BadValue. Unfortunately, there's no way + * to query an existing pointer barrier, so we can't + * actually check that the masked directions are proper. + * + * Just ensure we have no error. + */ + + ASSERT_NO_ERROR(error); +} +INSTANTIATE_TEST_CASE_P(, BarrierConflictingDirections, INVALID_DIRECTIONS); + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} |