[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