When you are coasting (but not corner coasting) you might want the
scrolling to slow down and stop on its own.  This also lets you
start coasting while using a two finger scroll (starting with two
fingers only works for vertical and I can't figure out why it
doesn't work for horizontal).  I couldn't figure out how to edit
the man pages so I didn't include anything there.  The diff is
against the  xf86-input-synaptics-1.2.2 tarball.

Signed-off-by: Patrick Curran <[email protected]>
---
 INSTALL                        |    1 +
 include/synaptics-properties.h |    3 +++
 src/properties.c               |    3 +++
 src/synaptics.c                |   28 +++++++++++++++++++++++-----
 src/synapticsstr.h             |    1 +
 tools/synclient.c              |    1 +
 6 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/INSTALL b/INSTALL
index 47d2913..2a0da9b 100644
--- a/INSTALL
+++ b/INSTALL
@@ -48,6 +48,7 @@ Section "InputDevice"
   Option       "MinSpeed"              "0.09"
   Option       "MaxSpeed"              "0.18"
   Option       "AccelFactor"           "0.0015"
+  Option       "CoastingFriction"              "45"
 EndSection
 
 Change the Identifier to the same name as in the ServerLayout section.
diff --git a/include/synaptics-properties.h b/include/synaptics-properties.h
index cf330d8..28c4905 100644
--- a/include/synaptics-properties.h
+++ b/include/synaptics-properties.h
@@ -133,6 +133,9 @@
 /* FLOAT */
 #define SYNAPTICS_PROP_COASTING_SPEED "Synaptics Coasting Speed"
 
+/* FLOAT */
+#define SYNAPTICS_PROP_COASTING_FRICTION "Synaptics Coasting Friction"
+
 /* 32 bit, 2 values, min, max */
 #define SYNAPTICS_PROP_PRESSURE_MOTION "Synaptics Pressure Motion"
 
diff --git a/src/properties.c b/src/properties.c
index 4366034..638a057 100644
--- a/src/properties.c
+++ b/src/properties.c
@@ -244,6 +244,9 @@ InitDeviceProperties(LocalDevicePtr local)
     fvalues[0] = para->coasting_speed;
     prop_coastspeed = InitFloatAtom(local->dev, SYNAPTICS_PROP_COASTING_SPEED, 
1, fvalues);
 
+    fvalues[0] = para->coasting_friction;
+    prop_coastspeed = InitFloatAtom(local->dev, 
SYNAPTICS_PROP_COASTING_FRICTION, 1, fvalues);
+
     values[0] = para->press_motion_min_z;
     values[1] = para->press_motion_max_z;
     prop_pressuremotion = InitAtom(local->dev, SYNAPTICS_PROP_PRESSURE_MOTION, 
32, 2, values);
diff --git a/src/synaptics.c b/src/synaptics.c
index 9997674..a43d3be 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -536,6 +536,7 @@ static void set_default_parameters(LocalDevicePtr local)
     pars->tap_and_drag_gesture = xf86SetBoolOption(opts, "TapAndDragGesture", 
TRUE);
     pars->resolution_horiz = xf86SetIntOption(opts, "HorizResolution", 
horizResolution);
     pars->resolution_vert = xf86SetIntOption(opts, "VertResolution", 
vertResolution);
+    pars->coasting_friction = xf86SetRealOption(opts, "CoastingFriction", 0);
 
     /* Warn about (and fix) incorrectly configured TopEdge/BottomEdge 
parameters */
     if (pars->top_edge > pars->bottom_edge) {
@@ -1753,7 +1754,7 @@ start_coasting(SynapticsPrivate *priv, struct 
SynapticsHwState *hw, edge_type ed
        if (vertical) {
            double dy = estimate_delta(HIST(0).y, HIST(1).y, HIST(2).y, 
HIST(3).y);
            int sdelta = para->scroll_dist_vert;
-           if ((edge & RIGHT_EDGE) && pkt_time > 0 && sdelta > 0) {
+        if (para->scroll_twofinger_vert || (edge & RIGHT_EDGE) && pkt_time > 0 
&& sdelta > 0) {
                double scrolls_per_sec = dy / pkt_time / sdelta;
                if (fabs(scrolls_per_sec) >= para->coasting_speed) {
                    priv->autoscroll_yspd = scrolls_per_sec;
@@ -1763,7 +1764,7 @@ start_coasting(SynapticsPrivate *priv, struct 
SynapticsHwState *hw, edge_type ed
        } else {
            double dx = estimate_delta(HIST(0).x, HIST(1).x, HIST(2).x, 
HIST(3).x);
            int sdelta = para->scroll_dist_horiz;
-           if ((edge & BOTTOM_EDGE) && pkt_time > 0 && sdelta > 0) {
+        if (para->scroll_twofinger_horiz || (edge & BOTTOM_EDGE) && pkt_time > 
0 && sdelta > 0) {
                double scrolls_per_sec = dx / pkt_time / sdelta;
                if (fabs(scrolls_per_sec) >= para->coasting_speed) {
                    priv->autoscroll_xspd = scrolls_per_sec;
@@ -1859,8 +1860,11 @@ HandleScrolling(SynapticsPrivate *priv, struct 
SynapticsHwState *hw,
        }
     }
     {
-       Bool oldv = priv->vert_scroll_edge_on || (priv->circ_scroll_on && 
priv->circ_scroll_vert);
-       Bool oldh = priv->horiz_scroll_edge_on || (priv->circ_scroll_on && 
!priv->circ_scroll_vert);
+    Bool oldv = priv->vert_scroll_twofinger_on || priv->vert_scroll_edge_on || 
+                    (priv->circ_scroll_on && priv->circ_scroll_vert);
+    Bool oldh = priv->horiz_scroll_twofinger_on || priv->horiz_scroll_edge_on 
|| 
+                    (priv->circ_scroll_on && !priv->circ_scroll_vert);
+
        if (priv->circ_scroll_on && !finger) {
            /* circular scroll locks in until finger is raised */
            DBG(7, ErrorF("cicular scroll off\n"));
@@ -1901,7 +1905,8 @@ HandleScrolling(SynapticsPrivate *priv, struct 
SynapticsHwState *hw,
         * and are no longer scrolling, then start coasting */
        if ((oldv || oldh) && !para->scroll_edge_corner &&
            !(priv->circ_scroll_on || priv->vert_scroll_edge_on ||
-             priv->horiz_scroll_edge_on)) {
+          priv->horiz_scroll_edge_on || priv->horiz_scroll_twofinger_on || 
+          priv->vert_scroll_twofinger_on)) {
            start_coasting(priv, hw, edge, oldv);
        }
     }
@@ -2008,6 +2013,7 @@ HandleScrolling(SynapticsPrivate *priv, struct 
SynapticsHwState *hw,
 
     if (priv->autoscroll_yspd) {
        double dtime = (hw->millis - HIST(0).millis) / 1000.0;
+    double ddy = para->coasting_friction * dtime;
        priv->autoscroll_y += priv->autoscroll_yspd * dtime;
        delay = MIN(delay, 20);
        while (priv->autoscroll_y > 1.0) {
@@ -2018,9 +2024,16 @@ HandleScrolling(SynapticsPrivate *priv, struct 
SynapticsHwState *hw,
            sd->up++;
            priv->autoscroll_y += 1.0;
        }
+    if (abs(priv->autoscroll_yspd)<ddy) {
+        stop_coasting(priv);
+    } else {
+        priv->autoscroll_yspd += (priv->autoscroll_yspd < 0 ? ddy : -1*ddy);
+    }
     }
+
     if (priv->autoscroll_xspd) {
        double dtime = (hw->millis - HIST(0).millis) / 1000.0;
+    double ddx = para->coasting_friction * dtime;
        priv->autoscroll_x += priv->autoscroll_xspd * dtime;
        delay = MIN(delay, 20);
        while (priv->autoscroll_x > 1.0) {
@@ -2031,6 +2044,11 @@ HandleScrolling(SynapticsPrivate *priv, struct 
SynapticsHwState *hw,
            sd->left++;
            priv->autoscroll_x += 1.0;
        }
+    if (abs(priv->autoscroll_xspd)<ddx) {
+        stop_coasting(priv);
+    } else {
+        priv->autoscroll_xspd += (priv->autoscroll_xspd < 0 ? ddx : -1*ddx);
+    }
     }
 
     return delay;
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index 2986173..2962522 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -149,6 +149,7 @@ typedef struct _SynapticsParameters
     unsigned int resolution_horiz;          /* horizontal resolution of 
touchpad in units/mm */
     unsigned int resolution_vert;           /* vertical resolution of touchpad 
in units/mm */
     int area_left_edge, area_right_edge, area_top_edge, area_bottom_edge; /* 
area coordinates absolute */
+    double coasting_friction;           /*add friction so coasting stops on 
its own*/
 } SynapticsParameters;
 
 
diff --git a/tools/synclient.c b/tools/synclient.c
index 032b129..ee15adf 100644
--- a/tools/synclient.c
+++ b/tools/synclient.c
@@ -133,6 +133,7 @@ static struct Parameter params[] = {
     {"PalmMinWidth",          PT_INT,    0, 15,    
SYNAPTICS_PROP_PALM_DIMENSIONS,     32,     0},
     {"PalmMinZ",              PT_INT,    0, 255,   
SYNAPTICS_PROP_PALM_DIMENSIONS,     32,     1},
     {"CoastingSpeed",         PT_DOUBLE, 0, 20,    
SYNAPTICS_PROP_COASTING_SPEED,      0 /* float*/,   0},
+    {"CoastingFriction",      PT_DOUBLE, 0, 200,   
SYNAPTICS_PROP_COASTING_FRICTION,   0 /* float*/,   0},
     {"PressureMotionMinZ",    PT_INT,    1, 255,   
SYNAPTICS_PROP_PRESSURE_MOTION,     32,     0},
     {"PressureMotionMaxZ",    PT_INT,    1, 255,   
SYNAPTICS_PROP_PRESSURE_MOTION,     32,     1},
     {"PressureMotionMinFactor", PT_DOUBLE, 0, 
10.0,SYNAPTICS_PROP_PRESSURE_MOTION_FACTOR,      0 /*float*/,    0},
-- 
1.7.1.1

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to