1/* 2 * Copyright © 2015 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 "litest.h" 27#include "litest-int.h" 28 29#define PROTOCOL_A_MAX_SLOTS 10 30 31struct protocolA_device { 32 struct slot { 33 bool active; 34 int x, y; 35 int tracking_id; 36 } slots[PROTOCOL_A_MAX_SLOTS]; 37 unsigned int nslots; 38}; 39 40static bool 41protocolA_create(struct litest_device *d) 42{ 43 struct protocolA_device *dev = zalloc(sizeof(*dev)); 44 45 dev->nslots = PROTOCOL_A_MAX_SLOTS; 46 47 d->private = dev; 48 49 return true; /* we want litest to create our device */ 50} 51 52static bool 53protocolA_down(struct litest_device *d, unsigned int slot, double x, double y) 54{ 55 struct protocolA_device *dev = d->private; 56 static int tracking_id; 57 bool first = true; 58 59 assert(slot <= PROTOCOL_A_MAX_SLOTS); 60 61 x = litest_scale(d, ABS_X, x); 62 y = litest_scale(d, ABS_Y, y); 63 64 for (unsigned int i = 0; i < dev->nslots; i++) { 65 struct slot *s = &dev->slots[i]; 66 67 if (slot == i) { 68 assert(!s->active); 69 s->active = true; 70 s->x = x; 71 s->y = y; 72 s->tracking_id = ++tracking_id; 73 } 74 if (!s->active) 75 continue; 76 77 if (first) { 78 litest_event(d, EV_ABS, ABS_X, s->x); 79 litest_event(d, EV_ABS, ABS_Y, s->y); 80 first = false; 81 } 82 83 litest_event(d, EV_ABS, ABS_MT_TRACKING_ID, s->tracking_id); 84 litest_event(d, EV_ABS, ABS_MT_POSITION_X, s->x); 85 litest_event(d, EV_ABS, ABS_MT_POSITION_Y, s->y); 86 litest_event(d, EV_SYN, SYN_MT_REPORT, 0); 87 } 88 89 if (!first) { 90 litest_event(d, EV_KEY, BTN_TOUCH, 1); 91 litest_event(d, EV_SYN, SYN_REPORT, 0); 92 } 93 94 return true; /* we handled the event */ 95} 96 97static bool 98protocolA_move(struct litest_device *d, unsigned int slot, double x, double y) 99{ 100 struct protocolA_device *dev = d->private; 101 bool first = true; 102 103 assert(slot <= PROTOCOL_A_MAX_SLOTS); 104 105 x = litest_scale(d, ABS_X, x); 106 y = litest_scale(d, ABS_Y, y); 107 108 for (unsigned int i = 0; i < dev->nslots; i++) { 109 struct slot *s = &dev->slots[i]; 110 111 if (slot == i) { 112 assert(s->active); 113 s->x = x; 114 s->y = y; 115 } 116 if (!s->active) 117 continue; 118 119 if (first) { 120 litest_event(d, EV_ABS, ABS_X, s->x); 121 litest_event(d, EV_ABS, ABS_X, s->y); 122 first = false; 123 } 124 125 litest_event(d, EV_ABS, ABS_MT_TRACKING_ID, s->tracking_id); 126 litest_event(d, EV_ABS, ABS_MT_POSITION_X, s->x); 127 litest_event(d, EV_ABS, ABS_MT_POSITION_Y, s->y); 128 litest_event(d, EV_SYN, SYN_MT_REPORT, 0); 129 } 130 131 if (!first) 132 litest_event(d, EV_SYN, SYN_REPORT, 0); 133 134 return true; /* we handled the event */ 135} 136 137static bool 138protocolA_up(struct litest_device *d, unsigned int slot) 139{ 140 struct protocolA_device *dev = d->private; 141 bool first = true; 142 143 assert(slot <= PROTOCOL_A_MAX_SLOTS); 144 145 for (unsigned int i = 0; i < dev->nslots; i++) { 146 struct slot *s = &dev->slots[i]; 147 148 if (slot == i) { 149 assert(s->active); 150 s->active = false; 151 litest_event(d, EV_ABS, ABS_MT_TRACKING_ID, s->tracking_id); 152 litest_event(d, EV_SYN, SYN_MT_REPORT, 0); 153 } 154 if (!s->active) 155 continue; 156 157 if (first) { 158 litest_event(d, EV_ABS, ABS_X, s->x); 159 litest_event(d, EV_ABS, ABS_X, s->y); 160 first = false; 161 } 162 163 litest_event(d, EV_ABS, ABS_MT_TRACKING_ID, s->tracking_id); 164 litest_event(d, EV_ABS, ABS_MT_POSITION_X, s->x); 165 litest_event(d, EV_ABS, ABS_MT_POSITION_Y, s->y); 166 litest_event(d, EV_SYN, SYN_MT_REPORT, 0); 167 168 } 169 170 if (first) 171 litest_event(d, EV_KEY, BTN_TOUCH, 0); 172 litest_event(d, EV_SYN, SYN_REPORT, 0); 173 174 return true; /* we handled the event */ 175} 176 177static struct litest_device_interface interface = { 178 .touch_down = protocolA_down, 179 .touch_move = protocolA_move, 180 .touch_up = protocolA_up, 181}; 182 183static struct input_absinfo absinfo[] = { 184 { ABS_X, 0, 32767, 0, 0, 0 }, 185 { ABS_Y, 0, 32767, 0, 0, 0 }, 186 { ABS_MT_POSITION_X, 0, 32767, 0, 0, 0 }, 187 { ABS_MT_POSITION_Y, 0, 32767, 0, 0, 0 }, 188 { ABS_MT_PRESSURE, 0, 1, 0, 0, 0 }, 189 { .value = -1 }, 190}; 191 192static struct input_id input_id = { 193 .bustype = 0x18, 194 .vendor = 0xeef, 195 .product = 0x20, 196}; 197 198static int events[] = { 199 EV_KEY, BTN_TOUCH, 200 INPUT_PROP_MAX, INPUT_PROP_DIRECT, 201 -1, -1, 202}; 203 204TEST_DEVICE("protocol-a", 205 .type = LITEST_PROTOCOL_A_SCREEN, 206 .features = LITEST_PROTOCOL_A|LITEST_TOUCH, 207 .create = protocolA_create, 208 209 .interface = &interface, 210 211 .name = "Protocol A touch screen", 212 .id = &input_id, 213 .events = events, 214 .absinfo = absinfo, 215) 216