1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <xorg/gtest/xorg-gtest.h>
#include <X11/extensions/XInput2.h>
#include "xit-server-input-test.h"
#include "device-interface.h"
#include "helpers.h"
using namespace xorg::testing;
class PointerMotionTest : public XITServerInputTest,
public DeviceInterface {
public:
/**
* Initializes a standard mouse device.
*/
virtual void SetUp() {
SetDevice("mice/PIXART-USB-OPTICAL-MOUSE-HWHEEL.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 \"CorePointer\" \"on\"\n"
"Option \"Device\" \"" + dev->GetDeviceNode() + "\"");
/* add default keyboard device to avoid server adding our device again */
config.AddInputSection("kbd", "kbd-device",
"Option \"CoreKeyboard\" \"on\"\n");
config.WriteConfig();
}
};
class PointerSubpixelTest : public PointerMotionTest {
/**
* Sets up an xorg.conf for a single evdev CoreKeyboard device based on
* the evemu device. The input from GetParam() is used as XkbLayout.
*/
virtual void SetUpConfigAndLog() {
config.AddDefaultScreenWithDriver();
config.AddInputSection("evdev", "--device--",
"Option \"CorePointer\" \"on\"\n"
"Option \"ConstantDeceleration\" \"20\"\n"
"Option \"Device\" \"" + dev->GetDeviceNode() + "\"");
/* add default keyboard device to avoid server adding our device again */
config.AddInputSection("kbd", "kbd-device",
"Option \"CoreKeyboard\" \"on\"\n");
config.WriteConfig();
}
};
TEST_F(PointerSubpixelTest, NoSubpixelCoreEvents)
{
XORG_TESTCASE("Move pointer by less than a pixels\n"
"Ensure no core motion event is received\n"
"Ensure XI2 motion events are received\n");
::Display *dpy = Display();
::Display *dpy2 = XOpenDisplay(server.GetDisplayString().c_str());
ASSERT_TRUE(dpy2);
double x, y;
QueryPointerPosition(dpy, &x, &y);
XSelectInput(dpy, DefaultRootWindow(dpy), PointerMotionMask);
XSync(dpy, False);
dev->PlayOne(EV_REL, REL_X, 1, true);
dev->PlayOne(EV_REL, REL_X, 1, true);
dev->PlayOne(EV_REL, REL_X, 1, true);
dev->PlayOne(EV_REL, REL_X, 1, true);
ASSERT_FALSE(XServer::WaitForEvent(Display(), 500));
XSelectInput(dpy, DefaultRootWindow(dpy), NoEventMask);
XSync(dpy, False);
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(dpy2, DefaultRootWindow(dpy), &mask, 1);
XSync(dpy2, False);
delete[] mask.mask;
dev->PlayOne(EV_REL, REL_X, 1, true);
dev->PlayOne(EV_REL, REL_X, 1, true);
dev->PlayOne(EV_REL, REL_X, 1, true);
dev->PlayOne(EV_REL, REL_X, 1, true);
ASSERT_TRUE(XServer::WaitForEventOfType(dpy2, GenericEvent, xi2_opcode, XI_Motion));
double new_x, new_y;
QueryPointerPosition(dpy, &new_x, &new_y);
ASSERT_EQ(x, new_x);
ASSERT_EQ(y, new_y);
XCloseDisplay(dpy2);
}
|