@@ -5,7 +5,7 @@
# Each configuration option enables a list of files.
obj-$(CONFIG_INPUT) += input-core.o
-input-core-objs := input.o input-compat.o ff-core.o
+input-core-objs := input.o input-compat.o ff-core.o input-trk.o
obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o
obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o
new file mode 100644
@@ -0,0 +1,193 @@
+/*
+ * Input Multitouch Tracking Library
+ *
+ * Copyright (c) 2010 Henrik Rydberg
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/input-trk.h>
+
+/* generated by mtdev-kernel - do not edit */
+static const u8 match_data[] = {
+ 0, 0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 0, 0, 0, 1, 1,
+ 1, 0, 0, 0, 1, 2, 1, 1, 0, 2, 2, 1, 2, 0, 0, 0,
+ 1, 2, 3, 1, 1, 0, 2, 3, 2, 1, 2, 0, 3, 3, 1, 2,
+ 3, 0, 0, 0, 1, 1, 1, 2, 1, 0, 0, 3, 0, 1, 1, 3,
+ 1, 0, 2, 2, 3, 1, 2, 0, 0, 4, 0, 1, 2, 2, 4, 2,
+ 1, 0, 0, 5, 0, 2, 1, 1, 5, 2, 0, 1, 1, 4, 1, 0,
+ 2, 3, 2, 4, 1, 2, 0, 3, 3, 4, 1, 2, 3, 0, 0, 5,
+ 0, 1, 2, 3, 2, 5, 2, 1, 0, 3, 3, 5, 2, 1, 3, 0,
+ 0, 6, 0, 2, 1, 3, 1, 6, 2, 0, 1, 3, 3, 6, 2, 3,
+ 1, 0, 0, 7, 0, 2, 3, 1, 1, 7, 2, 0, 3, 1, 2, 7,
+ 2, 3, 0, 1, 0, 0, 1, 1, 2, 2, 1, 2, 1, 0, 0, 3,
+ 0, 1, 1, 4, 2, 0, 3, 4, 2, 1, 0, 5, 0, 2, 2, 5,
+ 1, 2, 2, 4, 6, 2, 1, 0, 1, 5, 6, 2, 0, 1, 2, 3,
+ 7, 1, 2, 0, 0, 5, 7, 0, 2, 1, 1, 3, 8, 1, 0, 2,
+ 0, 4, 8, 0, 1, 2, 2, 5, 8, 2, 1, 0, 3, 3, 5, 8,
+ 2, 1, 3, 0, 1, 6, 8, 2, 0, 1, 3, 3, 6, 8, 2, 3,
+ 1, 0, 1, 7, 8, 2, 0, 3, 1, 2, 7, 8, 2, 3, 0, 1,
+ 2, 4, 9, 1, 2, 0, 3, 3, 4, 9, 1, 2, 3, 0, 0, 6,
+ 9, 0, 2, 1, 3, 3, 6, 9, 3, 2, 1, 0, 0, 7, 9, 0,
+ 2, 3, 1, 2, 7, 9, 3, 2, 0, 1, 1, 4, 10, 1, 0, 2,
+ 3, 3, 4, 10, 1, 3, 2, 0, 0, 5, 10, 0, 1, 2, 3, 3,
+ 5, 10, 3, 1, 2, 0, 0, 7, 10, 0, 3, 2, 1, 1, 7, 10,
+ 3, 0, 2, 1, 1, 4, 11, 1, 0, 3, 2, 2, 4, 11, 1, 3,
+ 0, 2, 0, 5, 11, 0, 1, 3, 2, 2, 5, 11, 3, 1, 0, 2,
+ 0, 6, 11, 0, 3, 1, 2, 1, 6, 11, 3, 0, 1, 2, 0, 0,
+ 1, 1, 2, 2, 3, 3, 1, 2, 1, 0, 0, 3, 0, 1, 1, 4,
+ 2, 0, 3, 4, 2, 1, 0, 5, 0, 2, 2, 5, 1, 2, 1, 6,
+ 3, 0, 3, 6, 3, 1, 5, 6, 3, 2, 0, 7, 0, 3, 2, 7,
+ 1, 3, 4, 7, 2, 3, 2, 4, 6, 2, 1, 0, 1, 5, 6, 2,
+ 0, 1, 2, 3, 7, 1, 2, 0, 0, 5, 7, 0, 2, 1, 1, 3,
+ 8, 1, 0, 2, 0, 4, 8, 0, 1, 2, 2, 4, 9, 3, 1, 0,
+ 1, 5, 9, 3, 0, 1, 2, 7, 9, 3, 2, 0, 5, 7, 9, 3,
+ 2, 1, 1, 8, 9, 3, 0, 2, 4, 8, 9, 3, 1, 2, 2, 3,
+ 10, 1, 3, 0, 0, 5, 10, 0, 3, 1, 2, 6, 10, 2, 3, 0,
+ 5, 6, 10, 2, 3, 1, 0, 8, 10, 0, 3, 2, 3, 8, 10, 1,
+ 3, 2, 1, 3, 11, 1, 0, 3, 0, 4, 11, 0, 1, 3, 1, 6,
+ 11, 2, 0, 3, 4, 6, 11, 2, 1, 3, 0, 7, 11, 0, 2, 3,
+ 3, 7, 11, 1, 2, 3, 3, 6, 9, 12, 3, 2, 1, 0, 2, 7,
+ 9, 12, 3, 2, 0, 1, 3, 5, 10, 12, 3, 1, 2, 0, 1, 7,
+ 10, 12, 3, 0, 2, 1, 2, 5, 11, 12, 3, 1, 0, 2, 1, 6,
+ 11, 12, 3, 0, 1, 2, 3, 6, 8, 13, 2, 3, 1, 0, 2, 7,
+ 8, 13, 2, 3, 0, 1, 3, 4, 10, 13, 1, 3, 2, 0, 0, 7,
+ 10, 13, 0, 3, 2, 1, 2, 4, 11, 13, 1, 3, 0, 2, 0, 6,
+ 11, 13, 0, 3, 1, 2, 3, 5, 8, 14, 2, 1, 3, 0, 1, 7,
+ 8, 14, 2, 0, 3, 1, 3, 4, 9, 14, 1, 2, 3, 0, 0, 7,
+ 9, 14, 0, 2, 3, 1, 1, 4, 11, 14, 1, 0, 3, 2, 0, 5,
+ 11, 14, 0, 1, 3, 2, 2, 5, 8, 15, 2, 1, 0, 3, 1, 6,
+ 8, 15, 2, 0, 1, 3, 2, 4, 9, 15, 1, 2, 0, 3, 0, 6,
+ 9, 15, 0, 2, 1, 3, 1, 4, 10, 15, 1, 0, 2, 3, 0, 5,
+ 10, 15, 0, 1, 2, 3,
+};
+
+/* generated by mtdev-kernel - do not edit */
+static const int match_index[][5] = {
+ { 0, 0, 1, 3, 6 },
+ { 10, 10, 12, 18, 30 },
+ { 50, 50, 54, 62, 92 },
+ { 164, 164, 170, 194, 230 },
+ { 398, 398, 406, 454, 598 },
+ { 790 }
+};
+
+static void set_dist(u32 *dist,
+ const struct trk_coord *b1, const struct trk_coord *e1,
+ const struct trk_coord *b2, const struct trk_coord *e2)
+{
+ const struct trk_coord *p, *q;
+
+ for (p = b1; p != e1; p++)
+ for (q = b2; q != e2; q++)
+ *dist++ = abs(q->x - p->x) + abs(q->y - p->y);
+}
+
+const u8 *match_four(const struct trk_coord *old, int nslot,
+ const struct trk_coord *pos, int npos)
+{
+ u32 d[16], obj, t;
+ const u8 *p, *b, *e;
+ const int *at;
+
+ set_dist(d, old, old + nslot, pos, pos + npos);
+
+ at = &match_index[nslot][npos];
+ b = &match_data[at[0]];
+ e = &match_data[at[1]];
+
+ obj = UINT_MAX, p = b;
+
+ switch (min(nslot, npos)) {
+ case 1:
+ for (; b != e; b += npos) {
+ t = d[*b++];
+ if (t < obj)
+ obj = t, p = b;
+ }
+ break;
+ case 2:
+ for (; b != e; b += npos) {
+ t = d[*b++], t += d[*b++];
+ if (t < obj)
+ obj = t, p = b;
+ }
+ break;
+ case 3:
+ for (; b != e; b += npos) {
+ t = d[*b++], t += d[*b++], t += d[*b++];
+ if (t < obj)
+ obj = t, p = b;
+ }
+ break;
+ case 4:
+ for (; b != e; b += npos) {
+ t = d[*b++], t += d[*b++], t += d[*b++], t += d[*b++];
+ if (t < obj)
+ obj = t, p = b;
+ }
+ break;
+ }
+
+ return p;
+}
+
+static int get_mt_value(const struct input_mt_slot *slot, unsigned code)
+{
+ return slot->abs[code - ABS_MT_FIRST];
+}
+
+/**
+ * input_trk_assign_slots_by_coord() - perform a best-match assignment
+ * @dev: input device with allocated MT slots
+ * @slots: the slot assignment to be filled
+ * @coords: the coordinate array to match
+ * @num_coords: number of coordinates
+ *
+ * Performs a best match against the current contacts and returns
+ * the slot assignment list. New contacts are assigned to unused
+ * slots.
+ *
+ * Returns zero on success, or negative error in case of failure.
+ */
+int input_trk_assign_slots_by_coord(struct input_dev *dev, int *slots,
+ const struct trk_coord *coords,
+ int num_coords)
+{
+ struct trk_coord old[4];
+ int old2slot[4], nold, i;
+ const u8 *p;
+
+ if (!dev->mt)
+ return -ENXIO;
+ if (dev->mtsize < 2 || dev->mtsize > 4)
+ return -ENXIO;
+ if (num_coords > dev->mtsize)
+ return -EINVAL;
+ if (num_coords < 1)
+ return 0;
+
+ nold = 0;
+ for (i = 0; i < dev->mtsize; i++) {
+ const struct input_mt_slot *mt = &dev->mt[i];
+ if (get_mt_value(mt, ABS_MT_TRACKING_ID) < 0)
+ continue;
+ old[nold].x = get_mt_value(mt, ABS_MT_POSITION_X);
+ old[nold].y = get_mt_value(mt, ABS_MT_POSITION_Y);
+ old2slot[nold++] = i;
+ }
+
+ p = match_four(old, nold, coords, num_coords);
+
+ for (i = 0; i < dev->mtsize; i++)
+ if (get_mt_value(&dev->mt[i], ABS_MT_TRACKING_ID) < 0)
+ old2slot[nold++] = i;
+
+ for (i = 0; i < num_coords; i++)
+ slots[i] = old2slot[p[i]];
+
+ return 0;
+}
+EXPORT_SYMBOL(input_trk_assign_slots_by_coord);
new file mode 100644
@@ -0,0 +1,30 @@
+#ifndef _INPUT_TRK_H
+#define _INPUT_TRK_H
+
+/*
+ * Input Multitouch Tracking Library
+ *
+ * Copyright (c) 2010 Henrik Rydberg
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/input.h>
+
+/**
+ * struct trk_coord - contact coordinate
+ * @x: horizontal coordinate
+ * @y: vertical coordinate
+ */
+struct trk_coord {
+ int x;
+ int y;
+};
+
+int input_trk_assign_slots_by_coord(struct input_dev *dev, int *slots,
+ const struct trk_coord *coords,
+ int num_coords);
+
+#endif