[PATCH xf86-input-synaptics 04/12] Handle clickpad press

Chase Douglas chase.douglas at canonical.com
Thu Feb 9 18:52:58 PST 2012


For click action, touch counts are shifted by one. When pressing the
left button with one touch, click action one is fired as normal.
However, when clicking with two touches, click action one is still
fired. This is because the user often uses one touch to position and
another to click, without lifting the positioning touch.

When clicking with three touches, click action two is fired, and four
touches fires click action three.

Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
---
 src/synaptics.c    |  103 ++++++++++++++++++++++++++++++++++++----------------
 src/synapticsstr.h |    4 ++-
 2 files changed, 75 insertions(+), 32 deletions(-)

diff --git a/src/synaptics.c b/src/synaptics.c
index 071eaed..a9b5b2d 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -1552,6 +1552,36 @@ SynapticsDetectFinger(SynapticsPrivate *priv, struct SynapticsHwState *hw)
 }
 
 static void
+handle_clickfinger(SynapticsParameters *para, struct SynapticsHwState *hw)
+{
+    int action = 0;
+    switch(hw->numFingers){
+        case 1:
+            action = para->click_action[F1_CLICK1];
+            break;
+        case 2:
+            action = para->click_action[F2_CLICK1];
+            break;
+        case 3:
+            action = para->click_action[F3_CLICK1];
+            break;
+    }
+    switch(action){
+        case 1:
+            hw->left = 1;
+            break;
+        case 2:
+            hw->left = 0;
+            hw->middle = 1;
+            break;
+        case 3:
+            hw->left = 0;
+            hw->right = 1;
+            break;
+    }
+}
+
+static void
 SelectTapButton(SynapticsPrivate *priv, edge_type edge)
 {
     TapEvent tap;
@@ -1673,6 +1703,8 @@ GetTimeOut(SynapticsPrivate *priv)
 	return para->tap_time_2;
     case TS_4:
 	return para->locked_drag_time;
+    case TS_CLICKPAD_PRESS:
+	return para->clickpad_timeout;
     default:
 	return -1;			    /* No timeout */
     }
@@ -1720,6 +1752,15 @@ HandleTapProcessing(SynapticsPrivate *priv, struct SynapticsHwState *hw,
 	    SetTapState(priv, TS_1, now);
 	break;
     case TS_1:
+	if (para->clickpad) {
+	    if (hw->right || hw->middle) {
+		SetTapState(priv, TS_CLICKPAD_MOVE, now);
+	    } else if (hw->left) {
+		is_timeout = FALSE;
+		SetTapState(priv, TS_CLICKPAD_PRESS, now);
+	        goto restart;
+	    }
+	}
 	if (move) {
 	    SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
 	    SetTapState(priv, TS_MOVE, now);
@@ -1743,6 +1784,11 @@ HandleTapProcessing(SynapticsPrivate *priv, struct SynapticsHwState *hw,
 	}
 	break;
     case TS_MOVE:
+	if (para->clickpad && hw->left) {
+	    is_timeout = FALSE;
+	    SetTapState(priv, TS_CLICKPAD_PRESS, now);
+	    goto restart;
+	}
 	if (move && priv->moving_state == MS_TRACKSTICK) {
 	    SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
 	}
@@ -1825,6 +1871,30 @@ HandleTapProcessing(SynapticsPrivate *priv, struct SynapticsHwState *hw,
 	    SetTapState(priv, TS_START, now);
 	}
 	break;
+    case TS_CLICKPAD_PRESS:
+	if (hw->numFingers > 1)
+	    hw->numFingers--;
+	if (hw->right || hw->middle) {
+	    SetTapState(priv, TS_CLICKPAD_MOVE, now);
+	    goto restart;
+	}
+	if (!hw->left) {
+	    handle_clickfinger(para, hw);
+	    priv->tap_button_state = TBS_BUTTON_DOWN_UP;
+	    SetTapState(priv, TS_1, now);
+	} else if (move || is_timeout) {
+	    SetTapState(priv, TS_CLICKPAD_MOVE, now);
+	    goto restart;
+	} else
+	    hw->left = 0;
+	break;
+    case TS_CLICKPAD_MOVE:
+	SetMovingState(priv, MS_TOUCHPAD_RELATIVE, now);
+	if (!hw->left && !hw->right && !hw->middle) {
+	    SetMovingState(priv, MS_FALSE, now);
+	    SetTapState(priv, TS_MOVE, now);
+	}
+	break;
     }
 
     timeout = GetTimeOut(priv);
@@ -1995,6 +2065,7 @@ ComputeDeltas(SynapticsPrivate *priv, const struct SynapticsHwState *hw,
 	case TS_1:
 	case TS_3:
 	case TS_5:
+	case TS_CLICKPAD_PRESS:
 	    moving_state = MS_TOUCHPAD_RELATIVE;
 	    break;
 	default:
@@ -2349,36 +2420,6 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
     return delay;
 }
 
-static void
-handle_clickfinger(SynapticsParameters *para, struct SynapticsHwState *hw)
-{
-    int action = 0;
-    switch(hw->numFingers){
-        case 1:
-            action = para->click_action[F1_CLICK1];
-            break;
-        case 2:
-            action = para->click_action[F2_CLICK1];
-            break;
-        case 3:
-            action = para->click_action[F3_CLICK1];
-            break;
-    }
-    switch(action){
-        case 1:
-            hw->left = 1;
-            break;
-        case 2:
-            hw->left = 0;
-            hw->middle = 1;
-            break;
-        case 3:
-            hw->left = 0;
-            hw->right = 1;
-            break;
-    }
-}
-
 
 /* Update the hardware state in shared memory. This is read-only these days,
  * nothing in the driver reads back from SHM. SHM configuration is a thing of the past.
@@ -2461,7 +2502,7 @@ update_hw_button_state(const InputInfoPtr pInfo, struct SynapticsHwState *hw,
     hw->middle |= HandleMidButtonEmulation(priv, hw, now, delay);
 
     /* Fingers emulate other buttons */
-    if(hw->left && hw->numFingers >= 1){
+    if(!para->clickpad && hw->left && hw->numFingers >= 1){
         handle_clickfinger(para, hw);
     }
 
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index 140bcf0..1ea09a0 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -99,7 +99,9 @@ enum TapState {
     TS_3,			/* After second touch */
     TS_DRAG,			/* Pointer drag enabled */
     TS_4,			/* After release when "locked drags" enabled */
-    TS_5			/* After touch when "locked drags" enabled */
+    TS_5,			/* After touch when "locked drags" enabled */
+    TS_CLICKPAD_PRESS,		/* After left button press, when clickpad */
+    TS_CLICKPAD_MOVE,		/* After left button press and move, when clickpad */
 };
 
 enum TapButtonState {
-- 
1.7.8.3



More information about the xorg-devel mailing list