1/** 2 * Copyright © 2011 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/* Test relies on assert() */ 25#undef NDEBUG 26 27#ifdef HAVE_DIX_CONFIG_H 28#include <dix-config.h> 29#endif 30 31#include <stdio.h> 32#include <stdlib.h> 33#include <X11/X.h> 34#include <xfixesint.h> 35#include <X11/extensions/xfixeswire.h> 36 37#include "tests-common.h" 38 39static void 40_fixes_test_direction(struct PointerBarrier *barrier, int d[4], int permitted) 41{ 42 BOOL blocking; 43 int i, j; 44 int dir = barrier_get_direction(d[0], d[1], d[2], d[3]); 45 46 barrier->directions = 0; 47 blocking = barrier_is_blocking_direction(barrier, dir); 48 assert(blocking); 49 50 for (j = 0; j <= BarrierNegativeY; j++) { 51 for (i = 0; i <= BarrierNegativeY; i++) { 52 barrier->directions |= 1 << i; 53 blocking = barrier_is_blocking_direction(barrier, dir); 54 assert((barrier->directions & permitted) == 55 permitted ? !blocking : blocking); 56 } 57 } 58 59} 60 61static void 62fixes_pointer_barrier_direction_test(void) 63{ 64 struct PointerBarrier barrier; 65 66 int x = 100; 67 int y = 100; 68 69 int directions[8][4] = { 70 {x, y, x, y + 100}, /* S */ 71 {x + 50, y, x - 50, y + 100}, /* SW */ 72 {x + 100, y, x, y}, /* W */ 73 {x + 100, y + 50, x, y - 50}, /* NW */ 74 {x, y + 100, x, y}, /* N */ 75 {x - 50, y + 100, x + 50, y}, /* NE */ 76 {x, y, x + 100, y}, /* E */ 77 {x, y - 50, x + 100, y + 50}, /* SE */ 78 }; 79 80 barrier.x1 = x; 81 barrier.x2 = x; 82 barrier.y1 = y - 50; 83 barrier.y2 = y + 49; 84 85 _fixes_test_direction(&barrier, directions[0], BarrierPositiveY); 86 _fixes_test_direction(&barrier, directions[1], 87 BarrierPositiveY | BarrierNegativeX); 88 _fixes_test_direction(&barrier, directions[2], BarrierNegativeX); 89 _fixes_test_direction(&barrier, directions[3], 90 BarrierNegativeY | BarrierNegativeX); 91 _fixes_test_direction(&barrier, directions[4], BarrierNegativeY); 92 _fixes_test_direction(&barrier, directions[5], 93 BarrierPositiveX | BarrierNegativeY); 94 _fixes_test_direction(&barrier, directions[6], BarrierPositiveX); 95 _fixes_test_direction(&barrier, directions[7], 96 BarrierPositiveY | BarrierPositiveX); 97 98} 99 100static void 101fixes_pointer_barriers_test(void) 102{ 103 struct PointerBarrier barrier; 104 int x1, y1, x2, y2; 105 double distance; 106 107 int x = 100; 108 int y = 100; 109 110 /* vert barrier */ 111 barrier.x1 = x; 112 barrier.x2 = x; 113 barrier.y1 = y - 50; 114 barrier.y2 = y + 50; 115 116 /* across at half-way */ 117 x1 = x + 1; 118 x2 = x - 1; 119 y1 = y; 120 y2 = y; 121 assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 122 assert(distance == 1); 123 124 /* definitely not across */ 125 x1 = x + 10; 126 x2 = x + 5; 127 assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 128 129 /* across, but outside of y range */ 130 x1 = x + 1; 131 x2 = x - 1; 132 y1 = y + 100; 133 y2 = y + 100; 134 assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 135 136 /* across, diagonally */ 137 x1 = x + 5; 138 x2 = x - 5; 139 y1 = y + 5; 140 y2 = y - 5; 141 assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 142 143 /* across but outside boundary, diagonally */ 144 x1 = x + 5; 145 x2 = x - 5; 146 y1 = y + 100; 147 y2 = y + 50; 148 assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 149 150 /* edge case: startpoint of movement on barrier → blocking */ 151 x1 = x; 152 x2 = x - 1; 153 y1 = y; 154 y2 = y; 155 assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 156 157 /* edge case: startpoint of movement on barrier → not blocking, positive */ 158 x1 = x; 159 x2 = x + 1; 160 y1 = y; 161 y2 = y; 162 assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 163 164 /* edge case: startpoint of movement on barrier → not blocking, negative */ 165 x1 = x - 1; 166 x2 = x - 2; 167 y1 = y; 168 y2 = y; 169 assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 170 171 /* edge case: endpoint of movement on barrier → blocking */ 172 x1 = x + 1; 173 x2 = x; 174 y1 = y; 175 y2 = y; 176 assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 177 178 /* startpoint on barrier but outside y range */ 179 x1 = x; 180 x2 = x - 1; 181 y1 = y + 100; 182 y2 = y + 100; 183 assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 184 185 /* endpoint on barrier but outside y range */ 186 x1 = x + 1; 187 x2 = x; 188 y1 = y + 100; 189 y2 = y + 100; 190 assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 191 192 /* horizontal barrier */ 193 barrier.x1 = x - 50; 194 barrier.x2 = x + 50; 195 barrier.y1 = y; 196 barrier.y2 = y; 197 198 /* across at half-way */ 199 x1 = x; 200 x2 = x; 201 y1 = y - 1; 202 y2 = y + 1; 203 assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 204 205 /* definitely not across */ 206 y1 = y + 10; 207 y2 = y + 5; 208 assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 209 210 /* across, but outside of y range */ 211 x1 = x + 100; 212 x2 = x + 100; 213 y1 = y + 1; 214 y2 = y - 1; 215 assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 216 217 /* across, diagonally */ 218 y1 = y + 5; 219 y2 = y - 5; 220 x1 = x + 5; 221 x2 = x - 5; 222 assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 223 224 /* across but outside boundary, diagonally */ 225 y1 = y + 5; 226 y2 = y - 5; 227 x1 = x + 100; 228 x2 = x + 50; 229 assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 230 231 /* edge case: startpoint of movement on barrier → blocking */ 232 y1 = y; 233 y2 = y - 1; 234 x1 = x; 235 x2 = x; 236 assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 237 238 /* edge case: startpoint of movement on barrier → not blocking, positive */ 239 y1 = y; 240 y2 = y + 1; 241 x1 = x; 242 x2 = x; 243 assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 244 245 /* edge case: startpoint of movement on barrier → not blocking, negative */ 246 y1 = y - 1; 247 y2 = y - 2; 248 x1 = x; 249 x2 = x; 250 assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 251 252 /* edge case: endpoint of movement on barrier → blocking */ 253 y1 = y + 1; 254 y2 = y; 255 x1 = x; 256 x2 = x; 257 assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 258 259 /* startpoint on barrier but outside y range */ 260 y1 = y; 261 y2 = y - 1; 262 x1 = x + 100; 263 x2 = x + 100; 264 assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 265 266 /* endpoint on barrier but outside y range */ 267 y1 = y + 1; 268 y2 = y; 269 x1 = x + 100; 270 x2 = x + 100; 271 assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 272 273 /* ray vert barrier */ 274 barrier.x1 = x; 275 barrier.x2 = x; 276 barrier.y1 = -1; 277 barrier.y2 = y + 100; 278 279 /* ray barrier simple case */ 280 y1 = y; 281 y2 = y; 282 x1 = x + 50; 283 x2 = x - 50; 284 assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 285 286 /* endpoint outside y range; should be blocked */ 287 y1 = y - 1000; 288 y2 = y - 1000; 289 x1 = x + 50; 290 x2 = x - 50; 291 assert(barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 292 293 /* endpoint outside y range */ 294 y1 = y + 150; 295 y2 = y + 150; 296 x1 = x + 50; 297 x2 = x - 50; 298 assert(!barrier_is_blocking(&barrier, x1, y1, x2, y2, &distance)); 299} 300 301static void 302fixes_pointer_barrier_clamp_test(void) 303{ 304 struct PointerBarrier barrier; 305 306 int x = 100; 307 int y = 100; 308 309 int cx, cy; /* clamped */ 310 311 /* vert barrier */ 312 barrier.x1 = x; 313 barrier.x2 = x; 314 barrier.y1 = y - 50; 315 barrier.y2 = y + 49; 316 barrier.directions = 0; 317 318 cx = INT_MAX; 319 cy = INT_MAX; 320 barrier_clamp_to_barrier(&barrier, BarrierPositiveX, &cx, &cy); 321 assert(cx == barrier.x1 - 1); 322 assert(cy == INT_MAX); 323 324 cx = 0; 325 cy = INT_MAX; 326 barrier_clamp_to_barrier(&barrier, BarrierNegativeX, &cx, &cy); 327 assert(cx == barrier.x1); 328 assert(cy == INT_MAX); 329 330 /* horiz barrier */ 331 barrier.x1 = x - 50; 332 barrier.x2 = x + 49; 333 barrier.y1 = y; 334 barrier.y2 = y; 335 barrier.directions = 0; 336 337 cx = INT_MAX; 338 cy = INT_MAX; 339 barrier_clamp_to_barrier(&barrier, BarrierPositiveY, &cx, &cy); 340 assert(cx == INT_MAX); 341 assert(cy == barrier.y1 - 1); 342 343 cx = INT_MAX; 344 cy = 0; 345 barrier_clamp_to_barrier(&barrier, BarrierNegativeY, &cx, &cy); 346 assert(cx == INT_MAX); 347 assert(cy == barrier.y1); 348} 349 350int 351fixes_test(void) 352{ 353 354 fixes_pointer_barriers_test(); 355 fixes_pointer_barrier_direction_test(); 356 fixes_pointer_barrier_clamp_test(); 357 358 return 0; 359} 360