[PATCH] Setup dix pointer acceleration from synaptics

Simon Thum simon.thum at gmx.de
Sat Jun 20 07:07:43 PDT 2009


Tries to setup dix accel so configured synaptics devices
behave alike while benefiting from dix velocity approximation.
Pressure-dependent acceleration is performed in a device-specific
profile.
---
 src/synaptics.c |  124 +++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 89 insertions(+), 35 deletions(-)

diff --git a/src/synaptics.c b/src/synaptics.c
index 6b902e9..94eed2f 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -77,6 +77,10 @@
 #include "synapticsstr.h"
 #include "synaptics-properties.h"
 
+#include <ptrveloc.h>
+#include <xserver-properties.h>
+#include <X11/Xatom.h> /* for XA_INTEGER */
+
 typedef enum {
     BOTTOM_EDGE = 1,
     TOP_EDGE = 2,
@@ -515,6 +519,46 @@ static void set_default_parameters(LocalDevicePtr local)
     }
 }
 
+static float SynapticsAccelerationProfile
+    (DeviceIntPtr dev,
+     DeviceVelocityPtr vel,
+     float velocity,
+     float thr,
+     float acc) {
+    LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+    SynapticsPrivate *priv = (SynapticsPrivate *) (local->private);
+    SynapticsParameters* para = &priv->synpara;
+
+    double accelfct;
+
+    /* speed up linear with finger velocity */
+    accelfct = velocity * para->accl;
+
+    if (accelfct > para->max_speed) {  /* clip speed factor */
+	accelfct = para->max_speed;
+    } else if (accelfct < para->min_speed) {
+	/* this may be bogus since dix also enforces a min accel */
+	accelfct = para->min_speed;
+    }
+
+    /* modify speed according to pressure */
+    if (priv->moving_state == MS_TOUCHPAD_RELATIVE) {
+	int minZ = para->press_motion_min_z;
+	int maxZ = para->press_motion_max_z;
+	double minFctr = para->press_motion_min_factor;
+	double maxFctr = para->press_motion_max_factor;
+	if (priv->hwState.z <= minZ) {
+	    accelfct *= minFctr;
+	} else if (priv->hwState.z >= maxZ) {
+	    accelfct *= maxFctr;
+	} else {
+	    accelfct *= minFctr + (priv->hwState.z - minZ) * (maxFctr - minFctr) / (maxZ - minZ);
+	}
+    }
+
+    return accelfct;
+}
+
 /*
  *  called by the module loader for initialization
  */
@@ -793,6 +837,8 @@ DeviceInit(DeviceIntPtr dev)
 {
     LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
     SynapticsPrivate *priv = (SynapticsPrivate *) (local->private);
+    Atom float_type, prop;
+    float tmpf;
     unsigned char map[SYN_MAX_BUTTONS + 1];
     int i;
     int min, max;
@@ -818,6 +864,45 @@ DeviceInit(DeviceIntPtr dev)
 			    GetMotionHistorySize(), 2
 #endif
 			    );
+
+    /*
+     * setup dix acceleration to match legacy synaptics settings, and
+     * etablish a device-specific profile to do stuff like pressure-related
+     * acceleration.
+     */
+    DeviceVelocityPtr pVel = GetDevicePredictableAccelData(dev);
+    if(pVel){
+	SetDeviceSpecificAccelerationProfile(pVel, SynapticsAccelerationProfile);
+
+	/* float property type */
+	float_type = XIGetKnownProperty(XATOM_FLOAT);
+
+	/* translate MinAcc to constant deceleration.
+	 * May be overridden in xf86IVD */
+	tmpf = 1.0 / priv->synpara.min_speed;
+
+	xf86Msg(X_CONFIG, "%s: (accel) MinSpeed is now constant deceleration %.1f\n",
+	        dev->name, tmpf);
+	prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
+	XIChangeDeviceProperty(dev, prop, float_type, 32,
+	                       PropModeReplace, 1, &tmpf, FALSE);
+
+	/* adjust accordingly */
+	priv->synpara.max_speed /= priv->synpara.min_speed;
+	/* leave priv->synpara.accl alone since velocity includes const decel */
+	priv->synpara.min_speed = 1.0;
+
+	xf86Msg(X_CONFIG, "%s: MaxSpeed is now %.1f\n",
+		dev->name, priv->synpara.max_speed);
+	xf86Msg(X_CONFIG, "%s: AccelFactor is now %.1f\n",
+		dev->name, priv->synpara.accl);
+
+	prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
+	i = AccelProfileDeviceSpecific;
+	XIChangeDeviceProperty(dev, prop, XA_INTEGER, 32,
+	                       PropModeReplace, 1, &i, FALSE);
+    }
+
     /* X valuator */
     if (priv->minx < priv->maxx)
     {
@@ -861,11 +946,6 @@ DeviceInit(DeviceIntPtr dev)
     return Success;
 }
 
-static int
-move_distance(int dx, int dy)
-{
-    return sqrt(SQR(dx) + SQR(dy));
-}
 
 /*
  * Convert from absolute X/Y coordinates to a coordinate system where
@@ -1474,9 +1554,8 @@ ComputeDeltas(SynapticsPrivate *priv, struct SynapticsHwState *hw,
 {
     SynapticsParameters *para = &priv->synpara;
     enum MovingState moving_state;
-    int dist;
     double dx, dy;
-    double speed, integral;
+    double integral;
     int delay = 1000000000;
 
     dx = dy = 0;
@@ -1556,36 +1635,11 @@ ComputeDeltas(SynapticsPrivate *priv, struct SynapticsHwState *hw,
 		}
 	    }
 
-	    /* speed depending on distance/packet */
-	    dist = move_distance(dx, dy);
-	    speed = dist * para->accl;
-	    if (speed > para->max_speed) {  /* set max speed factor */
-		speed = para->max_speed;
-	    } else if (speed < para->min_speed) { /* set min speed factor */
-		speed = para->min_speed;
-	    }
-
-	    /* modify speed according to pressure */
-	    if (priv->moving_state == MS_TOUCHPAD_RELATIVE) {
-		int minZ = para->press_motion_min_z;
-		int maxZ = para->press_motion_max_z;
-		double minFctr = para->press_motion_min_factor;
-		double maxFctr = para->press_motion_max_factor;
-
-		if (hw->z <= minZ) {
-		    speed *= minFctr;
-		} else if (hw->z >= maxZ) {
-		    speed *= maxFctr;
-		} else {
-		    speed *= minFctr + (hw->z - minZ) * (maxFctr - minFctr) / (maxZ - minZ);
-		}
-	    }
-
-	    /* save the fraction, report the integer part */
-	    tmpf = dx * speed + x_edge_speed * dtime + priv->frac_x;
+	    /* report edge speed as synthetic motion */
+	    tmpf = dx + x_edge_speed * dtime + priv->frac_x;
 	    priv->frac_x = modf(tmpf, &integral);
 	    dx = integral;
-	    tmpf = dy * speed + y_edge_speed * dtime + priv->frac_y;
+	    tmpf = dy + y_edge_speed * dtime + priv->frac_y;
 	    priv->frac_y = modf(tmpf, &integral);
 	    dy = integral;
 	}
-- 
1.6.0.6


--------------070402030500050609040709
Content-Type: text/plain;
 name="0002-dix-improve-pointer-acceleration-API.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: inline;
 filename="0002-dix-improve-pointer-acceleration-API.patch"



More information about the xorg-devel mailing list