summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2013-02-11 14:14:24 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2013-02-11 14:14:24 +1000
commitd6c88453751b0f621c6b1eaf7b47dbea770087a5 (patch)
tree4e15cca088bcc4dc1372cd856aec58f8f4eeaab1
parent2573ce812b80beab46e07d11196ee677b71250fa (diff)
parent1de0094f82f78da85ddcd4acd02ff9f341d9ec33 (diff)
Merge branch 'rel-device-matrix'
Conflicts: tests/server/Makefile.am
-rw-r--r--configure.ac1
-rw-r--r--tests/server/Makefile.am4
-rw-r--r--tests/server/input.cpp136
3 files changed, 140 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index b1e5ab2..beb0a64 100644
--- a/configure.ac
+++ b/configure.ac
@@ -55,6 +55,7 @@ PKG_CHECK_MODULES(XTEST, [xtst])
PKG_CHECK_MODULES(XFIXES, [xfixes])
PKG_CHECK_MODULES(XSCREENSAVER, [xscrnsaver])
PKG_CHECK_MODULES(DGA, [xxf86dga])
+PKG_CHECK_MODULES(PIXMAN, [pixman-1])
PKG_CHECK_MODULES(XORGGTEST, [xorg-gtest >= 0.6.0])
PKG_CHECK_MODULES(WACOM, xorg-wacom)
diff --git a/tests/server/Makefile.am b/tests/server/Makefile.am
index d6ea249..c5c8fa8 100644
--- a/tests/server/Makefile.am
+++ b/tests/server/Makefile.am
@@ -18,4 +18,6 @@ server_SOURCES = \
barriers-devices.cpp \
barriers-notify.cpp
-server_LDADD = $(XIT_LIBS) $(GTEST_LDADDS) $(XTEST_LIBS) $(XFIXES_LIBS) $(XSCREENSAVER_LIBS) $(DGA_LIBS)
+server_LDADD = $(XIT_LIBS) $(GTEST_LDADDS) $(XTEST_LIBS) $(XFIXES_LIBS) $(XSCREENSAVER_LIBS) $(XIT_LIBS) $(DGA_LIBS) $(PIXMAN_LIBS)
+
+server_CPPFLAGS = $(AM_CPPFLAGS) $(PIXMAN_CFLAGS)
diff --git a/tests/server/input.cpp b/tests/server/input.cpp
index aa005f6..0eb6f32 100644
--- a/tests/server/input.cpp
+++ b/tests/server/input.cpp
@@ -26,8 +26,12 @@
#include <config.h>
#endif
+#include <math.h>
+#include <pixman.h>
+
#include <xorg/gtest/xorg-gtest.h>
+#include <X11/Xatom.h>
#include <X11/extensions/XInput2.h>
#include "xit-server-input-test.h"
@@ -179,3 +183,135 @@ TEST_F(PointerSubpixelTest, NoSubpixelCoreEvents)
XCloseDisplay(dpy2);
}
+class PointerRelativeTransformationMatrixTest : public PointerMotionTest {
+public:
+ void SetDeviceMatrix(::Display *dpy, int deviceid, struct pixman_f_transform *m) {
+ float matrix[9];
+
+ for (int i = 0; i < 9; i++)
+ matrix[i] = m->m[i/3][i%3];
+
+ Atom prop = XInternAtom(dpy, "Coordinate Transformation Matrix", True);
+ XIChangeProperty(dpy, deviceid, prop, XInternAtom(dpy, "FLOAT", True),
+ 32, PropModeReplace,
+ reinterpret_cast<unsigned char*>(matrix), 9);
+ }
+
+ void DisablePtrAccel(::Display *dpy, int deviceid) {
+ int data = -1;
+
+ Atom prop = XInternAtom(dpy, "Device Accel Profile", True);
+ XIChangeProperty(dpy, deviceid, prop, XA_INTEGER, 32,
+ PropModeReplace, reinterpret_cast<unsigned char*>(&data), 1);
+ }
+
+ void MoveAndCompare(::Display *dpy, int dx, int dy) {
+ double x, y;
+
+ QueryPointerPosition(dpy, &x, &y);
+ dev->PlayOne(EV_REL, REL_X, dx);
+ dev->PlayOne(EV_REL, REL_Y, dy, true);
+ ASSERT_EVENT(XIDeviceEvent, motion, dpy, GenericEvent, xi2_opcode, XI_Motion);
+ ASSERT_EQ(motion->root_x, x + dx);
+ ASSERT_EQ(motion->root_y, y + dy);
+ }
+};
+
+
+TEST_F(PointerRelativeTransformationMatrixTest, IgnoreTranslationComponent)
+{
+ XORG_TESTCASE("Apply a translation matrix to the device\n"
+ "Move the pointer.\n"
+ "Verify matrix does not affect movement\n");
+
+ ::Display *dpy = Display();
+
+ int deviceid;
+ ASSERT_EQ(FindInputDeviceByName(dpy, "--device--", &deviceid), 1);
+
+ XIEventMask mask;
+ mask.deviceid = XIAllMasterDevices;
+ mask.mask_len = XIMaskLen(XI_Motion);
+ mask.mask = new unsigned char[mask.mask_len]();
+ XISetMask(mask.mask, XI_Motion);
+
+ XISelectEvents(dpy, DefaultRootWindow(dpy), &mask, 1);
+
+ DisablePtrAccel(dpy, deviceid);
+
+ struct pixman_f_transform m;
+ pixman_f_transform_init_translate(&m, 10, 0);
+ SetDeviceMatrix(dpy, deviceid, &m);
+
+ MoveAndCompare(dpy, 10, 0);
+ MoveAndCompare(dpy, 0, 10);
+ MoveAndCompare(dpy, 5, 5);
+
+ pixman_f_transform_init_translate(&m, 0, 10);
+ SetDeviceMatrix(dpy, deviceid, &m);
+
+ MoveAndCompare(dpy, 10, 0);
+ MoveAndCompare(dpy, 0, 10);
+ MoveAndCompare(dpy, 5, 5);
+}
+
+class PointerRelativeRotationMatrixTest : public PointerRelativeTransformationMatrixTest,
+ public ::testing::WithParamInterface<int> {
+};
+
+TEST_P(PointerRelativeRotationMatrixTest, RotationTest)
+{
+ XORG_TESTCASE("Apply a coordinate transformation to the relative device\n"
+ "Move the pointer.\n"
+ "Verify movement against matrix\n");
+
+ ::Display *dpy = Display();
+
+ int deviceid;
+ ASSERT_EQ(FindInputDeviceByName(dpy, "--device--", &deviceid), 1);
+
+ XIEventMask mask;
+ mask.deviceid = XIAllMasterDevices;
+ mask.mask_len = XIMaskLen(XI_Motion);
+ mask.mask = new unsigned char[mask.mask_len]();
+ XISetMask(mask.mask, XI_Motion);
+
+ XISelectEvents(dpy, DefaultRootWindow(dpy), &mask, 1);
+
+ int angle = GetParam() * M_PI/180.0;
+
+ struct pixman_f_transform m;
+ pixman_f_transform_init_rotate(&m, cos(angle), sin(angle));
+
+ SetDeviceMatrix(dpy, deviceid, &m);
+
+ int coords[][2] = {
+ {1, 0}, {-2, 0}, {3, 2}, {4, -7},
+ {-3, 6}, {-5, -9}, {0, 3}, {0, -5},
+ {0, 0}, /* null-terminated */
+ };
+
+ int i = 0;
+ while(coords[i][0] && coords[i][1]) {
+ double dx = coords[i][0], dy = coords[i][1];
+ struct pixman_f_vector p = { .v = {dx, dy, 1} };
+
+ ASSERT_TRUE(pixman_f_transform_point(&m, &p));
+
+ double x, y;
+ QueryPointerPosition(dpy, &x, &y);
+
+ /* Move pointer */
+ dev->PlayOne(EV_REL, REL_X, dx);
+ dev->PlayOne(EV_REL, REL_Y, dy, true);
+
+ /* Compare to two decimal places */
+ ASSERT_EVENT(XIDeviceEvent, motion, dpy, GenericEvent, xi2_opcode, XI_Motion);
+ ASSERT_LT(fabs(motion->root_x - (x + p.v[0])), 0.001);
+ ASSERT_LT(fabs(motion->root_y - (y + p.v[1])), 0.001);
+ i++;
+ }
+
+}
+
+INSTANTIATE_TEST_CASE_P(, PointerRelativeRotationMatrixTest, ::testing::Range(0, 360, 15));