[PATCH synaptics v5 11/18] Guess the number of clickpad ClickFingers based on finger distance

Peter Hutterer peter.hutterer at who-t.net
Mon Mar 12 23:37:38 PDT 2012


The actual distance should be done in cm, based on touchpad resolution etc.
That is left as an exercise for the reader.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/synaptics.c |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/src/synaptics.c b/src/synaptics.c
index c2e3943..7ee0238 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -2386,11 +2386,73 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
     return delay;
 }
 
+/**
+ * Check if any 2+ fingers are close enough together to assume this is a
+ * ClickFinger action.
+ */
+static int
+clickpad_guess_clickfingers(SynapticsPrivate *priv, struct SynapticsHwState *hw)
+{
+    int nfingers = 0;
+#if HAVE_MULTITOUCH
+    int i, j;
+    for (i = 0; i < hw->num_mt_mask - 1; i++) {
+        ValuatorMask *f1;
+
+        /* you can't click on open, you're not fast enough */
+        if (hw->slot_state[i] != SLOTSTATE_UPDATE)
+            continue;
+
+        f1 = hw->mt_mask[i];
+
+        for (j = i + 1; j < hw->num_mt_mask; j++) {
+            ValuatorMask *f2;
+            double x1, x2, y1, y2;
+
+            if (hw->slot_state[j] != SLOTSTATE_UPDATE)
+                continue;
+
+            f2 = hw->mt_mask[j];
+
+            x1 = valuator_mask_get_double(f1, 0);
+            y1 = valuator_mask_get_double(f1, 1);
+
+            x2 = valuator_mask_get_double(f2, 0);
+            y2 = valuator_mask_get_double(f2, 1);
+
+            /* FIXME: fingers closer together than 30% of touchpad width, but
+             * really, this should be dependent on the touchpad size. Also,
+             * you'll need to find a touchpad that doesn't lie about it's
+             * size. Good luck. */
+            if (abs(x1 - x2) < (priv->maxx - priv->minx) * .3 &&
+                abs(y1 - y2) < (priv->maxy - priv->miny) * .3)
+                nfingers++;
+        }
+    }
+#endif
+
+    /* 1 doesn't make sense */
+    return nfingers ? nfingers + 1 : 0;
+}
+
+
 static void
-handle_clickfinger(SynapticsParameters *para, struct SynapticsHwState *hw)
+handle_clickfinger(SynapticsPrivate *priv, struct SynapticsHwState *hw)
 {
+    SynapticsParameters *para = &priv->synpara;
     int action = 0;
-    switch(hw->numFingers){
+    int nfingers = hw->numFingers;
+
+    /* if this is a clickpad, clickfinger handling is:
+     * one finger down: no action, this is a normal click
+     * two fingers down: F2_CLICK
+     * three fingers down: F3_CLICK
+     */
+
+    if (para->clickpad)
+        nfingers = clickpad_guess_clickfingers(priv, hw);
+
+    switch(nfingers) {
         case 1:
             action = para->click_action[F1_CLICK1];
             break;
@@ -2501,7 +2563,7 @@ update_hw_button_state(const InputInfoPtr pInfo, struct SynapticsHwState *hw,
        triggered on transition, when left is pressed
      */
     if(hw->left && !old->left && hw->numFingers >= 1) {
-        handle_clickfinger(para, hw);
+        handle_clickfinger(priv, hw);
     }
 
     /* Two finger emulation */
-- 
1.7.7.6



More information about the xorg-devel mailing list