[PATCH synaptics] support inverted scroll direction

Alyssa Hung ahung at isisview.org
Wed Apr 11 19:00:56 PDT 2012


This patch adds two options to the synaptics driver: InvertEdgeScroll
and InvertTwoFingerScroll.

When enabled, they will cause the scroll direction to be inverted when
edge scrolling and two-finger scrolling, respectively. For instance,
moving a finger downward along the right edge will pull the scrolled
content down (causing the page to scroll up). This behaviour is
consistent with scrolling on modern touchscreen devices.

Options are provided separately for edge scrolling and two-finger
scrolling because they follow different metaphors; edge scrolling has
traditionally been analogous to dragging the scrollbar tab, and may
therefore be sensible to leave uninverted even when two-finger scroll
direction is inverted.

Signed-off-by: Alyssa Hung <ahung at isisview.org>
---
 include/synaptics-properties.h |    3 +++
 man/synaptics.man              |   10 ++++++++++
 src/properties.c               |   14 ++++++++++++++
 src/synaptics.c                |   18 ++++++++++++++++--
 src/synapticsstr.h             |    2 ++
 tools/synclient.c              |    2 ++
 6 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/include/synaptics-properties.h b/include/synaptics-properties.h
index 8c20a0c..558fc38 100644
--- a/include/synaptics-properties.h
+++ b/include/synaptics-properties.h
@@ -72,6 +72,9 @@
 /* 8 bit (BOOL), 2 values, vertical, horizontal */
 #define SYNAPTICS_PROP_SCROLL_TWOFINGER "Synaptics Two-Finger Scrolling"

+/* 8 bit (BOOL), 2 values, edge, two-finger */
+#define SYNAPTICS_PROP_SCROLL_INVERT "Synaptics Inverted Scrolling"
+
 /* FLOAT, 4 values, min, max, accel, trackstick */
 #define SYNAPTICS_PROP_SPEED "Synaptics Move Speed"

diff --git a/man/synaptics.man b/man/synaptics.man
index 864a95f..1947bf9 100644
--- a/man/synaptics.man
+++ b/man/synaptics.man
@@ -161,6 +161,11 @@ Enable vertical scrolling when dragging along the
right edge. Property:
 Enable horizontal scrolling when dragging along the bottom edge. Property:
 "Synaptics Edge Scrolling"
 .TP 7
+.BI "Option \*qInvertEdgeScroll\*q \*q" boolean \*q
+Invert scroll direction when scrolling by dragging along the right or bottom
+edge. When enabled, the content being scrolled will follow the direction of
+finger movement. Property: "Synaptics Inverted Scrolling"
+.TP 7
 .BI "Option \*qCornerCoasting\*q \*q" boolean \*q
 Enable edge scrolling to continue while the finger stays in an edge corner.
 Property: "Synaptics Edge Scrolling"
@@ -173,6 +178,11 @@ the touchpad. Property: "Synaptics Two-Finger Scrolling"
 Enable horizontal scrolling when dragging with two fingers anywhere on
 the touchpad. Property: "Synaptics Two-Finger Scrolling"
 .TP 7
+.BI "Option \*qInvertTwoFingerScroll\*q \*q" boolean \*q
+Invert scroll direction when scrolling by dragging two fingers. When enabled,
+the content being scrolled will follow the direction of finger movement.
+Property: "Synaptics Inverted Scrolling"
+.TP 7
 .BI "Option \*qVertScrollDelta\*q \*q" integer \*q
 Move distance of the finger for a scroll event. Property: "Synaptics Scrolling
 Distance"
diff --git a/src/properties.c b/src/properties.c
index 783b516..3fc1d2c 100644
--- a/src/properties.c
+++ b/src/properties.c
@@ -66,6 +66,7 @@ Atom prop_twofinger_width       = 0;
 Atom prop_scrolldist            = 0;
 Atom prop_scrolledge            = 0;
 Atom prop_scrolltwofinger       = 0;
+Atom prop_scrollinvert          = 0;
 Atom prop_speed                 = 0;
 Atom prop_edgemotion_pressure   = 0;
 Atom prop_edgemotion_speed      = 0;
@@ -230,6 +231,9 @@ InitDeviceProperties(InputInfoPtr pInfo)
     values[0] = para->scroll_twofinger_vert;
     values[1] = para->scroll_twofinger_horiz;
     prop_scrolltwofinger = InitAtom(pInfo->dev,
SYNAPTICS_PROP_SCROLL_TWOFINGER,8, 2, values);
+    values[0] = para->scroll_edge_invert;
+    values[1] = para->scroll_twofinger_invert;
+    prop_scrollinvert = InitAtom(pInfo->dev,
SYNAPTICS_PROP_SCROLL_INVERT, 8, 2, values);

     fvalues[0] = para->min_speed;
     fvalues[1] = para->max_speed;
@@ -501,6 +505,16 @@ SetProperty(DeviceIntPtr dev, Atom property,
XIPropertyValuePtr prop,
         twofinger = (BOOL*)prop->data;
         para->scroll_twofinger_vert  = twofinger[0];
         para->scroll_twofinger_horiz = twofinger[1];
+    } else if (property == prop_scrollinvert)
+    {
+	CARD8 *invert;
+
+	if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER)
+		return BadMatch;
+
+	invert = (BOOL*)prop->data;
+	para->scroll_edge_invert      = invert[0];
+	para->scroll_twofinger_invert = invert[1];
     } else if (property == prop_speed)
     {
         float *speed;
diff --git a/src/synaptics.c b/src/synaptics.c
index f07fd13..d0dacb1 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -716,6 +716,8 @@ static void set_default_parameters(InputInfoPtr pInfo)
     pars->scroll_edge_corner = xf86SetBoolOption(opts,
"CornerCoasting", FALSE);
     pars->scroll_twofinger_vert = xf86SetBoolOption(opts,
"VertTwoFingerScroll", vertTwoFingerScroll);
     pars->scroll_twofinger_horiz = xf86SetBoolOption(opts,
"HorizTwoFingerScroll", horizTwoFingerScroll);
+    pars->scroll_edge_invert = xf86SetBoolOption(opts,
"InvertEdgeScroll", FALSE);
+    pars->scroll_twofinger_invert = xf86SetBoolOption(opts,
"InvertTwoFingerScroll", FALSE);
     pars->edge_motion_min_z = xf86SetIntOption(opts,
"EdgeMotionMinZ", edgeMotionMinZ);
     pars->edge_motion_max_z = xf86SetIntOption(opts,
"EdgeMotionMaxZ", edgeMotionMaxZ);
     pars->edge_motion_min_speed = xf86SetIntOption(opts,
"EdgeMotionMinSpeed", edgeMotionMinSpeed);
@@ -2560,14 +2562,26 @@ HandleScrolling(SynapticsPrivate *priv, struct
SynapticsHwState *hw,
     if (priv->vert_scroll_edge_on || priv->vert_scroll_twofinger_on) {
 	/* + = down, - = up */
 	if (para->scroll_dist_vert > 0 && hw->y != priv->scroll.last_y) {
-	    priv->scroll.delta_y += (hw->y - priv->scroll.last_y);
+	    if ((priv->vert_scroll_edge_on && para->scroll_edge_invert) ||
+		(priv->vert_scroll_twofinger_on && para->scroll_twofinger_invert)) {
+		priv->scroll.delta_y -= (hw->y - priv->scroll.last_y);
+	    }
+	    else {
+		priv->scroll.delta_y += (hw->y - priv->scroll.last_y);
+	    }
 	    priv->scroll.last_y = hw->y;
 	}
     }
     if (priv->horiz_scroll_edge_on || priv->horiz_scroll_twofinger_on) {
 	/* + = right, - = left */
 	if (para->scroll_dist_horiz > 0 && hw->x != priv->scroll.last_x) {
-	    priv->scroll.delta_x += (hw->x - priv->scroll.last_x);
+	    if ((priv->horiz_scroll_edge_on && para->scroll_edge_invert) ||
+		(priv->horiz_scroll_twofinger_on && para->scroll_twofinger_invert)) {
+		priv->scroll.delta_x -= (hw->x - priv->scroll.last_x);
+	    }
+	    else {
+		priv->scroll.delta_x += (hw->x - priv->scroll.last_x);
+	    }
 	    priv->scroll.last_x = hw->x;
 	}
     }
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index 55aab3d..500cb1f 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -140,6 +140,8 @@ typedef struct _SynapticsParameters
     Bool scroll_edge_corner;		    /* Enable/disable continuous edge
scrolling when in the corner */
     Bool scroll_twofinger_vert;		    /* Enable/disable vertical
two-finger scrolling */
     Bool scroll_twofinger_horiz;	    /* Enable/disable horizontal
two-finger scrolling */
+    Bool scroll_edge_invert;		    /* Enable/disable invert scroll
direction when edge scrolling */
+    Bool scroll_twofinger_invert;	    /* Enable/disable invert scroll
direction when two-finger scrolling */
     double min_speed, max_speed, accl;	    /* movement parameters */
     double trackstick_speed;		    /* trackstick mode speed */
     int edge_motion_min_z;		    /* finger pressure at which minimum
edge motion speed is set */
diff --git a/tools/synclient.c b/tools/synclient.c
index 942312a..eea3f80 100644
--- a/tools/synclient.c
+++ b/tools/synclient.c
@@ -94,9 +94,11 @@ static struct Parameter params[] = {
     {"HorizScrollDelta",      PT_INT,    0, 1000,
SYNAPTICS_PROP_SCROLL_DISTANCE,	32,	1},
     {"VertEdgeScroll",        PT_BOOL,   0, 1,
SYNAPTICS_PROP_SCROLL_EDGE,	8,	0},
     {"HorizEdgeScroll",       PT_BOOL,   0, 1,
SYNAPTICS_PROP_SCROLL_EDGE,	8,	1},
+    {"InvertEdgeScroll",      PT_BOOL,   0, 1,
SYNAPTICS_PROP_SCROLL_INVERT,	8,	0},
     {"CornerCoasting",        PT_BOOL,   0, 1,
SYNAPTICS_PROP_SCROLL_EDGE,	8,	2},
     {"VertTwoFingerScroll",   PT_BOOL,   0, 1,
SYNAPTICS_PROP_SCROLL_TWOFINGER,	8,	0},
     {"HorizTwoFingerScroll",  PT_BOOL,   0, 1,
SYNAPTICS_PROP_SCROLL_TWOFINGER,	8,	1},
+    {"InvertTwoFingerScroll", PT_BOOL,   0, 1,
SYNAPTICS_PROP_SCROLL_INVERT,	8,	1},
     {"MinSpeed",              PT_DOUBLE, 0, 255.0,
SYNAPTICS_PROP_SPEED,	0, /*float */	0},
     {"MaxSpeed",              PT_DOUBLE, 0, 255.0,
SYNAPTICS_PROP_SPEED,	0, /*float */	1},
     {"AccelFactor",           PT_DOUBLE, 0, 1.0,
SYNAPTICS_PROP_SPEED,	0, /*float */	2},
-- 
1.7.10


More information about the xorg-devel mailing list