summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPovilas Kanapickas <povilas@radix.lt>2020-12-14 16:30:10 +0200
committerPovilas Kanapickas <povilas@radix.lt>2020-12-17 03:01:40 +0200
commit8422eb358677eaf60254393070d37f8dda2faed1 (patch)
treebbdb9e7e28b6aad13d9cc9c38fb52732e97b0791
parent9fea10e285396dcb8830599aa03687c8263a9417 (diff)
tests: Remove input driver tests
libinput is the way forward which has its own testsuite. Thus it does no longer make sense to test other input drivers. For input during other tests we have the inputtest driver. The current tests for input drivers are unreliable and effectively unfixable, because of the race condition introduced by separate input thread. The inputtest driver has the required synchronization capabilities.
-rw-r--r--meson.build51
-rw-r--r--tests/input/.gitignore7
-rw-r--r--tests/input/evdev.cpp2087
-rw-r--r--tests/input/kbd.cpp187
-rw-r--r--tests/input/legacy-drivers.cpp504
-rw-r--r--tests/input/mouse.cpp232
-rw-r--r--tests/input/synaptics.cpp1815
-rw-r--r--tests/input/wacom-hovering-expresskeys.cpp151
-rw-r--r--tests/input/wacom-input-matrix.cpp308
-rw-r--r--tests/input/wacom.cpp866
-rw-r--r--tests/input/wacom_devs.h73
11 files changed, 0 insertions, 6281 deletions
diff --git a/meson.build b/meson.build
index a35c923..d9db502 100644
--- a/meson.build
+++ b/meson.build
@@ -214,14 +214,6 @@ dep_tests = [
#
# input tests
#
-test('test-legacy-drivers',
- executable('test-legacy-drivers',
- 'tests/input/legacy-drivers.cpp',
- dependencies: dep_tests,
- ),
- is_parallel: false,
- suite: 'input',
-)
test('test-input-module-load',
executable('test-input-module-load',
'tests/input/input-module-load.cpp',
@@ -230,49 +222,6 @@ test('test-input-module-load',
is_parallel: false,
suite: 'input',
)
-test('test-kbd',
- executable('test-kbd',
- 'tests/input/kbd.cpp',
- dependencies: dep_tests,
- ),
- is_parallel: false,
- suite: 'input',
-)
-test('test-mouse',
- executable('test-mouse',
- 'tests/input/mouse.cpp',
- dependencies: dep_tests,
- ),
- is_parallel: false,
- suite: 'input',
-)
-test('test-evdev',
- executable('test-evdev',
- 'tests/input/evdev.cpp',
- dependencies: [dep_tests, dep_libevdev],
- ),
- is_parallel: false,
- suite: 'input',
-)
-test('test-synaptics',
- executable('test-synaptics',
- 'tests/input/synaptics.cpp',
- dependencies: dep_tests,
- ),
- is_parallel: false,
- suite: 'input',
-)
-test('test-wacom',
- executable('test-wacom',
- 'tests/input/wacom.cpp',
- 'tests/input/wacom_devs.h',
- 'tests/input/wacom-hovering-expresskeys.cpp',
- 'tests/input/wacom-input-matrix.cpp',
- dependencies: [dep_tests, dep_xserver, dep_wacom],
- ),
- is_parallel: false,
- suite: 'input',
-)
#
# library tests
diff --git a/tests/input/.gitignore b/tests/input/.gitignore
index b9fbb3f..a463b5d 100644
--- a/tests/input/.gitignore
+++ b/tests/input/.gitignore
@@ -1,8 +1 @@
-legacy-drivers
input-module-load
-kbd-driver
-mouse-driver
-evdev-driver
-synaptics-driver
-wacom-driver
-
diff --git a/tests/input/evdev.cpp b/tests/input/evdev.cpp
deleted file mode 100644
index 458ac6b..0000000
--- a/tests/input/evdev.cpp
+++ /dev/null
@@ -1,2087 +0,0 @@
-/*
- * Copyright © 2012-2013 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- */
-
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <math.h>
-#include <stdexcept>
-#include <map>
-#include <fstream>
-#include <xorg/gtest/xorg-gtest.h>
-#include <linux/input.h>
-#include <tuple>
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#define XK_LATIN1
-#include <X11/keysymdef.h>
-#include <X11/XF86keysym.h>
-#include <X11/Xutil.h>
-#include <X11/extensions/XInput.h>
-#include <X11/extensions/XInput2.h>
-
-#include <libevdev/libevdev.h>
-#include <libevdev/libevdev-uinput.h>
-
-#include "xit-server-input-test.h"
-#include "xit-event.h"
-#include "xit-property.h"
-#include "device-interface.h"
-#include "helpers.h"
-
-typedef std::pair <int, KeySym> Key_Pair;
-typedef std::multimap<std::string, Key_Pair> Keys_Map;
-typedef Keys_Map::iterator keys_mapIter;
-typedef std::vector<Key_Pair> MultiMedia_Keys_Map;
-typedef MultiMedia_Keys_Map::iterator multimediakeys_mapIter;
-
-class EvdevKeyboardTest : public XITServerInputTest,
- public DeviceInterface {
-public:
- virtual void SetUp() {
- SetDevice("keyboards/AT-Translated-Set-2-Keyboard.desc");
- XITServerInputTest::SetUp();
- }
-
- /**
- * 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 \"CoreKeyboard\" \"on\"\n"
- "Option \"GrabDevice\" \"on\""
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"");
- /* add default mouse device to avoid server adding our device again */
- config.AddInputSection("mouse", "mouse-device",
- "Option \"CorePointer\" \"on\"\n");
- config.WriteConfig();
- }
-};
-
-class EvdevXKBConfigRulesTest : public EvdevKeyboardTest {
- virtual void SetUpConfigAndLog() {
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("evdev", "--device--",
- "Option \"CoreKeyboard\" \"on\"\n"
- "Option \"XKBrules\" \"xorg\"\n"
- "Option \"GrabDevice\" \"on\""
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"");
- /* add default mouse device to avoid server adding our device again */
- config.AddInputSection("mouse", "mouse-device",
- "Option \"CorePointer\" \"on\"\n");
- config.WriteConfig();
- }
-};
-
-TEST_F(EvdevXKBConfigRulesTest, NoRuleChangeAllowed) {
- XORG_TESTCASE("Start server with 'xorg' ruleset\n"
- "Verify evdev changes this to 'evdev'\n");
-
-
- ASSERT_TRUE(SearchFileForString(server.GetLogFilePath(), "Option \"xkb_rules\" \"evdev\""));
- ASSERT_FALSE(SearchFileForString(server.GetLogFilePath(), "Option \"xkb_rules\" \"xorg\""));
-}
-
-struct xkb_config {
- std::string option; /* option set in the server */
- std::string parsed_option; /* option actually parsed (server ignores _) */
- std::string value;
-} xkb_configs[] = {
- { "xkb_layout", "xkb_layout", "de" },
- { "XkbLayout", "xkb_layout", "de" },
- { "xkb_model", "xkb_model", "pc105" },
- { "XkbModel", "xkb_model", "pc105" },
- { "xkb_variant", "xkb_variant", "dvorak" },
- { "XkbVariant", "xkb_variant", "dvorak" },
- { "xkb_Options", "xkb_options", "compose:caps" },
- { "XkbOptions", "xkb_options", "compose:caps" },
-
- /* test for empty options */
- { "xkb_layout", "xkb_layout", "" },
- { "XkbLayout", "xkb_layout", "" },
- { "xkb_model", "xkb_model", "" },
- { "XkbModel", "xkb_model", "" },
- { "xkb_variant", "xkb_variant", "" },
- { "XkbVariant", "xkb_variant", "" },
- { "xkb_options", "xkb_options", "" },
- { "XkbOptions", "xkb_options", "" },
-};
-
-void PrintTo(const struct xkb_config &xkb, ::std::ostream *os) {
- *os << "xkb: " << xkb.option << ": " << xkb.value;
-}
-
-class EvdevXKBConfigTest : public EvdevKeyboardTest,
- public ::testing::WithParamInterface<struct xkb_config> {
- virtual void SetUpConfigAndLog() {
- struct xkb_config xkb = GetParam();
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("evdev", "--device--",
- "Option \"CoreKeyboard\" \"on\"\n"
- "Option \"" + xkb.option + "\" \"" + xkb.value + "\"\n"
- "Option \"GrabDevice\" \"on\""
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"");
- /* add default mouse device to avoid server adding our device again */
- config.AddInputSection("mouse", "mouse-device",
- "Option \"CorePointer\" \"on\"\n");
- config.WriteConfig();
- }
-};
-
-TEST_P(EvdevXKBConfigTest, XKBOptionParseTest) {
- XORG_TESTCASE("Init device with XKB options set.\n"
- "Ensure options show up in the serverlog as the driver parses them\n");
-
- struct xkb_config xkb = GetParam();
-
- if (xkb.value.length() > 0)
- ASSERT_TRUE(SearchFileForString(server.GetLogFilePath(), "Option \"" + xkb.parsed_option + "\" \"" + xkb.value +"\""));
- else /* error message is "requires a string value" but thanks to a typo
- we'd need regex to check for that. oh well */
- ASSERT_TRUE(SearchFileForString(server.GetLogFilePath(), "Option \"" + xkb.parsed_option + "\" requires"));
-}
-
-INSTANTIATE_TEST_CASE_P(, EvdevXKBConfigTest, ::testing::ValuesIn(xkb_configs));
-
-
-/**
- * Evdev driver test for keyboard devices. Takes a string as parameter,
- * which is later used for the XkbLayout option.
- */
-class EvdevXKBTest : public EvdevKeyboardTest,
- public ::testing::WithParamInterface<std::string> {
-public:
- /**
- * Initializes a standard keyboard device.
- */
- virtual void SetUp() {
- // Define a map of pair to hold each key/keysym per layout
- // US, QWERTY => qwerty
- Keys.insert (std::pair<std::string, Key_Pair> ("us", Key_Pair (KEY_Q, XK_q)));
- Keys.insert (std::pair<std::string, Key_Pair> ("us", Key_Pair (KEY_W, XK_w)));
- Keys.insert (std::pair<std::string, Key_Pair> ("us", Key_Pair (KEY_E, XK_e)));
- Keys.insert (std::pair<std::string, Key_Pair> ("us", Key_Pair (KEY_R, XK_r)));
- Keys.insert (std::pair<std::string, Key_Pair> ("us", Key_Pair (KEY_T, XK_t)));
- Keys.insert (std::pair<std::string, Key_Pair> ("us", Key_Pair (KEY_Y, XK_y)));
- // German, QWERTY => qwertz
- Keys.insert (std::pair<std::string, Key_Pair> ("de", Key_Pair (KEY_Q, XK_q)));
- Keys.insert (std::pair<std::string, Key_Pair> ("de", Key_Pair (KEY_W, XK_w)));
- Keys.insert (std::pair<std::string, Key_Pair> ("de", Key_Pair (KEY_E, XK_e)));
- Keys.insert (std::pair<std::string, Key_Pair> ("de", Key_Pair (KEY_R, XK_r)));
- Keys.insert (std::pair<std::string, Key_Pair> ("de", Key_Pair (KEY_T, XK_t)));
- Keys.insert (std::pair<std::string, Key_Pair> ("de", Key_Pair (KEY_Y, XK_z)));
- // French, QWERTY => azerty
- Keys.insert (std::pair<std::string, Key_Pair> ("fr", Key_Pair (KEY_Q, XK_a)));
- Keys.insert (std::pair<std::string, Key_Pair> ("fr", Key_Pair (KEY_W, XK_z)));
- Keys.insert (std::pair<std::string, Key_Pair> ("fr", Key_Pair (KEY_E, XK_e)));
- Keys.insert (std::pair<std::string, Key_Pair> ("fr", Key_Pair (KEY_R, XK_r)));
- Keys.insert (std::pair<std::string, Key_Pair> ("fr", Key_Pair (KEY_T, XK_t)));
- Keys.insert (std::pair<std::string, Key_Pair> ("fr", Key_Pair (KEY_Y, XK_y)));
-
- // Define a vector of pair to hold each key/keysym for multimedia
- Multimedia_Keys.push_back (Key_Pair (KEY_MUTE, XF86XK_AudioMute));
- Multimedia_Keys.push_back (Key_Pair (KEY_VOLUMEUP, XF86XK_AudioRaiseVolume));
- Multimedia_Keys.push_back (Key_Pair (KEY_VOLUMEDOWN, XF86XK_AudioLowerVolume));
- Multimedia_Keys.push_back (Key_Pair (KEY_PLAYPAUSE, XF86XK_AudioPlay));
- Multimedia_Keys.push_back (Key_Pair (KEY_NEXTSONG, XF86XK_AudioNext));
- Multimedia_Keys.push_back (Key_Pair (KEY_PREVIOUSSONG, XF86XK_AudioPrev));
-
- EvdevKeyboardTest::SetUp();
- }
-
- /**
- * 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 \"CoreKeyboard\" \"on\"\n"
- "Option \"XkbRules\" \"xorg\"\n"
- "Option \"XkbModel\" \"dellusbmm\"\n"
- "Option \"XkbLayout\" \""+ GetParam() + "\"\n"
- "Option \"GrabDevice\" \"on\""
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"");
- /* add default mouse device to avoid server adding our device again */
- config.AddInputSection("mouse", "mouse-device",
- "Option \"CorePointer\" \"on\"\n");
- config.WriteConfig();
- }
-
- protected:
- /**
- * List of evdev keysyms to X11 keysyms for each layout.
- */
- Keys_Map Keys;
-
- /**
- * List of evdev keysyms to X11 keysyms for multimedia keys
- */
- MultiMedia_Keys_Map Multimedia_Keys;
-};
-
-
-TEST_P(EvdevXKBTest, DeviceExists)
-{
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--"), 1);
-}
-
-void play_key_pair (::Display *display, xorg::testing::evemu::Device *dev, Key_Pair pair)
-{
- dev->PlayOne(EV_KEY, pair.first, 1, 1);
- dev->PlayOne(EV_KEY, pair.first, 0, 1);
-
- XSync(display, False);
- ASSERT_NE(XPending(display), 0) << "No event pending" << std::endl;
-
- XEvent press;
- XNextEvent(display, &press);
-
- KeySym sym = XKeycodeToKeysym(display, press.xkey.keycode, 0);
- ASSERT_NE((KeySym)NoSymbol, sym) << "No keysym for keycode " << press.xkey.keycode << std::endl;
- ASSERT_EQ(pair.second, sym) << "Keysym not matching for keycode " << press.xkey.keycode << std::endl;
-
- XSync(display, False);
- while (XPending(display))
- XNextEvent(display, &press);
-}
-
-TEST_P(EvdevXKBTest, KeyboardLayout)
-{
- std::string layout = GetParam();
-
- XSelectInput(Display(), DefaultRootWindow(Display()), KeyPressMask | KeyReleaseMask);
- /* the server takes a while to start up bust the devices may not respond
- to events yet. Add a noop call that just delays everything long
- enough for this test to work */
- XInternAtom(Display(), "foo", True);
- XFlush(Display());
-
- keys_mapIter it;
- std::pair<keys_mapIter, keys_mapIter> keyRange = Keys.equal_range(layout);
- for (it = keyRange.first; it != keyRange.second; ++it)
- play_key_pair (Display(), dev.get(), (*it).second);
-
- // Now test multimedia keys
- multimediakeys_mapIter m_it;
- for (m_it = Multimedia_Keys.begin(); m_it != Multimedia_Keys.end(); m_it++)
- play_key_pair (Display(), dev.get(), (*m_it));
-}
-
-INSTANTIATE_TEST_CASE_P(, EvdevXKBTest, ::testing::Values("us", "de", "fr"));
-
-/**
- * Evdev driver test for mouse devices.
- */
-class EvdevMouseTest : public XITServerInputTest,
- public DeviceInterface {
-public:
- /**
- * Initializes a standard mouse device with two wheels.
- */
- virtual void SetUp() {
- SetDevice("mice/PIXART-USB-OPTICAL-MOUSE-HWHEEL.desc");
-
- xi2_major_minimum = 2;
- xi2_minor_minimum = 1;
-
- XITServerInputTest::SetUp();
- }
-
- /**
- * Sets up an xorg.conf for a single evdev CorePointer device based on
- * the evemu device.
- */
- virtual void SetUpConfigAndLog() {
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("evdev", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"GrabDevice\" \"on\""
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"");
- /* add default keyboard device to avoid server adding our device again */
- config.AddInputSection("kbd", "keyboard-device",
- "Option \"CoreKeyboard\" \"on\"\n");
- config.WriteConfig();
- }
-};
-
-TEST_F(EvdevMouseTest, TerminateWithButtonDown)
-{
- XORG_TESTCASE("Terminate server with button down.\n"
- "http://patchwork.freedesktop.org/patch/12193/");
-
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
- XSync(Display(), False);
-
- dev->PlayOne(EV_KEY, BTN_LEFT, 1, 1);
-
- ASSERT_TRUE(xorg::testing::XServer::WaitForEventOfType(Display(), ButtonPress, -1, -1, 1000));
- XEvent ev;
- XNextEvent(Display(), &ev);
- ASSERT_FALSE(XPending(Display()));
-}
-
-TEST_F(EvdevMouseTest, BtnReleaseMaskOnly)
-{
- XORG_TESTCASE("Ensure button release event is delivered if"
- "only the\n release mask is set (not the press mask)");
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonReleaseMask);
- XSync(Display(), False);
-
- dev->PlayOne(EV_KEY, BTN_LEFT, 1, true);
- dev->PlayOne(EV_KEY, BTN_LEFT, 0, true);
-
- ASSERT_TRUE(xorg::testing::XServer::WaitForEventOfType(Display(), ButtonRelease, -1, -1, 1000));
- XEvent ev;
- XNextEvent(Display(), &ev);
-
- ASSERT_FALSE(XPending(Display()));
-}
-
-TEST_F(EvdevMouseTest, WheelEmulationZeroIsBadValue)
-{
- XORG_TESTCASE("Set wheel emulation intertia to 0\n"
- "Expect BadValue\n"
- "https://bugs.freedesktop.org/show_bug.cgi?id=66125");
-
- ::Display *dpy = Display();
- int deviceid;
- ASSERT_TRUE(FindInputDeviceByName(Display(), "--device--", &deviceid));
-
-
- ASSERT_PROPERTY(short, emulation, dpy, deviceid, "Evdev Wheel Emulation Inertia");
- emulation.data[0] = 0;
-
- SetErrorTrap(dpy);
- emulation.Update();
- ASSERT_ERROR(ReleaseErrorTrap(dpy), BadValue);
-}
-
-TEST_F(EvdevMouseTest, SmoothScrollingAvailable)
-{
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1) << "Failed to find device.";
-
- int ndevices;
- XIDeviceInfo *info = XIQueryDevice(Display(), deviceid, &ndevices);
- ASSERT_EQ(ndevices, 1);
-
- int nvaluators = 0;
- bool hscroll_class_found = false;
- bool vscroll_class_found = false;
- for (int i = 0; i < info->num_classes; i++) {
- XIAnyClassInfo *any = info->classes[i];
- if (any->type == XIScrollClass) {
- XIScrollClassInfo *scroll = reinterpret_cast<XIScrollClassInfo*>(any);
- switch(scroll->scroll_type) {
- case XIScrollTypeVertical:
- vscroll_class_found = true;
- ASSERT_EQ(scroll->increment, -1);
- ASSERT_EQ(scroll->flags & XIScrollFlagPreferred, XIScrollFlagPreferred);
- break;
- case XIScrollTypeHorizontal:
- hscroll_class_found = true;
- ASSERT_EQ(scroll->increment, 1);
- break;
- default:
- FAIL() << "Invalid scroll class: " << scroll->type;
- }
- } else if (any->type == XIValuatorClass) {
- nvaluators++;
- }
- }
-
- ASSERT_EQ(nvaluators, 4);
- ASSERT_TRUE(hscroll_class_found);
- ASSERT_TRUE(vscroll_class_found);
-
- XIFreeDeviceInfo(info);
-}
-
-TEST_F(EvdevMouseTest, SmoothScrolling)
-{
- XIEventMask mask;
- mask.deviceid = XIAllMasterDevices;
- mask.mask_len = XIMaskLen(XI_Motion);
- mask.mask = new unsigned char[mask.mask_len];
- XISetMask(mask.mask, XI_Motion);
- XISetMask(mask.mask, XI_ButtonPress);
- XISetMask(mask.mask, XI_ButtonRelease);
- XISelectEvents(Display(), DefaultRootWindow(Display()), &mask, 1);
- XSync(Display(), False);
-
- delete mask.mask;
-
- dev->PlayOne(EV_REL, REL_WHEEL, -1, true);
-
- XEvent ev;
- XIDeviceEvent *e;
-
- ASSERT_TRUE(xorg::testing::XServer::WaitForEventOfType(Display(),
- GenericEvent,
- xi2_opcode,
- XI_Motion,
- 1000));
- XNextEvent(Display(), &ev);
- ASSERT_EQ(ev.xany.type, GenericEvent);
- ASSERT_EQ(ev.xcookie.evtype, XI_Motion);
- XGetEventData(Display(), &ev.xcookie);
- e = reinterpret_cast<XIDeviceEvent*>(ev.xcookie.data);
- ASSERT_GE(e->valuators.mask_len, 1); /* one 4-byte unit */
- ASSERT_TRUE(XIMaskIsSet(e->valuators.mask, 3)); /* order of axes is x, y, hwheel, wheel */
- XFreeEventData(Display(), &ev.xcookie);
-
- ASSERT_TRUE(xorg::testing::XServer::WaitForEventOfType(Display(),
- GenericEvent,
- xi2_opcode,
- XI_ButtonPress,
- 1000));
- XNextEvent(Display(), &ev);
- ASSERT_EQ(ev.xany.type, GenericEvent);
- ASSERT_EQ(ev.xcookie.evtype, XI_ButtonPress);
- XGetEventData(Display(), &ev.xcookie);
- e = reinterpret_cast<XIDeviceEvent*>(ev.xcookie.data);
- ASSERT_EQ(e->detail, 5);
- ASSERT_EQ(e->flags & XIPointerEmulated, XIPointerEmulated);
- XFreeEventData(Display(), &ev.xcookie);
- ASSERT_TRUE(xorg::testing::XServer::WaitForEventOfType(Display(),
- GenericEvent,
- xi2_opcode,
- XI_ButtonRelease,
- 1000));
- XNextEvent(Display(), &ev);
- ASSERT_EQ(ev.xany.type, GenericEvent);
- ASSERT_EQ(ev.xcookie.evtype, XI_ButtonRelease);
- XGetEventData(Display(), &ev.xcookie);
- e = reinterpret_cast<XIDeviceEvent*>(ev.xcookie.data);
- ASSERT_EQ(e->detail, 5);
- ASSERT_EQ(e->flags & XIPointerEmulated, XIPointerEmulated);
- XFreeEventData(Display(), &ev.xcookie);
-
- ASSERT_FALSE(XPending(Display()));
-}
-
-
-void scroll_wheel_event(::Display *display,
- xorg::testing::evemu::Device *dev,
- int axis, int value, unsigned int button) {
-
- dev->PlayOne(EV_REL, axis, value, 1);
-
- XSync(display, False);
-
- ASSERT_NE(XPending(display), 0) << "No event pending" << std::endl;
- XEvent btn;
- int nevents = 0;
- while(XPending(display)) {
- XNextEvent(display, &btn);
-
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, button);
-
- XNextEvent(display, &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonRelease);
- ASSERT_EQ(btn.xbutton.button, button);
-
- nevents++;
- }
-
- ASSERT_EQ(nevents, abs(value));
-}
-
-
-TEST_F(EvdevMouseTest, ScrollWheel)
-{
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
- /* the server takes a while to start up bust the devices may not respond
- to events yet. Add a noop call that just delays everything long
- enough for this test to work */
- XInternAtom(Display(), "foo", True);
- XFlush(Display());
-
- scroll_wheel_event(Display(), dev.get(), REL_WHEEL, 1, 4);
- scroll_wheel_event(Display(), dev.get(), REL_WHEEL, 2, 4);
- scroll_wheel_event(Display(), dev.get(), REL_WHEEL, 3, 4);
-
- scroll_wheel_event(Display(), dev.get(), REL_WHEEL, -1, 5);
- scroll_wheel_event(Display(), dev.get(), REL_WHEEL, -2, 5);
- scroll_wheel_event(Display(), dev.get(), REL_WHEEL, -3, 5);
-
- scroll_wheel_event(Display(), dev.get(), REL_HWHEEL, 1, 7);
- scroll_wheel_event(Display(), dev.get(), REL_HWHEEL, 2, 7);
- scroll_wheel_event(Display(), dev.get(), REL_HWHEEL, 3, 7);
-
- scroll_wheel_event(Display(), dev.get(), REL_HWHEEL, -1, 6);
- scroll_wheel_event(Display(), dev.get(), REL_HWHEEL, -2, 6);
- scroll_wheel_event(Display(), dev.get(), REL_HWHEEL, -3, 6);
-}
-
-TEST_F(EvdevMouseTest, DevNode)
-{
- Atom node_prop = XInternAtom(Display(), "Device Node", True);
-
- ASSERT_NE(node_prop, (Atom)None) << "This requires server 1.11";
-
- int deviceid = -1;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1) << "Failed to find device.";
-
- Atom type;
- int format;
- unsigned long nitems, bytes_after;
- char *data;
- XIGetProperty(Display(), deviceid, node_prop, 0, 100, False,
- AnyPropertyType, &type, &format, &nitems, &bytes_after,
- (unsigned char**)&data);
- ASSERT_EQ(type, XA_STRING);
-
- std::string devnode(data);
- ASSERT_EQ(devnode.compare(dev->GetDeviceNode()), 0);
-
- XFree(data);
-}
-
-TEST_F(EvdevMouseTest, MiddleButtonEmulation)
-{
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
- XFlush(Display());
-
- Atom mb_prop = XInternAtom(Display(), "Evdev Middle Button Emulation", True);
-
- ASSERT_NE(mb_prop, (Atom)None);
-
- int deviceid = -1;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1) << "Failed to find device.";
-
- Atom type;
- int format;
- unsigned long nitems, bytes_after;
- unsigned char *data;
- XIGetProperty(Display(), deviceid, mb_prop, 0, 100, False,
- AnyPropertyType, &type, &format, &nitems, &bytes_after,
- &data);
- ASSERT_EQ(type, XA_INTEGER);
- ASSERT_EQ(format, 8);
- ASSERT_EQ(nitems, 1U);
-
- /* enable mb emulation */
- *data = 1;
- XIChangeProperty(Display(), deviceid, mb_prop, type, format,
- PropModeReplace, data, 1);
- XSync(Display(), False);
-
- dev->PlayOne(EV_KEY, BTN_LEFT, 1, 1);
- dev->PlayOne(EV_KEY, BTN_RIGHT, 1, 1);
- dev->PlayOne(EV_KEY, BTN_RIGHT, 0, 1);
- dev->PlayOne(EV_KEY, BTN_LEFT, 0, 1);
-
- XSync(Display(), False);
-
- ASSERT_NE(XPending(Display()), 0) << "No event pending" << std::endl;
- XEvent btn;
-
- XNextEvent(Display(), &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, 2U);
-
- XNextEvent(Display(), &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonRelease);
- ASSERT_EQ(btn.xbutton.button, 2U);
-
- ASSERT_EQ(XPending(Display()), 0) << "Events pending when there should be none" << std::endl;
-
- /* disable mb emulation */
- *data = 0;
- XIChangeProperty(Display(), deviceid, mb_prop, type, format,
- PropModeReplace, data, 1);
- XSync(Display(), False);
-
- dev->PlayOne(EV_KEY, BTN_LEFT, 1, 1);
- dev->PlayOne(EV_KEY, BTN_RIGHT, 1, 1);
- dev->PlayOne(EV_KEY, BTN_RIGHT, 0, 1);
- dev->PlayOne(EV_KEY, BTN_LEFT, 0, 1);
-
- XSync(Display(), False);
-
- ASSERT_NE(XPending(Display()), 0) << "No event pending" << std::endl;
-
- XNextEvent(Display(), &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, 1U);
-
- XNextEvent(Display(), &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, 3U);
-
- XNextEvent(Display(), &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonRelease);
- ASSERT_EQ(btn.xbutton.button, 3U);
-
- XNextEvent(Display(), &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonRelease);
- ASSERT_EQ(btn.xbutton.button, 1U);
-
- ASSERT_EQ(XPending(Display()), 0) << "Events pending when there should be none" << std::endl;
-
- XFree(data);
-}
-
-void button_event(::Display *display,
- xorg::testing::evemu::Device *dev,
- int button, unsigned int logical) {
-
- dev->PlayOne(EV_KEY, button, 1, true);
- dev->PlayOne(EV_KEY, button, 0, true);
-
- XSync(display, False);
-
- ASSERT_NE(XPending(display), 0) << "No event pending" << std::endl;
-
- XEvent btn;
- XNextEvent(display, &btn);
-
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, logical);
-
- XNextEvent(display, &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonRelease);
- ASSERT_EQ(btn.xbutton.button, logical);
-
- ASSERT_EQ(XPending(display), 0) << "Events pending when there should be none" << std::endl;
-}
-
-#ifndef DOXYGEN_IGNORE_THIS
-
-typedef struct {
- int map[8];
- int nmap;
-} Mapping;
-
-void PrintTo(const Mapping &m, ::std::ostream *os) {
- for (int i = 0; i < m.nmap; i++)
- *os << m.map[i] << " ";
-}
-
-#endif /* DOXYGEN_IGNORE_THIS */
-
-/**
- * Button mapping test for the evdev driver. Takes a struct Mapping as input
- * parameter:
- */
-class EvdevButtonMappingTest : public EvdevMouseTest,
- public ::testing::WithParamInterface<Mapping> {
-public:
- /**
- * Set up a config for a single evdev CorePointer device with
- * Option "ButtonMapping" based on the Mapping provided by GetParam()
- */
- virtual void SetUpConfigAndLog() {
-
- const Mapping mapping = GetParam();
- std::stringstream ss;
- for (int i = 0; i < mapping.nmap; i++) {
- ss << mapping.map[i];
- if (i < mapping.nmap - 1)
- ss << " ";
- }
-
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("evdev", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"GrabDevice\" \"on\""
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\""
- "Option \"ButtonMapping\" \"" + ss.str() + "\"");
- config.WriteConfig();
- }
-};
-
-TEST_P(EvdevButtonMappingTest, ButtonMapping)
-{
- Mapping mapping = GetParam();
-
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
- XFlush(Display());
-
- XSync(Display(), True);
-
- button_event(Display(), dev.get(), BTN_LEFT, mapping.map[0]);
- button_event(Display(), dev.get(), BTN_MIDDLE, mapping.map[1]);
- button_event(Display(), dev.get(), BTN_RIGHT, mapping.map[2]);
-}
-
-Mapping mappings[] = {
- { {1, 2, 3}, 3 },
- { {3, 1, 1}, 3 },
- { {1, 3, 1}, 3 },
- { {3, 1, 2}, 3 },
-};
-
-INSTANTIATE_TEST_CASE_P(, EvdevButtonMappingTest,
- ::testing::ValuesIn(mappings));
-
-/**
- * Button mapping test for invalid button mappings the evdev driver. Takes a
- * string as input parameter.
- */
-class EvdevInvalidButtonMappingTest : public EvdevMouseTest,
- public ::testing::WithParamInterface<std::string> {
-public:
- /**
- * Set up a config for a single evdev CorePointer device with
- * Option "ButtonMapping" based on the string provided by GetParam()
- */
- virtual void SetUpConfigAndLog() {
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("evdev", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"GrabDevice\" \"on\""
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\""
- "Option \"ButtonMapping\" \"" + GetParam() + "\"");
- config.WriteConfig();
- }
-};
-
-TEST_P(EvdevInvalidButtonMappingTest, InvalidButtonMapping)
-{
- std::ifstream in_file(server.GetLogFilePath().c_str());
- std::string line;
- std::string error_msg("Invalid button mapping.");
-
- // grep for error message in the log file...
- if(in_file.is_open())
- {
- while (getline (in_file, line))
- {
- size_t found = line.find(error_msg);
- if (found != std::string::npos)
- return;
- }
- }
- FAIL() << "Invalid button mapping message not found in log";
-}
-
-
-/**
- * Test for the server honouring Option Floating "on".
- */
-class EvdevFloatingSlaveTest : public EvdevMouseTest {
-public:
- /**
- * Set up a config for a single evdev Floating device.
- */
- virtual void SetUpConfigAndLog() {
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("evdev", "--device--",
- "Option \"Floating\" \"on\"\n"
- "Option \"GrabDevice\" \"on\""
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"");
- config.WriteConfig();
- }
-};
-
-TEST_F(EvdevFloatingSlaveTest, FloatingDevice)
-{
- XORG_TESTCASE("Check that the server does not crash for a device\n"
- "with Option Floating set.\n"
- "xorg-server-1.12.99.903-49-gd53e6e0\n");
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1);
-
- int ndevices;
- XIDeviceInfo *info = XIQueryDevice(Display(), deviceid, &ndevices);
- ASSERT_EQ(ndevices, 1);
-
- ASSERT_EQ(info->use, XIFloatingSlave);
-
- XIFreeDeviceInfo(info);
-
- dev->PlayOne(EV_REL, ABS_X, 10, 1);
- dev->PlayOne(EV_REL, ABS_X, 4, 1);
-
- XSync(Display(), False);
- ASSERT_FALSE(XPending(Display()));
-
- ASSERT_EQ(server.GetState(), xorg::testing::Process::RUNNING);
-}
-
-
-INSTANTIATE_TEST_CASE_P(, EvdevInvalidButtonMappingTest,
- ::testing::Values(" ", "a", "64", "1 2 ", "-1",
- "1 a", "1 55", "1 -2"));
-
-class EvdevTrackballTest : public EvdevMouseTest {
- virtual void SetUp() {
- SetDevice("mice/Logitech-USB-Trackball.desc");
- XITServerInputTest::SetUp();
- }
-
- virtual void SetUpConfigAndLog() {
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("evdev", "Logitech USB Trackball",
- "Option \"Floating\" \"on\"\n"
- "Option \"GrabDevice\" \"on\""
- "Option \"TypeName\" \"TRACKBALL\""
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"");
- config.WriteConfig();
- }
-};
-
-TEST_F(EvdevTrackballTest, TypeIsXI_TRACKBALL)
-{
- XORG_TESTCASE("A trackball should be of type XI_TRACKBALL.\n"
- "https://bugs.freedesktop.org/show_bug.cgi?id=55867");
-
- ::Display *dpy = Display();
-
- Atom trackball_prop = XInternAtom(dpy, XI_TRACKBALL, True);
- ASSERT_NE(trackball_prop, (Atom)None);
-
- int ndevices;
- XDeviceInfo *info = XListInputDevices(dpy, &ndevices);
-
- for (int i = 0; i < ndevices; i++) {
- XDeviceInfo *di = &info[i];
- if (strcmp(di->name, "Logitech USB Trackball") == 0) {
- ASSERT_EQ(di->type, trackball_prop);
- return;
- }
- }
-
- FAIL() << "Failed to find device";
-}
-
-class EvdevJoystickTest : public EvdevMouseTest {
- virtual void SetUp() {
- SetDevice("joysticks/Sony-PLAYSTATION(R)3-Controller.desc");
- XITServerInputTest::SetUp();
- }
-};
-
-TEST_F(EvdevJoystickTest, MTAxesNoButtons)
-{
- XORG_TESTCASE("Set up a device with MT axes and only buttons > BTN_JOYSTICK\n"
- "Expect the device to _not_ be added.\n"
- "https://bugs.freedesktop.org/show_bug.cgi?id=58967");
-
-
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 0);
-}
-
-class EvdevTouchTest : public XITServerInputTest,
- public DeviceInterface {
-protected:
- virtual void SetUp() {
- SetDevice("tablets/N-Trig-MultiTouch.desc");
-
- xi2_major_minimum = 2;
- xi2_minor_minimum = 2;
-
- XITServerInputTest::SetUp();
- }
-
- virtual void SetUpConfigAndLog() {
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("evdev", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"\n"
- "Option \"GrabDevice\" \"on\"");
- config.WriteConfig();
- }
-
- virtual void TouchBegin(int x, int y) {
- dev->PlayOne(EV_KEY, BTN_TOUCH, 1);
- TouchUpdate(x, y);
- }
-
- virtual void TouchUpdate(int x, int y) {
- dev->PlayOne(EV_ABS, ABS_X, x);
- dev->PlayOne(EV_ABS, ABS_Y, y);
- dev->PlayOne(EV_ABS, ABS_MT_POSITION_X, x);
- dev->PlayOne(EV_ABS, ABS_MT_POSITION_Y, y);
- /* same values as the recordings file */
- dev->PlayOne(EV_ABS, ABS_MT_ORIENTATION, 0);
- dev->PlayOne(EV_ABS, ABS_MT_TOUCH_MAJOR, 468);
- dev->PlayOne(EV_ABS, ABS_MT_TOUCH_MINOR, 306);
- dev->PlayOne(EV_SYN, SYN_MT_REPORT, 0);
- dev->PlayOne(EV_SYN, SYN_REPORT, 0);
- }
-
- virtual void TouchEnd() {
- dev->PlayOne(EV_KEY, BTN_TOUCH, 0);
- dev->PlayOne(EV_SYN, SYN_REPORT, 0);
- }
-
-};
-
-enum directions {
- NONE,
- CW, /* top screen edge is right */
- INVERT, /* upside-down */
- CCW, /* top screen edge is left */
-};
-
-enum config_type {
- PROPERTY,
- XORG_CONF
-};
-
-class EvdevTouchRotationTest : public EvdevTouchTest,
- public
- ::testing::WithParamInterface<std::tuple<enum config_type, enum directions> > {
-public:
- void GetRotationSettings(enum directions dir, unsigned char *swap_axes,
- unsigned char *invert_x, unsigned char *invert_y)
- {
- switch(dir) {
- case NONE:
- *swap_axes = 0;
- *invert_x = 0;
- *invert_y = 0;
- break;
- case INVERT:
- *swap_axes = 0;
- *invert_x = 1;
- *invert_y = 1;
- break;
- case CW:
- *swap_axes = 1;
- *invert_x = 1;
- *invert_y = 0;
- break;
- case CCW:
- *swap_axes = 1;
- *invert_x = 0;
- *invert_y = 1;
- break;
- }
- }
-
- virtual void SetUpConfigAndLog() {
- std::tuple<enum config_type, enum directions> t = GetParam();
- enum config_type config_type = std::get<0>(t);
- enum directions dir = std::get<1>(t);
-
- unsigned char swap_axes = 0, invert_x = 0, invert_y = 0;
- if (config_type == XORG_CONF)
- GetRotationSettings(dir, &swap_axes, &invert_x, &invert_y);
-
- std::string sw = swap_axes ? "on" : "off";
- std::string ix = invert_x ? "on" : "off";
- std::string iy = invert_y ? "on" : "off";
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("evdev", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"SwapAxes\" \"" + sw + "\"\n" +
- "Option \"InvertX\" \"" + ix + "\"\n" +
- "Option \"InvertY\" \"" + iy + "\"\n" +
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"\n"
- "Option \"GrabDevice\" \"on\"");
- config.WriteConfig();
- }
-
- virtual void SetRotationProperty(::Display *dpy, int deviceid, enum directions dir)
- {
- Atom swap_axes_prop = XInternAtom(dpy, "Evdev Axes Swap", True);
- Atom invert_axes_prop = XInternAtom(dpy, "Evdev Axis Inversion", True);
-
- unsigned char swap;
- unsigned char inversion[2];
-
- GetRotationSettings(dir, &swap, &inversion[0], &inversion[1]);
-
- XIChangeProperty(dpy, deviceid, swap_axes_prop, XA_INTEGER, 8,
- PropModeReplace, &swap, 1);
- XIChangeProperty(dpy, deviceid, invert_axes_prop, XA_INTEGER, 8,
- PropModeReplace, inversion, 2);
- XSync(dpy, True);
- }
-};
-
-TEST_P(EvdevTouchRotationTest, AxisSwapInversion)
-{
- std::tuple<enum config_type, enum directions> t = GetParam();
- enum config_type config_type = std::get<0>(t);
- enum directions dir = std::get<1>(t);
-
- XORG_TESTCASE("Init a touch device.\n"
- "Set rotation/axis inversion properties\n"
- "Send events\n"
- "Ensure event coordinates are rotated\n"
- "https://bugs.freedesktop.org/show_bug.cgi?id=59340");
-
- std::string direction;
- switch (dir) {
- case NONE: direction = "none"; break;
- case CW: direction = "cw"; break;
- case CCW: direction = "ccw"; break;
- case INVERT: direction = "inverted"; break;
- }
-
- SCOPED_TRACE("Rotation is " + direction);
-
- ::Display *dpy = Display();
-
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(dpy, "--device--", &deviceid), 1);
-
- if (config_type == PROPERTY)
- SetRotationProperty(dpy, deviceid, dir);
-
- XIEventMask mask;
- mask.mask_len = XIMaskLen(XI_TouchEnd);
- mask.mask = new unsigned char[mask.mask_len]();
- mask.deviceid = VIRTUAL_CORE_POINTER_ID;
- XISetMask(mask.mask, XI_TouchBegin);
- XISetMask(mask.mask, XI_TouchUpdate);
- XISetMask(mask.mask, XI_TouchEnd);
- XISelectEvents(dpy, DefaultRootWindow(dpy), &mask, 1);
-
- int w = DisplayWidth(dpy, DefaultScreen(dpy));
- int h = DisplayHeight(dpy, DefaultScreen(dpy));
-
- int devw = 9600, devh = 7200; /* from recordings file */
-
- TouchBegin(devw * 0.25, devh * 0.25);
-
- ASSERT_EVENT(XIDeviceEvent, begin, dpy, GenericEvent, xi2_opcode, XI_TouchBegin);
-
- /* scaling in the server may get us a pixel or so off */
-#define EXPECT_APPROX(v, expected) \
- EXPECT_GE(v, expected - 1); \
- EXPECT_LE(v, expected + 1);
-
- /* x movement first */
- for (int i = 30; i < 75; i += 5) {
- double xpos = i/100.0;
- double x_expect = 0, y_expect = 0;
-
- TouchUpdate(devw * xpos, devh * 0.25);
-
- switch(dir) {
- case NONE:
- x_expect = w * xpos;
- y_expect = h * 0.25;
- break;
- case CW:
- x_expect = w * 0.75;
- y_expect = h * xpos;
- break;
- case CCW:
- x_expect = w * 0.25;
- y_expect = h * (1 - xpos);
- break;
- case INVERT:
- x_expect = w * (1 - xpos);
- y_expect = h * 0.75;
- break;
- default:
- FAIL();
- }
-
-
- ASSERT_EVENT(XIDeviceEvent, update, dpy, GenericEvent, xi2_opcode, XI_TouchUpdate);
- EXPECT_APPROX(update->root_x, x_expect);
- EXPECT_APPROX(update->root_y, y_expect);
- }
-
- /* y movement */
- for (int i = 30; i < 75; i += 5) {
- double ypos = i/100.0;
- double x_expect = 0, y_expect = 0;
-
- TouchUpdate(devw * 0.25, devh * ypos);
-
- switch(dir) {
- case NONE:
- x_expect = w * 0.25;
- y_expect = h * ypos;
- break;
- case CW:
- x_expect = w * (1 - ypos);
- y_expect = h * 0.25;
- break;
- case CCW:
- x_expect = w * ypos;
- y_expect = h * 0.75;
- break;
- case INVERT:
- x_expect = w * 0.75;
- y_expect = h * (1 - ypos);
- break;
- default:
- FAIL();
- }
-
- ASSERT_EVENT(XIDeviceEvent, update, dpy, GenericEvent, xi2_opcode, XI_TouchUpdate);
- EXPECT_APPROX(update->root_x, x_expect);
- EXPECT_APPROX(update->root_y, y_expect);
- }
-
- TouchEnd();
-}
-INSTANTIATE_TEST_CASE_P(, EvdevTouchRotationTest,
- ::testing::Combine(
- ::testing::Values(PROPERTY, XORG_CONF),
- ::testing::Values(NONE, CW, CCW, INVERT)));
-
-
-class EvdevAxisLabelTest : public XITServerInputTest,
- public DeviceInterface {
-public:
- virtual void SetUpConfigAndLog() {
- config.AddDefaultScreenWithDriver();
- config.SetAutoAddDevices(true);
- config.WriteConfig();
- }
-
- std::vector<Atom> GetAxisLabels(::Display *dpy, int deviceid) {
- int ndevices = 0;
- XIDeviceInfo *info = XIQueryDevice(dpy, deviceid, &ndevices);
-
- EXPECT_EQ(ndevices, 1);
-
- std::vector<Atom> atoms;
-
- for (int i = 0; info && i < info->num_classes; i++) {
- if (info->classes[i]->type != XIValuatorClass)
- continue;
-
- XIValuatorClassInfo *v = reinterpret_cast<XIValuatorClassInfo*>(info->classes[i]);
- atoms.push_back(v->label);
- }
-
- return atoms;
- }
-
- std::vector<Atom> GetAtoms(::Display *dpy, std::vector<std::string> names) {
- std::vector<Atom> atoms;
-
- std::vector<std::string>::const_iterator it = names.begin();
- while(it != names.end()) {
- Atom a = XInternAtom(dpy, it->c_str(), True);
- EXPECT_NE(a, (Atom)None) << "for label " << *it;
- atoms.push_back(a);
- it++;
- }
-
- return atoms;
- }
-
- void SetUpDevice(::Display *dpy,
- const std::string &recordings_file,
- const std::string name,
- int *deviceid) {
- *deviceid = -1;
- SetDevice(recordings_file);
- ASSERT_TRUE(WaitForDevice(name, 10000));
- ASSERT_EQ(1, FindInputDeviceByName(dpy, name, deviceid));
- ASSERT_NE(*deviceid, -1);
- }
-
- void CompareLabels(::Display *dpy, int deviceid, const char *axislabels[])
- {
- std::vector<std::string> strs;
- const char **l = axislabels;
-
- while(*l) {
- strs.push_back(*l);
- l++;
- }
-
- std::vector<Atom> expected_labels = GetAtoms(dpy, strs);
- std::vector<Atom> labels = GetAxisLabels(dpy, deviceid);
-
- ASSERT_EQ(labels.size(), expected_labels.size());
-
- std::vector<Atom>::const_iterator label = labels.begin();
- std::vector<Atom>::const_iterator expected = expected_labels.begin();
-
- while (label != labels.end()) {
- ASSERT_EQ(*label, *expected);
- label++;
- expected++;
- }
- }
-};
-
-TEST_F(EvdevAxisLabelTest, RelativeAxes)
-{
- ::Display *dpy = Display();
- int deviceid;
-
- SetUpDevice(dpy, "mice/PIXART-USB-OPTICAL-MOUSE.desc", "PIXART USB OPTICAL MOUSE", &deviceid);
- ASSERT_NE(deviceid, 0);
-
- const char *l[] = {"Rel X", "Rel Y", "Rel Vert Wheel", NULL};
-
- CompareLabels(dpy, deviceid, l);
-
-}
-
-TEST_F(EvdevAxisLabelTest, AbsoluteAxes)
-{
- ::Display *dpy = Display();
- int deviceid;
-
- SetUpDevice(dpy, "tablets/N-Trig-MultiTouch.desc", "N-Trig MultiTouch", &deviceid);
- ASSERT_NE(deviceid, 0);
-
- const char *l[] = {"Abs MT Position X", "Abs MT Position Y", "Abs Misc",
- "Abs MT Touch Major", "Abs MT Touch Minor", "Abs MT Orientation", NULL};
-
- CompareLabels(dpy, deviceid, l);
-}
-
-TEST_F(EvdevAxisLabelTest, RelAndAbsoluteAxes)
-{
- ::Display *dpy = Display();
- int deviceid;
-
- SetUpDevice(dpy, "tablets/QEMU-0.12.1-QEMU-USB-Tablet.desc", "QEMU 0.12.1 QEMU USB Tablet", &deviceid);
- ASSERT_NE(deviceid, 0);
-
- const char *l[] = {"Abs X", "Abs Y", "Rel Vert Wheel", NULL};
-
- CompareLabels(dpy, deviceid, l);
-}
-
-class EvdevQEMUTabletTest : public EvdevMouseTest {
-public:
- void SetUp(void) {
- SetDevice("tablets/QEMU-0.12.1-QEMU-USB-Tablet.desc");
- XITServerInputTest::SetUp();
- }
-};
-TEST_F(EvdevQEMUTabletTest, HasScrollingAxes) {
- XORG_TESTCASE("Create QEMU virtual tablet device.\n"
- "Ensure scrolling axes are present.\n");
-
- ::Display* dpy = Display();
-
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(dpy, "--device--", &deviceid), 1);
-
- int ndevices;
- XIDeviceInfo *info = XIQueryDevice(dpy, deviceid, &ndevices);
- ASSERT_EQ(ndevices, 1);
-
- bool scroll_found = false;
- for (int i = 0; i < info->num_classes; i++) {
- if (info->classes[i]->type != XIScrollClass)
- continue;
-
- scroll_found = true;
- XIScrollClassInfo *scroll = reinterpret_cast<XIScrollClassInfo*>(info->classes[i]);
- ASSERT_EQ(scroll->scroll_type, XIScrollTypeVertical);
- }
-
- ASSERT_TRUE(scroll_found);
-}
-
-TEST_F(EvdevQEMUTabletTest, SmoothScrollingWorks) {
- XORG_TESTCASE("Create QEMU virtual tablet device.\n"
- "Send scroll wheel events.\n"
- "Verify smooth scroll events are received on the right valuator\n"
- "https://bugs.freedesktop.org/show_bug.cgi?id=54387");
-
- ::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);
-
- dev->PlayOne(EV_REL, REL_WHEEL, -1, true);
-
- ASSERT_EVENT(XIDeviceEvent, down, dpy, GenericEvent, xi2_opcode, XI_Motion);
- ASSERT_EQ(down->valuators.mask[0], 1 << 2); /* only scroll valuator moved */
- ASSERT_EQ(down->valuators.values[0], -1.0);
-
- dev->PlayOne(EV_REL, REL_WHEEL, 1, true);
- ASSERT_EVENT(XIDeviceEvent, up, dpy, GenericEvent, xi2_opcode, XI_Motion);
- ASSERT_EQ(up->valuators.mask[0], 1 << 2); /* only scroll valuator moved */
- ASSERT_EQ(up->valuators.values[0], 0);
-}
-
-TEST_F(EvdevQEMUTabletTest, HasAbsoluteAxes) {
- XORG_TESTCASE("Create QEMU virtual tablet device.\n"
- "Ensure abs x and y axes are present.\n");
-
- ::Display* dpy = Display();
-
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(dpy, "--device--", &deviceid), 1);
-
- int ndevices;
- XIDeviceInfo *info = XIQueryDevice(dpy, deviceid, &ndevices);
- ASSERT_EQ(ndevices, 1);
-
- bool x_found, y_found = false;
- int naxes = 0;
- for (int i = 0; i < info->num_classes; i++) {
- if (info->classes[i]->type != XIValuatorClass)
- continue;
-
- naxes++;
-
- XIValuatorClassInfo *v = reinterpret_cast<XIValuatorClassInfo*>(info->classes[i]);
- if (v->number < 2) {
- ASSERT_EQ(v->mode, Absolute);
- ASSERT_EQ(v->min, 0);
- ASSERT_EQ(v->max, 0x7FFF);
-
- if (v->number == 0) {
- x_found = true;
- ASSERT_EQ(v->label, XInternAtom(dpy, "Abs X", True));
- } else if (v->number == 1) {
- y_found = true;
- ASSERT_EQ(v->label, XInternAtom(dpy, "Abs Y", True));
- }
- }
- }
-
- ASSERT_TRUE(x_found);
- ASSERT_TRUE(y_found);
-}
-
-TEST_F(EvdevQEMUTabletTest, AbsoluteAxesWork) {
- ::Display* dpy = Display();
-
- XSelectInput(dpy, DefaultRootWindow(dpy), PointerMotionMask);
-
- int w = DisplayWidth(dpy, DefaultScreen(dpy));
- int h = DisplayHeight(dpy, DefaultScreen(dpy));
-
- int coords[][4] = {
- { 0x7FFF, 0x7FFF/2, w - 1, (h - 1)/2 },
- { 0x0, 0x0, 0, 0 },
- { 0x7FFF/2, 0x0, (w - 1)/2, 0},
- { 0x7FFF, 0x7FFF/2, w - 1, (h - 1)/2 },
- { 0x7FFF, 0x7FFF, w - 1, h - 1 },
- { -1, -1, -1, -1}
- };
-
- int i = 0;
- while (coords[i][0] != -1) {
- dev->PlayOne(EV_ABS, ABS_X, coords[i][0]);
- dev->PlayOne(EV_ABS, ABS_Y, coords[i][1], true);
- ASSERT_EVENT(XEvent, ev, dpy, MotionNotify);
- ASSERT_EQ(ev->xmotion.x_root, coords[i][2]);
- ASSERT_EQ(ev->xmotion.y_root, coords[i][3]);
- i++;
- }
-}
-
-TEST_F(EvdevQEMUTabletTest, ScrollingWorks) {
- XORG_TESTCASE("Create QEMU virtual tablet device.\n"
- "Send scroll wheel events.\n"
- "Verify legacy scroll button events are received\n"
- "https://bugs.freedesktop.org/show_bug.cgi?id=54387");
-
- ::Display* dpy = Display();
-
- XSelectInput(dpy, DefaultRootWindow(dpy), ButtonPressMask|ButtonReleaseMask);
-
- dev->PlayOne(EV_REL, REL_WHEEL, -1, true);
-
- ASSERT_EVENT(XEvent, down_press, dpy, ButtonPress);
- ASSERT_EQ(down_press->xbutton.button, 5U);
- ASSERT_EVENT(XEvent, down_release, dpy, ButtonRelease);
- ASSERT_EQ(down_press->xbutton.button, 5U);
-
- dev->PlayOne(EV_REL, REL_WHEEL, 1, true);
- ASSERT_EVENT(XEvent, up_press, dpy, ButtonPress);
- ASSERT_EQ(up_press->xbutton.button, 4U);
- ASSERT_EVENT(XEvent, up_release, dpy, ButtonRelease);
- ASSERT_EQ(up_press->xbutton.button, 4U);
-}
-
-class EvdevTouchpadTest : public XITServerInputTest,
- public DeviceInterface {
-public:
- /**
- * Initializes a standard mouse device with two wheels.
- */
- virtual void SetUp() {
- SetDevice("touchpads/SynPS2-Synaptics-TouchPad.desc");
- XITServerInputTest::SetUp();
- }
-
- /**
- * Sets up an xorg.conf for a single evdev CorePointer device based on
- * the evemu device.
- */
- virtual void SetUpConfigAndLog() {
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("evdev", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"GrabDevice\" \"on\""
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"");
- /* add default keyboard device to avoid server adding our device again */
- config.AddInputSection("kbd", "keyboard-device",
- "Option \"CoreKeyboard\" \"on\"\n");
- config.WriteConfig();
- }
-};
-
-TEST_F(EvdevTouchpadTest, DeviceExists)
-{
- ASSERT_TRUE(FindInputDeviceByName(Display(), "--device--"));
-}
-
-TEST_F(EvdevTouchpadTest, AxisLabels)
-{
- XORG_TESTCASE("Create evdev touchpad.\n"
- "Verify axis label property is as expected\n");
-
- ::Display *dpy = Display();
- const std::string propname = "Axis Labels";
-
- int deviceid;
- ASSERT_TRUE(FindInputDeviceByName(Display(), "--device--", &deviceid));
-
-
- ASSERT_PROPERTY(Atom, labels, dpy, deviceid, propname);
- ASSERT_EQ(labels.nitems, 4U);
- ASSERT_EQ(labels.data[0], XInternAtom(dpy, "Abs X", True));
- ASSERT_EQ(labels.data[1], XInternAtom(dpy, "Abs Y", True));
- ASSERT_EQ(labels.data[2], XInternAtom(dpy, "Abs Pressure", True));
- ASSERT_EQ(labels.data[3], XInternAtom(dpy, "Abs Tool Width", True));
-}
-
-TEST_F(EvdevTouchpadTest, PointerMovement)
-{
- ::Display *dpy = Display();
- XSelectInput(dpy, DefaultRootWindow(dpy), PointerMotionMask);
-
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-move.events");
-
- XSync(dpy, False);
- ASSERT_GT(XPending(dpy), 0);
- while (XPending(dpy) > 0) {
- ASSERT_EVENT(XEvent, motion, dpy, MotionNotify);
- }
-}
-
-class EvdevAbsXMissingTest : public XITServerInputTest,
- public DeviceInterface
-{
-public:
- virtual void SetUp() {
- SetDevice("tablets/n4.desc");
-
- xi2_major_minimum = 2;
- xi2_minor_minimum = 2;
-
- XITServerInputTest::SetUp();
- }
-
- virtual void SetUpConfigAndLog() {
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("evdev", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"GrabDevice\" \"on\""
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"");
- /* add default keyboard device to avoid server adding our device again */
- config.AddInputSection("kbd", "keyboard-device",
- "Option \"CoreKeyboard\" \"on\"\n");
- config.WriteConfig();
- }
-};
-
-TEST_F(EvdevAbsXMissingTest, DevicePresent)
-{
- XORG_TESTCASE("Create device with ABS_MT_POSITION_X but no ABS_X\n"
- "Driver must not crash\n"
- "https://bugs.freedesktop.org/show_bug.cgi?id=64029");
-
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--"), 1);
-
- dev->Play(RECORDINGS_DIR "tablets/n4.events");
-}
-
-class EvdevDuplicateTest : public EvdevMouseTest {
- virtual void SetUpConfigAndLog() {
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("evdev", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"GrabDevice\" \"on\""
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"");
- /* add default keyboard device to avoid server adding our device again */
- config.AddInputSection("kbd", "keyboard-device",
- "Option \"CoreKeyboard\" \"on\"\n");
- config.SetAutoAddDevices(true);
- config.WriteConfig();
- }
-};
-
-TEST_F(EvdevDuplicateTest, TooManyDevices)
-{
- XORG_TESTCASE("Create more than MAXDEVICES evdev devices\n"
- "Server must not crash\n");
-
- const int NDEVICES = 50;
- std::unique_ptr<xorg::testing::evemu::Device> devices[NDEVICES];
- for (int i = 0; i < NDEVICES; i++) {
- devices[i] = std::unique_ptr<xorg::testing::evemu::Device>(
- new xorg::testing::evemu::Device(RECORDINGS_DIR "mice/PIXART-USB-OPTICAL-MOUSE.desc")
- );
- }
-
- /* expect at least two hotplugged, but the actual number depends on the
- local number of devices */
- int deviceid;
- ASSERT_GT(FindInputDeviceByName(Display(), "PIXART USB OPTICAL MOUSE", &deviceid), 2);
-}
-
-TEST_F(EvdevDuplicateTest, DuplicateDeviceCheck)
-{
- XORG_TESTCASE("Add a device through the xorg.conf and hotplugging\n"
- "Expect it to be added only once\n");
-
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(Display(), "PIXART USB OPTICAL MOUSE", &deviceid), 0);
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1);
-
- std::ifstream logfile(server.GetLogFilePath().c_str());
- std::string line;
- std::string dup_warn("device file is duplicate. Ignoring.");
- bool found = false;
- ASSERT_TRUE(logfile.is_open());
- while(!found && getline(logfile, line))
- found = line.find(dup_warn);
-
- ASSERT_TRUE(found) << "Expected message '" << dup_warn << "' in the log "
- << "but couldn't find it";
-}
-
-class EvdevDialTest : public EvdevMouseTest {
-public:
- virtual void SetUp() {
- SetDevice("mice/Microsoft-Microsoft®-2.4GHz-Transceiver-V2.0.desc");
- XITServerInputTest::SetUp();
- }
-};
-
-TEST_F(EvdevDialTest, HorizScrolling)
-{
- XORG_TESTCASE("Add a device with REL_DIAL\n"
- "Send REL_DIAL events\n"
- "Expect horizontal scroll events\n"
- "https://bugs.freedesktop.org/show_bug.cgi?id=73105");
-
- ::Display *dpy = Display();
- XSelectInput(dpy, DefaultRootWindow(dpy), ButtonPressMask | ButtonReleaseMask);
-
- dev->PlayOne(EV_REL, REL_DIAL, -1, true);
-
- ASSERT_EVENT(XEvent, left_press, dpy, ButtonPress);
- ASSERT_EQ(left_press->xbutton.button, 6U);
- ASSERT_EVENT(XEvent, left_release, dpy, ButtonRelease);
- ASSERT_EQ(left_release->xbutton.button, 6U);
-
- dev->PlayOne(EV_REL, REL_DIAL, 1, true);
-
- ASSERT_EVENT(XEvent, right_press, dpy, ButtonPress);
- ASSERT_EQ(right_press->xbutton.button, 7U);
- ASSERT_EVENT(XEvent, right_release, dpy, ButtonRelease);
- ASSERT_EQ(right_release->xbutton.button, 7U);
-}
-
-class EvdevXenPointerTest : public EvdevMouseTest {
-public:
- virtual void SetUp() {
- SetDevice("mice/Xen-Virtual-Pointer.desc");
- XITServerInputTest::SetUp();
- }
-
- virtual void SetUpConfigAndLog() {
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("evdev", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"GrabDevice\" \"on\""
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\""
- "Option \"IgnoreAbsoluteAxes\" \"off\"\n"
- "Option \"IgnoreRelativeAxes\" \"off\"\n");
- config.WriteConfig();
- }
-};
-
-TEST_F(EvdevXenPointerTest, AbsAxesInitialized)
-{
- XORG_TESTCASE("Add a Xen Virtual Pointer\n"
- "Search the log file for successful abs axes init\n");
-
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--"), 1);
- SearchFileForString(server.GetLogFilePath(),
- "Xen Virtual Pointer: initialized for absolute axes");
-}
-
-TEST_F(EvdevXenPointerTest, RelAxesInitialized)
-{
- XORG_TESTCASE("Add a Xen Virtual Pointer\n"
- "Search the log file for successful rel axes init\n");
-
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--"), 1);
- SearchFileForString(server.GetLogFilePath(),
- "Xen Virtual Pointer: initialized for relative axes");
-}
-
-TEST_F(EvdevXenPointerTest, AbsAxisEvent)
-{
- XORG_TESTCASE("Add a Xen Virtual Pointer\n"
- "Move the pointer through absolute axes\n"
- "Check the pointer moves\n");
-
- ::Display *dpy = Display();
- double x, y;
-
- ASSERT_EQ(FindInputDeviceByName(dpy, "--device--"), 1);
-
- QueryPointerPosition(dpy, &x, &y, VIRTUAL_CORE_POINTER_ID);
-
- XSelectInput(dpy, DefaultRootWindow(dpy), PointerMotionMask);
-
- dev->PlayOne(EV_ABS, ABS_X, 700);
- dev->PlayOne(EV_SYN, SYN_REPORT, 0);
- dev->PlayOne(EV_ABS, ABS_Y, 500);
- dev->PlayOne(EV_SYN, SYN_REPORT, 0);
-
- XSync(dpy, False);
- ASSERT_GE(XPending(dpy), 2);
-
-
- XEvent ev;
- XNextEvent(dpy, &ev);
- ASSERT_EQ(ev.xmotion.type, MotionNotify);
- ASSERT_GE(ev.xmotion.x_root, x);
- ASSERT_EQ(ev.xmotion.y_root, y);
- x = ev.xmotion.x_root;
-
- XNextEvent(dpy, &ev);
- ASSERT_EQ(ev.xmotion.type, MotionNotify);
- ASSERT_EQ(ev.xmotion.x_root, x);
- ASSERT_GE(ev.xmotion.x_root, y);
-}
-
-TEST_F(EvdevXenPointerTest, ScrollEvent)
-{
- XORG_TESTCASE("Add a Xen Virtual Pointer\n"
- "Generate a scroll event\n"
- "Check a scroll event is sent\n");
-
- ::Display *dpy = Display();
- XSelectInput(dpy, DefaultRootWindow(dpy), ButtonPressMask|ButtonReleaseMask);
-
- ASSERT_EQ(FindInputDeviceByName(dpy, "--device--"), 1);
-
- scroll_wheel_event(dpy, dev.get(), REL_WHEEL, 1, 4);
- scroll_wheel_event(dpy, dev.get(), REL_WHEEL, 2, 4);
- scroll_wheel_event(dpy, dev.get(), REL_WHEEL, -1, 5);
- scroll_wheel_event(dpy, dev.get(), REL_WHEEL, -2, 5);
-}
-
-enum EvdevMixedDeviceTestIgoreOptions {
- IGNORE_NONE,
- IGNORE_REL,
- IGNORE_ABS,
- IGNORE_BOTH,
- UNIGNORE_REL,
- UNIGNORE_ABS,
- UNIGNORE_BOTH
-};
-
-class EvdevMixedDeviceTest : public XITServerInputTest,
- public ::testing::WithParamInterface<enum EvdevMixedDeviceTestIgoreOptions>
-{
-public:
- virtual void SetUpConfigAndLog() {
- std::string ignore = "";
- enum EvdevMixedDeviceTestIgoreOptions ign = GetParam();
-
- switch(ign) {
- case IGNORE_NONE:
- break;
- case IGNORE_REL:
- ignore = "Option \"IgnoreRelativeAxes\" \"on\"";
- break;
- case IGNORE_ABS:
- ignore = "Option \"IgnoreAbsoluteAxes\" \"on\"";
- break;
- case IGNORE_BOTH:
- ignore = "Option \"IgnoreRelativeAxes\" \"on\"\n"
- "Option \"IgnoreAbsoluteAxes\" \"on\"";
- break;
- case UNIGNORE_REL:
- ignore = "Option \"IgnoreRelativeAxes\" \"off\"";
- break;
- case UNIGNORE_ABS:
- ignore = "Option \"IgnoreAbsoluteAxes\" \"off\"";
- break;
- case UNIGNORE_BOTH:
- ignore = "Option \"IgnoreRelativeAxes\" \"off\"\n"
- "Option \"IgnoreAbsoluteAxes\" \"off\"";
- break;
- }
-
- config.AddDefaultScreenWithDriver();
- config.AddInputClass("grab device",
- "MatchDevicePath \"/dev/input/event*\"",
- "Driver \"evdev\"" + ignore +
- "Option \"Emulate3Buttons\" \"off\""
- "Option \"GrabDevice\" \"on\"");
- config.SetAutoAddDevices(true);
- config.WriteConfig();
- }
-
- void CreateDevice(const std::string &name, ...) {
- int rc;
- int type, code;
- struct input_absinfo *absinfo;
- va_list args;
-
- evdev = libevdev_new();
- ASSERT_TRUE(evdev != NULL);
-
- libevdev_set_name(evdev, name.c_str());
-
- va_start(args, name);
- while(1) {
- type = va_arg(args, int);
- if (type == -1)
- break;
- code = va_arg(args, int);
- if (code == -1)
- break;
- absinfo = va_arg(args, struct input_absinfo*);
-
- libevdev_enable_event_code(evdev, type, code, absinfo);
- }
- va_end(args);
-
- rc = libevdev_uinput_create_from_device(evdev,
- LIBEVDEV_UINPUT_OPEN_MANAGED,
- &uinput);
- ASSERT_EQ(rc, 0);
- }
-
- ~EvdevMixedDeviceTest() {
- libevdev_uinput_destroy(uinput);
- libevdev_free(evdev);
- }
-
-protected:
- struct libevdev_uinput *uinput;
- struct libevdev *evdev;
-};
-
-TEST_P(EvdevMixedDeviceTest, RelScrollOnly)
-{
- XORG_TESTCASE("Add a device with only REL_WHEEL\n");
-
- const std::string name = "scroll only device";
-
- CreateDevice(name,
- EV_REL, REL_WHEEL, NULL,
- -1);
-
- ASSERT_TRUE(WaitForDevice(name, 2000));
- ::Display *dpy = Display();
- XSelectInput(dpy, DefaultRootWindow(dpy), ButtonPressMask);
-
- libevdev_uinput_write_event(uinput, EV_REL, REL_WHEEL, 1);
- libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
- libevdev_uinput_write_event(uinput, EV_REL, REL_WHEEL, -1);
- libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
-
- XSync(dpy, False);
-
- /* Mouse wheels are excempt, so we expect those to work for any
- combination of options */
- ASSERT_EVENT(XEvent, down, dpy, ButtonPress);
- ASSERT_EQ(down->xbutton.button, 4U);
- ASSERT_EVENT(XEvent, up, dpy, ButtonPress);
- ASSERT_EQ(up->xbutton.button, 5U);
-}
-
-TEST_P(EvdevMixedDeviceTest, AbsAndRelAxes)
-{
- XORG_TESTCASE("Add a device with abs and rel axes\n"
- "Test for events depending on Ignore*Axis settings\n");
-
- struct input_absinfo absinfo = { 0 };
-
- const std::string name = "abs and rel only device";
-
- absinfo.maximum = 100;
- /* give it a button so it still comes up even with both axis types ignored */
- CreateDevice(name,
- EV_KEY, BTN_LEFT, (struct input_absinfo*)NULL, /* RHEL6 sizeof(NULL) != sizeof(void*) */
- EV_REL, REL_X, (struct input_absinfo*)NULL,
- EV_REL, REL_Y, (struct input_absinfo*)NULL,
- EV_ABS, ABS_X, &absinfo,
- EV_ABS, ABS_Y, &absinfo,
- -1);
-
- ASSERT_TRUE(WaitForDevice(name, 2000));
- ::Display *dpy = Display();
- XSelectInput(dpy, DefaultRootWindow(dpy), PointerMotionMask);
-
- libevdev_uinput_write_event(uinput, EV_REL, REL_X, 1);
- libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
-
- XSync(dpy, False);
-
- switch(GetParam()) {
- case IGNORE_NONE:
- case IGNORE_ABS:
- case UNIGNORE_REL:
- case UNIGNORE_ABS:
- case UNIGNORE_BOTH:
- {
- ASSERT_EVENT(XEvent, motion, dpy, MotionNotify);
- }
- break;
- case IGNORE_REL:
- case IGNORE_BOTH:
- break;
- }
-
- ASSERT_TRUE(NoEventPending(dpy));
-
- libevdev_uinput_write_event(uinput, EV_ABS, ABS_X, 30);
- libevdev_uinput_write_event(uinput, EV_ABS, ABS_Y, 70);
- libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
-
- XSync(dpy, False);
-
- switch(GetParam()) {
- case IGNORE_NONE:
- case IGNORE_ABS:
- case IGNORE_BOTH:
- case UNIGNORE_REL:
- break;
- case IGNORE_REL:
- case UNIGNORE_ABS:
- case UNIGNORE_BOTH:
- {
- ASSERT_EVENT(XEvent, motion, dpy, MotionNotify);
- }
- break;
- }
-
- ASSERT_TRUE(NoEventPending(dpy));
-}
-
-TEST_P(EvdevMixedDeviceTest, AbsXYAndRelScroll)
-{
- XORG_TESTCASE("Add a device with Abs x/y and REL_WHEEL\n");
-
- struct input_absinfo absinfo = { 0 };
-
- const std::string name = "abs + scroll device";
-
- absinfo.maximum = 100;
- /* only abs x/y and wheel confuses evdev, add a button so it looks like
- an absolute mouse */
- CreateDevice(name,
- EV_KEY, BTN_LEFT, NULL,
- EV_REL, REL_WHEEL, NULL,
- EV_ABS, ABS_X, &absinfo,
- EV_ABS, ABS_Y, &absinfo,
- -1);
-
- ASSERT_TRUE(WaitForDevice(name, 2000));
-
- ::Display *dpy = Display();
- XSelectInput(dpy, DefaultRootWindow(dpy), ButtonPressMask|PointerMotionMask);
-
- libevdev_uinput_write_event(uinput, EV_REL, REL_WHEEL, 1);
- libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
- libevdev_uinput_write_event(uinput, EV_REL, REL_WHEEL, -1);
- libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
-
- XSync(dpy, False);
-
- ASSERT_EVENT(XEvent, down, dpy, ButtonPress);
- ASSERT_EQ(down->xbutton.button, 4U);
- ASSERT_EVENT(XEvent, up, dpy, ButtonPress);
- ASSERT_EQ(up->xbutton.button, 5U);
-
- ASSERT_TRUE(NoEventPending(dpy));
-
- double x, y;
- QueryPointerPosition(dpy, &x, &y, VIRTUAL_CORE_POINTER_ID);
-
- libevdev_uinput_write_event(uinput, EV_ABS, ABS_X, 70);
- libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
- libevdev_uinput_write_event(uinput, EV_ABS, ABS_Y, 70);
- libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0);
-
- XSync(dpy, False);
-
- switch(GetParam()) {
- case IGNORE_ABS:
- case IGNORE_BOTH:
- break;
- case IGNORE_NONE:
- case IGNORE_REL:
- case UNIGNORE_ABS:
- case UNIGNORE_REL:
- case UNIGNORE_BOTH:
- {
- ASSERT_EVENT(XEvent, xev, dpy, MotionNotify);
- ASSERT_GE(xev->xmotion.x_root, x);
- ASSERT_EVENT(XEvent, yev, dpy, MotionNotify);
- ASSERT_GE(yev->xmotion.y_root, y);
- }
- break;
- }
-
- ASSERT_TRUE(NoEventPending(dpy));
-}
-
-INSTANTIATE_TEST_CASE_P(, EvdevMixedDeviceTest, ::testing::Values(IGNORE_NONE,
- IGNORE_REL,
- IGNORE_ABS,
- IGNORE_BOTH,
- UNIGNORE_REL,
- UNIGNORE_ABS,
- UNIGNORE_BOTH));
-
-class EvdevFakeMTTest : public XITServerInputTest,
- public DeviceInterface {
-public:
- virtual void SetUp() {
- SetDevice("misc/Logitech-Logitech-Wireless-Headset.desc");
- XITServerInputTest::SetUp();
- }
-
- virtual void SetUpConfigAndLog() {
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("evdev", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"GrabDevice\" \"on\""
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"");
- /* add default keyboard device to avoid server adding our device again */
- config.AddInputSection("kbd", "keyboard-device",
- "Option \"CoreKeyboard\" \"on\"\n");
- config.WriteConfig();
- }
-};
-
-TEST_F(EvdevFakeMTTest, KeyEvents)
-{
- const int scancodes[] = {
- KEY_MUTE,
- KEY_VOLUMEDOWN,
- KEY_VOLUMEUP,
- KEY_PAUSE,
- KEY_NEXTSONG,
- KEY_PLAYPAUSE,
- KEY_PREVIOUSSONG,
- KEY_STOPCD,
- KEY_REWIND,
- KEY_PLAY,
- KEY_FASTFORWARD,
- -1
- };
-
- ::Display *dpy = Display();
- XSelectInput(dpy, DefaultRootWindow(Display()), KeyPressMask | KeyReleaseMask);
-
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--"), 1) << "Failed to find device.";
-
- const int *scancode = scancodes;
- while (*scancode != -1) {
- dev->PlayOne(EV_KEY, *scancode, 0, true);
- dev->PlayOne(EV_KEY, *scancode, 1, true);
- ASSERT_TRUE(xorg::testing::XServer::WaitForEventOfType(dpy, KeyPress));
- ASSERT_TRUE(xorg::testing::XServer::WaitForEventOfType(dpy, KeyRelease));
- scancode++;
- }
-}
-
-TEST_F(EvdevFakeMTTest, AxisEvents)
-{
- ::Display *dpy = Display();
-
- int ndevices, deviceid;
-
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1) << "Failed to find device.";
- XIDeviceInfo *info = XIQueryDevice(dpy, deviceid, &ndevices);
- ASSERT_EQ(ndevices, 1);
-
- int nvaluators = 0;
- for (int i = 0; i < info->num_classes; i++) {
- XIAnyClassInfo *any = info->classes[i];
- if (any->type == XIValuatorClass)
- nvaluators++;
- }
-
- ASSERT_EQ(nvaluators, 23);
-
- SelectXI2Events(dpy, deviceid, DefaultRootWindow(dpy), XI_Motion, -1);
-
- for (int code = ABS_MISC; code <= ABS_MAX; code++) {
- dev->PlayOne(EV_ABS, code, 0, true);
- dev->PlayOne(EV_ABS, code, 50, true);
- dev->PlayOne(EV_ABS, code, 100, true);
- std::cout << code << std::endl;
- if (code != ABS_MT_SLOT && code != ABS_MT_TRACKING_ID) {
- ASSERT_TRUE(xorg::testing::XServer::WaitForEventOfType(dpy,
- GenericEvent,
- xi2_opcode,
- XI_Motion));
- }
- XSync(dpy, True);
- }
-}
-
-int main(int argc, char **argv) {
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/tests/input/kbd.cpp b/tests/input/kbd.cpp
deleted file mode 100644
index 4cac8b3..0000000
--- a/tests/input/kbd.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright © 2012-2013 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- */
-
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdexcept>
-#include <map>
-#include <xorg/gtest/xorg-gtest.h>
-#include <linux/input.h>
-
-#include <X11/Xlib.h>
-#define XK_LATIN1
-#include <X11/keysymdef.h>
-#include <X11/XF86keysym.h>
-#include <X11/Xutil.h>
-#include <X11/extensions/XInput.h>
-#include <X11/extensions/XInput2.h>
-
-#include "xit-server-input-test.h"
-#include "xit-event.h"
-#include "device-interface.h"
-#include "helpers.h"
-
-typedef std::pair <int, KeySym> Key_Pair;
-typedef std::multimap<std::string, Key_Pair> Keys_Map;
-typedef Keys_Map::iterator keys_mapIter;
-typedef std::vector<Key_Pair> MultiMedia_Keys_Map;
-typedef MultiMedia_Keys_Map::iterator multimediakeys_mapIter;
-
-/**
- * Keyboard driver test. This class takes a string as parameter that is used
- * for the XkbLayout option.
- */
-class KeyboardTest : public XITServerInputTest,
- public DeviceInterface {
-public:
- virtual void SetUp() {
- SetDevice("keyboards/AT-Translated-Set-2-Keyboard.desc");
- XITServerInputTest::SetUp();
- }
-
- virtual void SetUpConfigAndLog() {
-
- /* we don't use the dummy driver here, for some reason we won't get
- * key events with it */
- config.AddInputSection("kbd", "--device--",
- "Option \"CoreKeyboard\" \"on\"\n");
- config.WriteConfig();
- }
-
-
-};
-
-TEST_F(KeyboardTest, DeviceExists)
-{
- ASSERT_TRUE(FindInputDeviceByName(Display(), "--device--"));
-}
-
-class KeyboardLayoutTest : public KeyboardTest,
- public ::testing::WithParamInterface<std::string> {
- /**
- * Initializes a standard keyboard device.
- */
- virtual void SetUp() {
- KeyboardTest::SetUp();
-
- // Define a map of pair to hold each key/keysym per layout
- // US, QWERTY => qwerty
- Keys.insert (std::pair<std::string, Key_Pair> ("us", Key_Pair (KEY_Q, XK_q)));
- Keys.insert (std::pair<std::string, Key_Pair> ("us", Key_Pair (KEY_W, XK_w)));
- Keys.insert (std::pair<std::string, Key_Pair> ("us", Key_Pair (KEY_E, XK_e)));
- Keys.insert (std::pair<std::string, Key_Pair> ("us", Key_Pair (KEY_R, XK_r)));
- Keys.insert (std::pair<std::string, Key_Pair> ("us", Key_Pair (KEY_T, XK_t)));
- Keys.insert (std::pair<std::string, Key_Pair> ("us", Key_Pair (KEY_Y, XK_y)));
- // German, QWERTY => qwertz
- Keys.insert (std::pair<std::string, Key_Pair> ("de", Key_Pair (KEY_Q, XK_q)));
- Keys.insert (std::pair<std::string, Key_Pair> ("de", Key_Pair (KEY_W, XK_w)));
- Keys.insert (std::pair<std::string, Key_Pair> ("de", Key_Pair (KEY_E, XK_e)));
- Keys.insert (std::pair<std::string, Key_Pair> ("de", Key_Pair (KEY_R, XK_r)));
- Keys.insert (std::pair<std::string, Key_Pair> ("de", Key_Pair (KEY_T, XK_t)));
- Keys.insert (std::pair<std::string, Key_Pair> ("de", Key_Pair (KEY_Y, XK_z)));
- // French, QWERTY => azerty
- Keys.insert (std::pair<std::string, Key_Pair> ("fr", Key_Pair (KEY_Q, XK_a)));
- Keys.insert (std::pair<std::string, Key_Pair> ("fr", Key_Pair (KEY_W, XK_z)));
- Keys.insert (std::pair<std::string, Key_Pair> ("fr", Key_Pair (KEY_E, XK_e)));
- Keys.insert (std::pair<std::string, Key_Pair> ("fr", Key_Pair (KEY_R, XK_r)));
- Keys.insert (std::pair<std::string, Key_Pair> ("fr", Key_Pair (KEY_T, XK_t)));
- Keys.insert (std::pair<std::string, Key_Pair> ("fr", Key_Pair (KEY_Y, XK_y)));
-
- // Define a vector of pair to hold each key/keysym for multimedia
- Multimedia_Keys.push_back (Key_Pair (KEY_MUTE, XF86XK_AudioMute));
- Multimedia_Keys.push_back (Key_Pair (KEY_VOLUMEUP, XF86XK_AudioRaiseVolume));
- Multimedia_Keys.push_back (Key_Pair (KEY_VOLUMEDOWN, XF86XK_AudioLowerVolume));
- Multimedia_Keys.push_back (Key_Pair (KEY_PLAYPAUSE, XF86XK_AudioPlay));
- Multimedia_Keys.push_back (Key_Pair (KEY_NEXTSONG, XF86XK_AudioNext));
- Multimedia_Keys.push_back (Key_Pair (KEY_PREVIOUSSONG, XF86XK_AudioPrev));
- }
-
- /**
- * Sets up an xorg.conf for a single kbd CoreKeyboard device.
- * The input from GetParam() is used as XkbLayout.
- */
- virtual void SetUpConfigAndLog() {
-
- /* we don't use the dummy driver here, for some reason we won't get
- * key events with it */
- config.AddInputSection("kbd", "--device--",
- "Option \"CoreKeyboard\" \"on\"\n"
- "Option \"XkbRules\" \"xorg\"\n"
- "Option \"XkbModel\" \"dellusbmm\"\n"
- "Option \"XkbLayout\" \""+ GetParam() + "\"\n");
- config.WriteConfig();
- }
-
- protected:
- /**
- * List of evdev keysyms to X11 keysyms for each layout.
- */
- Keys_Map Keys;
-
- /**
- * List of evdev keysyms to X11 keysyms for multimedia keys
- */
- MultiMedia_Keys_Map Multimedia_Keys;
-};
-
-void play_key_pair (::Display *display, xorg::testing::evemu::Device *dev, Key_Pair pair)
-{
- dev->PlayOne(EV_KEY, pair.first, 1, true);
- dev->PlayOne(EV_KEY, pair.first, 0, true);
-
- ASSERT_EVENT(XEvent, press, display, KeyPress);
- KeySym sym = XKeycodeToKeysym(display, press->xkey.keycode, 0);
- ASSERT_NE((KeySym)NoSymbol, sym) << "No keysym for keycode " << press->xkey.keycode << std::endl;
- ASSERT_EQ(pair.second, sym) << "Keysym not matching for keycode " << press->xkey.keycode << std::endl;
-
- XSync(display, False);
- while (XPending(display))
- XSync(display, True);
-}
-
-TEST_P(KeyboardLayoutTest, KeyboardLayout)
-{
- std::string layout = GetParam();
-
- ASSERT_TRUE(WaitForDevice("--device--"));
- XSelectInput(Display(), DefaultRootWindow(Display()), KeyPressMask | KeyReleaseMask);
-
- keys_mapIter it;
- std::pair<keys_mapIter, keys_mapIter> keyRange = Keys.equal_range(layout);
- for (it = keyRange.first; it != keyRange.second; ++it)
- play_key_pair (Display(), dev.get(), (*it).second);
-
- // Now test multimedia keys
- multimediakeys_mapIter m_it;
- for (m_it = Multimedia_Keys.begin(); m_it != Multimedia_Keys.end(); m_it++)
- play_key_pair (Display(), dev.get(), (*m_it));
-}
-
-INSTANTIATE_TEST_CASE_P(, KeyboardLayoutTest, ::testing::Values("us", "de", "fr"));
-
-int main(int argc, char **argv) {
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/tests/input/legacy-drivers.cpp b/tests/input/legacy-drivers.cpp
deleted file mode 100644
index b4154c5..0000000
--- a/tests/input/legacy-drivers.cpp
+++ /dev/null
@@ -1,504 +0,0 @@
-/*
- * Copyright © 2012-2013 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- */
-
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdexcept>
-#include <fstream>
-#include <xorg/gtest/xorg-gtest.h>
-
-#include <sys/prctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <X11/Xlib.h>
-#include <X11/extensions/XInput.h>
-#include <X11/extensions/XInput2.h>
-
-#include "xit-server-input-test.h"
-#include "xit-event.h"
-#include "helpers.h"
-
-/* no implementation, this class only exists for better test names */
-class LegacyInputDriverTest : public SimpleInputDriverTest {};
-
-static int count_devices(Display *dpy) {
- int ndevices;
- XIDeviceInfo *info;
-
- info = XIQueryDevice(dpy, XIAllDevices, &ndevices);
- XIFreeDeviceInfo(info);
- return ndevices;
-}
-
-TEST_P(LegacyInputDriverTest, InputDeviceSectionSimple)
-{
- std::string param;
-
- param = GetParam();
-
- int expected_devices;
-
- /* apparently when the acecad driver is loaded neither mouse nor kbd
- * loads - probably a bug but that's current behaviour on RHEL 6.3 */
- if (param.compare("acecad") == 0)
- expected_devices = 4;
- else {
- expected_devices = 6;
- /* xserver git 1357cd7251 , no <default pointer> */
- if (server.GetVersion().compare("1.11.0") > 0)
- expected_devices--;
- }
-
- ASSERT_EQ(count_devices(Display()), expected_devices);
-
- /* No joke, they all fail. some fail for missing Device option, others
- * for not finding the device, etc. */
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--"), 0);
-}
-
-INSTANTIATE_TEST_CASE_P(, LegacyInputDriverTest,
- ::testing::Values("acecad", "aiptek", "elographics",
- "fpit", "hyperpen", "mutouch",
- "penmount"));
-
-/**
- * Void input driver test class
- */
-class VoidTest : public XITServerInputTest {
-public:
- /**
- * Initialize an xorg.conf with a single CorePointer void device.
- */
- virtual void SetUpConfigAndLog() {
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("void", "--device--", "Option \"CorePointer\" \"on\"\n");
- config.WriteConfig();
- server.SetOption("-config", config.GetPath());
- }
-};
-
-TEST_F(VoidTest, InputDeviceSectionSimple)
-{
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--"), 1);
-}
-
-
-/***********************************************************************
- * *
- * ACECAD *
- * *
- ***********************************************************************/
-TEST(AcecadTest, InputDeviceSectionWithOptionDevice)
-{
- XOrgConfig config;
- XITServer server;
-
- config.AddInputSection("acecad", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"Device\" \"/dev/input/event0\"\n");
- config.AddDefaultScreenWithDriver();
- server.Start(config);
-
- ::Display *dpy = XOpenDisplay(server.GetDisplayString().c_str());
- int major = 2;
- int minor = 0;
- ASSERT_EQ(Success, XIQueryVersion(dpy, &major, &minor));
-
- int ndevices;
- XIDeviceInfo *info;
-
- info = XIQueryDevice(dpy, XIAllDevices, &ndevices);
- XIFreeDeviceInfo(info);
-
- /* VCP, VCK, xtest, mouse, keyboard, acecad */
- int expected_devices = 7;
-
- /* xserver git 1357cd7251 , no <default pointer> */
- if (server.GetVersion().compare("1.11.0") > 0)
- expected_devices--;
-
- ASSERT_EQ(count_devices(dpy), expected_devices);
- ASSERT_EQ(FindInputDeviceByName(dpy, "--device--"), 1);
-
- config.RemoveConfig();
- server.RemoveLogFile();
-}
-
-/***********************************************************************
- * *
- * AIPTEK *
- * *
- ***********************************************************************/
-
-class AiptekTest : public XITServerInputTest,
- public ::testing::WithParamInterface<std::string> {
- virtual void SetUpConfigAndLog() {
-
- std::string type = GetParam();
-
- config.AddInputSection("aiptek", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"Device\" \"/dev/input/event0\"\n"
- "Option \"Type\" \"" + type + "\"");
- config.AddDefaultScreenWithDriver();
- config.WriteConfig();
- }
-};
-
-TEST_P(AiptekTest, InputDeviceSectionWithType)
-{
- ::Display *dpy = Display();
-
- /* VCP, VCK, xtest, mouse, keyboard, aiptek */
- int expected_devices = 7;
-
- /* xserver git 1357cd7251, no <default pointer> */
- if (server.GetVersion().compare("1.11.0") > 0)
- expected_devices--;
-
- ASSERT_EQ(count_devices(dpy), expected_devices);
- ASSERT_EQ(FindInputDeviceByName(dpy, "--device--"), 1);
-
- config.RemoveConfig();
- server.RemoveLogFile();
-}
-
-INSTANTIATE_TEST_CASE_P(, AiptekTest,
- ::testing::Values("stylus", "cursor", "eraser"));
-
-/***********************************************************************
- * *
- * ELOGRAPHICS *
- * *
- ***********************************************************************/
-TEST(ElographicsTest, InputDeviceSectionWithOptionDevice)
-{
- XOrgConfig config;
- XITServer server;
-
- config.AddInputSection("elographics", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"Device\" \"/dev/input/event0\"\n");
- config.AddDefaultScreenWithDriver();
- server.Start(config);
-
- ::Display *dpy = XOpenDisplay(server.GetDisplayString().c_str());
- int major = 2;
- int minor = 0;
- ASSERT_EQ(Success, XIQueryVersion(dpy, &major, &minor));
-
- /* VCP, VCK, xtest, mouse, keyboard, aiptek */
- int expected_devices = 7;
-
- /* xserver git 1357cd7251, no <default pointer> */
- if (server.GetVersion().compare("1.11.0") > 0)
- expected_devices--;
-
- ASSERT_EQ(count_devices(dpy), expected_devices);
-
- int deviceid;
- if (FindInputDeviceByName(dpy, "--device--", &deviceid) != 1) {
- SCOPED_TRACE("\n"
- " Elographics device '--device--' not found.\n"
- " Maybe this is elographics < 1.4.\n"
- " Checking for TOUCHSCREEN instead, see git commit\n"
- " xf86-input-elographics-1.3.0-1-g55f337f");
- ASSERT_EQ(FindInputDeviceByName(dpy, "TOUCHSCREEN", &deviceid), 1);
- } else
- ASSERT_EQ(FindInputDeviceByName(dpy, "--device--", &deviceid), 1);
-
- int ndevices;
- XIDeviceInfo *info = XIQueryDevice(dpy, deviceid, &ndevices);
- ASSERT_EQ(ndevices, 1);
-
- ASSERT_EQ(info->use, XISlavePointer) << "https://bugs.freedesktop.org/show_bug.cgi?id=40870";
- ASSERT_EQ(info->attachment, VIRTUAL_CORE_POINTER_ID);
-
- XIFreeDeviceInfo(info);
-
- config.RemoveConfig();
- server.RemoveLogFile();
-}
-
-/* Create a named pipe that pumps out elographics 10-byte packets */
-struct elo_packet {
- unsigned char header; /* always 'U' */
- unsigned char expected; /* always 'T' (touch packet) in this program */
- unsigned char has_pressure; /* 0x80 if pressure is present, 0 otherwise */
- unsigned char x_lo;
- unsigned char x_hi;
- unsigned char y_lo;
- unsigned char y_hi;
- unsigned char pressure_hi;
- unsigned char pressure_lo;
- unsigned char checksum; /* 0x88 + bytes[1..8] */
-};
-
-static void elo_init_packet(struct elo_packet *packet, short x, short y, short pressure)
-{
- int i;
-
- packet->header = 'U';
- packet->expected = 'T';
- packet->has_pressure = 0x80;
- packet->x_lo = x & 0xFF;
- packet->x_hi = (x & 0xFF00) >> 8;
- packet->y_lo = y & 0xFF;
- packet->y_hi = (y & 0xFF00) >> 8;
- packet->pressure_lo = pressure & 0xFF;
- packet->pressure_hi = (pressure & 0xFF00) >> 8;
-
- packet->checksum = 0xaa;
-
- for (i = 0; i < 9; i++)
- packet->checksum += *(((unsigned char*)packet) + i);
-}
-
-static void elo_sighandler(int sig)
-{
- unlink("/tmp/elographics.pipe");
- exit(0);
-}
-
-static void elo_sighandler_pipe(int sig)
-{
-}
-
-int elo_simulate(void)
-{
- int i;
- int rc, fd;
- struct elo_packet packet;
- const char *path = "/tmp/elographics.pipe";
-
- rc = mkfifo(path, 0x755);
- if (rc == -1) {
- perror("Failed to create pipe:");
- return 1;
- }
-
- signal(SIGINT, elo_sighandler);
- signal(SIGTERM, elo_sighandler);
- signal(SIGPIPE, elo_sighandler_pipe);
-
- fd = open(path, O_WRONLY);
- if (fd == -1) {
- perror("Failed to open pipe:");
- rc = 1;
- goto out;
- }
-
- for (i = 0; i < 30; i++) {
- elo_init_packet(&packet, 100 * i, 100 * i, 10);
- rc = write(fd, &packet, sizeof(packet));
- if (rc == -1 && errno == SIGPIPE)
- i--;
- usleep(50000);
- }
-
- if (i == 30)
- rc = 0;
-
-out:
- unlink(path);
-
- return rc;
-}
-
-pid_t elo_fork(void)
-{
- /* fork here */
- pid_t pid = fork();
- if (pid == 0) { /* child */
-#ifdef __linux
- prctl(PR_SET_PDEATHSIG, SIGTERM);
-#endif
- if (elo_simulate())
- throw new std::runtime_error("simulation failed\n");
- exit(0);
- }
- return pid;
-}
-
-TEST(ElographicsTest, StylusMovement)
-{
- XOrgConfig config;
- XITServer server;
-
- config.AddInputSection("elographics", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"DebugLevel\" \"10\"\n"
- "Option \"Model\" \"Sunit dSeries\"" /* does not send packets to device*/
- "Option \"Device\" \"/tmp/elographics.pipe\"\n");
- config.AddDefaultScreenWithDriver();
-
- /* fork here */
- elo_fork();
-
- /* parent */
- server.Start(config);
-
- ::Display *dpy = XOpenDisplay(server.GetDisplayString().c_str());
- int major = 2;
- int minor = 0;
- ASSERT_EQ(Success, XIQueryVersion(dpy, &major, &minor));
-
- XSelectInput(dpy, DefaultRootWindow(dpy), PointerMotionMask);
- XSync(dpy, False);
-
- if (FindInputDeviceByName(dpy, "--device--") != 1) {
- SCOPED_TRACE("\n"
- " Elographics device '--device--' not found.\n"
- " Maybe this is elographics < 1.4.\n"
- " Checking for TOUCHSCREEN instead, see git commit\n"
- " xf86-input-elographics-1.3.0-1-g55f337f");
- ASSERT_EQ(FindInputDeviceByName(dpy, "TOUCHSCREEN"), 1);
- } else
- ASSERT_EQ(FindInputDeviceByName(dpy, "--device--"), 1);
-
- ASSERT_EVENT(XEvent, first, dpy, MotionNotify);
- ASSERT_EVENT(XEvent, second, dpy, MotionNotify);
- ASSERT_LT(first->xmotion.x_root, second->xmotion.x_root);
-
- int status;
- wait(&status);
-
- config.RemoveConfig();
- server.RemoveLogFile();
-}
-
-#ifndef HAVE_RHEL6
-TEST(ElographicsTest, InvertX)
-{
- XOrgConfig config;
- XITServer server;
-
- config.AddInputSection("elographics", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"DebugLevel\" \"10\"\n"
- "Option \"MinX\" \"3000\"\n"
- "Option \"MaxX\" \"0\"\n"
- "Option \"Model\" \"Sunit dSeries\"" /* does not send packets to device*/
- "Option \"Device\" \"/tmp/elographics.pipe\"\n");
- config.AddDefaultScreenWithDriver();
-
- /* fork here */
- elo_fork();
-
- /* parent */
- server.Start(config);
-
- ::Display *dpy = XOpenDisplay(server.GetDisplayString().c_str());
- int major = 2;
- int minor = 0;
- ASSERT_EQ(Success, XIQueryVersion(dpy, &major, &minor));
-
- XSelectInput(dpy, DefaultRootWindow(dpy), PointerMotionMask);
- XSync(dpy, False);
-
- if (FindInputDeviceByName(dpy, "--device--") != 1) {
- SCOPED_TRACE("\n"
- " Elographics device '--device--' not found.\n"
- " Maybe this is elographics < 1.4.\n"
- " Checking for TOUCHSCREEN instead, see git commit\n"
- " xf86-input-elographics-1.3.0-1-g55f337f");
- ASSERT_EQ(FindInputDeviceByName(dpy, "TOUCHSCREEN"), 1);
- } else
- ASSERT_EQ(FindInputDeviceByName(dpy, "--device--"), 1);
-
- ASSERT_EVENT(XEvent, first, dpy, MotionNotify);
- ASSERT_EVENT(XEvent, second, dpy, MotionNotify);
- ASSERT_GT(first->xmotion.x_root, second->xmotion.x_root);
- ASSERT_LT(first->xmotion.y_root, second->xmotion.y_root);
-
- int status;
- wait(&status);
-
- config.RemoveConfig();
- server.RemoveLogFile();
-}
-
-TEST(ElographicsTest, InvertY)
-{
- XOrgConfig config;
- XITServer server;
-
- config.AddInputSection("elographics", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"DebugLevel\" \"10\"\n"
- "Option \"MinY\" \"3000\"\n"
- "Option \"MaxY\" \"0\"\n"
- "Option \"Model\" \"Sunit dSeries\"" /* does not send packets to device*/
- "Option \"Device\" \"/tmp/elographics.pipe\"\n");
- config.AddDefaultScreenWithDriver();
-
- /* fork here */
- elo_fork();
-
- /* parent */
- server.Start(config);
-
- ::Display *dpy = XOpenDisplay(server.GetDisplayString().c_str());
- int major = 2;
- int minor = 0;
- ASSERT_EQ(Success, XIQueryVersion(dpy, &major, &minor));
-
- XSelectInput(dpy, DefaultRootWindow(dpy), PointerMotionMask);
- XSync(dpy, False);
-
- if (FindInputDeviceByName(dpy, "--device--") != 1) {
- SCOPED_TRACE("\n"
- " Elographics device '--device--' not found.\n"
- " Maybe this is elographics < 1.4.\n"
- " Checking for TOUCHSCREEN instead, see git commit\n"
- " xf86-input-elographics-1.3.0-1-g55f337f");
- ASSERT_EQ(FindInputDeviceByName(dpy, "TOUCHSCREEN"), 1);
- } else
- ASSERT_EQ(FindInputDeviceByName(dpy, "--device--"), 1);
-
- ASSERT_EVENT(XEvent, first, dpy, MotionNotify);
- ASSERT_EVENT(XEvent, second, dpy, MotionNotify);
- ASSERT_LT(first->xmotion.x_root, second->xmotion.x_root);
- ASSERT_GT(first->xmotion.y_root, second->xmotion.y_root);
-
- int status;
- wait(&status);
-
- config.RemoveConfig();
- server.RemoveLogFile();
-}
-#endif
-
-int main(int argc, char **argv) {
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/tests/input/mouse.cpp b/tests/input/mouse.cpp
deleted file mode 100644
index 6220dc7..0000000
--- a/tests/input/mouse.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright © 2012-2013 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- */
-
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdexcept>
-#include <map>
-#include <fstream>
-#include <xorg/gtest/xorg-gtest.h>
-#include <linux/input.h>
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#define XK_LATIN1
-#include <X11/keysymdef.h>
-#include <X11/XF86keysym.h>
-#include <X11/Xutil.h>
-#include <X11/extensions/XInput.h>
-#include <X11/extensions/XInput2.h>
-
-#include "xit-server-input-test.h"
-#include "device-interface.h"
-#include "helpers.h"
-
-/**
- * Mouse driver test.
- */
-class MouseTest : public XITServerInputTest,
- public DeviceInterface {
-public:
- /**
- * Initializes a standard mouse device with two wheels.
- */
- virtual void SetUp() {
- SetDevice("mice/PIXART-USB-OPTICAL-MOUSE-HWHEEL.desc");
- XITServerInputTest::SetUp();
- }
-
- /**
- * Sets up an xorg.conf for a single mouse CorePointer device based on
- * the evemu device.
- */
- virtual void SetUpConfigAndLog() {
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("mouse", "--device--",
- "Option \"ZAxisMapping\" \"4 5 6 7\"\n"
- "Option \"Protocol\" \"ImPS/2\"\n"
- "Option \"CorePointer\" \"on\"\n");
- config.WriteConfig();
- }
-};
-
-void scroll_wheel_event(::Display *display,
- xorg::testing::evemu::Device *dev,
- int axis, int value, unsigned int button) {
-
- dev->PlayOne(EV_REL, axis, value, 1);
- XSync(display, False);
-
- ASSERT_EQ(xorg::testing::XServer::WaitForEventOfType(display, ButtonPress, -1, -1, 1000), true);
-
- XEvent btn;
- int nevents = 0;
- while(XPending(display)) {
- XNextEvent(display, &btn);
-
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, button);
-
- XNextEvent(display, &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonRelease);
- ASSERT_EQ(btn.xbutton.button, button);
-
- nevents++;
- }
-
- ASSERT_EQ(nevents, abs(value));
-}
-
-
-TEST_F(MouseTest, ScrollWheel)
-{
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
- XFlush(Display());
- XSync(Display(), False);
-
- scroll_wheel_event(Display(), dev.get(), REL_WHEEL, 1, 4);
- scroll_wheel_event(Display(), dev.get(), REL_WHEEL, 2, 4);
- scroll_wheel_event(Display(), dev.get(), REL_WHEEL, 3, 4);
-
- scroll_wheel_event(Display(), dev.get(), REL_WHEEL, -1, 5);
- scroll_wheel_event(Display(), dev.get(), REL_WHEEL, -2, 5);
- scroll_wheel_event(Display(), dev.get(), REL_WHEEL, -3, 5);
-
- /* Vertical scrolling only, it appears we can't send HScroll events */
-}
-
-TEST_F(MouseTest, Move)
-{
- XSelectInput(Display(), DefaultRootWindow(Display()), PointerMotionMask);
- XFlush(Display());
- XSync(Display(), False);
-
- dev->PlayOne(EV_REL, REL_X, -1, 1);
-
- ASSERT_EQ(xorg::testing::XServer::WaitForEventOfType(Display(), MotionNotify, -1, -1, 1000), true);
-
- int x, y;
- XEvent ev;
- XNextEvent(Display(), &ev);
- x = ev.xmotion.x_root;
- y = ev.xmotion.y_root;
-
- /* left */
- dev->PlayOne(EV_REL, REL_X, -1, 1);
- ASSERT_EQ(xorg::testing::XServer::WaitForEventOfType(Display(), MotionNotify, -1, -1, 1000), true);
-
- XNextEvent(Display(), &ev);
- ASSERT_LT(ev.xmotion.x_root, x);
- ASSERT_EQ(ev.xmotion.y_root, y);
- x = ev.xmotion.x_root;
-
- /* right */
- dev->PlayOne(EV_REL, REL_X, 1, 1);
- ASSERT_EQ(xorg::testing::XServer::WaitForEventOfType(Display(), MotionNotify, -1, -1, 1000), true);
-
- XNextEvent(Display(), &ev);
- ASSERT_GT(ev.xmotion.x_root, x);
- ASSERT_EQ(ev.xmotion.y_root, y);
- x = ev.xmotion.x_root;
-
- /* up */
- dev->PlayOne(EV_REL, REL_Y, -1, 1);
- ASSERT_EQ(xorg::testing::XServer::WaitForEventOfType(Display(), MotionNotify, -1, -1, 1000), true);
-
- XNextEvent(Display(), &ev);
- ASSERT_EQ(ev.xmotion.x_root, x);
- ASSERT_LT(ev.xmotion.y_root, y);
- y = ev.xmotion.y_root;
-
- /* down */
- dev->PlayOne(EV_REL, REL_Y, 1, 1);
- ASSERT_EQ(xorg::testing::XServer::WaitForEventOfType(Display(), MotionNotify, -1, -1, 1000), true);
-
- XNextEvent(Display(), &ev);
- ASSERT_EQ(ev.xmotion.x_root, x);
- ASSERT_GT(ev.xmotion.y_root, y);
- y = ev.xmotion.y_root;
-}
-
-TEST_F(MouseTest, BtnPress)
-{
- XORG_TESTCASE("Terminating the server with a button down crashes the server.\n"
- "http://patchwork.freedesktop.org/patch/12193/");
-
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
- XSync(Display(), False);
-
- dev->PlayOne(EV_KEY, BTN_LEFT, 1, 1);
-
- ASSERT_EQ(xorg::testing::XServer::WaitForEventOfType(Display(), ButtonPress, -1, -1, 1000), true);
- XEvent ev;
- XNextEvent(Display(), &ev);
- ASSERT_FALSE(XPending(Display()));
-}
-
-TEST_F(MouseTest, BtnRelease)
-{
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonReleaseMask);
- XSync(Display(), False);
-
- dev->PlayOne(EV_KEY, BTN_LEFT, 1, true);
-
- dev->PlayOne(EV_KEY, BTN_LEFT, 0, true);
- ASSERT_EQ(xorg::testing::XServer::WaitForEventOfType(Display(), ButtonRelease, -1, -1, 1000), true);
- XEvent ev;
- XNextEvent(Display(), &ev);
-
- ASSERT_FALSE(XPending(Display()));
-}
-
-TEST_F(MouseTest, DevNode)
-{
- Atom node_prop = XInternAtom(Display(), "Device Node", True);
-
- ASSERT_NE(node_prop, (Atom)None) << "This requires server 1.11";
-
- int deviceid = -1;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1) << "Failed to find device.";
-
- Atom type;
- int format;
- unsigned long nitems, bytes_after;
- char *data;
- XIGetProperty(Display(), deviceid, node_prop, 0, 100, False,
- AnyPropertyType, &type, &format, &nitems, &bytes_after,
- (unsigned char**)&data);
- ASSERT_EQ(type, XA_STRING);
-
- std::string devnode(data);
- ASSERT_EQ(devnode.compare("/dev/input/mice"), 0);
-
- XFree(data);
-}
-
-int main(int argc, char **argv) {
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/tests/input/synaptics.cpp b/tests/input/synaptics.cpp
deleted file mode 100644
index fbba447..0000000
--- a/tests/input/synaptics.cpp
+++ /dev/null
@@ -1,1815 +0,0 @@
-/*
- * Copyright © 2012-2013 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- */
-
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdexcept>
-#include <stdint.h>
-#include <map>
-#include <utility>
-#include <sstream>
-#include <xorg/gtest/xorg-gtest.h>
-#include <linux/input.h>
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#define XK_LATIN1
-#include <X11/keysymdef.h>
-#include <X11/XF86keysym.h>
-#include <X11/Xutil.h>
-#include <X11/extensions/XInput.h>
-#include <X11/extensions/XInput2.h>
-
-#include "xit-server-input-test.h"
-#include "xit-property.h"
-#include "xit-event.h"
-#include "device-interface.h"
-#include "helpers.h"
-
-/**
- * Synaptics driver test for touchpad devices. This class uses a traditional
- * touchpad device.
- */
-class SynapticsTest : public XITServerInputTest,
- public DeviceInterface {
-public:
- /**
- * Initializes a standard touchpad device.
- */
- virtual void SetUp() {
- SetDevice("touchpads/SynPS2-Synaptics-TouchPad.desc");
-
- xi2_major_minimum = 2;
- xi2_minor_minimum = 1;
-
- XITServerInputTest::SetUp();
- }
-
- /**
- * Sets up an xorg.conf for a single synaptics CorePointer device based on
- * the evemu device. Options enabled: tapping (1 finger), two-finger
- * vertical scroll.
- */
- virtual void SetUpConfigAndLog() {
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("synaptics", "--device--",
- "Option \"Protocol\" \"event\"\n"
- "Option \"CorePointer\" \"on\"\n"
- "Option \"TapButton1\" \"1\"\n"
- "Option \"GrabEventDevice\" \"1\"\n"
- "Option \"FastTaps\" \"1\"\n"
- "Option \"VertTwoFingerScroll\" \"1\"\n"
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"\n");
- config.WriteConfig();
- }
-};
-
-TEST_F(SynapticsTest, DevicePresent)
-{
- int ndevices;
- XIDeviceInfo *info;
-
- info = XIQueryDevice(Display(), XIAllDevices, &ndevices);
-
- /* VCP, VCK, VC XTEST keyboard, VC XTEST pointer, default keyboard, --device-- */
- ASSERT_EQ(6, ndevices);
- bool found = false;
- while(ndevices--) {
- if (strcmp(info[ndevices].name, "--device--") == 0) {
- ASSERT_EQ(found, false) << "Duplicate device" << std::endl;
- found = true;
- }
- }
- ASSERT_EQ(found, true);
- XIFreeDeviceInfo(info);
-}
-
-TEST_F(SynapticsTest, SmoothScrollingAvailable)
-{
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1) << "Failed to find device.";
-
- int ndevices;
- XIDeviceInfo *info = XIQueryDevice(Display(), deviceid, &ndevices);
- ASSERT_EQ(ndevices, 1);
-
- int nvaluators = 0;
- bool hscroll_class_found = false;
- bool vscroll_class_found = false;
- for (int i = 0; i < info->num_classes; i++) {
- XIAnyClassInfo *any = info->classes[i];
- if (any->type == XIScrollClass) {
- XIScrollClassInfo *scroll = reinterpret_cast<XIScrollClassInfo*>(any);
- switch(scroll->scroll_type) {
- case XIScrollTypeVertical:
- vscroll_class_found = true;
- ASSERT_EQ(scroll->increment, 100); /* default driver increment */
- ASSERT_EQ(scroll->flags & XIScrollFlagPreferred, 0);
- break;
- case XIScrollTypeHorizontal:
- hscroll_class_found = true;
- ASSERT_EQ(scroll->increment, 100); /* default driver increment */
- break;
- default:
- FAIL() << "Invalid scroll class: " << scroll->type;
- }
- } else if (any->type == XIValuatorClass) {
- nvaluators++;
- }
- }
-
- ASSERT_EQ(nvaluators, 4);
- ASSERT_TRUE(hscroll_class_found);
- ASSERT_TRUE(vscroll_class_found);
-
- XIFreeDeviceInfo(info);
-}
-
-#ifndef HAVE_RHEL6
-/**
- * Synaptics driver test for smooth scrolling increments.
- */
-class SynapticsSmoothScrollTest : public SynapticsTest,
- public ::testing::WithParamInterface<std::pair<int, int> > {
- /**
- * Sets up an xorg.conf for a single synaptics CorePointer device based on
- * the evemu device. Options enabled: tapping (1 finger), two-finger
- * vertical scroll.
- */
- virtual void SetUpConfigAndLog() {
-
- std::pair<int, int> params = GetParam();
-
- std::string vdelta = static_cast<std::stringstream*>( &(std::stringstream() << params.first) )->str();
- std::string hdelta = static_cast<std::stringstream*>( &(std::stringstream() << params.second) )->str();
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("synaptics", "--device--",
- "Option \"Protocol\" \"event\"\n"
- "Option \"CorePointer\" \"on\"\n"
- "Option \"TapButton1\" \"1\"\n"
- "Option \"GrabEventDevice\" \"1\"\n"
- "Option \"FastTaps\" \"1\"\n"
- "Option \"VertTwoFingerScroll\" \"1\"\n"
- "Option \"HorizTwoFingerScroll\" \"1\"\n"
- "Option \"VertScrollDelta\" \"" + vdelta + "\"\n"
- "Option \"HorizScrollDelta\" \"" + hdelta + "\"\n"
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"\n");
- config.WriteConfig();
- }
-
-};
-
-TEST_P(SynapticsSmoothScrollTest, ScrollDelta)
-{
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1) << "Failed to find device.";
-
- int ndevices;
- XIDeviceInfo *info = XIQueryDevice(Display(), deviceid, &ndevices);
- ASSERT_EQ(ndevices, 1);
-
- std::pair<int, int> deltas = GetParam();
-
- bool hscroll_class_found = false;
- bool vscroll_class_found = false;
- for (int i = 0; i < info->num_classes; i++) {
- XIAnyClassInfo *any = info->classes[i];
- if (any->type == XIScrollClass) {
- XIScrollClassInfo *scroll = reinterpret_cast<XIScrollClassInfo*>(any);
- switch(scroll->scroll_type) {
- case XIScrollTypeVertical:
- vscroll_class_found = true;
- ASSERT_EQ(scroll->increment, deltas.first); /* default driver increment */
- break;
- case XIScrollTypeHorizontal:
- hscroll_class_found = true;
- ASSERT_EQ(scroll->increment, deltas.second); /* default driver increment */
- break;
- default:
- FAIL() << "Invalid scroll class: " << scroll->type;
- }
- }
- }
-
- /* The server doesn't allow a 0 increment on scroll axes, so the device
- comes up with no scroll axes. */
- if (deltas.second == 0)
- ASSERT_FALSE(hscroll_class_found);
- else
- ASSERT_TRUE(hscroll_class_found);
-
- if (deltas.first == 0)
- ASSERT_FALSE(vscroll_class_found);
- else
- ASSERT_TRUE(vscroll_class_found);
-
- XIFreeDeviceInfo(info);
-}
-
-INSTANTIATE_TEST_CASE_P(, SynapticsSmoothScrollTest,
- ::testing::Values(std::make_pair(0, 0),
- std::make_pair(1, 1),
- std::make_pair(100, 100),
- std::make_pair(-1, -1),
- std::make_pair(-100, 1),
- std::make_pair(1, 100)
- ));
-
-#endif
-
-
-void check_buttons_event(::Display *display,
- xorg::testing::evemu::Device *dev,
- const std::string& events_path,
- unsigned int button,
- int expect_nevents) {
-
- dev->Play(RECORDINGS_DIR "touchpads/" + events_path);
- XSync(display, False);
-
- ASSERT_NE(XPending(display), 0) << "No event pending" << std::endl;
- XEvent btn;
- int nevents = 0;
- while(XPending(display)) {
- XNextEvent(display, &btn);
-
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, button);
-
- XNextEvent(display, &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonRelease);
- ASSERT_EQ(btn.xbutton.button, button);
-
- nevents++;
- }
-
- /* if we get more than 5 events difference, something is probably wrong */
- ASSERT_LT(abs(expect_nevents - nevents), 5);
-}
-
-TEST_F(SynapticsTest, ScrollWheel)
-{
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
- /* the server takes a while to start up bust the devices may not respond
- to events yet. Add a noop call that just delays everything long
- enough for this test to work */
- XInternAtom(Display(), "foo", True);
- XFlush(Display());
- check_buttons_event(Display(), dev.get(), "SynPS2-Synaptics-TouchPad-two-finger-scroll-up.events", 4, 17);
- check_buttons_event(Display(), dev.get(), "SynPS2-Synaptics-TouchPad-two-finger-scroll-down.events", 5, 10);
-}
-
-TEST_F(SynapticsTest, TapEvent)
-{
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
- /* the server takes a while to start up bust the devices may not respond
- to events yet. Add a noop call that just delays everything long
- enough for this test to work */
- XInternAtom(Display(), "foo", True);
- XFlush(Display());
- check_buttons_event(Display(), dev.get(), "SynPS2-Synaptics-TouchPad-tap.events", 1, 1);
-}
-
-void check_drag_event(::Display *display,
- xorg::testing::evemu::Device *dev,
- const std::string& events_path,
- int expect_npress,
- int expect_nmotion,
- int expect_nrelease) {
-
- dev->Play(RECORDINGS_DIR "touchpads/" + events_path);
- XSync(display, False);
-
- ASSERT_NE(XPending(display), 0) << "No event pending" << std::endl;
- XEvent ev;
- int nevents = 0;
-
- while (XCheckMaskEvent (display, ButtonPressMask, &ev))
- nevents++;
- ASSERT_EQ(expect_npress, nevents);
- ASSERT_EQ(ev.xbutton.button, 1U);
-
- nevents = 0;
- while (XCheckMaskEvent (display, PointerMotionMask, &ev))
- nevents++;
- /* if we get more than 5 events difference, something is probably wrong */
- ASSERT_LT(abs(expect_nmotion -nevents), 5);
-
- nevents = 0;
- while (XCheckMaskEvent (display, ButtonReleaseMask, &ev))
- nevents++;
- ASSERT_EQ(expect_nrelease, nevents);
- ASSERT_EQ(ev.xbutton.button, 1U);
-
- while(XPending(display))
- XNextEvent(display, &ev);
-}
-
-TEST_F(SynapticsTest, TapAndDragEvent)
-{
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
- /* the server takes a while to start up bust the devices may not respond
- to events yet. Add a noop call that just delays everything long
- enough for this test to work */
- XInternAtom(Display(), "foo", True);
- XFlush(Display());
- /* 1 press, 30 moves then 1 release is what we expect */
- check_drag_event(Display(), dev.get(), "SynPS2-Synaptics-TouchPad-tap-and-move.events", 1, 30, 1);
-}
-
-/**
- * Synaptics driver test for Bug 53037 - Device coordinate scaling breaks
- * XWarpPointer requests
- *
- * If a device with a device coordinate range is the lastSlave, a
- * WarpPointer request on some coordinates may end up on different pixels
- * than requested. The server scales from screen to device coordinates, then
- * back to screen - a rounding error may then change to the wrong pixel.
- *
- * https://bugs.freedesktop.org/show_bug.cgi?id=53037
- *
- * Takes a pair of integers, not used by the class itself.
- */
-class SynapticsWarpTest : public SynapticsTest,
- public ::testing::WithParamInterface<std::pair<int, int> >{
-};
-
-TEST_P(SynapticsWarpTest, WarpScaling)
-{
- XORG_TESTCASE("https://bugs.freedesktop.org/show_bug.cgi?id=53037");
-
- /* Play one event so this device is lastSlave */
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-move.events");
-
- int x = GetParam().first,
- y = GetParam().second;
-
- XWarpPointer(Display(), 0, DefaultRootWindow(Display()), 0, 0, 0, 0, x, y);
-
- Window root, child;
- int rx, ry, wx, wy;
- unsigned int mask;
-
- XQueryPointer(Display(), DefaultRootWindow(Display()), &root, &child,
- &rx, &ry, &wx, &wy, &mask);
- ASSERT_EQ(root, DefaultRootWindow(Display()));
- /* Warping to negative should clip to 0 */
- ASSERT_EQ(rx, std::max(x, 0));
- ASSERT_EQ(ry, std::max(y, 0));
-}
-
-INSTANTIATE_TEST_CASE_P(, SynapticsWarpTest,
- ::testing::Values(std::make_pair(0, 0),
- std::make_pair(1, 1),
- std::make_pair(2, 2),
- std::make_pair(200, 200),
- std::make_pair(-1, -1)
- ));
-
-
-class SynapticsWarpZaphodTest : public SynapticsWarpTest {
- virtual void SetUpConfigAndLog() {
- if (xinerama.empty())
- xinerama = "off";
- config.SetAutoAddDevices(true); /* to avoid ServerLayout being
- written */
- config.AppendRawConfig(
- "Section \"ServerLayout\"\n"
- " Identifier \"X.org Configured\"\n"
- " Screen 0 \"Screen0\"\n"
- " Screen 1 \"Screen1\" LeftOf \"Screen0\"\n"
- " Option \"Xinerama\" \"" + xinerama + "\n"
- " Option \"AutoAddDevices\" \"off\"\n"
- "EndSection\n"
- "\n"
- "Section \"Device\"\n"
- " Identifier \"Card0\"\n"
- " Driver \"dummy\"\n"
- "EndSection\n"
- "\n"
- "Section \"Device\"\n"
- " Identifier \"Card1\"\n"
- " Driver \"dummy\"\n"
- "EndSection\n"
- "\n"
- "Section \"Screen\"\n"
- " Identifier \"Screen0\"\n"
- " Device \"Card0\"\n"
- "EndSection\n"
- "\n"
- "Section \"Screen\"\n"
- " Identifier \"Screen1\"\n"
- " Device \"Card1\"\n"
- "EndSection"
- "\n"
- "Section \"InputDevice\"\n"
- " Identifier \"synaptics\"\n"
- " Driver \"synaptics\"\n"
- " Option \"Device\" \"" + dev->GetDeviceNode() + "\"\n"
- "EndSection\n");
- config.WriteConfig();
- }
-
-protected:
- std::string xinerama;
-};
-
-TEST_P(SynapticsWarpZaphodTest, WarpScaling)
-{
- XORG_TESTCASE("Start server with Xinerama off\n"
- "Play synaptics event to ensure it is the lastSlave\n"
- "Warp pointer on left root window\n"
- "Compare coordinates to expected\n"
- "Warp pointer on right root window\n"
- "Compare coordinates to expected\n"
- "https://bugs.freedesktop.org/show_bug.cgi?id=53037");
-
- ::Display *dpy = Display();
- ASSERT_EQ(ScreenCount(dpy), 2);
-
- /* Play one event so this device is lastSlave */
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-move.events");
-
- int x = GetParam().first,
- y = GetParam().second;
-
- Window lroot = RootWindow(dpy, 1);
- /* Warp on left root window */
- XWarpPointer(dpy, 0, lroot, 0, 0, 0, 0, x, y);
-
- Window root, child;
- int rx, ry, wx, wy;
- unsigned int mask;
-
- bool same_screen;
- same_screen= XQueryPointer(dpy, lroot, &root, &child,
- &rx, &ry, &wx, &wy, &mask);
- ASSERT_TRUE(same_screen);
- ASSERT_EQ(root, lroot);
-
- /* Warping to negative of left screen should clip to 0 */
- ASSERT_EQ(rx, std::max(x, 0));
- ASSERT_EQ(ry, std::max(y, 0));
-
- /* Now warp to right root window */
- Window rroot = RootWindow(dpy, 0);
- XWarpPointer(dpy, 0, rroot, 0, 0, 0, 0, x, y);
- /* Query from left root window */
- same_screen = XQueryPointer(dpy, lroot, &root, &child,
- &rx, &ry, &wx, &wy, &mask);
- ASSERT_FALSE(same_screen);
- ASSERT_EQ(root, rroot);
- ASSERT_EQ(rx, std::max(x, 0));
- ASSERT_EQ(ry, std::max(y, 0));
-
- /* WarpPointer doesn't let us warp relative between two screens, so we
- can't test that here */
-}
-
-INSTANTIATE_TEST_CASE_P(, SynapticsWarpZaphodTest,
- ::testing::Values(std::make_pair(0, 0),
- std::make_pair(1, 1),
- std::make_pair(2, 2),
- std::make_pair(200, 200),
- std::make_pair(-1, -1)
- ));
-
-class SynapticsWarpXineramaTest : public SynapticsWarpZaphodTest {
- virtual void SetUp() {
- xinerama = "on";
- SynapticsWarpZaphodTest::SetUp();
- }
-};
-
-TEST_P(SynapticsWarpXineramaTest, WarpScaling)
-{
- XORG_TESTCASE("Start server with Xinerama on\n"
- "Play synaptics event to ensure it is the lastSlave\n"
- "Warp pointer on left root window\n"
- "Compare coordinates to expected\n"
- "Warp pointer on right root window\n"
- "Compare coordinates to expected\n"
- "https://bugs.freedesktop.org/show_bug.cgi?id=53037");
-
- ::Display *dpy = Display();
- ASSERT_EQ(ScreenCount(dpy), 1);
-
- /* Play one event so this device is lastSlave */
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-move.events");
-
- int x = GetParam().first,
- y = GetParam().second;
-
- Window root = DefaultRootWindow(dpy);
-
- /* Warp on left screen */
- XWarpPointer(dpy, 0, root, 0, 0, 0, 0, x, y);
-
- Window r, child;
- int rx, ry, wx, wy;
- unsigned int mask;
-
- XQueryPointer(dpy, root, &r, &child,
- &rx, &ry, &wx, &wy, &mask);
-
- /* Warping to negative of left screen should clip to 0 */
- ASSERT_EQ(rx, std::max(x, 0));
- ASSERT_EQ(ry, std::max(y, 0));
-
- int w = DisplayWidth(dpy, 0);
-
- /* Now warp to right screen */
- XWarpPointer(dpy, 0, root, 0, 0, 0, 0, w/2 + x, y);
- XQueryPointer(dpy, root, &root, &child,
- &rx, &ry, &wx, &wy, &mask);
- ASSERT_EQ(rx, w/2 + x);
- ASSERT_EQ(ry, std::max(y, 0));
-}
-
-TEST_F(SynapticsWarpXineramaTest, WarpScalingRelative)
-{
- XORG_TESTCASE("Start server with Xinerama on\n"
- "Play synaptics event to ensure it is the lastSlave\n"
- "Warp pointer to right screen\n"
- "Warp pointer relatively to the left\n"
- "Compare coordinates to expected\n"
- "https://bugs.freedesktop.org/show_bug.cgi?id=53037");
-
- ::Display *dpy = Display();
- ASSERT_EQ(ScreenCount(dpy), 1);
-
- /* Play one event so this device is lastSlave */
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-move.events");
-
- Window root = DefaultRootWindow(dpy);
-
- int w = DisplayWidth(dpy, 0);
-
- /* Warp to right screen */
- XWarpPointer(dpy, 0, root, 0, 0, 0, 0, w/2 + 10, 100);
-
- Window child;
- int rx, ry, wx, wy;
- unsigned int mask;
-
- /* Now warp relative right to left window */
- XWarpPointer(dpy, 0, None, 0, 0, 0, 0, -100, 0);
- XQueryPointer(dpy, root, &root, &child,
- &rx, &ry, &wx, &wy, &mask);
- ASSERT_EQ(rx, w/2 + 10 - 100);
- ASSERT_EQ(ry, 100);
-}
-
-INSTANTIATE_TEST_CASE_P(, SynapticsWarpXineramaTest,
- ::testing::Values(std::make_pair(0, 0),
- std::make_pair(1, 1),
- std::make_pair(2, 2),
- std::make_pair(200, 200),
- std::make_pair(-1, -1)
- ));
-
-/**
- * Synaptics driver test for clickpad devices.
- */
-class SynapticsClickpadTest : public XITServerInputTest,
- public DeviceInterface {
-public:
- /**
- * Initializes a clickpad, as the one found on the Lenovo x220t.
- */
- virtual void SetUp() {
- SetDevice("touchpads/SynPS2-Synaptics-TouchPad-Clickpad.desc");
- XITServerInputTest::SetUp();
- nfingers_down = 0;
- }
-
- /**
- * Set up a single clickpad CorePointer device.
- */
- virtual void SetUpConfigAndLog() {
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("synaptics", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"TapButton1\" \"1\"\n"
- "Option \"GrabEventDevice\" \"1\"\n"
- "Option \"VertTwoFingerScroll\" \"1\"\n"
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"\n");
- config.WriteConfig();
- }
-
- int nfingers_down;
-
- virtual void TouchBegin(unsigned int slot, int x, int y) {
- static unsigned int tracking_id;
- nfingers_down |= 1 << slot;
- dev->PlayOne(EV_KEY, BTN_TOUCH, 1);
- dev->PlayOne(EV_ABS, ABS_MT_SLOT, slot);
- dev->PlayOne(EV_ABS, ABS_PRESSURE, 40);
- dev->PlayOne(EV_ABS, ABS_MT_TRACKING_ID, tracking_id++);
- TouchUpdate(slot, x, y);
- }
-
- virtual void TouchUpdate(unsigned int slot, int x, int y, bool sync = true) {
- dev->PlayOne(EV_ABS, ABS_MT_SLOT, slot);
- dev->PlayOne(EV_ABS, ABS_X, x);
- dev->PlayOne(EV_ABS, ABS_Y, y);
- dev->PlayOne(EV_ABS, ABS_MT_POSITION_X, x);
- dev->PlayOne(EV_ABS, ABS_MT_POSITION_Y, y);
- dev->PlayOne(EV_ABS, ABS_MT_PRESSURE, 68);
- if (sync)
- dev->PlayOne(EV_SYN, SYN_REPORT, 0);
- }
-
- virtual void TouchEnd(unsigned int slot) {
- dev->PlayOne(EV_ABS, ABS_MT_SLOT, slot);
- dev->PlayOne(EV_ABS, ABS_MT_TRACKING_ID, -1);
- nfingers_down &= ~(1 << slot);
- if (!nfingers_down)
- dev->PlayOne(EV_KEY, BTN_TOUCH, 0);
- dev->PlayOne(EV_SYN, SYN_REPORT, 0);
- }
-
- virtual void
- SetClickfingerProperty(const char* name,
- unsigned char cf1 = 1, unsigned char cf2 = 1, unsigned char cf3 = 1)
- {
- ::Display *dpy = Display();
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(dpy, name, &deviceid), 1);
-
- Atom clickfinger_prop = XInternAtom(dpy, "Synaptics Click Action", True);
- ASSERT_NE(clickfinger_prop, (Atom)None);
-
- unsigned char data[3] = {cf1, cf2, cf3};
-
- XIChangeProperty(dpy, deviceid, clickfinger_prop, XA_INTEGER, 8,
- PropModeReplace, data, 3);
- XSync(dpy, False);
- }
-
-
-
-};
-
-static void
-set_clickpad_property(Display *dpy, const char* name)
-{
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(dpy, name, &deviceid), 1);
- ASSERT_PROPERTY(char, clickpad_prop, dpy, deviceid, "Synaptics ClickPad");
- clickpad_prop.data[0] = 1;
- clickpad_prop.Update();
- XSync(dpy, False);
-}
-
-TEST_F(SynapticsClickpadTest, ClickpadProperties)
-{
-#ifndef INPUT_PROP_BUTTONPAD
- SCOPED_TRACE("<linux/input.h>'s INPUT_PROP_BUTTONPAD is missing.\n"
- "Clickpad detection will not work on this kernel");
-#endif
- int major = 2;
- int minor = 0;
- ASSERT_EQ(Success, XIQueryVersion(Display(), &major, &minor));
-
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1);
-
- ASSERT_PROPERTY(char, prop_clickpad, Display(), deviceid, "Synaptics ClickPad");
- ASSERT_EQ(prop_clickpad.type, XA_INTEGER);
- ASSERT_EQ(prop_clickpad.format, 8);
- ASSERT_EQ(prop_clickpad.nitems, 1U);
-#ifdef INPUT_PROP_BUTTONPAD
- ASSERT_EQ(prop_clickpad.data[0], 1);
-#else
- ASSERT_EQ(prop_clickpad.data[0], 0) << "Not expecting ClickPad to be set on a kernel without INPUT_PROP_BUTTONPAD";
-#endif
-
- /* This option is assigned by the xorg.conf.d, it won't activate for
- xorg.conf devices. */
-#ifndef INPUT_PROP_BUTTONPAD
- int prop = XInternAtom(Display(), "Synaptics Soft Button Areas", True);
- ASSERT_EQ(prop, (Atom)None) << "Not expecting Soft Buttons property on non-clickpads";
- return;
-#endif
-
- ASSERT_PROPERTY(int, prop_softbutton, Display(), deviceid, "Synaptics Soft Button Areas");
-
- ASSERT_EQ(prop_softbutton.format, 32);
- ASSERT_EQ(prop_softbutton.nitems, 8U);
- ASSERT_EQ(prop_softbutton.type, XA_INTEGER);
-
- ASSERT_EQ(prop_softbutton.data[0], 0);
- ASSERT_EQ(prop_softbutton.data[1], 0);
- ASSERT_EQ(prop_softbutton.data[2], 0);
- ASSERT_EQ(prop_softbutton.data[3], 0);
- ASSERT_EQ(prop_softbutton.data[4], 0);
- ASSERT_EQ(prop_softbutton.data[5], 0);
- ASSERT_EQ(prop_softbutton.data[6], 0);
- ASSERT_EQ(prop_softbutton.data[7], 0);
-}
-
-TEST_F(SynapticsClickpadTest, Tap)
-{
- set_clickpad_property(Display(), "--device--");
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
- XSync(Display(), False);
-
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.tap.events");
-
- XSync(Display(), False);
-
- XEvent btn;
- ASSERT_NE(XPending(Display()), 0) << "No event pending" << std::endl;
- XNextEvent(Display(), &btn);
-
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, 1U);
-
- XNextEvent(Display(), &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonRelease);
- ASSERT_EQ(btn.xbutton.button, 1U);
-
- XSync(Display(), True);
-}
-
-TEST_F(SynapticsClickpadTest, VertScrollDown)
-{
- set_clickpad_property(Display(), "--device--");
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
- XSync(Display(), False);
-
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.two-finger-scroll-down.events");
-
- XSync(Display(), False);
-
- XEvent btn;
- ASSERT_NE(XPending(Display()), 0) << "No event pending" << std::endl;
- XNextEvent(Display(), &btn);
-
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, 5U);
-
- XNextEvent(Display(), &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonRelease);
- ASSERT_EQ(btn.xbutton.button, 5U);
-
- XSync(Display(), True);
-}
-
-TEST_F(SynapticsClickpadTest, VertScrollUp)
-{
- set_clickpad_property(Display(), "--device--");
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
- XSync(Display(), False);
-
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.two-finger-scroll-up.events");
-
- XSync(Display(), False);
-
- XEvent btn;
- ASSERT_NE(XPending(Display()), 0) << "No event pending" << std::endl;
- XNextEvent(Display(), &btn);
-
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, 4U);
-
- XNextEvent(Display(), &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonRelease);
- ASSERT_EQ(btn.xbutton.button, 4U);
-
- XSync(Display(), True);
-}
-
-TEST_F(SynapticsClickpadTest, DisableDevice)
-{
- XORG_TESTCASE("Disable and re-enable the device with no fingers down\n");
-
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1);
-
- DeviceSetEnabled(Display(), deviceid, false);
- DeviceSetEnabled(Display(), deviceid, true);
-}
-
-TEST_F(SynapticsClickpadTest, DisableDeviceOneFingerDownAndLift)
-{
- XORG_TESTCASE("Disable the device with one fingers down, lift finger,\n"
- "re-enable device.");
-
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1);
-
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.one-finger-down.events");
- DeviceSetEnabled(Display(), deviceid, false);
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.one-finger-up.events");
- DeviceSetEnabled(Display(), deviceid, true);
-}
-
-TEST_F(SynapticsClickpadTest, DisableDeviceOneFingerDown)
-{
- XORG_TESTCASE("Disable the device with one finger down, re-enable with\n"
- "finger still down\n");
-
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1);
-
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.one-finger-down.events");
- DeviceSetEnabled(Display(), deviceid, false);
- DeviceSetEnabled(Display(), deviceid, true);
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.one-finger-up.events");
-}
-
-TEST_F(SynapticsClickpadTest, DisableDeviceTwoFingersDownAndLift)
-{
- XORG_TESTCASE("Disable the device with two fingers down, lift fingers, "
- "re-enable.");
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1);
-
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.two-finger-down.events");
- DeviceSetEnabled(Display(), deviceid, false);
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.two-finger-up.events");
- DeviceSetEnabled(Display(), deviceid, true);
-}
-
-TEST_F(SynapticsClickpadTest, DisableDeviceTwoFingersDown)
-{
- XORG_TESTCASE("Disable the device with two fingers down, re-enable, with\n"
- "fingers still down");
-
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1);
-
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.two-finger-down.events");
- DeviceSetEnabled(Display(), deviceid, false);
- DeviceSetEnabled(Display(), deviceid, true);
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.two-finger-up.events");
-}
-
-TEST_F(SynapticsClickpadTest, DisableDeviceOneFingerResume)
-{
- XORG_TESTCASE("Disable the device with no fingers down, re-enable with\n"
- "one finger down\n");
-
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1);
-
- DeviceSetEnabled(Display(), deviceid, false);
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.one-finger-down.events");
- DeviceSetEnabled(Display(), deviceid, true);
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.one-finger-up.events");
-}
-
-TEST_F(SynapticsClickpadTest, DisableDeviceTwoFingersResume)
-{
- XORG_TESTCASE("Disable the device with no fingers down, re-enable with\n"
- "two fingers down");
-
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1);
-
- DeviceSetEnabled(Display(), deviceid, false);
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.two-finger-down.events");
- DeviceSetEnabled(Display(), deviceid, true);
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.two-finger-up.events");
-}
-
-TEST_F(SynapticsClickpadTest, DisableDeviceOneFingerTwoFingersResume)
-{
- XORG_TESTCASE("Disable the device with one finger down, re-enable with\n"
- "two fingers down");
-
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1);
-
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.one-finger-down.events");
- DeviceSetEnabled(Display(), deviceid, false);
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.one-finger-up.events");
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.two-finger-down.events");
- DeviceSetEnabled(Display(), deviceid, true);
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.two-finger-up.events");
-}
-
-TEST_F(SynapticsClickpadTest, DisableDeviceTwoFingersOneFingerResume)
-{
- XORG_TESTCASE("Disable the device with two fingers down, re-enable with\n"
- "one finger down");
-
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(Display(), "--device--", &deviceid), 1);
-
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.two-finger-down.events");
- DeviceSetEnabled(Display(), deviceid, false);
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.two-finger-up.events");
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.one-finger-down.events");
- DeviceSetEnabled(Display(), deviceid, true);
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.one-finger-up.events");
-}
-
-TEST_F(SynapticsClickpadTest, ClickFinger2)
-{
- XORG_TESTCASE("Put two fingers on the touchpad\n"
- "Trigger BTN_LEFT\n"
- "Expect ClickFinger2 action\n");
- ::Display *dpy = Display();
-
- SetClickfingerProperty("--device--", 0, 2, 0);
-
- XSelectInput(dpy, DefaultRootWindow(dpy), ButtonPressMask | ButtonReleaseMask);
-
- TouchBegin(0, 2000, 2000);
- TouchBegin(1, 2300, 2010);
- dev->PlayOne(EV_KEY, BTN_LEFT, 1, true);
- dev->PlayOne(EV_KEY, BTN_LEFT, 0, true);
- TouchEnd(1);
- TouchEnd(0);
-
- ASSERT_EVENT(XEvent, press, dpy, ButtonPress);
- ASSERT_EVENT(XEvent, release, dpy, ButtonRelease);
- ASSERT_EQ(press->xbutton.button, 2U);
- ASSERT_EQ(release->xbutton.button, 2U);
-}
-
-TEST_F(SynapticsClickpadTest, ClickFinger2Distance)
-{
- XORG_TESTCASE("Put two fingers on the touchpad, too far apart for clickfinger\n"
- "Trigger BTN_LEFT\n"
- "Expect ClickFinger1 action\n");
- ::Display *dpy = Display();
-
- SetClickfingerProperty("--device--", 3, 2, 0);
-
- XSelectInput(dpy, DefaultRootWindow(dpy), ButtonPressMask | ButtonReleaseMask);
-
- TouchBegin(0, 2000, 2000);
- TouchBegin(1, 4300, 2010);
- dev->PlayOne(EV_KEY, BTN_LEFT, 1, true);
- dev->PlayOne(EV_KEY, BTN_LEFT, 0, true);
- TouchEnd(1);
- TouchEnd(0);
-
- /* one finger on a clickpad doesn't trigger clickfinger, just normal
- button press */
- ASSERT_EVENT(XEvent, press, dpy, ButtonPress);
- ASSERT_EVENT(XEvent, release, dpy, ButtonRelease);
- ASSERT_EQ(press->xbutton.button, 1U);
- ASSERT_EQ(release->xbutton.button, 1U);
-}
-
-TEST_F(SynapticsClickpadTest, ClickFinger3)
-{
- XORG_TESTCASE("Put two fingers on the touchpad\n"
- "Trigger BTN_TOOL_TRIPLETAP\n"
- "Trigger BTN_LEFT\n"
- "Expect ClickFinger2 action\n");
- ::Display *dpy = Display();
-
- SetClickfingerProperty("--device--", 0, 0, 2);
-
- XSelectInput(dpy, DefaultRootWindow(dpy), ButtonPressMask | ButtonReleaseMask);
-
- TouchBegin(0, 2000, 2000);
- TouchBegin(1, 2300, 2010);
- /* this touchpad only does two touchpoints */
- dev->PlayOne(EV_KEY, BTN_TOOL_TRIPLETAP, 1, true);
- dev->PlayOne(EV_KEY, BTN_LEFT, 1, true);
- dev->PlayOne(EV_KEY, BTN_LEFT, 0, true);
- TouchEnd(1);
- TouchEnd(0);
-
- ASSERT_EVENT(XEvent, press, dpy, ButtonPress);
- ASSERT_EVENT(XEvent, release, dpy, ButtonRelease);
- ASSERT_EQ(press->xbutton.button, 2U);
- ASSERT_EQ(release->xbutton.button, 2U);
-}
-
-TEST_F(SynapticsClickpadTest, ClickFinger3Distance)
-{
- XORG_TESTCASE("Put two fingers on the touchpad, far apart\n"
- "Trigger BTN_TOOL_TRIPLETAP\n"
- "Trigger BTN_LEFT\n"
- "Expect ClickFinger3 action\n");
- ::Display *dpy = Display();
-
- SetClickfingerProperty("--device--", 0, 2, 3);
-
- XSelectInput(dpy, DefaultRootWindow(dpy), ButtonPressMask | ButtonReleaseMask);
-
- TouchBegin(0, 2000, 2000);
- TouchBegin(1, 4300, 2010);
- dev->PlayOne(EV_KEY, BTN_TOOL_TRIPLETAP, 1, true);
- dev->PlayOne(EV_KEY, BTN_LEFT, 1, true);
- dev->PlayOne(EV_KEY, BTN_LEFT, 0, true);
- TouchEnd(1);
- TouchEnd(0);
-
- /* xf86-input-synaptics-1.7.99.1-7-ga6f0f4c changed the behaviour, now
- we always expect clickfinger 3, regardless of distance */
- ASSERT_EVENT(XEvent, press, dpy, ButtonPress);
- ASSERT_EVENT(XEvent, release, dpy, ButtonRelease);
- ASSERT_EQ(press->xbutton.button, 3U);
- ASSERT_EQ(release->xbutton.button, 3U);
-}
-
-TEST_F(SynapticsClickpadTest, SecondaryButtonPropertyNotSet)
-{
- XORG_TESTCASE("Secondary software button property must not exist on this device\n");
-
- int deviceid;
- ASSERT_TRUE(FindInputDeviceByName(Display(), "--device--", &deviceid));
- ASSERT_FALSE(DevicePropertyExists(Display(), deviceid, "Synaptics Secondary Soft Button Areas"));
-}
-
-/**
- * Synaptics driver test for clickpad devices with the SoftButtonArea option
- * set.
- */
-class SynapticsClickpadSoftButtonsTest : public SynapticsClickpadTest {
-public:
- /**
- * Sets up a single CorePointer synaptics clickpad device with the
- * SoftButtonArea option set to 50% left/right, 82% from the top.
- */
- virtual void SetUpConfigAndLog() {
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("synaptics", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"ClickPad\" \"on\"\n"
- "Option \"GrabEventDevice\" \"1\"\n"
- "Option \"SoftButtonAreas\" \"50% 0 82% 0 0 0 0 0\"\n"
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"\n");
- config.WriteConfig();
- }
-};
-
-TEST_F(SynapticsClickpadSoftButtonsTest, LeftClick)
-{
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
- XSync(Display(), False);
-
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.left-phys-click.events");
-
- XEvent btn;
- ASSERT_NE(XPending(Display()), 0) << "No event pending" << std::endl;
- XNextEvent(Display(), &btn);
-
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, 1U);
-
- XNextEvent(Display(), &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonRelease);
- ASSERT_EQ(btn.xbutton.button, 1U);
-
- XSync(Display(), True);
-}
-
-TEST_F(SynapticsClickpadSoftButtonsTest, RightClick)
-{
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
- XSync(Display(), False);
-
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.right-phys-click.events");
-
- XEvent btn;
- ASSERT_NE(XPending(Display()), 0) << "No event pending" << std::endl;
- XNextEvent(Display(), &btn);
-
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, 3U);
-
- XNextEvent(Display(), &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonRelease);
- ASSERT_EQ(btn.xbutton.button, 3U);
-
- XSync(Display(), True);
-}
-
-enum {
- RBL = 0,
- RBR = 1,
- RBT = 2,
- RBB = 3,
- MBL = 4,
- MBR = 5,
- MBT = 6,
- MBB = 7,
-};
-
-TEST_F(SynapticsClickpadSoftButtonsTest, InvalidButtonArea)
-{
- XORG_TESTCASE("Update soft button area property with ranges of \n"
- "left > right or top > bottom\n");
-
- ::Display *dpy = Display();
-
- int deviceid;
- ASSERT_TRUE(FindInputDeviceByName(dpy, "--device--", &deviceid));
-
- XITProperty<int> softbutton_prop(dpy, deviceid, "Synaptics Soft Button Areas");
-
- softbutton_prop.data[RBL] = 3000;
- softbutton_prop.data[RBR] = 2000;
-
- SetErrorTrap(dpy);
- softbutton_prop.Update();
- ASSERT_ERROR(ReleaseErrorTrap(dpy), BadValue);
-
- softbutton_prop.data[RBT] = 3000;
- softbutton_prop.data[RBB] = 2000;
-
- SetErrorTrap(dpy);
- softbutton_prop.Update();
- XSync(dpy, True);
- ASSERT_ERROR(ReleaseErrorTrap(dpy), BadValue);
-
- softbutton_prop.data[MBL] = 3000;
- softbutton_prop.data[MBR] = 2000;
-
- SetErrorTrap(dpy);
- softbutton_prop.Update();
- ASSERT_ERROR(ReleaseErrorTrap(dpy), BadValue);
-
- softbutton_prop.data[MBT] = 3000;
- softbutton_prop.data[MBB] = 2000;
-
- SetErrorTrap(dpy);
- softbutton_prop.Update();
- ASSERT_ERROR(ReleaseErrorTrap(dpy), BadValue);
-}
-
-TEST_F(SynapticsClickpadSoftButtonsTest, SinglePixelOverlap)
-{
- XORG_TESTCASE("Overlap of soft button areas by one 1 device unit is permitted");
-
- ::Display *dpy = Display();
-
- int deviceid;
- ASSERT_TRUE(FindInputDeviceByName(dpy, "--device--", &deviceid));
-
- XITProperty<int> softbutton_prop(dpy, deviceid, "Synaptics Soft Button Areas");
-
- softbutton_prop.data[RBL] = 2000;
- softbutton_prop.data[RBR] = 3000;
- softbutton_prop.data[MBL] = 1000;
- softbutton_prop.data[MBR] = 2000;
-
- softbutton_prop.data[RBT] = 2000;
- softbutton_prop.data[MBT] = 2000;
- softbutton_prop.data[RBB] = 3000;
- softbutton_prop.data[MBB] = 3000;
-
- SetErrorTrap(dpy);
- softbutton_prop.Update();
- ASSERT_TRUE(ReleaseErrorTrap(dpy) == NULL);
-
- softbutton_prop.data[RBL] = 2000;
- softbutton_prop.data[RBR] = 3000;
- softbutton_prop.data[MBL] = 2000;
- softbutton_prop.data[MBR] = 3000;
-
- softbutton_prop.data[RBT] = 2000;
- softbutton_prop.data[MBT] = 3000;
- softbutton_prop.data[RBB] = 3000;
- softbutton_prop.data[MBB] = 4000;
-
- SetErrorTrap(dpy);
- softbutton_prop.Update();
- ASSERT_TRUE(ReleaseErrorTrap(dpy) == NULL);
-}
-
-class SynapticsClickpadSoftButtonsWithAreaTest : public SynapticsClickpadSoftButtonsTest {
-public:
- /**
- * Sets up a single CorePointer synaptics clickpad device with the
- * SoftButtonArea option set to 50% left/right, 82% from the top.
- */
- virtual void SetUpConfigAndLog() {
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("synaptics", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"ClickPad\" \"on\"\n"
- "Option \"GrabEventDevice\" \"1\"\n"
- "Option \"SoftButtonAreas\" \"50% 0 82% 0 0 0 0 0\"\n"
- "Option \"AreaBottomEdge\" \"3900\"\n"
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"\n");
- config.WriteConfig();
- }
-};
-
-TEST_F(SynapticsClickpadSoftButtonsTest, LeftClickInDeadArea)
-{
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
- XSync(Display(), False);
-
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.left-phys-click.events");
-
- XEvent btn;
- ASSERT_NE(XPending(Display()), 0) << "No event pending" << std::endl;
- XNextEvent(Display(), &btn);
-
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, 1U);
-
- XNextEvent(Display(), &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonRelease);
- ASSERT_EQ(btn.xbutton.button, 1U);
-
- XSync(Display(), True);
-}
-
-TEST_F(SynapticsClickpadSoftButtonsWithAreaTest, RightClickInDeadArea)
-{
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
- XSync(Display(), False);
-
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.right-phys-click.events");
-
- XEvent btn;
- ASSERT_NE(XPending(Display()), 0) << "No event pending" << std::endl;
- XNextEvent(Display(), &btn);
-
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, 3U);
-
- XNextEvent(Display(), &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonRelease);
- ASSERT_EQ(btn.xbutton.button, 3U);
-
- XSync(Display(), True);
-}
-
-/**
- * Synaptics driver test for clickpad devices with the SoftButtonArea set at
- * runtime.
- */
-class SynapticsClickpadSoftButtonsRuntimeTest : public SynapticsClickpadTest {
-public:
- /**
- * Sets up a single CorePointer synaptics clickpad device with the
- * SoftButtonArea option set to 50% left/right, 82% from the top.
- */
- virtual void SetUpConfigAndLog() {
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("synaptics", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"ClickPad\" \"off\"\n"
- "Option \"GrabEventDevice\" \"1\"\n"
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"\n");
- config.WriteConfig();
- }
-};
-
-TEST_F(SynapticsClickpadSoftButtonsRuntimeTest, SoftButtonsFirst)
-{
- XORG_TESTCASE("https://bugs.freedesktop.org/show_bug.cgi?id=54102");
-
- ::Display *dpy = Display();
- Atom softbutton_prop = XInternAtom(dpy, "Synaptics Soft Button Areas", True);
- ASSERT_EQ(softbutton_prop, (Atom)None);
-
- softbutton_prop = XInternAtom(dpy, "Synaptics Soft Button Areas", False);
-
- int deviceid;
- ASSERT_TRUE(FindInputDeviceByName(dpy, "--device--", &deviceid));
-
- uint32_t propdata[8] = {0};
- propdata[0] = 3472;
- propdata[2] = 3900;
-
- XIChangeProperty(dpy, deviceid, softbutton_prop, XA_INTEGER, 32,
- PropModeReplace,
- reinterpret_cast<unsigned char*>(propdata), 8);
- XSync(dpy, False);
-
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
- XSync(Display(), False);
-
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.right-phys-click.events");
-
- ASSERT_TRUE(xorg::testing::XServer::WaitForEventOfType(Display(), ButtonPress, -1, -1, 1000));
-
- /* expect left-click, the clickpad prop is still off */
- XEvent btn;
- XNextEvent(Display(), &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, 1U);
-
- Atom clickpad_prop = XInternAtom(dpy, "Synaptics ClickPad", False);
- unsigned char on = 1;
- XIChangeProperty(dpy, deviceid, clickpad_prop, XA_INTEGER, 8,
- PropModeReplace, &on, 1);
- XSync(Display(), False);
-
- /* now expect right click */
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.right-phys-click.events");
-
- ASSERT_TRUE(xorg::testing::XServer::WaitForEventOfType(Display(), ButtonPress, -1, -1, 1000));
-
- XNextEvent(Display(), &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, 3U);
-}
-
-TEST_F(SynapticsClickpadSoftButtonsRuntimeTest, SoftButtonsSecond)
-{
- ::Display *dpy = Display();
- Atom softbutton_prop = XInternAtom(dpy, "Synaptics Soft Button Areas", True);
- ASSERT_EQ(softbutton_prop, (Atom)None);
-
-
- int deviceid;
- ASSERT_TRUE(FindInputDeviceByName(dpy, "--device--", &deviceid));
-
-
- Atom clickpad_prop = XInternAtom(dpy, "Synaptics ClickPad", False);
- unsigned char on = 1;
- XIChangeProperty(dpy, deviceid, clickpad_prop, XA_INTEGER, 8,
- PropModeReplace, &on, 1);
- XSync(Display(), False);
-
- /* prop must now be initialized */
- softbutton_prop = XInternAtom(dpy, "Synaptics Soft Button Areas", True);
- ASSERT_GT(softbutton_prop, (Atom)None);
-
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
- XSync(Display(), False);
-
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.right-phys-click.events");
-
- ASSERT_TRUE(xorg::testing::XServer::WaitForEventOfType(Display(), ButtonPress, -1, -1, 1000));
-
- /* expect left-click, soft button areas should be 0 */
- XEvent btn;
- XNextEvent(Display(), &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, 1U);
-
- uint32_t propdata[8] = {0};
- propdata[0] = 3472;
- propdata[2] = 3900;
-
- XIChangeProperty(dpy, deviceid, softbutton_prop, XA_INTEGER, 32,
- PropModeReplace,
- reinterpret_cast<unsigned char*>(propdata), 8);
- XSync(dpy, False);
-
- dev->Play(RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.right-phys-click.events");
-
- /* now expect right click */
- ASSERT_TRUE(xorg::testing::XServer::WaitForEventOfType(Display(), ButtonPress, -1, -1, 1000));
-
- XNextEvent(Display(), &btn);
- ASSERT_EQ(btn.xbutton.type, ButtonPress);
- ASSERT_EQ(btn.xbutton.button, 3U);
-}
-
-TEST(SynapticsClickPad, HotPlugSoftButtons)
-{
-#ifndef INPUT_PROP_BUTTONPAD
- SCOPED_TRACE("<linux/input.h>'s INPUT_PROP_BUTTONPAD is missing.\n"
- "Clickpad detection will not work on this kernel");
-#endif
- std::unique_ptr<xorg::testing::evemu::Device> dev;
-
- dev = std::unique_ptr<xorg::testing::evemu::Device>(
- new xorg::testing::evemu::Device(
- RECORDINGS_DIR "touchpads/SynPS2-Synaptics-TouchPad-Clickpad.desc"
- )
- );
-
- XOrgConfig config;
- XITServer server;
-
- config.SetAutoAddDevices(true);
- config.AddDefaultScreenWithDriver();
- server.Start(config);
-
- ::Display *dpy = XOpenDisplay(server.GetDisplayString().c_str());
- int major = 2;
- int minor = 0;
- ASSERT_EQ(Success, XIQueryVersion(dpy, &major, &minor));
-
- int deviceid;
- int ndevices = FindInputDeviceByName(dpy, "SynPS/2 Synaptics TouchPad", &deviceid);
- ASSERT_GT(ndevices, 0);
- EXPECT_EQ(ndevices, 1) << "More than one touchpad found, cannot "
- "guarantee right behaviour.";
-
- ASSERT_PROPERTY(char, prop_clickpad, dpy, deviceid, "Synaptics ClickPad");
- ASSERT_EQ(prop_clickpad.type, XA_INTEGER);
- ASSERT_EQ(prop_clickpad.format, 8);
- ASSERT_EQ(prop_clickpad.nitems, 1U);
-
-#ifdef INPUT_PROP_BUTTONPAD
- ASSERT_EQ(prop_clickpad.data[0], 1);
-#else
- ASSERT_EQ(prop_clickpad.data[0], 0) << "Not expecting ClickPad to be set on a kernel without INPUT_PROP_BUTTONPAD";
-#endif
-
- /* This option is assigned by the xorg.conf.d, it won't activate for
- xorg.conf devices. */
-#ifndef INPUT_PROP_BUTTONPAD
- int prop = XInternAtom(dpy, "Synaptics Soft Button Areas", True);
- ASSERT_EQ(prop, (Atom)None) << "Not expecting Soft Buttons property on non-clickpads";
- return;
-#endif
-
- ASSERT_PROPERTY(int, prop_softbutton, dpy, deviceid, "Synaptics Soft Button Areas");
-
- ASSERT_EQ(prop_softbutton.format, 32);
- ASSERT_EQ(prop_softbutton.nitems, 8U);
- ASSERT_EQ(prop_softbutton.type, XA_INTEGER);
-
- ASSERT_EQ(prop_softbutton.data[0], 3472);
- ASSERT_EQ(prop_softbutton.data[1], 0);
- ASSERT_EQ(prop_softbutton.data[2], 3900);
- ASSERT_EQ(prop_softbutton.data[3], 0);
- ASSERT_EQ(prop_softbutton.data[4], 0);
- ASSERT_EQ(prop_softbutton.data[5], 0);
- ASSERT_EQ(prop_softbutton.data[6], 0);
- ASSERT_EQ(prop_softbutton.data[7], 0);
-
- config.RemoveConfig();
- server.RemoveLogFile();
-}
-
-class SynapticsScrollButtonTest : public SynapticsTest {
-public:
- virtual void SetUp() {
- SetDevice("touchpads/SynPS2-Synaptics-TouchPad-ScrollButtons.events");
- XITServerInputTest::SetUp();
- }
-
- virtual void SetUpConfigAndLog() {
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("synaptics", "--device--",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"GrabEventDevice\" \"1\"\n"
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"\n");
- config.WriteConfig();
- }
-
-};
-
-TEST_F(SynapticsScrollButtonTest, ScrollButtonPropertyExists)
-{
- XORG_TESTCASE("Initialize with a touchpad with scroll buttons\n"
- "Make sure the scroll button properties exists\n");
-
- ::Display *dpy = Display();
- int deviceid;
- ASSERT_TRUE(FindInputDeviceByName(dpy, "--device--", &deviceid));
-
- XITProperty<char> scrollbutton_prop(dpy, deviceid, "Synaptics Button Scrolling");
- XITProperty<char> scrollbutton_repeat_prop(dpy, deviceid, "Synaptics Button Scrolling Repeat");
- XITProperty<int> scrollbutton_time_prop(dpy, deviceid, "Synaptics Button Scrolling Time");
-}
-
-TEST_F(SynapticsScrollButtonTest, ScrollButtonUpDownScroll)
-{
- XORG_TESTCASE("Initialize with a touchpad with scroll buttons\n"
- "Trigger events for BTN_0 and BTN_1\n"
- "Expect up/down scrolling, respectively\n");
-
- ::Display *dpy = Display();
- int deviceid;
- ASSERT_TRUE(FindInputDeviceByName(dpy, "--device--", &deviceid));
-
- XSelectInput(dpy, DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
-
- dev->PlayOne(EV_KEY, BTN_0, 1, true);
- dev->PlayOne(EV_KEY, BTN_0, 0, true);
- dev->PlayOne(EV_KEY, BTN_0, 1, true);
- dev->PlayOne(EV_KEY, BTN_0, 0, true);
-
- ASSERT_EVENT(XEvent, up1, dpy, ButtonPress);
- ASSERT_EVENT(XEvent, up2, dpy, ButtonRelease);
- ASSERT_EVENT(XEvent, up3, dpy, ButtonPress);
- ASSERT_EVENT(XEvent, up4, dpy, ButtonRelease);
-
- ASSERT_EQ(up1->xbutton.button, 4U);
- ASSERT_EQ(up2->xbutton.button, 4U);
- ASSERT_EQ(up3->xbutton.button, 4U);
- ASSERT_EQ(up4->xbutton.button, 4U);
-
- dev->PlayOne(EV_KEY, BTN_1, 1, true);
- dev->PlayOne(EV_KEY, BTN_1, 0, true);
- dev->PlayOne(EV_KEY, BTN_1, 1, true);
- dev->PlayOne(EV_KEY, BTN_1, 0, true);
-
- ASSERT_EVENT(XEvent, down1, dpy, ButtonPress);
- ASSERT_EVENT(XEvent, down2, dpy, ButtonRelease);
- ASSERT_EVENT(XEvent, down3, dpy, ButtonPress);
- ASSERT_EVENT(XEvent, down4, dpy, ButtonRelease);
-
- ASSERT_EQ(down1->xbutton.button, 5U);
- ASSERT_EQ(down2->xbutton.button, 5U);
- ASSERT_EQ(down3->xbutton.button, 5U);
- ASSERT_EQ(down4->xbutton.button, 5U);
-}
-
-TEST_F(SynapticsScrollButtonTest, ScrollButtonUpDownMiddleDouble)
-{
- XORG_TESTCASE("Initialize with a touchpad with scroll buttons\n"
- "Disable up/down scrolling through property\n"
- "Trigger events for BTN_0 and BTN_1\n"
- "Expect middle and double-click, respectively\n");
-
- ::Display *dpy = Display();
- int deviceid;
- ASSERT_TRUE(FindInputDeviceByName(dpy, "--device--", &deviceid));
-
- ASSERT_PROPERTY(char, scrollbutton_prop, dpy, deviceid, "Synaptics Button Scrolling");
- scrollbutton_prop.data[0] = 0;
- scrollbutton_prop.Update();
-
- XSelectInput(dpy, DefaultRootWindow(Display()), ButtonPressMask | ButtonReleaseMask);
-
- dev->PlayOne(EV_KEY, BTN_0, 1, true);
- dev->PlayOne(EV_KEY, BTN_0, 0, true);
-
- ASSERT_EVENT(XEvent, double1, dpy, ButtonPress);
- ASSERT_EVENT(XEvent, double2, dpy, ButtonRelease);
- ASSERT_EVENT(XEvent, double3, dpy, ButtonPress);
- ASSERT_EVENT(XEvent, double4, dpy, ButtonRelease);
-
- ASSERT_EQ(double1->xbutton.button, 1U);
- ASSERT_EQ(double2->xbutton.button, 1U);
- ASSERT_EQ(double3->xbutton.button, 1U);
- ASSERT_EQ(double4->xbutton.button, 1U);
-
- dev->PlayOne(EV_KEY, BTN_1, 1, true);
- dev->PlayOne(EV_KEY, BTN_1, 0, true);
- dev->PlayOne(EV_KEY, BTN_1, 1, true);
- dev->PlayOne(EV_KEY, BTN_1, 0, true);
-
- ASSERT_EVENT(XEvent, middle1, dpy, ButtonPress);
- ASSERT_EVENT(XEvent, middle2, dpy, ButtonRelease);
- ASSERT_EVENT(XEvent, middle3, dpy, ButtonPress);
- ASSERT_EVENT(XEvent, middle4, dpy, ButtonRelease);
-
- ASSERT_EQ(middle1->xbutton.button, 2U);
- ASSERT_EQ(middle2->xbutton.button, 2U);
- ASSERT_EQ(middle3->xbutton.button, 2U);
- ASSERT_EQ(middle4->xbutton.button, 2U);
-}
-
-class SynapticsSecondarySoftButtonTest : public SynapticsClickpadTest {
-public:
- /**
- * Initializes a standard touchpad device.
- */
- virtual void SetUp() {
- SetDevice("touchpads/SynPS2-Synaptics-TouchPad-T440.desc");
-
- xi2_major_minimum = 2;
- xi2_minor_minimum = 1;
-
- XITServerInputTest::SetUp();
- }
-
- /**
- * Sets up an xorg.conf for a single synaptics CorePointer device based on
- * the evemu device. Options enabled: tapping (1 finger), two-finger
- * vertical scroll.
- */
- virtual void SetUpConfigAndLog() {
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("synaptics", "--device--",
- "Option \"Protocol\" \"event\"\n"
- "Option \"CorePointer\" \"on\"\n"
- "Option \"TapButton1\" \"1\"\n"
- "Option \"GrabEventDevice\" \"1\"\n"
- "Option \"FastTaps\" \"1\"\n"
- "Option \"VertTwoFingerScroll\" \"1\"\n"
- "Option \"SecondarySoftButtonAreas\" \"58% 0 0 8% 42% 58% 0 8%\"\n"
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"\n");
- config.WriteConfig();
- }
-};
-
-TEST_F(SynapticsSecondarySoftButtonTest, PropertyExists)
-{
- XORG_TESTCASE("Start with a default value for SecondarySoftButtonAreas\n"
- "Expect the property to exist and be non-zero");
-
- ::Display *dpy = Display();
- int deviceid;
- ASSERT_EQ(FindInputDeviceByName(dpy, "--device--", &deviceid), 1);
-
- ASSERT_PROPERTY(int, prop, dpy, deviceid, "Synaptics Secondary Soft Button Areas");
-
- ASSERT_EQ(prop.type, XA_INTEGER);
- ASSERT_EQ(prop.nitems, 8U);
- ASSERT_EQ(prop.format, 32);
-
- ASSERT_NE(prop.data[0], 0);
- ASSERT_NE(prop.data[3], 0);
- ASSERT_NE(prop.data[4], 0);
- ASSERT_NE(prop.data[5], 0);
- ASSERT_NE(prop.data[7], 0);
-
- ASSERT_EQ(prop.data[1], 0);
- ASSERT_EQ(prop.data[2], 0);
- ASSERT_EQ(prop.data[6], 0);
-}
-
-TEST_F(SynapticsSecondarySoftButtonTest, NoMovementWithinTopButtons)
-{
- XORG_TESTCASE("Start with the top buttons enabled\n"
- "Put a finger down in the top buttons\n"
- "Move finger across, staying in the area\n"
- "Don't expect events\n");
-
- ::Display *dpy = Display();
-
- XSelectInput(dpy, DefaultRootWindow(dpy), PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
-
- TouchBegin(0, 1500, 1500);
- TouchUpdate(0, 1600, 1500);
- TouchUpdate(0, 1700, 1500);
- TouchEnd(0);
-
- ASSERT_TRUE(NoEventPending(dpy));
-}
-
-TEST_F(SynapticsSecondarySoftButtonTest, NoMovementInTopButtonsAfterClick)
-{
- XORG_TESTCASE("Start with the top buttons enabled\n"
- "Put a finger down in the top buttons\n"
- "Press\n"
- "Move finger out of button area\n"
- "Don't expect motion events\n");
-
- ::Display *dpy = Display();
-
- XSelectInput(dpy, DefaultRootWindow(dpy), PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
-
- TouchBegin(0, 1500, 1500);
- dev->PlayOne(EV_KEY, BTN_LEFT, 1, true);
- TouchUpdate(0, 1600, 1500);
- TouchUpdate(0, 1700, 1500);
-
- ASSERT_EVENT(XEvent, press, dpy, ButtonPress);
- ASSERT_TRUE(NoEventPending(dpy));
-
- dev->PlayOne(EV_KEY, BTN_LEFT, 0, true);
- TouchEnd(0);
- ASSERT_EVENT(XEvent, release, dpy, ButtonRelease);
-}
-
-TEST_F(SynapticsSecondarySoftButtonTest, MovementInTopButtonsMovingOut)
-{
- XORG_TESTCASE("Start with the top buttons enabled\n"
- "Put a finger down in the top buttons\n"
- "Move finger out of the buttons\n"
- "Expect motion events\n");
-
- ::Display *dpy = Display();
-
- XSelectInput(dpy, DefaultRootWindow(dpy), PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
-
- TouchBegin(0, 1500, 1500);
- TouchUpdate(0, 1600, 2600);
- TouchUpdate(0, 1700, 3500);
- TouchEnd(0);
-
- ASSERT_EVENT(XEvent, motion, dpy, MotionNotify);
-}
-
-TEST_F(SynapticsSecondarySoftButtonTest, MovementIntoTopButtons)
-{
- XORG_TESTCASE("Start with the top buttons enabled\n"
- "Put a finger down outside the top buttons\n"
- "Move finger into the buttons\n"
- "Expect motion events\n"
- "Move finger within the buttons\n"
- "Expect motion events\n");
-
- ::Display *dpy = Display();
-
- XSelectInput(dpy, DefaultRootWindow(dpy), PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
-
- TouchBegin(0, 1500, 3500);
- TouchUpdate(0, 1500, 2500);
- TouchUpdate(0, 1500, 1500);
-
- while (XPending(dpy)) {
- ASSERT_EVENT(XEvent, motion, dpy, MotionNotify);
- XSync(dpy, False);
- }
-
- TouchUpdate(0, 1600, 1500);
- TouchUpdate(0, 1700, 1500);
- TouchUpdate(0, 1800, 1500);
- TouchUpdate(0, 1900, 1500);
-
- TouchEnd(0);
-
- ASSERT_EVENT(XEvent, motion, dpy, MotionNotify);
- while (XPending(dpy)) {
- ASSERT_EVENT(XEvent, motion, dpy, MotionNotify);
- XSync(dpy, False);
- }
-}
-
-TEST_F(SynapticsSecondarySoftButtonTest, TopButtonLeftClick)
-{
- XORG_TESTCASE("Start with the top buttons set\n"
- "Put a finger down in the top buttons\n"
- "Click\n"
- "Expect left click\n");
-
- ::Display *dpy = Display();
-
- XSelectInput(dpy, DefaultRootWindow(dpy), PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
-
- TouchBegin(0, 1500, 1500);
- dev->PlayOne(EV_KEY, BTN_LEFT, 1, true);
- dev->PlayOne(EV_KEY, BTN_LEFT, 0, true);
- TouchEnd(0);
-
- ASSERT_EVENT(XEvent, press, dpy, ButtonPress);
- ASSERT_EVENT(XEvent, release, dpy, ButtonRelease);
- ASSERT_EQ(press->xbutton.button, 1U);
- ASSERT_EQ(release->xbutton.button, 1U);
-}
-
-TEST_F(SynapticsSecondarySoftButtonTest, TopButtonRightClick)
-{
- XORG_TESTCASE("Start with the top buttons set\n"
- "Put a finger down in the top buttons\n"
- "Click\n"
- "Expect right click\n");
-
- ::Display *dpy = Display();
-
- XSelectInput(dpy, DefaultRootWindow(dpy), PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
-
- TouchBegin(0, 4500, 1500);
- dev->PlayOne(EV_KEY, BTN_LEFT, 1, true);
- dev->PlayOne(EV_KEY, BTN_LEFT, 0, true);
- TouchEnd(0);
-
- ASSERT_EVENT(XEvent, press, dpy, ButtonPress);
- ASSERT_EVENT(XEvent, release, dpy, ButtonRelease);
- ASSERT_EQ(press->xbutton.button, 3U);
- ASSERT_EQ(release->xbutton.button, 3U);
-}
-
-TEST_F(SynapticsSecondarySoftButtonTest, TopButtonMiddleClick)
-{
- XORG_TESTCASE("Start with the top buttons set\n"
- "Put a finger down in the top buttons\n"
- "Click\n"
- "Expect middle click\n");
-
- ::Display *dpy = Display();
-
- XSelectInput(dpy, DefaultRootWindow(dpy), PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
-
- TouchBegin(0, 3292, 1500);
- dev->PlayOne(EV_KEY, BTN_LEFT, 1, true);
- dev->PlayOne(EV_KEY, BTN_LEFT, 0, true);
- TouchEnd(0);
-
- ASSERT_EVENT(XEvent, press, dpy, ButtonPress);
- ASSERT_EVENT(XEvent, release, dpy, ButtonRelease);
- ASSERT_EQ(press->xbutton.button, 2U);
- ASSERT_EQ(release->xbutton.button, 2U);
-}
-
-int main(int argc, char **argv) {
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/tests/input/wacom-hovering-expresskeys.cpp b/tests/input/wacom-hovering-expresskeys.cpp
deleted file mode 100644
index 3060d96..0000000
--- a/tests/input/wacom-hovering-expresskeys.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright © 2012-2013 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- */
-
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdexcept>
-#include <map>
-#include <unistd.h>
-
-#include <xorg/gtest/xorg-gtest.h>
-#include <linux/input.h>
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xutil.h>
-#include <X11/extensions/XInput.h>
-#include <X11/extensions/XInput2.h>
-
-#include <stdexcept>
-#include <fstream>
-#include <xorg/gtest/xorg-gtest.h>
-
-#include <wacom-properties.h>
-#include <xserver-properties.h>
-#include <unistd.h>
-
-#include "xit-server-input-test.h"
-#include "device-interface.h"
-#include "helpers.h"
-
-#define EV_MASK KeyPressMask | KeyReleaseMask | ButtonPressMask | \
- ButtonReleaseMask | EnterWindowMask | \
- LeaveWindowMask | PointerMotionMask | \
- ButtonMotionMask | KeymapStateMask | \
- ExposureMask | VisibilityChangeMask | \
- StructureNotifyMask
-
-/**
- * Wacom driver test class. This class takes a struct Tablet that defines
- * which device should be initialised.
- */
-class WacomHoveringTest : public XITServerInputTest,
- public DeviceInterface {
-public:
- /**
- * Initializes a standard tablet device.
- */
- virtual void SetUp() {
- SetDevice("tablets/Wacom-Intuos5-touch-M-Pen.desc");
- XITServerInputTest::SetUp();
- }
-
- /**
- * Sets up an xorg.conf for a single mouse CorePointer device based on
- * the evemu device.
- */
- virtual void SetUpConfigAndLog() {
- server.SetOption("-retro", "");
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("wacom", "Stylus",
- "Option \"Type\" \"stylus\"\n"
- "Option \"DebugLevel\" \"3\"\n"
- "Option \"CommonDBG\" \"3\"\n"
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"\n");
- config.AddInputSection("wacom", "Pad",
- "Option \"Type\" \"pad\"\n"
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"\n");
- config.AddInputSection("wacom", "Cursor",
- "Option \"Type\" \"cursor\"\n"
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"\n");
- config.AddInputSection("wacom", "Eraser",
- "Option \"Type\" \"eraser\"\n"
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"\n");
- config.WriteConfig();
- }
-};
-
-/**
- * FIXME: look at this test - is it still useful?
- */
-TEST_F(WacomHoveringTest, DISABLED_HoveringTest)
-{
- XORG_TESTCASE("Test that hovering the Expresskeys pad while "
- "using the stylus does not generate spurious "
- "motion events to (0,0).\n"
- "Note: This test is useless since the problem cannot be reproduced via evemu\n"
- "https://bugs.freedesktop.org/show_bug.cgi?id=54250");
-
- XEvent ev;
- Window win;
- unsigned long white, black;
-
- /* the server takes a while to start up but the devices may not respond
- to events yet. Add a noop call that just delays everything long
- enough for this test to work */
- XInternAtom(Display(), "foo", True);
- XFlush(Display());
-
- white = WhitePixel(Display(), DefaultScreen (Display()));
- black = BlackPixel(Display(), DefaultScreen (Display()));
-
- // Create a fullscreen window
- win = XCreateSimpleWindow (Display(),
- DefaultRootWindow(Display()),
- 20, 20, 600, 600, 10, black, white);
-
- XSelectInput(Display(), win, EV_MASK);
-
- XMapWindow (Display(), win);
- XSync(Display(), False);
- ASSERT_TRUE(xorg::testing::XServer::WaitForEventOfType(Display(), Expose, -1, -1, 1000));
-
- // Play the recorded events
- dev->Play(RECORDINGS_DIR "tablets/Wacom-Intuos5-touch-M-Pen-hovering-expresskeys.events");
-
- XSync (Display(), False);
- EXPECT_NE(XPending(Display()), 0) << "No event received??" << std::endl;
-
- // Capture events and check for spurious motion events to (0,0) caused by hovering the Expresskeys
- while(XPending(Display())) {
- XNextEvent(Display(), &ev);
- if (ev.type == MotionNotify) {
- EXPECT_FALSE (ev.xmotion.x_root == 0 && ev.xmotion.y_root == 0);
- } else if (ev.type == EnterNotify || ev.type == LeaveNotify) {
- EXPECT_FALSE (ev.xcrossing.x_root == 0 && ev.xcrossing.y_root == 0);
- }
- }
-}
diff --git a/tests/input/wacom-input-matrix.cpp b/tests/input/wacom-input-matrix.cpp
deleted file mode 100644
index 472a2e6..0000000
--- a/tests/input/wacom-input-matrix.cpp
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright © 2012-2013 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- */
-
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdexcept>
-#include <map>
-#include <unistd.h>
-
-#include <xorg/gtest/xorg-gtest.h>
-#include <linux/input.h>
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xutil.h>
-#include <X11/extensions/XInput.h>
-#include <X11/extensions/XInput2.h>
-
-#include <stdexcept>
-#include <fstream>
-#include <xorg/gtest/xorg-gtest.h>
-
-#include <X11/extensions/XInput.h>
-#include <X11/extensions/XInput2.h>
-
-#include <wacom-properties.h>
-#include <xserver-properties.h>
-#include <unistd.h>
-
-#include "xit-server-input-test.h"
-#include "device-interface.h"
-#include "helpers.h"
-
-#define NUM_ELEMS_MATRIX 9
-
-typedef struct Matrix {
- float elem[NUM_ELEMS_MATRIX];
-} Matrix;
-
-/**
- * Wacom driver test class. This class takes a struct Tablet that defines
- * which device should be initialised.
- */
-class WacomMatrixTest : public XITServerInputTest,
- public DeviceInterface {
-public:
- /**
- * Initializes a standard tablet device.
- */
- virtual void SetUp() {
- SetDevice("tablets/Wacom-Intuos5-touch-M-Pen.desc");
- XITServerInputTest::SetUp();
- }
-
- /**
- * Sets up an xorg.conf for a single mouse CorePointer device based on
- * the evemu device.
- */
- virtual void SetUpConfigAndLog() {
-
- config.AddDefaultScreenWithDriver();
- config.AddInputSection("wacom", "Stylus",
- "Option \"CorePointer\" \"on\"\n"
- "Option \"Type\" \"stylus\"\n"
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"\n");
-
- config.WriteConfig();
- }
-protected:
- int xrandr_event, xrandr_error;
-};
-
-TEST_F(WacomMatrixTest, DevicePresent)
-{
- XORG_TESTCASE("Test presence of tools as defined in the xorg.conf");
-
- int ndevices;
- XIDeviceInfo *info;
-
- info = XIQueryDevice(Display(), XIAllDevices, &ndevices);
-
- bool found = false;
- while(ndevices--) {
- if (strcmp(info[ndevices].name, "Stylus") == 0) {
- ASSERT_EQ(found, false) << "Duplicate device" << std::endl;
- found = true;
- }
- }
- ASSERT_EQ(found, true);
- XIFreeDeviceInfo(info);
-}
-
-bool set_input_matrix (Display *dpy, int deviceid, Matrix *matrix)
-{
- Atom prop_float, prop_matrix;
-
- union {
- unsigned char *c;
- float *f;
- } data;
- int format_return;
- Atom type_return;
- unsigned long nitems;
- unsigned long bytes_after;
- int rc;
-
- prop_float = XInternAtom(dpy, "FLOAT", False);
- prop_matrix = XInternAtom(dpy, XI_PROP_TRANSFORM, False);
-
- if (!prop_float)
- return False;
-
- if (!prop_matrix)
- return False;
-
- rc = XIGetProperty(dpy, deviceid, prop_matrix, 0, 9, False, prop_float,
- &type_return, &format_return, &nitems, &bytes_after,
- &data.c);
-
- if (rc != Success || prop_float != type_return || format_return != 32 ||
- nitems != NUM_ELEMS_MATRIX || bytes_after != 0)
- return False;
-
- memcpy(data.f, matrix->elem, sizeof(matrix->elem));
-
- XIChangeProperty(dpy, deviceid, prop_matrix, prop_float,
- format_return, PropModeReplace, data.c, nitems);
-
- XFree(data.c);
-
- return True;
-}
-
-/**
- * compute the input trarnsformation matrix to match the area specified
- * by the given (x,y) width x height.
- */
-Bool compute_input_matrix (Display *dpy, int x, int y, int width, int height, Matrix *matrix)
-{
- // Reset matrix to no transformation by default
- matrix->elem[0] = 1.0f;
- matrix->elem[1] = 0.0f;
- matrix->elem[2] = 0.0f;
- matrix->elem[3] = 0.0f;
- matrix->elem[4] = 1.0f;
- matrix->elem[5] = 0.0f;
- matrix->elem[6] = 0.0f;
- matrix->elem[7] = 0.0f;
- matrix->elem[8] = 1.0f;
-
- int screen_x = 0;
- int screen_y = 0;
- int screen_width = WidthOfScreen (DefaultScreenOfDisplay (dpy));
- int screen_height = HeightOfScreen (DefaultScreenOfDisplay (dpy));
-
- if ((x < screen_x) ||
- (y < screen_y) ||
- (x + width > screen_x + screen_width) ||
- (y + height > screen_y + screen_height))
- return False;
-
- float x_scale = (float) x / screen_width;
- float y_scale = (float) y / screen_height;
- float width_scale = (float) width / screen_width;
- float height_scale = (float) height / screen_height;
-
- matrix->elem[0] = width_scale;
- matrix->elem[1] = 0.0f;
- matrix->elem[2] = x_scale;
-
- matrix->elem[3] = 0.0f;
- matrix->elem[4] = height_scale;
- matrix->elem[5] = y_scale;
-
- matrix->elem[6] = 0.0f;
- matrix->elem[7] = 0.0f;
- matrix->elem[8] = 1.0f;
-
- return True;
-}
-
-/**
- * Moves the stylus from x1/y1 to x2/y2 in 3 steps
- */
-void move_stylus (xorg::testing::evemu::Device *dev,
- int x1, int y1, int x2, int y2)
-{
- dev->PlayOne(EV_ABS, ABS_X, x1, True);
- dev->PlayOne(EV_ABS, ABS_Y, y1, True);
- dev->PlayOne(EV_ABS, ABS_DISTANCE, 0, True);
- dev->PlayOne(EV_KEY, BTN_TOOL_PEN, 1, True);
-
- dev->PlayOne(EV_ABS, ABS_X, x1 + (x2 - x1)/2, True);
- dev->PlayOne(EV_ABS, ABS_Y, y1 + (y2 - y1)/2, True);
- dev->PlayOne(EV_ABS, ABS_DISTANCE, 0, True);
- dev->PlayOne(EV_KEY, BTN_TOOL_PEN, 1, True);
-
- dev->PlayOne(EV_ABS, ABS_X, x2, True);
- dev->PlayOne(EV_ABS, ABS_Y, y2, True);
- dev->PlayOne(EV_ABS, ABS_DISTANCE, 0, True);
- dev->PlayOne(EV_KEY, BTN_TOOL_PEN, 1, True);
-
- dev->PlayOne(EV_KEY, BTN_TOOL_PEN, 0, True);
-}
-
-void test_area (Display *dpy, xorg::testing::evemu::Device *dev,
- int deviceid, int x, int y, int width, int height)
-{
- XEvent ev;
-
- Matrix matrix;
- compute_input_matrix (dpy, x, y, width, height, &matrix);
- ASSERT_TRUE (set_input_matrix (dpy, deviceid, &matrix));
-
- XSync(dpy, True);
-
- // Simulate stylus movement for the entire tablet resolution
- int minx, maxx;
- int miny, maxy;
-
- dev->GetAbsData(ABS_X, &minx, &maxx);
- dev->GetAbsData(ABS_Y, &miny, &maxy);
-
- move_stylus (dev, 0, 0, maxx, 0);
- move_stylus (dev, maxx, 0, maxx, maxy);
- move_stylus (dev, maxx, maxy, 0, maxy);
- move_stylus (dev, 0, maxy, 0, 0);
-
- XSync (dpy, False);
- EXPECT_NE(XPending(dpy), 0) << "No event received??" << std::endl;
-
- // Capture motion events and check they remain within the mapped area
- XSync (dpy, False);
- while(XCheckMaskEvent (dpy, PointerMotionMask, &ev)) {
- EXPECT_GE (ev.xmotion.x_root, x);
- EXPECT_LT (ev.xmotion.x_root, x + width);
- EXPECT_GE (ev.xmotion.y_root, y);
- EXPECT_LE (ev.xmotion.y_root, y + height);
- }
-
- XSync(dpy, True);
-}
-
-TEST_F(WacomMatrixTest, InputMatrix)
-{
- XORG_TESTCASE("Test input transformation matrix");
-
- /* the server takes a while to start up but the devices may not respond
- to events yet. Add a noop call that just delays everything long
- enough for this test to work */
- XInternAtom(Display(), "foo", True);
- XFlush(Display());
-
- EXPECT_TRUE(InitRandRSupport(Display(), &xrandr_event, &xrandr_error));
-
- int monitor_x, monitor_y, monitor_width, monitor_height;
- int n_monitors = GetNMonitors (Display());
-
- monitor_x = 0;
- monitor_y = 0;
- monitor_width = WidthOfScreen (DefaultScreenOfDisplay (Display()));
- monitor_height = HeightOfScreen (DefaultScreenOfDisplay (Display()));
-
- if (n_monitors > 0)
- GetMonitorGeometry (Display(), 0, &monitor_x, &monitor_y, &monitor_width, &monitor_height);
-
- int deviceid;
- FindInputDeviceByName(Display(), "Stylus", &deviceid);
- ASSERT_NE (deviceid, 0);
-
- XSelectInput(Display(), DefaultRootWindow(Display()), PointerMotionMask |
- ButtonMotionMask);
- XSync(Display(), False);
-
- // Check with upper left quarter
- test_area (Display(), dev.get(), deviceid, monitor_x, monitor_y, monitor_width / 2, monitor_height / 2);
-
- // Check with upper right quarter
- test_area (Display(), dev.get(), deviceid, monitor_x + monitor_width / 2, monitor_y, monitor_width / 2, monitor_height / 2);
-
- // Check with bottom left quarter
- test_area (Display(), dev.get(), deviceid, monitor_x, monitor_y + monitor_height / 2, monitor_width / 2, monitor_height / 2);
-
- // Check with bottom right quarter
- test_area (Display(), dev.get(), deviceid, monitor_x + monitor_width / 2, monitor_y + monitor_height / 2, monitor_width / 2, monitor_height / 2);
-}
diff --git a/tests/input/wacom.cpp b/tests/input/wacom.cpp
deleted file mode 100644
index a7dd832..0000000
--- a/tests/input/wacom.cpp
+++ /dev/null
@@ -1,866 +0,0 @@
-/*
- * Copyright © 2012-2013 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- */
-
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdexcept>
-#include <stdint.h>
-#include <map>
-#include <unistd.h>
-
-#include <xorg/gtest/xorg-gtest.h>
-#include <linux/input.h>
-
-#include <X11/Xlib.h>
-#include <X11/XKBlib.h>
-#include <X11/Xatom.h>
-#define XK_LATIN1
-#include <X11/keysymdef.h>
-#include <X11/XF86keysym.h>
-#include <X11/Xutil.h>
-#include <X11/extensions/XInput.h>
-#include <X11/extensions/XInput2.h>
-
-#include "wacom_devs.h"
-
-#include <stdexcept>
-#include <fstream>
-#include <xorg/gtest/xorg-gtest.h>
-
-#include <X11/extensions/XInput.h>
-#include <X11/extensions/XInput2.h>
-
-#include <wacom-properties.h>
-#include <unistd.h>
-
-#include "xit-server-input-test.h"
-#include "xit-property.h"
-#include "xit-event.h"
-#include "device-interface.h"
-#include "helpers.h"
-
-/**
- * Wacom driver test class for one device (Intuos4). Use this to test driver
- * features that don't depend on the actual device much.
- */
-class WacomDeviceTest : public XITServerInputTest,
- public DeviceInterface {
-public:
-
- /**
- * @return button number for idx minus the 4 scroll buttons
- */
- virtual int ButtonNumber(int idx) const {
- return ((idx > 3) ? idx - 4 : idx);
- }
-
- virtual void TipDown(void) {
- dev->PlayOne(EV_ABS, ABS_X, 4000);
- dev->PlayOne(EV_ABS, ABS_Y, 4000);
- dev->PlayOne(EV_KEY, BTN_TOOL_PEN, 1);
- dev->PlayOne(EV_SYN, SYN_REPORT, 0);
-
- dev->PlayOne(EV_ABS, ABS_X, 4200);
- dev->PlayOne(EV_ABS, ABS_Y, 4200);
- dev->PlayOne(EV_ABS, ABS_DISTANCE, 0);
- dev->PlayOne(EV_ABS, ABS_PRESSURE, 70);
- dev->PlayOne(EV_KEY, BTN_TOUCH, 1);
- dev->PlayOne(EV_SYN, SYN_REPORT, 0);
- }
-
- virtual void TipUp(void) {
- dev->PlayOne(EV_ABS, ABS_X, 4000);
- dev->PlayOne(EV_ABS, ABS_Y, 4000);
- dev->PlayOne(EV_ABS, ABS_DISTANCE, 0);
- dev->PlayOne(EV_ABS, ABS_PRESSURE, 0);
- dev->PlayOne(EV_KEY, BTN_TOOL_PEN, 0);
- dev->PlayOne(EV_KEY, BTN_TOUCH, 0);
- dev->PlayOne(EV_SYN, SYN_REPORT, 0);
- }
-
- virtual void SetUp()
- {
- SetDevice("tablets/Wacom-Intuos4-6x9.desc");
-
- XITServerInputTest::SetUp();
- }
-
- virtual void SetUpConfigAndLog() {
- config.AddDefaultScreenWithDriver();
- config.AddInputClass("wacom", "MatchDriver \"wacom\"",
- "Option \"GrabDevice\" \"on\""
- "Option \"CommonDBG\" \"12\""
- "Option \"DebugLevel\" \"12\"");
- config.SetAutoAddDevices(true);
- config.WriteConfig();
- }
-};
-
-
-/**
- * Wacom driver test class. This class takes a struct Tablet that defines
- * which device should be initialised.
- */
-class WacomDriverTest : public WacomDeviceTest,
- public ::testing::WithParamInterface<Tablet> {
-protected:
- /**
- * Write a configuration file for a hotplug-enabled server using the
- * dummy video driver.
- */
- virtual void SetUpConfigAndLog() {
- config.AddDefaultScreenWithDriver();
- config.SetAutoAddDevices(true);
- config.WriteConfig();
- }
-
- /**
- * Create an evemu device based on GetParam()'s tablet.
- */
- void VerifyDevice (const Tablet& tablet)
- {
- char tool_name[255];
-
- if (tablet.stylus) {
- snprintf (tool_name, sizeof (tool_name), "%s %s", tablet.name, tablet.stylus);
- if (!FindInputDeviceByName(Display(), tool_name)) {
- ASSERT_TRUE(WaitForDevice(tool_name, 5000))
- << "Tool '" << tool_name << "' not found" << std::endl;
- }
- }
-
- if (tablet.eraser) {
- snprintf (tool_name, sizeof (tool_name), "%s %s", tablet.name, tablet.eraser);
- if (!FindInputDeviceByName(Display(), tool_name)) {
- ASSERT_TRUE(WaitForDevice(tool_name, 5000))
- << "Tool '" << tool_name << "' not found" << std::endl;
- }
- }
-
- if (tablet.cursor) {
- snprintf (tool_name, sizeof (tool_name), "%s %s", tablet.name, tablet.cursor);
- if (!FindInputDeviceByName(Display(), tool_name)) {
- ASSERT_TRUE(WaitForDevice(tool_name, 5000))
- << "Tool '" << tool_name << "' not found" << std::endl;
- }
- }
-
- if (tablet.touch) {
- snprintf (tool_name, sizeof (tool_name), "%s %s", tablet.name, tablet.touch);
- if (!FindInputDeviceByName(Display(), tool_name)) {
- ASSERT_TRUE(WaitForDevice(tool_name, 5000))
- << "Tool '" << tool_name << "' not found" << std::endl;
- }
- }
-
- if (tablet.pad) {
- snprintf (tool_name, sizeof (tool_name), "%s %s", tablet.name, tablet.pad);
- if (!FindInputDeviceByName(Display(), tool_name)) {
- ASSERT_TRUE(WaitForDevice(tool_name, 5000))
- << "Tool '" << tool_name << "' not found" << std::endl;
- }
- }
- }
-
- virtual void SetUp()
- {
- Tablet tablet = GetParam();
- SetDevice("tablets/" + std::string (tablet.descfile));
-
- XITServerInputTest::SetUp();
-
- VerifyDevice(tablet);
- }
-};
-
-TEST_P(WacomDriverTest, DeviceNames)
-{
- XORG_TESTCASE("Test names of the tools and type properties match the tools");
-
- Tablet tablet = GetParam();
-
- int major = 2;
- int minor = 0;
- ASSERT_EQ(Success, XIQueryVersion(Display(), &major, &minor));
-
-
- int deviceid;
- char tool_name[255];
-
- if (tablet.stylus) {
- snprintf (tool_name, sizeof (tool_name), "%s %s", tablet.name, tablet.stylus);
- ASSERT_TRUE(WaitForDevice(tool_name, 5000));
- ASSERT_EQ(FindInputDeviceByName(Display(), tool_name, &deviceid), 1) << "Tool not found " << tool_name <<std::endl;
-
- EXPECT_TRUE(DevicePropertyExists(Display(), deviceid, WACOM_PROP_PRESSURECURVE))
- << "Property " << WACOM_PROP_PRESSURECURVE << " not found on " << tool_name << std::endl;
- EXPECT_TRUE(DevicePropertyExists(Display(), deviceid, WACOM_PROP_ROTATION))
- << "Property " << WACOM_PROP_ROTATION << " not found on " << tool_name << std::endl;
- EXPECT_TRUE(DevicePropertyExists(Display(), deviceid, WACOM_PROP_TOOL_TYPE))
- << "Property " << WACOM_PROP_TOOL_TYPE << " not found on " << tool_name << std::endl;
- }
-
- if (tablet.eraser) {
- snprintf (tool_name, sizeof (tool_name), "%s %s", tablet.name, tablet.eraser);
- ASSERT_TRUE(WaitForDevice(tool_name, 5000));
- ASSERT_EQ(FindInputDeviceByName(Display(), tool_name, &deviceid), 1) << "Tool not found " << tool_name <<std::endl;
-
- EXPECT_TRUE(DevicePropertyExists(Display(), deviceid, WACOM_PROP_PRESSURECURVE))
- << "Property " << WACOM_PROP_PRESSURECURVE << " not found on " << tool_name << std::endl;
- EXPECT_TRUE(DevicePropertyExists(Display(), deviceid, WACOM_PROP_ROTATION))
- << "Property " << WACOM_PROP_ROTATION << " not found on " << tool_name << std::endl;
- }
-
- if (tablet.cursor) {
- snprintf (tool_name, sizeof (tool_name), "%s %s", tablet.name, tablet.cursor);
- ASSERT_TRUE(WaitForDevice(tool_name, 5000));
- ASSERT_EQ(FindInputDeviceByName(Display(), tool_name, &deviceid), 1) << "Tool not found " << tool_name <<std::endl;
-
- EXPECT_TRUE(DevicePropertyExists(Display(), deviceid, WACOM_PROP_WHEELBUTTONS))
- << "Property " << WACOM_PROP_WHEELBUTTONS << " not found on " << tool_name << std::endl;
- }
-
- if (tablet.pad) {
- snprintf (tool_name, sizeof (tool_name), "%s %s", tablet.name, tablet.pad);
- ASSERT_TRUE(WaitForDevice(tool_name, 5000));
- ASSERT_EQ(FindInputDeviceByName(Display(), tool_name, &deviceid), 1) << "Tool not found " << tool_name <<std::endl;
-
- EXPECT_TRUE(DevicePropertyExists(Display(), deviceid, WACOM_PROP_STRIPBUTTONS))
- << "Property " << WACOM_PROP_STRIPBUTTONS << " not found on " << tool_name << std::endl;
- }
-
- if (tablet.touch) {
- snprintf (tool_name, sizeof (tool_name), "%s %s", tablet.name, tablet.touch);
- ASSERT_TRUE(WaitForDevice(tool_name, 5000));
- ASSERT_EQ(FindInputDeviceByName(Display(), tool_name, &deviceid), 1) << "Tool not found " << tool_name <<std::endl;
-
- EXPECT_TRUE(DevicePropertyExists(Display(), deviceid, WACOM_PROP_TOUCH))
- << "Property " << WACOM_PROP_TOUCH << " not found on " << tool_name << std::endl;
- EXPECT_TRUE(DevicePropertyExists(Display(), deviceid, WACOM_PROP_ENABLE_GESTURE))
- << "Property " << WACOM_PROP_ENABLE_GESTURE << " not found on " << tool_name << std::endl;
- EXPECT_TRUE(DevicePropertyExists(Display(), deviceid, WACOM_PROP_GESTURE_PARAMETERS))
- << "Property " << WACOM_PROP_GESTURE_PARAMETERS << " not found on " << tool_name << std::endl;
- }
-}
-
-void check_for_type (Display *dpy, XIDeviceInfo *list, int ndevices, const char *type)
-{
- XIDeviceInfo *info;
- int loop;
- bool found = false;
- Atom tool_type = XInternAtom(dpy, type, True);
-
- ASSERT_NE((Atom)None, tool_type);
-
- info = list;
- for (loop = 0; loop < ndevices; loop++, info++) {
- if (DevicePropertyExists(dpy, info->deviceid, WACOM_PROP_TOOL_TYPE)) {
- ASSERT_PROPERTY(Atom, prop, dpy, info->deviceid, WACOM_PROP_TOOL_TYPE);
- if (prop.data[0] == tool_type) {
- found = True;
- break;
- }
- }
- }
- ASSERT_TRUE(found) << type << " not found" << std::endl;
-}
-
-TEST_P(WacomDriverTest, DeviceType)
-{
- XORG_TESTCASE("Test type of the tools for the device");
-
- Tablet tablet = GetParam();
-
- VerifyDevice(tablet);
-
- XIDeviceInfo *list;
- int ndevices;
- list = XIQueryDevice(Display(), XIAllDevices, &ndevices);
-
- if (tablet.stylus)
- check_for_type (Display(), list, ndevices, WACOM_PROP_XI_TYPE_STYLUS);
-
- if (tablet.eraser)
- check_for_type (Display(), list, ndevices, WACOM_PROP_XI_TYPE_ERASER);
-
- if (tablet.cursor)
- check_for_type (Display(), list, ndevices, WACOM_PROP_XI_TYPE_CURSOR);
-
- if (tablet.pad)
- check_for_type (Display(), list, ndevices, WACOM_PROP_XI_TYPE_PAD);
-
- if (tablet.touch)
- check_for_type (Display(), list, ndevices, WACOM_PROP_XI_TYPE_TOUCH);
-
- XIFreeDeviceInfo (list);
-}
-
-void set_rotate(Display *dpy, int deviceid, const char *rotate)
-{
- int rotation = 0;
-
- if (strcasecmp(rotate, "cw") == 0)
- rotation = 1;
- else if (strcasecmp(rotate, "ccw") == 0)
- rotation = 2;
- else if (strcasecmp(rotate, "half") == 0)
- rotation = 3;
-
- ASSERT_PROPERTY(char, prop, dpy, deviceid, WACOM_PROP_ROTATION);
-
- prop.data[0] = rotation;
- prop.Update();
-}
-
-int stylus_move_right (Display *dpy, xorg::testing::evemu::Device *dev)
-{
- int root_x1, root_x2;
- int loop, step;
- XEvent ev;
-
- XSync(dpy, False);
- while(XPending(dpy))
- XNextEvent(dpy, &ev);
-
- // Might be considered as uninitialized otherwise
- root_x1 = 0;
-
- // Move to device coord (1000,1000)
- dev->PlayOne(EV_ABS, ABS_X, 1000);
- dev->PlayOne(EV_ABS, ABS_Y, 1000);
- dev->PlayOne(EV_ABS, ABS_DISTANCE, 0);
- dev->PlayOne(EV_KEY, BTN_TOOL_PEN, 1, true);
-
- XSync (dpy, False);
- EXPECT_NE(XPending(dpy), 0) << "No event received??" << std::endl;
-
- // Capture motion events and save screen coordinates
- XSync (dpy, False);
- while(XCheckMaskEvent (dpy, PointerMotionMask, &ev))
- root_x1 = ev.xmotion.x_root;
-
- root_x2 = root_x1;
-
- step = 10;
- for (loop = 1000; loop < 3000; loop += step) {
- dev->PlayOne(EV_ABS, ABS_X, loop);
- dev->PlayOne(EV_ABS, ABS_DISTANCE, step, true);
- }
- dev->PlayOne(EV_KEY, BTN_TOOL_PEN, 0, true);
-
- XSync (dpy, False);
- EXPECT_NE(XPending(dpy), 0) << "Still no event received??" << std::endl;
-
- XSync (dpy, False);
- while(XCheckMaskEvent (dpy, PointerMotionMask|PointerMotionHintMask, &ev))
- root_x2 = ev.xmotion.x_root;
-
- XSync (dpy, False);
- while(XPending(dpy))
- XNextEvent(dpy, &ev);
-
- return (root_x2 - root_x1);
-}
-
-// FIXME
-// This test would fail in some random case, as it the X events were
-// not generated...
-TEST_P(WacomDriverTest, Rotation)
-{
- XORG_TESTCASE("Test rotation is applied on a device");
-
- Tablet tablet = GetParam();
-
- VerifyDevice(tablet);
- XSync(Display(), True);
-
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask |
- ButtonReleaseMask |
- PointerMotionMask |
- ButtonMotionMask);
-
- char tool_name[255];
- int displace;
- int deviceid;
-
- if (tablet.stylus) {
- snprintf (tool_name, sizeof (tool_name), "%s %s", tablet.name, tablet.stylus);
- ASSERT_EQ(FindInputDeviceByName(Display(), tool_name, &deviceid), 1) << "Tool not found " << tool_name <<std::endl;
-
- // Try with no rotation
- set_rotate (Display(), deviceid, "none");
-
- displace = stylus_move_right (Display(), dev.get());
- ASSERT_NE (displace, 0) << "Did not get any event from " << tool_name << std::endl;
- EXPECT_TRUE(displace > 0) << "Pointer moved to the wrong direction with rotate none for " << tool_name << std::endl;
-
- // Set opposite rotation
- set_rotate (Display(), deviceid, "half");
-
- displace = stylus_move_right (Display(), dev.get());
- ASSERT_NE (displace, 0) << "Did not get any event from " << tool_name << std::endl;
- EXPECT_TRUE(displace < 0) << "Pointer moved to the wrong direction with rotate half for " << tool_name << std::endl;
- }
-}
-
-INSTANTIATE_TEST_CASE_P(, WacomDriverTest,
- ::testing::ValuesIn(tablets));
-
-TEST(WacomDriver, PrivToolDoubleFree)
-{
- XORG_TESTCASE("Two devices with the same device node cause a double-free\n"
- "of priv->tool in wcmPreInitParseOptions.\n"
- "https://bugs.freedesktop.org/show_bug.cgi?id=55200");
-
- XOrgConfig config;
- XITServer server;
-
- auto stylus = std::unique_ptr<xorg::testing::evemu::Device>(
- new xorg::testing::evemu::Device(RECORDINGS_DIR "tablets/Wacom-Intuos5-touch-M-Pen.desc")
- );
-
- config.AddInputSection("wacom", "I5 stylus",
- "Option \"Device\" \"" + stylus->GetDeviceNode() + "\"\n"
- "Option \"USB\" \"on\"\n"
- "Option \"Type\" \"stylus\"\n"
- );
-
- config.AddInputSection("wacom", "I5 stylus 2",
- "Option \"Device\" \"" + stylus->GetDeviceNode() + "\"\n"
- "Option \"USB\" \"on\"\n"
- "Option \"Type\" \"stylus\"\n"
- );
- config.AddDefaultScreenWithDriver();
-
- EXPECT_NO_THROW(server.Start(config));
-}
-
-class WacomLensCursorTest : public WacomDriverTest
-{
-};
-
-TEST_P(WacomLensCursorTest, CursorMove)
-{
- ::Display *dpy = Display();
-
- XSelectInput(dpy, DefaultRootWindow(dpy), ButtonPressMask |
- ButtonReleaseMask |
- PointerMotionMask |
- ButtonMotionMask);
- XSync(dpy, False);
-
- dev->Play(RECORDINGS_DIR "tablets/Wacom-Intuos4-8x13.lens-cursor-move.events");
-
- XSync(dpy, False);
-
- ASSERT_EVENT(XEvent, m1, dpy, MotionNotify);
- ASSERT_EVENT(XEvent, m2, dpy, MotionNotify);
- ASSERT_EVENT(XEvent, m3, dpy, MotionNotify);
-}
-
-INSTANTIATE_TEST_CASE_P(, WacomLensCursorTest, ::testing::ValuesIn(lens_cursor_tablets));
-
-class WacomToolProximityTest : public XITServerInputTest,
- public DeviceInterface,
- public ::testing::WithParamInterface<int> {
-public:
- virtual void SetUpConfigAndLog() {
- std::string tool_type;
- switch (GetParam()) {
- case BTN_TOOL_PEN:
- case BTN_TOOL_BRUSH:
- case BTN_TOOL_AIRBRUSH:
- case BTN_TOOL_PENCIL:
- tool_type = "stylus";
- break;
- case BTN_TOOL_RUBBER:
- tool_type = "eraser";
- break;
- case BTN_TOOL_MOUSE:
- case BTN_TOOL_LENS:
- tool_type = "cursor";
- break;
- default:
- FAIL() << "Invalid tool type";
- }
-
- config.AddDefaultScreenWithDriver();
- config.SetAutoAddDevices(false);
- config.AddInputSection("wacom", "--cursor--",
- "Option \"Type\" \"" + tool_type + "\"\n"
- "Option \"GrabDevice\" \"off\"\n"
- "Option \"DebugLevel\" \"12\"\n"
- "Option \"CommonDBG\" \"12\"\n"
- "Option \"CursorProx\" \"63\"\n"
- "Option \"Device\" \"" + dev->GetDeviceNode() + "\"");
- config.WriteConfig();
- }
-
- virtual void SetUp() {
- SetDevice("tablets/Wacom-Intuos4-8x13.desc");
-
- int tool_type = GetParam();
-
- /* bring device into prox */
- dev->PlayOne(EV_ABS, ABS_X, 6784, false);
- dev->PlayOne(EV_ABS, ABS_Y, 2946, false);
- dev->PlayOne(EV_ABS, ABS_DISTANCE, 63, false);
- dev->PlayOne(EV_KEY, tool_type, 1, false);
- dev->PlayOne(EV_MSC, MSC_SERIAL, -494927850, true);
-
- dev->PlayOne(EV_ABS, ABS_X, 6740, false);
- dev->PlayOne(EV_ABS, ABS_DISTANCE, 45, false);
- dev->PlayOne(EV_MSC, MSC_SERIAL, -494927850, true);
-
- XITServerInputTest::SetUp();
- }
-};
-
-
-TEST_P(WacomToolProximityTest, ToolMovesOnProximity)
-{
- XORG_TESTCASE("Create device with the given tool.\n"
- "Get tool into proximity.\n"
- "Start server.\n"
- "Check that events from the tool move the cursor\n"
- "https://bugs.freedesktop.org/show_bug.cgi?id=56536");
-
- XSelectInput(Display(), DefaultRootWindow(Display()), ButtonPressMask |
- ButtonReleaseMask |
- PointerMotionMask |
- ButtonMotionMask);
- dev->PlayOne(EV_ABS, ABS_X, 6800, false);
- dev->PlayOne(EV_ABS, ABS_Y, 2900, false);
- dev->PlayOne(EV_ABS, ABS_DISTANCE, 40, false);
- dev->PlayOne(EV_MSC, MSC_SERIAL, -494927850, true);
-
- dev->PlayOne(EV_ABS, ABS_X, 6800, false);
- dev->PlayOne(EV_ABS, ABS_Y, 2900, false);
- dev->PlayOne(EV_ABS, ABS_DISTANCE, 40, false);
- dev->PlayOne(EV_MSC, MSC_SERIAL, -494927850, true);
-
-
- ASSERT_TRUE(xorg::testing::XServer::WaitForEventOfType(Display(), MotionNotify));
-}
-
-INSTANTIATE_TEST_CASE_P(, WacomToolProximityTest, ::testing::Values(BTN_TOOL_PEN,
- BTN_TOOL_AIRBRUSH,
- BTN_TOOL_PENCIL,
- BTN_TOOL_BRUSH,
- BTN_TOOL_RUBBER,
- BTN_TOOL_LENS,
- BTN_TOOL_MOUSE));
-
-
-class WacomPropertyTest : public WacomDeviceTest {
-public:
- virtual void SetUp(void) {
- std::string name = "Wacom Intuos4 6x9 stylus";
- WacomDeviceTest::SetUp();
- ASSERT_TRUE(WaitForDevice(name, 5000));
- XSync(Display(), True);
- ASSERT_EQ(FindInputDeviceByName(Display(), name, &stylus_id), 1);
- }
-
- int stylus_id;
-};
-
-TEST_F(WacomPropertyTest, ButtonActionPropertiesPresent)
-{
- XORG_TESTCASE("Ensure the button action properties are present.\n");
-
- ::Display *dpy = Display();
-
- unsigned int nbuttons = 0;
- XIDeviceInfo *info;
- int ndevices;
- info = XIQueryDevice(dpy, stylus_id, &ndevices);
- ASSERT_EQ(ndevices, 1);
- ASSERT_TRUE(info != NULL);
-
- for (int i = 0; i < info->num_classes; i++) {
- if (info->classes[i]->type != XIButtonClass)
- continue;
-
- XIButtonClassInfo *b = reinterpret_cast<XIButtonClassInfo*>(info->classes[i]);
- nbuttons = b->num_buttons;
- break;
- }
- XIFreeDeviceInfo(info);
-
- ASSERT_GT(nbuttons, 0U);
-
- ASSERT_PROPERTY(Atom, btnaction_prop, dpy, stylus_id, "Wacom Button Actions");
- ASSERT_EQ(btnaction_prop.type, XA_ATOM);
- ASSERT_EQ(btnaction_prop.nitems, nbuttons);
- ASSERT_EQ(btnaction_prop.format, 32);
-
- for (unsigned int i = 0; i < nbuttons; i++) {
- if (i >= 3 && i <= 6) { /* scroll buttons, 0 indexed */
- ASSERT_EQ(btnaction_prop.data[i], (Atom)None);
- continue;
- }
-
- std::stringstream propname;
- propname << "Wacom button action " << ButtonNumber(i);
-
- ASSERT_PROPERTY(int, action_prop, dpy, stylus_id, propname.str());
- ASSERT_EQ(btnaction_prop.data[i], action_prop.prop);
- }
-}
-
-TEST_F(WacomPropertyTest, Button1DoubleMiddleClick)
-{
- XORG_TESTCASE("Change Button0 action property to middle double click\n"
- "Trigger tip event.\n"
- "Ensure we get two press/release pairs for button 2.\n");
-
- const unsigned int BTN1_PRESS = 0x0080000 | 0x00100000 | 1; /* btn 1 press */
- const unsigned int BTN2_PRESS = 0x0080000 | 0x00100000 | 2; /* btn 1 press */
- const unsigned int BTN2_RELEASE = 0x0080000 | 0x00000000 | 2; /* btn 1 release */
- const std::string propname = "Wacom button action 0";
-
- ::Display *dpy = Display();
-
- ASSERT_PROPERTY(unsigned int, prop, dpy, stylus_id, propname);
- ASSERT_NE(prop.prop, (Atom)None);
- ASSERT_EQ(prop.nitems, 1U);
- ASSERT_EQ(prop.At(0), BTN1_PRESS);
-
- /* AC_BUTTON AC_KEYBTNPRESS */
- prop.Set(0, BTN2_PRESS);
- prop.Set(1, BTN2_RELEASE);
- prop.Set(2, BTN2_PRESS);
- prop.Set(3, BTN2_RELEASE);
- prop.Update();
-
- XSelectInput(dpy, DefaultRootWindow(dpy), ButtonPressMask | ButtonReleaseMask);
-
- TipDown();
-
- ASSERT_EVENT(XEvent, press1, dpy, ButtonPress);
- ASSERT_EQ(press1->xbutton.button, 2U);
- ASSERT_EVENT(XEvent, release1, dpy, ButtonRelease);
- ASSERT_EQ(release1->xbutton.button, 2U);
- ASSERT_EVENT(XEvent, press2, dpy, ButtonPress);
- ASSERT_EQ(press2->xbutton.button, 2U);
- ASSERT_EVENT(XEvent, release2, dpy, ButtonRelease);
- ASSERT_EQ(release2->xbutton.button, 2U);
-
- TipUp();
- XSync(dpy, False);
- ASSERT_TRUE(NoEventPending(dpy));
-}
-
-TEST_F(WacomPropertyTest, ButtonActionInvalidFormat)
-{
- XORG_TESTCASE("Try to change button 0 action property to a different format.\n"
- "Expect error\n");
-
- const std::string propname = "Wacom button action ";
-
- ::Display *dpy = Display();
-
- ASSERT_PROPERTY(Atom, btnaction_prop, dpy, stylus_id, "Wacom Button Actions");
-
- int data[1] = {0};
-
- for (unsigned int i = 0; i < btnaction_prop.nitems; i++) {
- std::stringstream ss;
- ss << propname << ButtonNumber(i);
-
- SetErrorTrap(dpy);
- XITProperty<int> prop_8(dpy, stylus_id, ss.str(), XA_INTEGER, 8, 1, data);
- ASSERT_ERROR(ReleaseErrorTrap(dpy), BadMatch);
-
- SetErrorTrap(dpy);
- XITProperty<int> prop_16(dpy, stylus_id, ss.str(), XA_INTEGER, 16, 1, data);
- ASSERT_ERROR(ReleaseErrorTrap(dpy), BadMatch);
- }
-}
-
-TEST_F(WacomPropertyTest, ButtonActionInvalidType)
-{
- XORG_TESTCASE("Try to change button 0 action property to a different type.\n"
- "Expect error\n");
-
- const std::string propname = "Wacom button action ";
-
- ::Display *dpy = Display();
-
- ASSERT_PROPERTY(Atom, btnaction_prop, dpy, stylus_id, "Wacom Button Actions");
-
- int data[1] = {0};
-
- /* All built-in types */
- for (unsigned int i = XA_PRIMARY; i < XA_LAST_PREDEFINED; i++) {
- if (i == XA_INTEGER)
- continue;
-
- for (unsigned int j = 0; j < btnaction_prop.nitems; j++) {
- std::stringstream ss;
- ss << propname << ButtonNumber(j);
-
- SetErrorTrap(dpy);
- XITProperty<int> prop_str(dpy, stylus_id, ss.str(), i, 32, 1, data);
- ASSERT_ERROR(ReleaseErrorTrap(dpy), BadMatch);
- }
- }
-}
-
-TEST_F(WacomPropertyTest, ButtonActionHighButtonValue)
-{
- XORG_TESTCASE("Try to change button 0 action property to a button > 32.\n"
- "Expect success\n");
- const unsigned int BTN100_PRESS = 0x0080000 | 0x00100000 | 100; /* btn 1 press */
-
- const std::string propname = "Wacom button action 0";
-
- ::Display *dpy = Display();
-
- SetErrorTrap(dpy);
- XITProperty<unsigned int> prop_str(dpy, stylus_id, propname, XA_INTEGER, 32, 1, &BTN100_PRESS);
- ASSERT_FALSE(ReleaseErrorTrap(dpy));
-}
-
-TEST_F(WacomPropertyTest, ButtonActionPropertySetToNone)
-{
- XORG_TESTCASE("Change button X action property value to None\n"
- "Ensure this triggers an error\n");
-
- ::Display *dpy = Display();
- ASSERT_PROPERTY(Atom, btnactions, dpy, stylus_id, "Wacom Button Actions");
-
- for (unsigned int i = 0; i < btnactions.nitems; i++) {
- const std::string propname = "Wacom button action ";
- std::stringstream ss;
- ss << propname << ButtonNumber(i);
-
- ASSERT_PROPERTY(unsigned int, prop, dpy, stylus_id, ss.str());
- prop.Resize(1);
- prop.Set(0, None);
-
- SetErrorTrap(dpy);
- prop.Update();
- ASSERT_ERROR(ReleaseErrorTrap(dpy), BadValue);
- }
-}
-
-TEST_F(WacomPropertyTest, ButtonActionPropertyUnset)
-{
- XORG_TESTCASE("Change Wacom Button Actions property value to None for a button\n"
- "Ensure this does not generate an error\n");
-
- const std::string propname = "Wacom Button Actions";
-
- ::Display *dpy = Display();
-
- ASSERT_PROPERTY(unsigned int, prop, dpy, stylus_id, propname);
- for (unsigned int i = 0; i < prop.nitems; i++) {
- ASSERT_PROPERTY(unsigned int, prop, dpy, stylus_id, propname);
- prop.Set(i, None);
-
- SetErrorTrap(dpy);
- prop.Update();
- ASSERT_FALSE(ReleaseErrorTrap(dpy));
- }
-}
-
-TEST_F(WacomPropertyTest, ButtonActionKeyPress)
-{
- XORG_TESTCASE("Change button action to a key press.\n"
- "Press phys button.\n"
- "Ensure key press is received\n"
- "Release phys button.\n"
- "Ensure key release is received\n");
-
- unsigned int KEY_A_KEYCODE = 38;
- unsigned int KEY_A_PRESS = 0x0010000 | 0x00100000 | KEY_A_KEYCODE;
- const std::string propname = "Wacom button action 0";
-
- ::Display *dpy = Display();
-
- ASSERT_PROPERTY(unsigned int, prop, dpy, stylus_id, propname);
- prop.Resize(1);
- prop.Set(0, KEY_A_PRESS);
- prop.Update();
-
- XSelectInput(dpy, DefaultRootWindow(dpy), KeyPressMask | KeyReleaseMask |
- ButtonPressMask | ButtonReleaseMask);
-
- TipDown();
- ASSERT_EVENT(XEvent, press, dpy, KeyPress);
- ASSERT_EQ(press->xkey.keycode, KEY_A_KEYCODE);
- ASSERT_TRUE(NoEventPending(dpy));
-
- TipUp();
- ASSERT_EVENT(XEvent, release, dpy, KeyRelease);
- ASSERT_EQ(release->xkey.keycode, KEY_A_KEYCODE);
- ASSERT_TRUE(NoEventPending(dpy));
-}
-
-TEST_F(WacomPropertyTest, ButtonActionKeyPressRelease)
-{
- XORG_TESTCASE("Change button action to a key press and release.\n"
- "Press phys button.\n"
- "Ensure key press is received\n"
- "Ensure key release is received\n"
- "Release phys button.\n"
- "Ensure no more events are waiting\n");
-
- unsigned int KEY_A_KEYCODE = 38;
- unsigned int KEY_A_PRESS = 0x0010000 | 0x00100000 | KEY_A_KEYCODE;
- unsigned int KEY_A_RELEASE = 0x0010000 | KEY_A_KEYCODE;
- const std::string propname = "Wacom button action 0";
-
- ::Display *dpy = Display();
-
- ASSERT_PROPERTY(unsigned int, prop, dpy, stylus_id, propname);
- prop.Resize(2);
- prop.Set(0, KEY_A_PRESS);
- prop.Set(1, KEY_A_RELEASE);
- prop.Update();
-
- XSelectInput(dpy, DefaultRootWindow(dpy), KeyPressMask | KeyReleaseMask |
- ButtonPressMask | ButtonReleaseMask);
-
- TipDown();
- ASSERT_EVENT(XEvent, press, dpy, KeyPress);
- ASSERT_EQ(press->xkey.keycode, KEY_A_KEYCODE);
- ASSERT_EQ(XPending(dpy), 1);
-
- ASSERT_EVENT(XEvent, release, dpy, KeyRelease);
- ASSERT_EQ(release->xkey.keycode, KEY_A_KEYCODE);
- ASSERT_TRUE(NoEventPending(dpy));
-
- TipUp();
- XSync(dpy, False);
- ASSERT_TRUE(NoEventPending(dpy));
-}
-
-int main(int argc, char **argv) {
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/tests/input/wacom_devs.h b/tests/input/wacom_devs.h
deleted file mode 100644
index 047d91b..0000000
--- a/tests/input/wacom_devs.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright © 2012-2013 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- */
-
-#if HAVE_CONFIG_H
-#include <config.h>
-#endif
-#ifndef __WACOM_DEVS_H__
-#define __WACOM_DEVS_H__
-
-#ifndef DOXYGEN_IGNORE_THIS
-
-typedef struct
-{
- const char *test_id;
- const char *descfile;
- const char *name;
- const char *stylus;
- const char *eraser;
- const char *cursor;
- const char *pad;
- const char *touch;
-} Tablet;
-
-void PrintTo(const Tablet& t, ::std::ostream *os) {
- *os << "Tablet tested: " << t.test_id << " " << t.name;
-}
-
-Tablet tablets[] = {
- { "00", "Wacom-PTK-540WL.desc", "PTK-540WL", "stylus", "eraser", "cursor", "pad", "touch" },
- { "01", "Wacom-Bamboo-16FG-4x5-Finger.desc", "Wacom Bamboo 16FG 4x5 Finger", NULL, NULL, NULL, NULL, "touch" },
- { "02", "Wacom-Bamboo-16FG-4x5-Pen.desc", "Wacom Bamboo 16FG 4x5 Pen", "stylus", NULL, NULL, NULL, NULL },
- { "03", "Wacom-Bamboo-One.desc", "Wacom Bamboo1", "stylus", NULL, NULL, NULL, NULL },
- { "04", "Wacom-Bamboo-2FG-4x5-Finger.desc", "Wacom Bamboo 2FG 4x5 Finger", NULL, NULL, NULL, "pad", "touch" },
- { "05", "Wacom-Bamboo-2FG-4x5-Pen.desc", "Wacom Bamboo 2FG 4x5 Pen", "stylus", "eraser", NULL, NULL, NULL },
- { "06", "Wacom-Cintiq-12WX.desc", "Wacom Cintiq 12WX", "stylus", "eraser", NULL, "pad", NULL },
- { "07", "Wacom-Cintiq-21UX2.desc", "Wacom Cintiq 21UX2", "stylus", "eraser", NULL, "pad", NULL },
- { "08", "Wacom-Intuos3-4x6.desc", "Wacom Intuos3 4x6", "stylus", NULL, NULL, NULL, NULL },
- { "09", "Wacom-Intuos4-6x9.desc", "Wacom Intuos4 6x9", "stylus", "eraser", "cursor", NULL, NULL },
- { "10", "Wacom-Intuos5-touch-M-Finger.desc", "Wacom Intuos5 touch M Finger", NULL, NULL, NULL, NULL, "touch" },
- { "11", "Wacom-Intuos5-touch-M-Pen.desc", "Wacom Intuos5 touch M Pen", "stylus", "eraser", "cursor", "pad", NULL },
- { "12", "Wacom-ISDv4-E6-Finger.desc", "Wacom ISDv4 E6 Finger", NULL, NULL, NULL, NULL, "touch" },
- { "13", "Wacom-ISDv4-E6-Pen.desc", "Wacom ISDv4 E6 Pen", "stylus", "eraser", NULL, NULL, NULL },
- { "14", "Wacom-Intuos4-8x13.desc", "Wacom Intuos4 8x13", "stylus", "eraser", "cursor", NULL, NULL },
-};
-
-Tablet lens_cursor_tablets[] = {
- { "00", "Wacom-Intuos4-8x13.desc", "Wacom Intuos4 8x13", "stylus", "eraser", "cursor", NULL, NULL },
-};
-
-#endif /* DOXYGEN_IGNORE_THIS */
-
-#endif