aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-04-11 01:25:50 +0200
committerHenrik Rydberg <rydberg@euromail.se>2010-04-15 06:10:07 +0200
commit40b3cd568e8cc64a5f7f748f2003d90aa5e738ef (patch)
tree69a4df96bd1e6b90b74a09335a69c985ee7ae0ce
parent030f4fdbe44d1af41c55cdda5baf71ba3225829f (diff)
downloadxorg-input-kobomultitouch-40b3cd568e8cc64a5f7f748f2003d90aa5e738ef.tar.gz
xorg-input-kobomultitouch-40b3cd568e8cc64a5f7f748f2003d90aa5e738ef.tar.bz2
xorg-input-kobomultitouch-40b3cd568e8cc64a5f7f748f2003d90aa5e738ef.zip
Add robust position event filtering
The kernel filtering is bypassed for MT events. This patch reintroduces filtering at the earliest possible point, right after the fingers have been identified. For drivers that do not set proper fuzz parameters, sensible values are derived based on a generic signal-to-noise ratio. The defuzz code is borrowed from the Linux kernel, thanks GPL. Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
-rw-r--r--src/capabilities.c9
-rw-r--r--src/capabilities.h1
-rw-r--r--src/hwstate.c21
3 files changed, 31 insertions, 0 deletions
diff --git a/src/capabilities.c b/src/capabilities.c
index 7316f01..620ab60 100644
--- a/src/capabilities.c
+++ b/src/capabilities.c
@@ -26,6 +26,8 @@
#define ADDCAP(s, c, x) strcat(s, c->has_##x ? " " #x : "")
+static const int SN_COORD = 250; /* coordinate signal-to-noise ratio */
+
static const int bits_per_long = 8 * sizeof(long);
static inline int nlongs(int nbit)
@@ -78,6 +80,13 @@ int read_capabilities(struct Capabilities *cap, int fd)
cap->has_mtdata = cap->has_position_x && cap->has_position_y;
+ cap->xfuzz = cap->abs_position_x.fuzz;
+ cap->yfuzz = cap->abs_position_y.fuzz;
+ if (cap->xfuzz <= 0 || cap->yfuzz <= 0) {
+ cap->xfuzz = get_cap_xsize(cap) / SN_COORD;
+ cap->yfuzz = get_cap_ysize(cap) / SN_COORD;
+ }
+
return 0;
}
diff --git a/src/capabilities.h b/src/capabilities.h
index dc257ce..591eed6 100644
--- a/src/capabilities.h
+++ b/src/capabilities.h
@@ -38,6 +38,7 @@ struct Capabilities {
struct input_absinfo abs_orientation;
struct input_absinfo abs_position_x;
struct input_absinfo abs_position_y;
+ int xfuzz, yfuzz;
};
int read_capabilities(struct Capabilities *cap, int fd);
diff --git a/src/hwstate.c b/src/hwstate.c
index 40cef5b..4af636c 100644
--- a/src/hwstate.c
+++ b/src/hwstate.c
@@ -44,16 +44,37 @@ inline int dist2(const struct FingerData *a, const struct FingerData *b)
return dx * dx + dy * dy;
}
+/* Dmitry Torokhov's code from kernel/driver/input/input.c */
+static int defuzz(int value, int old_val, int fuzz)
+{
+ if (fuzz) {
+ if (value > old_val - fuzz / 2 && value < old_val + fuzz / 2)
+ return old_val;
+
+ if (value > old_val - fuzz && value < old_val + fuzz)
+ return (old_val * 3 + value) / 4;
+
+ if (value > old_val - fuzz * 2 && value < old_val + fuzz * 2)
+ return (old_val + value) / 2;
+ }
+
+ return value;
+}
+
static void set_finger(struct FingerState *fs,
const struct FingerData *hw, int id,
const struct Capabilities *caps)
{
+ int x = defuzz(hw->position_x, fs->hw.position_x, caps->xfuzz);
+ int y = defuzz(hw->position_y, fs->hw.position_y, caps->yfuzz);
fs->hw = *hw;
fs->id = id;
if (!caps->has_touch_minor)
fs->hw.touch_minor = hw->touch_major;
if (!caps->has_width_minor)
fs->hw.width_minor = hw->width_major;
+ fs->hw.position_x = x;
+ fs->hw.position_y = y;
}
void modify_hwstate(struct HWState *s,