1 /*- 2 * Copyright (c) 2016 Vladimir Kondratyev <[email protected]> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #include <sys/param.h> 30 #include <sys/lock.h> 31 #include <sys/malloc.h> 32 #include <sys/mutex.h> 33 #include <sys/systm.h> 34 35 #include <dev/evdev/evdev.h> 36 #include <dev/evdev/evdev_private.h> 37 #include <dev/evdev/input.h> 38 39 #ifdef DEBUG 40 #define debugf(fmt, args...) printf("evdev: " fmt "\n", ##args) 41 #else 42 #define debugf(fmt, args...) 43 #endif 44 45 typedef u_int slotset_t; 46 47 _Static_assert(MAX_MT_SLOTS < sizeof(slotset_t) * 8, "MAX_MT_SLOTS too big"); 48 49 #define FOREACHBIT(v, i) \ 50 for ((i) = ffs(v) - 1; (i) != -1; (i) = ffs((v) & (~1 << (i))) - 1) 51 52 struct { 53 uint16_t mt; 54 uint16_t st; 55 int32_t max; 56 } static evdev_mtstmap[] = { 57 { ABS_MT_POSITION_X, ABS_X, 0 }, 58 { ABS_MT_POSITION_Y, ABS_Y, 0 }, 59 { ABS_MT_PRESSURE, ABS_PRESSURE, 255 }, 60 { ABS_MT_TOUCH_MAJOR, ABS_TOOL_WIDTH, 15 }, 61 }; 62 63 struct evdev_mt_slot { 64 int32_t val[MT_CNT]; 65 }; 66 67 struct evdev_mt { 68 int last_reported_slot; 69 u_int mtst_events; 70 /* the set of slots with active touches */ 71 slotset_t touches; 72 /* the set of slots with unsynchronized state */ 73 slotset_t frame; 74 struct evdev_mt_slot slots[]; 75 }; 76 77 static void evdev_mt_send_st_compat(struct evdev_dev *); 78 static void evdev_mt_send_autorel(struct evdev_dev *); 79 80 static inline int 81 ffc_slot(struct evdev_dev *evdev, slotset_t slots) 82 { 83 return (ffs(~slots & (2U << MAXIMAL_MT_SLOT(evdev)) - 1) - 1); 84 } 85 86 void 87 evdev_mt_init(struct evdev_dev *evdev) 88 { 89 int slot, slots; 90 91 slots = MAXIMAL_MT_SLOT(evdev) + 1; 92 93 evdev->ev_mt = malloc(offsetof(struct evdev_mt, slots) + 94 sizeof(struct evdev_mt_slot) * slots, M_EVDEV, M_WAITOK | M_ZERO); 95 96 /* Initialize multitouch protocol type B states */ 97 for (slot = 0; slot < slots; slot++) 98 evdev->ev_mt->slots[slot].val[ABS_MT_INDEX(ABS_MT_TRACKING_ID)] 99 = -1; 100 101 if (bit_test(evdev->ev_flags, EVDEV_FLAG_MT_STCOMPAT)) 102 evdev_support_mt_compat(evdev); 103 } 104 105 void 106 evdev_mt_free(struct evdev_dev *evdev) 107 { 108 free(evdev->ev_mt, M_EVDEV); 109 } 110 111 void 112 evdev_mt_sync_frame(struct evdev_dev *evdev) 113 { 114 if (bit_test(evdev->ev_flags, EVDEV_FLAG_MT_AUTOREL)) 115 evdev_mt_send_autorel(evdev); 116 if (evdev->ev_report_opened && 117 bit_test(evdev->ev_flags, EVDEV_FLAG_MT_STCOMPAT)) 118 evdev_mt_send_st_compat(evdev); 119 evdev->ev_mt->frame = 0; 120 } 121 122 int 123 evdev_mt_get_last_slot(struct evdev_dev *evdev) 124 { 125 return (evdev->ev_mt->last_reported_slot); 126 } 127 128 void 129 evdev_mt_set_last_slot(struct evdev_dev *evdev, int slot) 130 { 131 struct evdev_mt *mt = evdev->ev_mt; 132 133 MPASS(slot >= 0 && slot <= MAXIMAL_MT_SLOT(evdev)); 134 135 mt->frame |= 1U << slot; 136 mt->last_reported_slot = slot; 137 } 138 139 int32_t 140 evdev_mt_get_value(struct evdev_dev *evdev, int slot, int16_t code) 141 { 142 struct evdev_mt *mt = evdev->ev_mt; 143 144 MPASS(slot >= 0 && slot <= MAXIMAL_MT_SLOT(evdev)); 145 146 return (mt->slots[slot].val[ABS_MT_INDEX(code)]); 147 } 148 149 void 150 evdev_mt_set_value(struct evdev_dev *evdev, int slot, int16_t code, 151 int32_t value) 152 { 153 struct evdev_mt *mt = evdev->ev_mt; 154 155 MPASS(slot >= 0 && slot <= MAXIMAL_MT_SLOT(evdev)); 156 157 if (code == ABS_MT_TRACKING_ID) { 158 if (value != -1) 159 mt->touches |= 1U << slot; 160 else 161 mt->touches &= ~(1U << slot); 162 } 163 mt->slots[slot].val[ABS_MT_INDEX(code)] = value; 164 } 165 166 int 167 evdev_get_mt_slot_by_tracking_id(struct evdev_dev *evdev, int32_t tracking_id) 168 { 169 struct evdev_mt *mt = evdev->ev_mt; 170 int slot; 171 172 FOREACHBIT(mt->touches, slot) 173 if (evdev_mt_get_value(evdev, slot, ABS_MT_TRACKING_ID) == 174 tracking_id) 175 return (slot); 176 /* 177 * Do not allow allocation of new slot in a place of just 178 * released one within the same report. 179 */ 180 return (ffc_slot(evdev, mt->touches | mt->frame)); 181 } 182 183 static inline int32_t 184 evdev_mt_normalize(int32_t value, int32_t mtmin, int32_t mtmax, int32_t stmax) 185 { 186 if (stmax != 0 && mtmax != mtmin) { 187 value = (value - mtmin) * stmax / (mtmax - mtmin); 188 value = MAX(MIN(value, stmax), 0); 189 } 190 return (value); 191 } 192 193 void 194 evdev_support_mt_compat(struct evdev_dev *evdev) 195 { 196 struct input_absinfo *ai; 197 int i; 198 199 if (evdev->ev_absinfo == NULL) 200 return; 201 202 evdev_support_event(evdev, EV_KEY); 203 evdev_support_key(evdev, BTN_TOUCH); 204 205 /* Touchscreens should not advertise tap tool capabilities */ 206 if (!bit_test(evdev->ev_prop_flags, INPUT_PROP_DIRECT)) 207 evdev_support_nfingers(evdev, MAXIMAL_MT_SLOT(evdev) + 1); 208 209 /* Echo 0-th MT-slot as ST-slot */ 210 for (i = 0; i < nitems(evdev_mtstmap); i++) { 211 if (!bit_test(evdev->ev_abs_flags, evdev_mtstmap[i].mt) || 212 bit_test(evdev->ev_abs_flags, evdev_mtstmap[i].st)) 213 continue; 214 ai = evdev->ev_absinfo + evdev_mtstmap[i].mt; 215 evdev->ev_mt->mtst_events |= 1U << i; 216 if (evdev_mtstmap[i].max != 0) 217 evdev_support_abs(evdev, evdev_mtstmap[i].st, 218 0, 219 evdev_mtstmap[i].max, 220 0, 221 evdev_mt_normalize( 222 ai->flat, 0, ai->maximum, evdev_mtstmap[i].max), 223 0); 224 else 225 evdev_support_abs(evdev, evdev_mtstmap[i].st, 226 ai->minimum, 227 ai->maximum, 228 0, 229 ai->flat, 230 ai->resolution); 231 } 232 } 233 234 static void 235 evdev_mt_send_st_compat(struct evdev_dev *evdev) 236 { 237 struct evdev_mt *mt = evdev->ev_mt; 238 int nfingers, i, st_slot; 239 240 EVDEV_LOCK_ASSERT(evdev); 241 242 nfingers = bitcount(mt->touches); 243 evdev_send_event(evdev, EV_KEY, BTN_TOUCH, nfingers > 0); 244 245 /* Send first active MT-slot state as single touch report */ 246 st_slot = ffs(mt->touches) - 1; 247 if (st_slot != -1) 248 FOREACHBIT(mt->mtst_events, i) 249 evdev_send_event(evdev, EV_ABS, evdev_mtstmap[i].st, 250 evdev_mt_normalize(evdev_mt_get_value(evdev, 251 st_slot, evdev_mtstmap[i].mt), 252 evdev->ev_absinfo[evdev_mtstmap[i].mt].minimum, 253 evdev->ev_absinfo[evdev_mtstmap[i].mt].maximum, 254 evdev_mtstmap[i].max)); 255 256 /* Touchscreens should not report tool taps */ 257 if (!bit_test(evdev->ev_prop_flags, INPUT_PROP_DIRECT)) 258 evdev_send_nfingers(evdev, nfingers); 259 260 if (nfingers == 0) 261 evdev_send_event(evdev, EV_ABS, ABS_PRESSURE, 0); 262 } 263 264 void 265 evdev_push_mt_compat(struct evdev_dev *evdev) 266 { 267 268 EVDEV_ENTER(evdev); 269 evdev_mt_send_st_compat(evdev); 270 EVDEV_EXIT(evdev); 271 } 272 273 static void 274 evdev_mt_send_autorel(struct evdev_dev *evdev) 275 { 276 struct evdev_mt *mt = evdev->ev_mt; 277 int slot; 278 279 EVDEV_LOCK_ASSERT(evdev); 280 281 FOREACHBIT(mt->touches & ~mt->frame, slot) { 282 evdev_send_event(evdev, EV_ABS, ABS_MT_SLOT, slot); 283 evdev_send_event(evdev, EV_ABS, ABS_MT_TRACKING_ID, -1); 284 } 285 } 286 287 void 288 evdev_mt_push_autorel(struct evdev_dev *evdev) 289 { 290 EVDEV_ENTER(evdev); 291 evdev_mt_send_autorel(evdev); 292 EVDEV_EXIT(evdev); 293 } 294