1 /*****************************************************************************
2 *
3 * mtdev - Multitouch Protocol Translation Library (MIT license)
4 *
5 * Copyright (C) 2010 Henrik Rydberg <rydberg@euromail.se>
6 * Copyright (C) 2010 Canonical Ltd.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 *
27 ****************************************************************************/
28
29 #include "state.h"
30 #include "iobuf.h"
31 #include "evbuf.h"
32 #include "match.h"
33
34 #ifndef input_event_sec
35 #define input_event_sec time.tv_sec
36 #define input_event_usec time.tv_usec
37 #endif
38
istouch(const struct mtdev_slot * data,const struct mtdev * dev)39 static inline int istouch(const struct mtdev_slot *data,
40 const struct mtdev *dev)
41 {
42 return data->touch_major ||
43 !mtdev_has_mt_event(dev, ABS_MT_TOUCH_MAJOR);
44 }
45
isfilled(unsigned int mask)46 static inline int isfilled(unsigned int mask)
47 {
48 return GETBIT(mask, mtdev_abs2mt(ABS_MT_POSITION_X)) &&
49 GETBIT(mask, mtdev_abs2mt(ABS_MT_POSITION_Y));
50 }
51
52 /* Response-augmented EWMA filter, courtesy of Vojtech Pavlik */
defuzz(int value,int old_val,int fuzz)53 static int defuzz(int value, int old_val, int fuzz)
54 {
55 if (fuzz) {
56 if (value > old_val - fuzz / 2 && value < old_val + fuzz / 2)
57 return old_val;
58
59 if (value > old_val - fuzz && value < old_val + fuzz)
60 return (old_val * 3 + value) / 4;
61
62 if (value > old_val - fuzz * 2 && value < old_val + fuzz * 2)
63 return (old_val + value) / 2;
64 }
65
66 return value;
67 }
68
69 /*
70 * solve - solve contact matching problem
71 * @state: mtdev state
72 * @dev: device capabilities
73 * @sid: array of current tracking ids
74 * @sx: array of current position x
75 * @sy: array of current position y
76 * @sn: number of current contacts
77 * @nid: array of new or matched tracking ids, to be filled
78 * @nx: array of new position x
79 * @ny: array of new position y
80 * @nn: number of new contacts
81 * @touch: which of the new contacts to fill
82 */
solve(struct mtdev_state * state,const struct mtdev * dev,const int * sid,const int * sx,const int * sy,int sn,int * nid,const int * nx,const int * ny,int nn,bitmask_t touch)83 static void solve(struct mtdev_state *state, const struct mtdev *dev,
84 const int *sid, const int *sx, const int *sy, int sn,
85 int *nid, const int *nx, const int *ny, int nn,
86 bitmask_t touch)
87 {
88 int A[DIM2_FINGER], *row;
89 int n2s[DIM_FINGER];
90 int id, i, j;
91
92 /* setup distance matrix for contact matching */
93 for (j = 0; j < sn; j++) {
94 row = A + nn * j;
95 for (i = 0; i < nn; i++)
96 row[i] = dist2(nx[i] - sx[j], ny[i] - sy[j]);
97 }
98
99 mtdev_match(n2s, A, nn, sn);
100
101 /* update matched contacts and create new ones */
102 foreach_bit(i, touch) {
103 j = n2s[i];
104 id = j >= 0 ? sid[j] : MT_ID_NULL;
105 if (id == MT_ID_NULL)
106 id = state->lastid++ & MT_ID_MAX;
107 nid[i] = id;
108 }
109 }
110
111 /*
112 * assign_tracking_id - assign tracking ids to all contacts
113 * @state: mtdev state
114 * @dev: device capabilities
115 * @data: array of all present contacts, to be filled
116 * @prop: array of all set contacts properties
117 * @size: number of contacts in array
118 * @touch: which of the contacts are actual touches
119 */
assign_tracking_id(struct mtdev_state * state,const struct mtdev * dev,struct mtdev_slot * data,bitmask_t * prop,int size,bitmask_t touch)120 static void assign_tracking_id(struct mtdev_state *state,
121 const struct mtdev *dev,
122 struct mtdev_slot *data, bitmask_t *prop,
123 int size, bitmask_t touch)
124 {
125 int sid[DIM_FINGER], sx[DIM_FINGER], sy[DIM_FINGER], sn = 0;
126 int nid[DIM_FINGER], nx[DIM_FINGER], ny[DIM_FINGER], i;
127 foreach_bit(i, state->used) {
128 sid[sn] = state->data[i].tracking_id;
129 sx[sn] = state->data[i].position_x;
130 sy[sn] = state->data[i].position_y;
131 sn++;
132 }
133 for (i = 0; i < size; i++) {
134 nx[i] = data[i].position_x;
135 ny[i] = data[i].position_y;
136 }
137 solve(state, dev, sid, sx, sy, sn, nid, nx, ny, size, touch);
138 for (i = 0; i < size; i++) {
139 data[i].tracking_id = GETBIT(touch, i) ? nid[i] : MT_ID_NULL;
140 SETBIT(prop[i], mtdev_abs2mt(ABS_MT_TRACKING_ID));
141 }
142 }
143
144 /*
145 * process_typeA - consume MT events and update mtdev state
146 * @state: mtdev state
147 * @data: array of all present contacts, to be filled
148 * @prop: array of all set contacts properties, to be filled
149 *
150 * This function is called when a SYN_REPORT is seen, right before
151 * that event is pushed to the queue.
152 *
153 * Returns -1 if the packet is not MT related and should not affect
154 * the current mtdev state.
155 */
process_typeA(struct mtdev_state * state,struct mtdev_slot * data,bitmask_t * prop)156 static int process_typeA(struct mtdev_state *state,
157 struct mtdev_slot *data, bitmask_t *prop)
158 {
159 struct input_event ev;
160 int consumed, mtcode;
161 int mtcnt = 0, size = 0;
162 prop[size] = 0;
163 while (!evbuf_empty(&state->inbuf)) {
164 evbuf_get(&state->inbuf, &ev);
165 consumed = 0;
166 switch (ev.type) {
167 case EV_SYN:
168 switch (ev.code) {
169 case SYN_MT_REPORT:
170 if (size < DIM_FINGER && isfilled(prop[size]))
171 size++;
172 if (size < DIM_FINGER)
173 prop[size] = 0;
174 mtcnt++;
175 consumed = 1;
176 break;
177 }
178 break;
179 case EV_KEY:
180 switch (ev.code) {
181 case BTN_TOUCH:
182 mtcnt++;
183 break;
184 }
185 break;
186 case EV_ABS:
187 if (size < DIM_FINGER && mtdev_is_absmt(ev.code)) {
188 mtcode = mtdev_abs2mt(ev.code);
189 set_sval(&data[size], mtcode, ev.value);
190 SETBIT(prop[size], mtcode);
191 mtcnt++;
192 consumed = 1;
193 }
194 break;
195 }
196 if (!consumed)
197 evbuf_put(&state->outbuf, &ev);
198 }
199 return mtcnt ? size : -1;
200 }
201
202 /*
203 * process_typeB - propagate events without parsing
204 * @state: mtdev state
205 *
206 * This function is called when a SYN_REPORT is seen, right before
207 * that event is pushed to the queue.
208 */
process_typeB(struct mtdev_state * state)209 static void process_typeB(struct mtdev_state *state)
210 {
211 struct input_event ev;
212 while (!evbuf_empty(&state->inbuf)) {
213 evbuf_get(&state->inbuf, &ev);
214 evbuf_put(&state->outbuf, &ev);
215 }
216 }
217
218 /*
219 * filter_data - apply input filtering on new incoming data
220 * @state: mtdev state
221 * @dev: device capabilities
222 * @data: the incoming data to filter
223 * @prop: the properties to filter
224 * @slot: the slot the data refers to
225 */
filter_data(const struct mtdev_state * state,const struct mtdev * dev,struct mtdev_slot * data,bitmask_t prop,int slot)226 static void filter_data(const struct mtdev_state *state,
227 const struct mtdev *dev,
228 struct mtdev_slot *data, bitmask_t prop,
229 int slot)
230 {
231 int i;
232 foreach_bit(i, prop) {
233 int fuzz = mtdev_get_abs_fuzz(dev, mtdev_mt2abs(i));
234 int oldval = get_sval(&state->data[slot], i);
235 int value = get_sval(data, i);
236 set_sval(data, i, defuzz(value, oldval, fuzz));
237 }
238 }
239
240 /*
241 * push_slot_changes - propagate state changes
242 * @state: mtdev state
243 * @data: the incoming data to propagate
244 * @prop: the properties to propagate
245 * @slot: the slot the data refers to
246 * @syn: reference to the SYN_REPORT event
247 */
push_slot_changes(struct mtdev_state * state,const struct mtdev_slot * data,bitmask_t prop,int slot,const struct input_event * syn)248 static void push_slot_changes(struct mtdev_state *state,
249 const struct mtdev_slot *data, bitmask_t prop,
250 int slot, const struct input_event *syn)
251 {
252 struct input_event ev;
253 int i, count = 0;
254 foreach_bit(i, prop)
255 if (get_sval(&state->data[slot], i) != get_sval(data, i))
256 count++;
257 if (!count)
258 return;
259 ev.input_event_sec = syn->input_event_sec;
260 ev.input_event_usec = syn->input_event_usec;
261 ev.type = EV_ABS;
262 ev.code = ABS_MT_SLOT;
263 ev.value = slot;
264 if (state->slot != ev.value) {
265 evbuf_put(&state->outbuf, &ev);
266 state->slot = ev.value;
267 }
268 foreach_bit(i, prop) {
269 ev.code = mtdev_mt2abs(i);
270 ev.value = get_sval(data, i);
271 if (get_sval(&state->data[slot], i) != ev.value) {
272 evbuf_put(&state->outbuf, &ev);
273 set_sval(&state->data[slot], i, ev.value);
274 }
275 }
276 }
277
278 /*
279 * apply_typeA_changes - parse and propagate state changes
280 * @state: mtdev state
281 * @dev: device capabilities
282 * @data: array of data to apply
283 * @prop: array of properties to apply
284 * @size: number of contacts in array
285 * @syn: reference to the SYN_REPORT event
286 */
apply_typeA_changes(struct mtdev_state * state,const struct mtdev * dev,struct mtdev_slot * data,const bitmask_t * prop,int size,const struct input_event * syn)287 static void apply_typeA_changes(struct mtdev_state *state,
288 const struct mtdev *dev,
289 struct mtdev_slot *data, const bitmask_t *prop,
290 int size, const struct input_event *syn)
291 {
292 bitmask_t unused = ~state->used;
293 bitmask_t used = 0;
294 int i, slot, id;
295 for (i = 0; i < size; i++) {
296 id = data[i].tracking_id;
297 foreach_bit(slot, state->used) {
298 if (state->data[slot].tracking_id != id)
299 continue;
300 filter_data(state, dev, &data[i], prop[i], slot);
301 push_slot_changes(state, &data[i], prop[i], slot, syn);
302 SETBIT(used, slot);
303 id = MT_ID_NULL;
304 break;
305 }
306 if (id != MT_ID_NULL) {
307 slot = firstbit(unused);
308 push_slot_changes(state, &data[i], prop[i], slot, syn);
309 SETBIT(used, slot);
310 CLEARBIT(unused, slot);
311 }
312 }
313
314 /* clear unused slots and update slot usage */
315 foreach_bit(slot, state->used & ~used) {
316 struct mtdev_slot tdata = state->data[slot];
317 bitmask_t tprop = BITMASK(mtdev_abs2mt(ABS_MT_TRACKING_ID));
318 tdata.tracking_id = MT_ID_NULL;
319 push_slot_changes(state, &tdata, tprop, slot, syn);
320 }
321 state->used = used;
322 }
323
324 /*
325 * convert_A_to_B - propagate a type A packet as a type B packet
326 * @state: mtdev state
327 * @dev: device capabilities
328 * @syn: reference to the SYN_REPORT event
329 */
convert_A_to_B(struct mtdev_state * state,const struct mtdev * dev,const struct input_event * syn)330 static void convert_A_to_B(struct mtdev_state *state,
331 const struct mtdev *dev,
332 const struct input_event *syn)
333 {
334 struct mtdev_slot data[DIM_FINGER];
335 bitmask_t prop[DIM_FINGER];
336 int size = process_typeA(state, data, prop);
337 if (size < 0)
338 return;
339 if (!mtdev_has_mt_event(dev, ABS_MT_TRACKING_ID)) {
340 bitmask_t touch = 0;
341 int i;
342 for (i = 0; i < size; i++)
343 MODBIT(touch, i, istouch(&data[i], dev));
344 assign_tracking_id(state, dev, data, prop, size, touch);
345 }
346 apply_typeA_changes(state, dev, data, prop, size, syn);
347 }
348
mtdev_new(void)349 struct mtdev *mtdev_new(void)
350 {
351 return calloc(1, sizeof(struct mtdev));
352 }
353
mtdev_init(struct mtdev * dev)354 int mtdev_init(struct mtdev *dev)
355 {
356 int i;
357 memset(dev, 0, sizeof(struct mtdev));
358 dev->state = calloc(1, sizeof(struct mtdev_state));
359 if (!dev->state)
360 return -ENOMEM;
361 for (i = 0; i < DIM_FINGER; i++)
362 dev->state->data[i].tracking_id = MT_ID_NULL;
363 return 0;
364 }
365
mtdev_open(struct mtdev * dev,int fd)366 int mtdev_open(struct mtdev *dev, int fd)
367 {
368 int ret = -EINVAL;
369
370 if (!dev || fd < 0)
371 goto error;
372 ret = mtdev_init(dev);
373 if (ret)
374 goto error;
375 ret = mtdev_configure(dev, fd);
376 if (ret)
377 goto error;
378 return 0;
379
380 error:
381 mtdev_close(dev);
382 return ret;
383 }
384
mtdev_new_open(int fd)385 struct mtdev *mtdev_new_open(int fd)
386 {
387 struct mtdev *dev;
388
389 dev = mtdev_new();
390 if (!dev)
391 return NULL;
392 if (!mtdev_open(dev, fd))
393 return dev;
394
395 mtdev_delete(dev);
396 return NULL;
397 }
398
mtdev_put_event(struct mtdev * dev,const struct input_event * ev)399 void mtdev_put_event(struct mtdev *dev, const struct input_event *ev)
400 {
401 struct mtdev_state *state = dev->state;
402 if (ev->type == EV_SYN && ev->code == SYN_REPORT) {
403 bitmask_t head = state->outbuf.head;
404 if (mtdev_has_mt_event(dev, ABS_MT_SLOT))
405 process_typeB(state);
406 else
407 convert_A_to_B(state, dev, ev);
408 if (state->outbuf.head != head)
409 evbuf_put(&state->outbuf, ev);
410 } else {
411 evbuf_put(&state->inbuf, ev);
412 }
413 }
414
mtdev_close_delete(struct mtdev * dev)415 void mtdev_close_delete(struct mtdev *dev)
416 {
417 mtdev_close(dev);
418 mtdev_delete(dev);
419 }
420
mtdev_close(struct mtdev * dev)421 void mtdev_close(struct mtdev *dev)
422 {
423 if (dev) {
424 free(dev->state);
425 memset(dev, 0, sizeof(struct mtdev));
426 }
427 }
428
mtdev_delete(struct mtdev * dev)429 void mtdev_delete(struct mtdev *dev)
430 {
431 free(dev);
432 }
433