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 35START_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} 48END_TEST 49 50START_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} 63END_TEST 64 65START_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} 89END_TEST 90 91START_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} 106END_TEST 107 108START_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} 123END_TEST 124 125START_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} 173END_TEST 174 175START_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} 223END_TEST 224 225START_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} 256END_TEST 257 258TEST_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