1 /*
2 * Copyright © 2016 Red Hat, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include <config.h>
25
26 #include <check.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <libinput.h>
30 #include <unistd.h>
31
32 #include "libinput-util.h"
33 #include "litest.h"
34
START_TEST(trackball_rotation_config_defaults)35 START_TEST(trackball_rotation_config_defaults)
36 {
37 struct litest_device *dev = litest_current_device();
38 struct libinput_device *device = dev->libinput_device;
39 int angle;
40
41 ck_assert(libinput_device_config_rotation_is_available(device));
42
43 angle = libinput_device_config_rotation_get_angle(device);
44 ck_assert_int_eq(angle, 0);
45 angle = libinput_device_config_rotation_get_default_angle(device);
46 ck_assert_int_eq(angle, 0);
47 }
48 END_TEST
49
START_TEST(trackball_rotation_config_invalid_range)50 START_TEST(trackball_rotation_config_invalid_range)
51 {
52 struct litest_device *dev = litest_current_device();
53 struct libinput_device *device = dev->libinput_device;
54 enum libinput_config_status status;
55
56 status = libinput_device_config_rotation_set_angle(device, 360);
57 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
58 status = libinput_device_config_rotation_set_angle(device, 361);
59 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
60 status = libinput_device_config_rotation_set_angle(device, -1);
61 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
62 }
63 END_TEST
64
START_TEST(trackball_rotation_config_no_rotation)65 START_TEST(trackball_rotation_config_no_rotation)
66 {
67 struct litest_device *dev = litest_current_device();
68 struct libinput_device *device = dev->libinput_device;
69 enum libinput_config_status status;
70 int angle;
71
72 ck_assert(!libinput_device_config_rotation_is_available(device));
73
74 angle = libinput_device_config_rotation_get_angle(device);
75 ck_assert_int_eq(angle, 0);
76 angle = libinput_device_config_rotation_get_default_angle(device);
77 ck_assert_int_eq(angle, 0);
78
79 /* 0 always succeeds */
80 status = libinput_device_config_rotation_set_angle(device, 0);
81 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
82
83 for (angle = 1; angle < 360; angle++) {
84 status = libinput_device_config_rotation_set_angle(device,
85 angle);
86 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
87 }
88 }
89 END_TEST
90
START_TEST(trackball_rotation_config_right_angle)91 START_TEST(trackball_rotation_config_right_angle)
92 {
93 struct litest_device *dev = litest_current_device();
94 struct libinput_device *device = dev->libinput_device;
95 enum libinput_config_status status;
96 int angle;
97
98 ck_assert(libinput_device_config_rotation_is_available(device));
99
100 for (angle = 0; angle < 360; angle += 90) {
101 status = libinput_device_config_rotation_set_angle(device,
102 angle);
103 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
104 }
105 }
106 END_TEST
107
START_TEST(trackball_rotation_config_odd_angle)108 START_TEST(trackball_rotation_config_odd_angle)
109 {
110 struct litest_device *dev = litest_current_device();
111 struct libinput_device *device = dev->libinput_device;
112 enum libinput_config_status status;
113 int angle;
114
115 ck_assert(libinput_device_config_rotation_is_available(device));
116
117 for (angle = 0; angle < 360; angle++) {
118 status = libinput_device_config_rotation_set_angle(device,
119 angle);
120 ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
121 }
122 }
123 END_TEST
124
START_TEST(trackball_rotation_x)125 START_TEST(trackball_rotation_x)
126 {
127 struct litest_device *dev = litest_current_device();
128 struct libinput *li = dev->libinput;
129 struct libinput_device *device = dev->libinput_device;
130 struct libinput_event *event;
131 struct libinput_event_pointer *ptrev;
132 int angle;
133 double dx, dy;
134
135 litest_drain_events(li);
136
137 for (angle = 0; angle < 360; angle++) {
138 libinput_device_config_rotation_set_angle(device, angle);
139
140 litest_event(dev, EV_REL, REL_X, 1);
141 litest_event(dev, EV_SYN, SYN_REPORT, 0);
142 libinput_dispatch(li);
143
144 event = libinput_get_event(li);
145 ptrev = litest_is_motion_event(event);
146
147 /* Test unaccelerated because pointer accel may mangle the
148 other coords */
149 dx = libinput_event_pointer_get_dx_unaccelerated(ptrev);
150 dy = libinput_event_pointer_get_dy_unaccelerated(ptrev);
151
152 switch (angle) {
153 case 0:
154 ck_assert_double_eq(dx, 1.0);
155 ck_assert_double_eq(dy, 0.0);
156 break;
157 case 90:
158 ck_assert_double_eq(dx, 0.0);
159 ck_assert_double_eq(dy, 1.0);
160 break;
161 case 180:
162 ck_assert_double_eq(dx, -1.0);
163 ck_assert_double_eq(dy, 0.0);
164 break;
165 case 270:
166 ck_assert_double_eq(dx, 0.0);
167 ck_assert_double_eq(dy, -1.0);
168 break;
169 }
170 libinput_event_destroy(event);
171 }
172 }
173 END_TEST
174
START_TEST(trackball_rotation_y)175 START_TEST(trackball_rotation_y)
176 {
177 struct litest_device *dev = litest_current_device();
178 struct libinput *li = dev->libinput;
179 struct libinput_device *device = dev->libinput_device;
180 struct libinput_event *event;
181 struct libinput_event_pointer *ptrev;
182 int angle;
183 double dx, dy;
184
185 litest_drain_events(li);
186
187 for (angle = 0; angle < 360; angle++) {
188 libinput_device_config_rotation_set_angle(device, angle);
189
190 litest_event(dev, EV_REL, REL_Y, 1);
191 litest_event(dev, EV_SYN, SYN_REPORT, 0);
192 libinput_dispatch(li);
193
194 event = libinput_get_event(li);
195 ptrev = litest_is_motion_event(event);
196
197 /* Test unaccelerated because pointer accel may mangle the
198 other coords */
199 dx = libinput_event_pointer_get_dx_unaccelerated(ptrev);
200 dy = libinput_event_pointer_get_dy_unaccelerated(ptrev);
201
202 switch (angle) {
203 case 0:
204 ck_assert_double_eq(dx, 0.0);
205 ck_assert_double_eq(dy, 1.0);
206 break;
207 case 90:
208 ck_assert_double_eq(dx, -1.0);
209 ck_assert_double_eq(dy, 0.0);
210 break;
211 case 180:
212 ck_assert_double_eq(dx, 0.0);
213 ck_assert_double_eq(dy, -1.0);
214 break;
215 case 270:
216 ck_assert_double_eq(dx, 1.0);
217 ck_assert_double_eq(dy, 0.0);
218 break;
219 }
220 libinput_event_destroy(event);
221 }
222 }
223 END_TEST
224
START_TEST(trackball_rotation_accel)225 START_TEST(trackball_rotation_accel)
226 {
227 struct litest_device *dev = litest_current_device();
228 struct libinput *li = dev->libinput;
229 struct libinput_device *device = dev->libinput_device;
230 struct libinput_event *event;
231 struct libinput_event_pointer *ptrev;
232 double dx, dy;
233
234 litest_drain_events(li);
235
236 /* Pointer accel mangles the coordinates, so we only test one angle
237 * and rely on the unaccelerated tests above to warn us when
238 * something's off */
239 libinput_device_config_rotation_set_angle(device, 90);
240
241 litest_event(dev, EV_REL, REL_Y, 1);
242 litest_event(dev, EV_REL, REL_X, 1);
243 litest_event(dev, EV_SYN, SYN_REPORT, 0);
244 libinput_dispatch(li);
245
246 event = libinput_get_event(li);
247 ptrev = litest_is_motion_event(event);
248
249 dx = libinput_event_pointer_get_dx(ptrev);
250 dy = libinput_event_pointer_get_dy(ptrev);
251
252 ck_assert_double_lt(dx, 0.0);
253 ck_assert_double_gt(dy, 0.0);
254 libinput_event_destroy(event);
255 }
256 END_TEST
257
TEST_COLLECTION(trackball)258 TEST_COLLECTION(trackball)
259 {
260 litest_add(trackball_rotation_config_defaults, LITEST_TRACKBALL, LITEST_ANY);
261 litest_add(trackball_rotation_config_invalid_range, LITEST_TRACKBALL, LITEST_ANY);
262 litest_add(trackball_rotation_config_no_rotation, LITEST_POINTINGSTICK, LITEST_ANY);
263 litest_add(trackball_rotation_config_right_angle, LITEST_TRACKBALL, LITEST_ANY);
264 litest_add(trackball_rotation_config_odd_angle, LITEST_TRACKBALL, LITEST_ANY);
265 litest_add(trackball_rotation_x, LITEST_TRACKBALL, LITEST_ANY);
266 litest_add(trackball_rotation_y, LITEST_TRACKBALL, LITEST_ANY);
267 litest_add(trackball_rotation_accel, LITEST_TRACKBALL, LITEST_ANY);
268 }
269