128515619Smrg/* 228515619Smrg * Copyright © 2011 Red Hat, Inc. 328515619Smrg * 428515619Smrg * Permission to use, copy, modify, distribute, and sell this software 528515619Smrg * and its documentation for any purpose is hereby granted without 628515619Smrg * fee, provided that the above copyright notice appear in all copies 728515619Smrg * and that both that copyright notice and this permission notice 828515619Smrg * appear in supporting documentation, and that the name of Red Hat 928515619Smrg * not be used in advertising or publicity pertaining to distribution 1028515619Smrg * of the software without specific, written prior permission. Red 1128515619Smrg * Hat makes no representations about the suitability of this software 1228515619Smrg * for any purpose. It is provided "as is" without express or implied 1328515619Smrg * warranty. 1428515619Smrg * 1528515619Smrg * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1628515619Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN 1728515619Smrg * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1828515619Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 1928515619Smrg * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 2028515619Smrg * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 2128515619Smrg * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 2228515619Smrg * 2328515619Smrg * Authors: 2428515619Smrg * Peter Hutterer 2528515619Smrg */ 2628515619Smrg 2728515619Smrg#if HAVE_CONFIG_H 2828515619Smrg#include <config.h> 2928515619Smrg#endif 3028515619Smrg 3128515619Smrg#include <stdio.h> 3228515619Smrg#include <assert.h> 3328515619Smrg 3428515619Smrg#include "synapticsstr.h" 3528515619Smrg#include "eventcomm.h" 3628515619Smrg 3728515619Smrg#define ArrayLength(a) (sizeof(a) / (sizeof((a)[0]))) 3828515619Smrg 3928515619Smrgint fd_read, fd_write; 4028515619Smrg 4128515619Smrg/* A syn event, always handy to have */ 4228515619Smrgstruct input_event syn = { {0, 0}, EV_SYN, SYN_REPORT, 0 }; 4328515619Smrg 4428515619Smrgstatic void 4528515619Smrgcreate_pipe_fd(void) 4628515619Smrg{ 4728515619Smrg int pipefd[2]; 4828515619Smrg 4928515619Smrg assert(pipe(pipefd) != -1); 5028515619Smrg 5128515619Smrg fd_read = pipefd[0]; 5228515619Smrg fd_write = pipefd[1]; 5328515619Smrg} 5428515619Smrg 5528515619Smrgstatic void 5628515619Smrgreset_data(struct SynapticsHwState **hw, struct CommData *comm, 5728515619Smrg SynapticsPrivate * priv) 5828515619Smrg{ 5928515619Smrg SynapticsHwStateFree(&comm->hwState); 6028515619Smrg memset(comm, 0, sizeof(struct CommData)); 6128515619Smrg SynapticsHwStateFree(hw); 6228515619Smrg *hw = SynapticsHwStateAlloc(priv); 6328515619Smrg comm->hwState = SynapticsHwStateAlloc(priv); 6428515619Smrg} 6528515619Smrg 6628515619Smrg/** 6728515619Smrg * Write n input events to fd, followed by the syn event. 6828515619Smrg */ 6928515619Smrgstatic void 7028515619Smrgwrite_event(int fd, struct input_event *ev, int n) 7128515619Smrg{ 7228515619Smrg write(fd, ev, sizeof(struct input_event) * n); 7328515619Smrg write(fd, &syn, sizeof(syn)); 7428515619Smrg} 7528515619Smrg 7628515619Smrgstatic void 7728515619Smrgtest_buttons(int fd, InputInfoPtr pInfo, struct CommData *comm) 7828515619Smrg{ 7928515619Smrg SynapticsPrivate *priv = (SynapticsPrivate *) pInfo->private; 8028515619Smrg struct SynapticsHwState *hw = NULL; 8128515619Smrg struct input_event ev = { {0, 0}, EV_KEY, 0, 0 }; 8228515619Smrg 8328515619Smrg reset_data(&hw, comm, priv); 8428515619Smrg 8528515619Smrg#define _test_press_release(_code, field) \ 8628515619Smrg ev.code = (_code); \ 8728515619Smrg ev.value = 1; \ 8828515619Smrg write_event(fd, &ev, 1); \ 8928515619Smrg EventReadHwState(pInfo, comm, hw); \ 9028515619Smrg assert(hw->field == 1); \ 9128515619Smrg ev.value = 0; /* button release */ \ 9228515619Smrg write_event(fd_write, &ev, 1); \ 9328515619Smrg EventReadHwState(pInfo, comm, hw); \ 9428515619Smrg assert(hw->field == 0); 9528515619Smrg 9628515619Smrg _test_press_release(BTN_LEFT, left); 9728515619Smrg _test_press_release(BTN_RIGHT, right); 9828515619Smrg _test_press_release(BTN_MIDDLE, middle); 9928515619Smrg _test_press_release(BTN_FORWARD, up); 10028515619Smrg _test_press_release(BTN_BACK, down); 10128515619Smrg _test_press_release(BTN_0, multi[0]); 10228515619Smrg _test_press_release(BTN_1, multi[1]); 10328515619Smrg _test_press_release(BTN_2, multi[2]); 10428515619Smrg _test_press_release(BTN_3, multi[3]); 10528515619Smrg _test_press_release(BTN_4, multi[4]); 10628515619Smrg _test_press_release(BTN_5, multi[5]); 10728515619Smrg _test_press_release(BTN_6, multi[6]); 10828515619Smrg _test_press_release(BTN_7, multi[7]); 10928515619Smrg 11028515619Smrg SynapticsHwStateFree(&hw); 11128515619Smrg} 11228515619Smrg 11328515619Smrg/** 11428515619Smrg * This test checks that the recognised event fields set the right hardware 11528515619Smrg * state. It's a fairly limited test and does not check whether any of the 11628515619Smrg * others change the HW state at all. 11728515619Smrg */ 11828515619Smrgstatic void 11928515619Smrgtest_read_hw_state(void) 12028515619Smrg{ 12128515619Smrg InputInfoRec info = { 0 }; 12228515619Smrg SynapticsPrivate private; 12328515619Smrg struct SynapticsHwState *hw = NULL; 12428515619Smrg struct CommData comm = { 0 }; 12528515619Smrg 12628515619Smrg struct input_event ev[] = { 12728515619Smrg {{0, 0}, EV_KEY, BTN_TOOL_FINGER, 1}, 12828515619Smrg {{0, 0}, EV_KEY, BTN_TOOL_DOUBLETAP, 1}, 12928515619Smrg {{0, 0}, EV_KEY, BTN_TOOL_TRIPLETAP, 1}, 13028515619Smrg {{0, 0}, EV_ABS, ABS_X, 42}, 13128515619Smrg {{0, 0}, EV_ABS, ABS_Y, 21}, 13228515619Smrg {{0, 0}, EV_ABS, ABS_PRESSURE, 56}, 13328515619Smrg {{0, 0}, EV_ABS, ABS_TOOL_WIDTH, 204}, 13428515619Smrg }; 13528515619Smrg 13628515619Smrg memset(&private, 0, sizeof(private)); 13728515619Smrg 13828515619Smrg info.private = &private; 13928515619Smrg info.fd = fd_read; 14028515619Smrg 14128515619Smrg private.proto_data = EventProtoDataAlloc(); 14228515619Smrg 14328515619Smrg /* just the syn event */ 14428515619Smrg reset_data(&hw, &comm, &private); 14528515619Smrg write(fd_write, &syn, sizeof(syn)); 14628515619Smrg EventReadHwState(&info, &comm, hw); 14728515619Smrg assert(hw->numFingers == 0); 14828515619Smrg 14928515619Smrg /* one finger */ 15028515619Smrg reset_data(&hw, &comm, &private); 15128515619Smrg write_event(fd_write, &ev[0], 1); 15228515619Smrg EventReadHwState(&info, &comm, hw); 15328515619Smrg assert(hw->numFingers == 1); 15428515619Smrg 15528515619Smrg /* two fingers */ 15628515619Smrg reset_data(&hw, &comm, &private); 15728515619Smrg write_event(fd_write, &ev[1], 1); 15828515619Smrg EventReadHwState(&info, &comm, hw); 15928515619Smrg assert(hw->numFingers == 2); 16028515619Smrg 16128515619Smrg /* three fingers */ 16228515619Smrg reset_data(&hw, &comm, &private); 16328515619Smrg write_event(fd_write, &ev[2], 1); 16428515619Smrg EventReadHwState(&info, &comm, hw); 16528515619Smrg assert(hw->numFingers == 3); 16628515619Smrg 16728515619Smrg /* x/y data */ 16828515619Smrg reset_data(&hw, &comm, &private); 16928515619Smrg write_event(fd_write, &ev[3], 2); 17028515619Smrg EventReadHwState(&info, &comm, hw); 17128515619Smrg assert(hw->x == ev[3].value); 17228515619Smrg assert(hw->y == ev[4].value); 17328515619Smrg 17428515619Smrg /* pressure */ 17528515619Smrg reset_data(&hw, &comm, &private); 17628515619Smrg write_event(fd_write, &ev[5], 1); 17728515619Smrg EventReadHwState(&info, &comm, hw); 17828515619Smrg assert(hw->z == ev[5].value); 17928515619Smrg 18028515619Smrg /* finger width */ 18128515619Smrg reset_data(&hw, &comm, &private); 18228515619Smrg write_event(fd_write, &ev[6], 1); 18328515619Smrg EventReadHwState(&info, &comm, hw); 18428515619Smrg assert(hw->fingerWidth == ev[6].value); 18528515619Smrg 18628515619Smrg /* the various buttons */ 18728515619Smrg test_buttons(fd_write, &info, &comm); 18828515619Smrg 18928515619Smrg free(private.proto_data); 19028515619Smrg SynapticsHwStateFree(&hw); 19128515619Smrg SynapticsHwStateFree(&comm.hwState); 19228515619Smrg} 19328515619Smrg 19428515619Smrgstatic Bool 19528515619Smrgcompare_hw_state(const struct SynapticsHwState *a, 19628515619Smrg const struct SynapticsHwState *b) 19728515619Smrg{ 19828515619Smrg#define COMPARE(x) \ 19928515619Smrg if (a->x != b->x) return a->x - b->x 20028515619Smrg 20128515619Smrg COMPARE(millis); 20228515619Smrg COMPARE(x); 20328515619Smrg COMPARE(y); 20428515619Smrg COMPARE(z); 20528515619Smrg COMPARE(numFingers); 20628515619Smrg COMPARE(fingerWidth); 20728515619Smrg COMPARE(left); 20828515619Smrg COMPARE(right); 20928515619Smrg COMPARE(up); 21028515619Smrg COMPARE(down); 21128515619Smrg if (memcmp(a->multi, b->multi, sizeof(a->multi))) 21228515619Smrg return memcmp(a->multi, b->multi, sizeof(a->multi)); 21328515619Smrg COMPARE(middle); 21428515619Smrg 21528515619Smrg#undef COMPARE 21628515619Smrg 21728515619Smrg return 0; 21828515619Smrg} 21928515619Smrg 22028515619Smrg/** 22128515619Smrg * Make sure that axes/keys unknown to the driver don't change the hardware 22228515619Smrg * state. 22328515619Smrg */ 22428515619Smrgstatic void 22528515619Smrgtest_ignore_hw_state(void) 22628515619Smrg{ 22728515619Smrg int i; 22828515619Smrg InputInfoRec info = { 0 }; 22928515619Smrg SynapticsPrivate private; 23028515619Smrg struct SynapticsHwState *hw = NULL; 23128515619Smrg struct SynapticsHwState *hw_zero = NULL; 23228515619Smrg struct CommData comm = { 0 }; 23328515619Smrg 23428515619Smrg int known_abs[] = { 23528515619Smrg ABS_X, 23628515619Smrg ABS_Y, 23728515619Smrg ABS_PRESSURE, 23828515619Smrg ABS_TOOL_WIDTH, 23928515619Smrg }; 24028515619Smrg 24128515619Smrg int known_keys[] = { 24228515619Smrg BTN_LEFT, 24328515619Smrg BTN_RIGHT, 24428515619Smrg BTN_MIDDLE, 24528515619Smrg BTN_FORWARD, 24628515619Smrg BTN_BACK, 24728515619Smrg BTN_0, 24828515619Smrg BTN_1, 24928515619Smrg BTN_2, 25028515619Smrg BTN_3, 25128515619Smrg BTN_4, 25228515619Smrg BTN_5, 25328515619Smrg BTN_6, 25428515619Smrg BTN_7, 25528515619Smrg BTN_TOOL_FINGER, 25628515619Smrg BTN_TOOL_DOUBLETAP, 25728515619Smrg BTN_TOOL_TRIPLETAP, 25828515619Smrg BTN_TOUCH 25928515619Smrg }; 26028515619Smrg 26128515619Smrg struct input_event ev = { {0, 0}, 0, 0, 1 }; 26228515619Smrg 26328515619Smrg memset(&private, 0, sizeof(private)); 26428515619Smrg info.private = &private; 26528515619Smrg info.fd = fd_read; 26628515619Smrg 26728515619Smrg private.proto_data = EventProtoDataAlloc(); 26828515619Smrg 26928515619Smrg reset_data(&hw_zero, &comm, &private); 27028515619Smrg 27128515619Smrg#define _assert_no_change(_type, _code) \ 27228515619Smrg reset_data(&hw, &comm, &private); \ 27328515619Smrg ev.type = _type; \ 27428515619Smrg ev.code = _code; \ 27528515619Smrg ev.value = 1; \ 27628515619Smrg write_event(fd_write, &ev, 1); \ 27728515619Smrg EventReadHwState(&info, &comm, hw); \ 27828515619Smrg assert(compare_hw_state(hw, hw_zero) == 0); 27928515619Smrg 28028515619Smrg for (i = ABS_X; i < ABS_MAX; i++) { 28128515619Smrg int j, skip = 0; 28228515619Smrg 28328515619Smrg for (j = 0; j < ArrayLength(known_abs); j++) { 28428515619Smrg if (i == known_abs[j]) { 28528515619Smrg skip = 1; 28628515619Smrg break; 28728515619Smrg } 28828515619Smrg } 28928515619Smrg 29028515619Smrg if (skip) 29128515619Smrg continue; 29228515619Smrg 29328515619Smrg _assert_no_change(EV_ABS, i); 29428515619Smrg } 29528515619Smrg 29628515619Smrg for (i = KEY_RESERVED; i < KEY_MAX; i++) { 29728515619Smrg int j, skip = 0; 29828515619Smrg 29928515619Smrg for (j = 0; j < ArrayLength(known_keys); j++) { 30028515619Smrg if (i == known_keys[j]) { 30128515619Smrg skip = 1; 30228515619Smrg break; 30328515619Smrg } 30428515619Smrg } 30528515619Smrg 30628515619Smrg if (skip) 30728515619Smrg continue; 30828515619Smrg 30928515619Smrg _assert_no_change(EV_KEY, i); 31028515619Smrg } 31128515619Smrg 31228515619Smrg free(private.proto_data); 31328515619Smrg SynapticsHwStateFree(&hw); 31428515619Smrg SynapticsHwStateFree(&hw_zero); 31528515619Smrg SynapticsHwStateFree(&comm.hwState); 31628515619Smrg} 31728515619Smrg 31828515619Smrgint 31928515619Smrgmain(int argc, char **argv) 32028515619Smrg{ 32128515619Smrg create_pipe_fd(); 32228515619Smrg 32328515619Smrg test_read_hw_state(); 32428515619Smrg test_ignore_hw_state(); 32528515619Smrg return 0; 32628515619Smrg} 327