diff options
author | Henrik Rydberg <rydberg@euromail.se> | 2010-04-11 01:25:50 +0200 |
---|---|---|
committer | Henrik Rydberg <rydberg@euromail.se> | 2010-04-15 06:10:07 +0200 |
commit | 40b3cd568e8cc64a5f7f748f2003d90aa5e738ef (patch) | |
tree | 69a4df96bd1e6b90b74a09335a69c985ee7ae0ce /src/hwstate.c | |
parent | 030f4fdbe44d1af41c55cdda5baf71ba3225829f (diff) | |
download | xorg-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>
Diffstat (limited to 'src/hwstate.c')
-rw-r--r-- | src/hwstate.c | 21 |
1 files changed, 21 insertions, 0 deletions
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, |