summaryrefslogtreecommitdiff
path: root/src/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core.c')
-rw-r--r--src/core.c126
1 files changed, 80 insertions, 46 deletions
diff --git a/src/core.c b/src/core.c
index a6798b0..1f7c1fe 100644
--- a/src/core.c
+++ b/src/core.c
@@ -32,10 +32,16 @@
32#include "match.h" 32#include "match.h"
33 33
34static inline int istouch(const struct mtdev_slot *data, 34static inline int istouch(const struct mtdev_slot *data,
35 const struct mtdev_caps *caps) 35 const struct mtdev *dev)
36{ 36{
37 return data->abs[MTDEV_TOUCH_MAJOR] || 37 return data->touch_major ||
38 !caps->has_abs[MTDEV_TOUCH_MAJOR]; 38 !mtdev_has_mt_event(dev, ABS_MT_TOUCH_MAJOR);
39}
40
41static inline int isfilled(unsigned int mask)
42{
43 return GETBIT(mask, mtdev_abs2mt(ABS_MT_POSITION_X)) &&
44 GETBIT(mask, mtdev_abs2mt(ABS_MT_POSITION_Y));
39} 45}
40 46
41/* Response-augmented EWMA filter, courtesy of Vojtech Pavlik */ 47/* Response-augmented EWMA filter, courtesy of Vojtech Pavlik */
@@ -58,7 +64,7 @@ static int defuzz(int value, int old_val, int fuzz)
58/* 64/*
59 * solve - solve contact matching problem 65 * solve - solve contact matching problem
60 * @state: mtdev state 66 * @state: mtdev state
61 * @caps: device capabilities 67 * @dev: device capabilities
62 * @sid: array of current tracking ids 68 * @sid: array of current tracking ids
63 * @sx: array of current position x 69 * @sx: array of current position x
64 * @sy: array of current position y 70 * @sy: array of current position y
@@ -69,7 +75,7 @@ static int defuzz(int value, int old_val, int fuzz)
69 * @nn: number of new contacts 75 * @nn: number of new contacts
70 * @touch: which of the new contacts to fill 76 * @touch: which of the new contacts to fill
71 */ 77 */
72static void solve(struct mtdev_state *state, const struct mtdev_caps *caps, 78static void solve(struct mtdev_state *state, const struct mtdev *dev,
73 const int *sid, const int *sx, const int *sy, int sn, 79 const int *sid, const int *sx, const int *sy, int sn,
74 int *nid, const int *nx, const int *ny, int nn, 80 int *nid, const int *nx, const int *ny, int nn,
75 bitmask_t touch) 81 bitmask_t touch)
@@ -100,34 +106,33 @@ static void solve(struct mtdev_state *state, const struct mtdev_caps *caps,
100/* 106/*
101 * assign_tracking_id - assign tracking ids to all contacts 107 * assign_tracking_id - assign tracking ids to all contacts
102 * @state: mtdev state 108 * @state: mtdev state
103 * @caps: device capabilities 109 * @dev: device capabilities
104 * @data: array of all present contacts, to be filled 110 * @data: array of all present contacts, to be filled
105 * @prop: array of all set contacts properties 111 * @prop: array of all set contacts properties
106 * @size: number of contacts in array 112 * @size: number of contacts in array
107 * @touch: which of the contacts are actual touches 113 * @touch: which of the contacts are actual touches
108 */ 114 */
109static void assign_tracking_id(struct mtdev_state *state, 115static void assign_tracking_id(struct mtdev_state *state,
110 const struct mtdev_caps *caps, 116 const struct mtdev *dev,
111 struct mtdev_slot *data, bitmask_t *prop, 117 struct mtdev_slot *data, bitmask_t *prop,
112 int size, bitmask_t touch) 118 int size, bitmask_t touch)
113{ 119{
114 int sid[DIM_FINGER], sx[DIM_FINGER], sy[DIM_FINGER], sn = 0; 120 int sid[DIM_FINGER], sx[DIM_FINGER], sy[DIM_FINGER], sn = 0;
115 int nid[DIM_FINGER], nx[DIM_FINGER], ny[DIM_FINGER], i; 121 int nid[DIM_FINGER], nx[DIM_FINGER], ny[DIM_FINGER], i;
116 foreach_bit(i, state->used) { 122 foreach_bit(i, state->used) {
117 sid[sn] = state->data[i].abs[MTDEV_TRACKING_ID]; 123 sid[sn] = state->data[i].tracking_id;
118 sx[sn] = state->data[i].abs[MTDEV_POSITION_X]; 124 sx[sn] = state->data[i].position_x;
119 sy[sn] = state->data[i].abs[MTDEV_POSITION_Y]; 125 sy[sn] = state->data[i].position_y;
120 sn++; 126 sn++;
121 } 127 }
122 for (i = 0; i < size; i++) { 128 for (i = 0; i < size; i++) {
123 nx[i] = data[i].abs[MTDEV_POSITION_X]; 129 nx[i] = data[i].position_x;
124 ny[i] = data[i].abs[MTDEV_POSITION_Y]; 130 ny[i] = data[i].position_y;
125 } 131 }
126 solve(state, caps, sid, sx, sy, sn, nid, nx, ny, size, touch); 132 solve(state, dev, sid, sx, sy, sn, nid, nx, ny, size, touch);
127 for (i = 0; i < size; i++) { 133 for (i = 0; i < size; i++) {
128 data[i].abs[MTDEV_TRACKING_ID] = 134 data[i].tracking_id = GETBIT(touch, i) ? nid[i] : MT_ID_NULL;
129 GETBIT(touch, i) ? nid[i] : MT_ID_NULL; 135 SETBIT(prop[i], mtdev_abs2mt(ABS_MT_TRACKING_ID));
130 prop[i] |= BITMASK(MTDEV_TRACKING_ID);
131 } 136 }
132} 137}
133 138
@@ -157,9 +162,7 @@ static int process_typeA(struct mtdev_state *state,
157 case EV_SYN: 162 case EV_SYN:
158 switch (ev.code) { 163 switch (ev.code) {
159 case SYN_MT_REPORT: 164 case SYN_MT_REPORT:
160 if (size < DIM_FINGER && 165 if (size < DIM_FINGER && isfilled(prop[size]))
161 GETBIT(prop[size], MTDEV_POSITION_X) &&
162 GETBIT(prop[size], MTDEV_POSITION_Y))
163 size++; 166 size++;
164 if (size < DIM_FINGER) 167 if (size < DIM_FINGER)
165 prop[size] = 0; 168 prop[size] = 0;
@@ -178,8 +181,8 @@ static int process_typeA(struct mtdev_state *state,
178 case EV_ABS: 181 case EV_ABS:
179 if (size < DIM_FINGER && mtdev_is_absmt(ev.code)) { 182 if (size < DIM_FINGER && mtdev_is_absmt(ev.code)) {
180 mtcode = mtdev_abs2mt(ev.code); 183 mtcode = mtdev_abs2mt(ev.code);
181 data[size].abs[mtcode] = ev.value; 184 set_sval(&data[size], mtcode, ev.value);
182 prop[size] |= BITMASK(mtcode); 185 SETBIT(prop[size], mtcode);
183 mtcnt++; 186 mtcnt++;
184 consumed = 1; 187 consumed = 1;
185 } 188 }
@@ -210,21 +213,22 @@ static void process_typeB(struct mtdev_state *state)
210/* 213/*
211 * filter_data - apply input filtering on new incoming data 214 * filter_data - apply input filtering on new incoming data
212 * @state: mtdev state 215 * @state: mtdev state
213 * @caps: device capabilities 216 * @dev: device capabilities
214 * @data: the incoming data to filter 217 * @data: the incoming data to filter
215 * @prop: the properties to filter 218 * @prop: the properties to filter
216 * @slot: the slot the data refers to 219 * @slot: the slot the data refers to
217 */ 220 */
218static void filter_data(const struct mtdev_state *state, 221static void filter_data(const struct mtdev_state *state,
219 const struct mtdev_caps *caps, 222 const struct mtdev *dev,
220 struct mtdev_slot *data, bitmask_t prop, 223 struct mtdev_slot *data, bitmask_t prop,
221 int slot) 224 int slot)
222{ 225{
223 int i; 226 int i;
224 foreach_bit(i, prop) { 227 foreach_bit(i, prop) {
225 int fuzz = caps->abs[i].fuzz; 228 int fuzz = mtdev_get_abs_fuzz(dev, mtdev_mt2abs(i));
226 int oldval = state->data[slot].abs[i]; 229 int oldval = get_sval(&state->data[slot], i);
227 data->abs[i] = defuzz(data->abs[i], oldval, fuzz); 230 int value = get_sval(data, i);
231 set_sval(data, i, defuzz(value, oldval, fuzz));
228 } 232 }
229} 233}
230 234
@@ -243,7 +247,7 @@ static void push_slot_changes(struct mtdev_state *state,
243 struct input_event ev; 247 struct input_event ev;
244 int i, count = 0; 248 int i, count = 0;
245 foreach_bit(i, prop) 249 foreach_bit(i, prop)
246 if (state->data[slot].abs[i] != data->abs[i]) 250 if (get_sval(&state->data[slot], i) != get_sval(data, i))
247 count++; 251 count++;
248 if (!count) 252 if (!count)
249 return; 253 return;
@@ -257,10 +261,10 @@ static void push_slot_changes(struct mtdev_state *state,
257 } 261 }
258 foreach_bit(i, prop) { 262 foreach_bit(i, prop) {
259 ev.code = mtdev_mt2abs(i); 263 ev.code = mtdev_mt2abs(i);
260 ev.value = data->abs[i]; 264 ev.value = get_sval(data, i);
261 if (state->data[slot].abs[i] != ev.value) { 265 if (get_sval(&state->data[slot], i) != ev.value) {
262 evbuf_put(&state->outbuf, &ev); 266 evbuf_put(&state->outbuf, &ev);
263 state->data[slot].abs[i] = ev.value; 267 set_sval(&state->data[slot], i, ev.value);
264 } 268 }
265 } 269 }
266} 270}
@@ -268,14 +272,14 @@ static void push_slot_changes(struct mtdev_state *state,
268/* 272/*
269 * apply_typeA_changes - parse and propagate state changes 273 * apply_typeA_changes - parse and propagate state changes
270 * @state: mtdev state 274 * @state: mtdev state
271 * @caps: device capabilities 275 * @dev: device capabilities
272 * @data: array of data to apply 276 * @data: array of data to apply
273 * @prop: array of properties to apply 277 * @prop: array of properties to apply
274 * @size: number of contacts in array 278 * @size: number of contacts in array
275 * @syn: reference to the SYN_REPORT event 279 * @syn: reference to the SYN_REPORT event
276 */ 280 */
277static void apply_typeA_changes(struct mtdev_state *state, 281static void apply_typeA_changes(struct mtdev_state *state,
278 const struct mtdev_caps *caps, 282 const struct mtdev *dev,
279 struct mtdev_slot *data, const bitmask_t *prop, 283 struct mtdev_slot *data, const bitmask_t *prop,
280 int size, const struct input_event *syn) 284 int size, const struct input_event *syn)
281{ 285{
@@ -283,11 +287,11 @@ static void apply_typeA_changes(struct mtdev_state *state,
283 bitmask_t used = 0; 287 bitmask_t used = 0;
284 int i, slot, id; 288 int i, slot, id;
285 for (i = 0; i < size; i++) { 289 for (i = 0; i < size; i++) {
286 id = data[i].abs[MTDEV_TRACKING_ID]; 290 id = data[i].tracking_id;
287 foreach_bit(slot, state->used) { 291 foreach_bit(slot, state->used) {
288 if (state->data[slot].abs[MTDEV_TRACKING_ID] != id) 292 if (state->data[slot].tracking_id != id)
289 continue; 293 continue;
290 filter_data(state, caps, &data[i], prop[i], slot); 294 filter_data(state, dev, &data[i], prop[i], slot);
291 push_slot_changes(state, &data[i], prop[i], slot, syn); 295 push_slot_changes(state, &data[i], prop[i], slot, syn);
292 SETBIT(used, slot); 296 SETBIT(used, slot);
293 id = MT_ID_NULL; 297 id = MT_ID_NULL;
@@ -304,8 +308,8 @@ static void apply_typeA_changes(struct mtdev_state *state,
304 /* clear unused slots and update slot usage */ 308 /* clear unused slots and update slot usage */
305 foreach_bit(slot, state->used & ~used) { 309 foreach_bit(slot, state->used & ~used) {
306 struct mtdev_slot tdata = state->data[slot]; 310 struct mtdev_slot tdata = state->data[slot];
307 bitmask_t tprop = BITMASK(MTDEV_TRACKING_ID); 311 bitmask_t tprop = BITMASK(mtdev_abs2mt(ABS_MT_TRACKING_ID));
308 tdata.abs[MTDEV_TRACKING_ID] = MT_ID_NULL; 312 tdata.tracking_id = MT_ID_NULL;
309 push_slot_changes(state, &tdata, tprop, slot, syn); 313 push_slot_changes(state, &tdata, tprop, slot, syn);
310 } 314 }
311 state->used = used; 315 state->used = used;
@@ -314,11 +318,11 @@ static void apply_typeA_changes(struct mtdev_state *state,
314/* 318/*
315 * convert_A_to_B - propagate a type A packet as a type B packet 319 * convert_A_to_B - propagate a type A packet as a type B packet
316 * @state: mtdev state 320 * @state: mtdev state
317 * @caps: device capabilities 321 * @dev: device capabilities
318 * @syn: reference to the SYN_REPORT event 322 * @syn: reference to the SYN_REPORT event
319 */ 323 */
320static void convert_A_to_B(struct mtdev_state *state, 324static void convert_A_to_B(struct mtdev_state *state,
321 const struct mtdev_caps *caps, 325 const struct mtdev *dev,
322 const struct input_event *syn) 326 const struct input_event *syn)
323{ 327{
324 struct mtdev_slot data[DIM_FINGER]; 328 struct mtdev_slot data[DIM_FINGER];
@@ -326,14 +330,19 @@ static void convert_A_to_B(struct mtdev_state *state,
326 int size = process_typeA(state, data, prop); 330 int size = process_typeA(state, data, prop);
327 if (size < 0) 331 if (size < 0)
328 return; 332 return;
329 if (!caps->has_abs[MTDEV_TRACKING_ID]) { 333 if (!mtdev_has_mt_event(dev, ABS_MT_TRACKING_ID)) {
330 bitmask_t touch = 0; 334 bitmask_t touch = 0;
331 int i; 335 int i;
332 for (i = 0; i < size; i++) 336 for (i = 0; i < size; i++)
333 MODBIT(touch, i, istouch(&data[i], caps)); 337 MODBIT(touch, i, istouch(&data[i], dev));
334 assign_tracking_id(state, caps, data, prop, size, touch); 338 assign_tracking_id(state, dev, data, prop, size, touch);
335 } 339 }
336 apply_typeA_changes(state, caps, data, prop, size, syn); 340 apply_typeA_changes(state, dev, data, prop, size, syn);
341}
342
343struct mtdev *mtdev_new(void)
344{
345 return calloc(1, sizeof(struct mtdev));
337} 346}
338 347
339int mtdev_init(struct mtdev *dev) 348int mtdev_init(struct mtdev *dev)
@@ -344,7 +353,7 @@ int mtdev_init(struct mtdev *dev)
344 if (!dev->state) 353 if (!dev->state)
345 return -ENOMEM; 354 return -ENOMEM;
346 for (i = 0; i < DIM_FINGER; i++) 355 for (i = 0; i < DIM_FINGER; i++)
347 dev->state->data[i].abs[MTDEV_TRACKING_ID] = MT_ID_NULL; 356 dev->state->data[i].tracking_id = MT_ID_NULL;
348 return 0; 357 return 0;
349} 358}
350 359
@@ -364,15 +373,29 @@ int mtdev_open(struct mtdev *dev, int fd)
364 return ret; 373 return ret;
365} 374}
366 375
376struct mtdev *mtdev_new_open(int fd)
377{
378 struct mtdev *dev;
379
380 dev = mtdev_new();
381 if (!dev)
382 return NULL;
383 if (!mtdev_open(dev, fd))
384 return dev;
385
386 mtdev_delete(dev);
387 return NULL;
388}
389
367void mtdev_put_event(struct mtdev *dev, const struct input_event *ev) 390void mtdev_put_event(struct mtdev *dev, const struct input_event *ev)
368{ 391{
369 struct mtdev_state *state = dev->state; 392 struct mtdev_state *state = dev->state;
370 if (ev->type == EV_SYN && ev->code == SYN_REPORT) { 393 if (ev->type == EV_SYN && ev->code == SYN_REPORT) {
371 bitmask_t head = state->outbuf.head; 394 bitmask_t head = state->outbuf.head;
372 if (dev->caps.has_slot) 395 if (mtdev_has_mt_event(dev, ABS_MT_SLOT))
373 process_typeB(state); 396 process_typeB(state);
374 else 397 else
375 convert_A_to_B(state, &dev->caps, ev); 398 convert_A_to_B(state, dev, ev);
376 if (state->outbuf.head != head) 399 if (state->outbuf.head != head)
377 evbuf_put(&state->outbuf, ev); 400 evbuf_put(&state->outbuf, ev);
378 } else { 401 } else {
@@ -380,8 +403,19 @@ void mtdev_put_event(struct mtdev *dev, const struct input_event *ev)
380 } 403 }
381} 404}
382 405
406void mtdev_close_delete(struct mtdev *dev)
407{
408 mtdev_close(dev);
409 mtdev_delete(dev);
410}
411
383void mtdev_close(struct mtdev *dev) 412void mtdev_close(struct mtdev *dev)
384{ 413{
385 free(dev->state); 414 free(dev->state);
386 memset(dev, 0, sizeof(struct mtdev)); 415 memset(dev, 0, sizeof(struct mtdev));
387} 416}
417
418void mtdev_delete(struct mtdev *dev)
419{
420 free(dev);
421}