1/* 2 * Copyright © 2011 Red Hat, Inc. 3 * 4 * Permission to use, copy, modify, distribute, and sell this software 5 * and its documentation for any purpose is hereby granted without 6 * fee, provided that the above copyright notice appear in all copies 7 * and that both that copyright notice and this permission notice 8 * appear in supporting documentation, and that the name of Red Hat 9 * not be used in advertising or publicity pertaining to distribution 10 * of the software without specific, written prior permission. Red 11 * Hat makes no representations about the suitability of this software 12 * for any purpose. It is provided "as is" without express or implied 13 * warranty. 14 * 15 * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN 17 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 19 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 20 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 * 23 * Authors: 24 * Peter Hutterer 25 */ 26 27#if HAVE_CONFIG_H 28#include <config.h> 29#endif 30 31#include <stdio.h> 32#include <assert.h> 33 34#include "synapticsstr.h" 35#include "eventcomm.h" 36 37#define ArrayLength(a) (sizeof(a) / (sizeof((a)[0]))) 38 39int fd_read, fd_write; 40 41/* A syn event, always handy to have */ 42struct input_event syn = { {0, 0}, EV_SYN, SYN_REPORT, 0 }; 43 44static void 45create_pipe_fd(void) 46{ 47 int pipefd[2]; 48 49 assert(pipe(pipefd) != -1); 50 51 fd_read = pipefd[0]; 52 fd_write = pipefd[1]; 53} 54 55static void 56reset_data(struct SynapticsHwState **hw, struct CommData *comm, 57 SynapticsPrivate * priv) 58{ 59 SynapticsHwStateFree(&comm->hwState); 60 memset(comm, 0, sizeof(struct CommData)); 61 SynapticsHwStateFree(hw); 62 *hw = SynapticsHwStateAlloc(priv); 63 comm->hwState = SynapticsHwStateAlloc(priv); 64} 65 66/** 67 * Write n input events to fd, followed by the syn event. 68 */ 69static void 70write_event(int fd, struct input_event *ev, int n) 71{ 72 write(fd, ev, sizeof(struct input_event) * n); 73 write(fd, &syn, sizeof(syn)); 74} 75 76static void 77test_buttons(int fd, InputInfoPtr pInfo, struct CommData *comm) 78{ 79 SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private; 80 struct SynapticsHwState *hw = NULL; 81 struct input_event ev = { {0, 0}, EV_KEY, 0, 0 }; 82 83 reset_data(&hw, comm, priv); 84 85#define _test_press_release(_code, field) \ 86 ev.code = (_code); \ 87 ev.value = 1; \ 88 write_event(fd, &ev, 1); \ 89 EventReadHwState(pInfo, comm, hw); \ 90 assert(hw->field == 1); \ 91 ev.value = 0; /* button release */ \ 92 write_event(fd_write, &ev, 1); \ 93 EventReadHwState(pInfo, comm, hw); \ 94 assert(hw->field == 0); 95 96 _test_press_release(BTN_LEFT, left); 97 _test_press_release(BTN_RIGHT, right); 98 _test_press_release(BTN_MIDDLE, middle); 99 _test_press_release(BTN_FORWARD, up); 100 _test_press_release(BTN_BACK, down); 101 _test_press_release(BTN_0, multi[0]); 102 _test_press_release(BTN_1, multi[1]); 103 _test_press_release(BTN_2, multi[2]); 104 _test_press_release(BTN_3, multi[3]); 105 _test_press_release(BTN_4, multi[4]); 106 _test_press_release(BTN_5, multi[5]); 107 _test_press_release(BTN_6, multi[6]); 108 _test_press_release(BTN_7, multi[7]); 109 110 SynapticsHwStateFree(&hw); 111} 112 113/** 114 * This test checks that the recognised event fields set the right hardware 115 * state. It's a fairly limited test and does not check whether any of the 116 * others change the HW state at all. 117 */ 118static void 119test_read_hw_state(void) 120{ 121 InputInfoRec info = { 0 }; 122 SynapticsPrivate private; 123 struct SynapticsHwState *hw = NULL; 124 struct CommData comm = { 0 }; 125 126 struct input_event ev[] = { 127 {{0, 0}, EV_KEY, BTN_TOOL_FINGER, 1}, 128 {{0, 0}, EV_KEY, BTN_TOOL_DOUBLETAP, 1}, 129 {{0, 0}, EV_KEY, BTN_TOOL_TRIPLETAP, 1}, 130 {{0, 0}, EV_ABS, ABS_X, 42}, 131 {{0, 0}, EV_ABS, ABS_Y, 21}, 132 {{0, 0}, EV_ABS, ABS_PRESSURE, 56}, 133 {{0, 0}, EV_ABS, ABS_TOOL_WIDTH, 204}, 134 }; 135 136 memset(&private, 0, sizeof(private)); 137 138 info.private = &private; 139 info.fd = fd_read; 140 141 private.proto_data = EventProtoDataAlloc(); 142 143 /* just the syn event */ 144 reset_data(&hw, &comm, &private); 145 write(fd_write, &syn, sizeof(syn)); 146 EventReadHwState(&info, &comm, hw); 147 assert(hw->numFingers == 0); 148 149 /* one finger */ 150 reset_data(&hw, &comm, &private); 151 write_event(fd_write, &ev[0], 1); 152 EventReadHwState(&info, &comm, hw); 153 assert(hw->numFingers == 1); 154 155 /* two fingers */ 156 reset_data(&hw, &comm, &private); 157 write_event(fd_write, &ev[1], 1); 158 EventReadHwState(&info, &comm, hw); 159 assert(hw->numFingers == 2); 160 161 /* three fingers */ 162 reset_data(&hw, &comm, &private); 163 write_event(fd_write, &ev[2], 1); 164 EventReadHwState(&info, &comm, hw); 165 assert(hw->numFingers == 3); 166 167 /* x/y data */ 168 reset_data(&hw, &comm, &private); 169 write_event(fd_write, &ev[3], 2); 170 EventReadHwState(&info, &comm, hw); 171 assert(hw->x == ev[3].value); 172 assert(hw->y == ev[4].value); 173 174 /* pressure */ 175 reset_data(&hw, &comm, &private); 176 write_event(fd_write, &ev[5], 1); 177 EventReadHwState(&info, &comm, hw); 178 assert(hw->z == ev[5].value); 179 180 /* finger width */ 181 reset_data(&hw, &comm, &private); 182 write_event(fd_write, &ev[6], 1); 183 EventReadHwState(&info, &comm, hw); 184 assert(hw->fingerWidth == ev[6].value); 185 186 /* the various buttons */ 187 test_buttons(fd_write, &info, &comm); 188 189 free(private.proto_data); 190 SynapticsHwStateFree(&hw); 191 SynapticsHwStateFree(&comm.hwState); 192} 193 194static Bool 195compare_hw_state(const struct SynapticsHwState *a, 196 const struct SynapticsHwState *b) 197{ 198#define COMPARE(x) \ 199 if (a->x != b->x) return a->x - b->x 200 201 COMPARE(millis); 202 COMPARE(x); 203 COMPARE(y); 204 COMPARE(z); 205 COMPARE(numFingers); 206 COMPARE(fingerWidth); 207 COMPARE(left); 208 COMPARE(right); 209 COMPARE(up); 210 COMPARE(down); 211 if (memcmp(a->multi, b->multi, sizeof(a->multi))) 212 return memcmp(a->multi, b->multi, sizeof(a->multi)); 213 COMPARE(middle); 214 215#undef COMPARE 216 217 return 0; 218} 219 220/** 221 * Make sure that axes/keys unknown to the driver don't change the hardware 222 * state. 223 */ 224static void 225test_ignore_hw_state(void) 226{ 227 int i; 228 InputInfoRec info = { 0 }; 229 SynapticsPrivate private; 230 struct SynapticsHwState *hw = NULL; 231 struct SynapticsHwState *hw_zero = NULL; 232 struct CommData comm = { 0 }; 233 234 int known_abs[] = { 235 ABS_X, 236 ABS_Y, 237 ABS_PRESSURE, 238 ABS_TOOL_WIDTH, 239 }; 240 241 int known_keys[] = { 242 BTN_LEFT, 243 BTN_RIGHT, 244 BTN_MIDDLE, 245 BTN_FORWARD, 246 BTN_BACK, 247 BTN_0, 248 BTN_1, 249 BTN_2, 250 BTN_3, 251 BTN_4, 252 BTN_5, 253 BTN_6, 254 BTN_7, 255 BTN_TOOL_FINGER, 256 BTN_TOOL_DOUBLETAP, 257 BTN_TOOL_TRIPLETAP, 258 BTN_TOUCH 259 }; 260 261 struct input_event ev = { {0, 0}, 0, 0, 1 }; 262 263 memset(&private, 0, sizeof(private)); 264 info.private = &private; 265 info.fd = fd_read; 266 267 private.proto_data = EventProtoDataAlloc(); 268 269 reset_data(&hw_zero, &comm, &private); 270 271#define _assert_no_change(_type, _code) \ 272 reset_data(&hw, &comm, &private); \ 273 ev.type = _type; \ 274 ev.code = _code; \ 275 ev.value = 1; \ 276 write_event(fd_write, &ev, 1); \ 277 EventReadHwState(&info, &comm, hw); \ 278 assert(compare_hw_state(hw, hw_zero) == 0); 279 280 for (i = ABS_X; i < ABS_MAX; i++) { 281 int j, skip = 0; 282 283 for (j = 0; j < ArrayLength(known_abs); j++) { 284 if (i == known_abs[j]) { 285 skip = 1; 286 break; 287 } 288 } 289 290 if (skip) 291 continue; 292 293 _assert_no_change(EV_ABS, i); 294 } 295 296 for (i = KEY_RESERVED; i < KEY_MAX; i++) { 297 int j, skip = 0; 298 299 for (j = 0; j < ArrayLength(known_keys); j++) { 300 if (i == known_keys[j]) { 301 skip = 1; 302 break; 303 } 304 } 305 306 if (skip) 307 continue; 308 309 _assert_no_change(EV_KEY, i); 310 } 311 312 free(private.proto_data); 313 SynapticsHwStateFree(&hw); 314 SynapticsHwStateFree(&hw_zero); 315 SynapticsHwStateFree(&comm.hwState); 316} 317 318int 319main(int argc, char **argv) 320{ 321 create_pipe_fd(); 322 323 test_read_hw_state(); 324 test_ignore_hw_state(); 325 return 0; 326} 327