diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2013-02-11 14:14:24 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2013-02-11 14:14:24 +1000 |
commit | d6c88453751b0f621c6b1eaf7b47dbea770087a5 (patch) | |
tree | 4e15cca088bcc4dc1372cd856aec58f8f4eeaab1 | |
parent | 2573ce812b80beab46e07d11196ee677b71250fa (diff) | |
parent | 1de0094f82f78da85ddcd4acd02ff9f341d9ec33 (diff) |
Merge branch 'rel-device-matrix'
Conflicts:
tests/server/Makefile.am
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | tests/server/Makefile.am | 4 | ||||
-rw-r--r-- | tests/server/input.cpp | 136 |
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)); |