Peter Hutterer wrote: > I've had this running on my laptop pretty much since you sent out the patch > and given that I was at a conference and on holidays after, I pretty much > exclusively used the touchpad for more than two weeks. Cool!
> My first impression was - it's slow. Much slower than the current method and Maybe you were a double acceleration victim before - it's by design in that case. I also added a small fix, so it now also scales for a (presumed) synaptics reporting rate, and tries to get the algorithm's accel parameter right. Maybe it's better now. > while I played around with xset initially to make it faster, I eventually Fun fact: As long as you're in profile 1 (device-dependent), xset won't do anything. X accel default settings seem to make no sense to the synaptics accel, so it left them side-by-side. > stopped doing that, frequent reboots make it cumbersome. There's some > additional knobs I guess that I can use, but I haven't tried tweaking them > yet. Guess why I added accel stuff to xorg.conf.d ;) Of course, your average DE will simply over-xset it all ;( > > That aside, I like it a lot. I have a lot more control over the pointer, > don't overshoot anymore and generally the pointer now feels it's doing what > it should. I didn't realize how much I got used to it until a recent Fedora > update changed my test setup and went back to the old accel. Nice to hear - that's exactly what it should achieve. > > aside from that, looks good to me and I'd be happy to put that one in. We'll > see if we get positive feedback. > Yay! Attached. Cheers, Simon
>From 76ea8499aa308ad535f499cc1e6712dd1ea82373 Mon Sep 17 00:00:00 2001 From: Simon Thum <[email protected]> Date: Wed, 9 Sep 2009 14:41:08 +0200 Subject: [PATCH] Setup pointer acceleration for synaptics Setup dix pointer accel from the synaptics driver so synaptics devices behave like before while benefiting from dix velocity approximation. This fixes the longstanding issue with synaptics being accelerated twice, in different layers and different algorithms. The pressure-dependent synaptics acceleration is now performed in the device-specific profile. Signed-off-by: Simon Thum <[email protected]> --- src/synaptics.c | 128 ++++++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 93 insertions(+), 35 deletions(-) diff --git a/src/synaptics.c b/src/synaptics.c index 0fdc496..f24d336 100644 --- a/src/synaptics.c +++ b/src/synaptics.c @@ -49,6 +49,7 @@ * Linuxcare Inc. David Kennedy <[email protected]> * Fred Hucht <[email protected]> * Fedor P. Goncharov <[email protected]> + * Simon Thum <[email protected]> * * Trademarks are the property of their respective owners. */ @@ -80,6 +81,7 @@ #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 #include <X11/Xatom.h> #include <xserver-properties.h> +#include <ptrveloc.h> #endif typedef enum { @@ -543,6 +545,44 @@ 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; + + /* clip acceleration factor */ + if (accelfct > para->max_speed) + accelfct = para->max_speed; + else if (accelfct < para->min_speed) + 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 */ @@ -852,12 +892,15 @@ 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; #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 Atom btn_labels[SYN_MAX_BUTTONS] = { 0 }; Atom axes_labels[2] = { 0 }; + DeviceVelocityPtr pVel; InitAxesLabels(axes_labels, 2); InitButtonLabels(btn_labels, SYN_MAX_BUTTONS); @@ -890,6 +933,51 @@ DeviceInit(DeviceIntPtr dev) , axes_labels #endif ); + + /* + * setup dix acceleration to match legacy synaptics settings, and + * etablish a device-specific profile to do stuff like pressure-related + * acceleration. + */ +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 + if (NULL != (pVel = GetDevicePredictableAccelData(dev))) { + SetDeviceSpecificAccelerationProfile(pVel, + SynapticsAccelerationProfile); + + /* float property type */ + float_type = XIGetKnownProperty(XATOM_FLOAT); + + /* translate MinAcc to constant deceleration. + * May be overridden in xf86InitValuatorDefaults */ + 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; + priv->synpara.accl *= tmpf; /* dix velocity includes const decel */ + priv->synpara.min_speed = 1.0; + + /* synaptics seems to report 80 packet/s, but dix scales for + * 100 packet/s by default. */ + pVel->corr_mul = 12.5f; /*1000[ms]/80[/s] = 12.5 */ + + 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); + } +#endif + /* X valuator */ if (priv->minx < priv->maxx) { @@ -941,11 +1029,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 @@ -1585,9 +1668,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; @@ -1667,36 +1749,12 @@ 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. Of course, it would be + * cooler to report floats than to buffer, but anyway. */ + 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.4.4
_______________________________________________ xorg mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/xorg
