On Thu, Jun 09, 2011 at 08:57:30PM +0100, Daniel Stone wrote: > From: Derek Foreman <[email protected]> > > Attempt to decrease the possibility of errant motion as much as possible > by adding three new configurable filters, disabled by default: > - Synaptics Max Jerk: maximum change in acceleration before the > packet is declared errant (xorg.conf MaxJerk) > - Synaptics Max Accel: maximum acceleration the pointer can have > before being declared errant (xorg.conf MaxAccel) > - Synaptics Max Error: maximum error from a best-fit prediction of > the next position before being declared errant (xorg.conf MaxError) > - Synaptics Max Distance: maximum distance a finger can move in a > single report before being declared errant (xorg.conf MaxDistance) >
woo! more configuration options! :) > Signed-off-by: Derek Foreman <[email protected]> > Reviewed-by: Daniel Stone <[email protected]> > --- > include/synaptics-properties.h | 12 ++++++++++ > man/synaptics.man | 23 ++++++++++++++++++++ > src/properties.c | 46 > +++++++++++++++++++++++++++++++++++++++- > src/synaptics.c | 44 ++++++++++++++++++++++++++++++++++++++ > src/synapticsstr.h | 6 +++++ > 5 files changed, 130 insertions(+), 1 deletions(-) > > diff --git a/include/synaptics-properties.h b/include/synaptics-properties.h > index 77a1806..3e54fbb 100644 > --- a/include/synaptics-properties.h > +++ b/include/synaptics-properties.h > @@ -158,4 +158,16 @@ > /* 32 Bit Integer, 2 values, horizontal hysteresis, vertical hysteresis */ > #define SYNAPTICS_PROP_NOISE_CANCELLATION "Synaptics Noise Cancellation" > > +/* FLOAT */ > +#define SYNAPTICS_PROP_MAX_DISTANCE "Synaptics Max Distance" > + > +/* FLOAT */ > +#define SYNAPTICS_PROP_MAX_JERK "Synaptics Max Jerk" > + > +/* FLOAT */ > +#define SYNAPTICS_PROP_MAX_ACCEL "Synaptics Max Accel" > + > +/* FLOAT */ > +#define SYNAPTICS_PROP_MAX_ERROR "Synaptics Max Error" any reason these 4 couldn't be accumulated? they are related enough to justify it, imo. "Synaptics Acceleration Filters" or something more appropriate > + > #endif /* _SYNAPTICS_PROPERTIES_H_ */ > diff --git a/man/synaptics.man b/man/synaptics.man > index cb5f4c6..5b365e6 100644 > --- a/man/synaptics.man > +++ b/man/synaptics.man > @@ -510,6 +510,29 @@ AreaBottomEdge option to any integer value other than > zero. If supported by the > server (version 1.9 and later), the edge may be specified in percent of > the total height of the touchpad. Property: "Synaptics Area" > . > +.TP > +.BI "Option \*qMaxAccel\*q \*q" integer \*q > +If acceleration increases beyond the specified value, ignore the packet that > +provoked it, assuming that it is erroneous. Property: "Synaptics Max Accel" > +. > +.TP > +.BI "Option \*qMaxDistance\*q \*q" integer \*q > +Ignore any single packet containing movement greater than the specified value > +in pixels, assuming that it is erroneous. Property: "Synaptics Max Distance" > +. > +.TP > +.BI "Option \*qMaxError\*q \*q" integer \*q > +Ignore any single packet containing movement where the error from a best-fit > +line determining the expected pointer position from historical values is > larger > +than the specified value, assuming that it is erroneous. > +Property: "Synaptics Max Error" > +. > +.TP > +.BI "Option \*qMaxJerk\*q \*q" integer \*q > +If the derivative of acceleration increases beyond the specified value, > ignore > +the packet that provoked it, assuming that it is erroneous. > +Property: "Synaptics Max Jerk" > +. > > .SH CONFIGURATION DETAILS > .SS Area handling > diff --git a/src/properties.c b/src/properties.c > index 8370c0b..ad4c026 100644 > --- a/src/properties.c > +++ b/src/properties.c > @@ -94,6 +94,10 @@ Atom prop_area = 0; > Atom prop_noise_cancellation = 0; > Atom prop_product_id = 0; > Atom prop_device_node = 0; > +Atom prop_max_distance = 0; > +Atom prop_max_jerk = 0; > +Atom prop_max_accel = 0; > +Atom prop_max_error = 0; > > static Atom > InitAtom(DeviceIntPtr dev, char *name, int format, int nvalues, int *values) > @@ -313,6 +317,17 @@ InitDeviceProperties(InputInfoPtr pInfo) > XISetDevicePropertyDeletable(pInfo->dev, prop_device_node, FALSE); > } > > + fvalues[0] = para->max_distance; > + prop_max_distance = InitFloatAtom(pInfo->dev, > SYNAPTICS_PROP_MAX_DISTANCE, 1, fvalues); > + > + fvalues[0] = para->max_jerk; > + prop_max_jerk = InitFloatAtom(pInfo->dev, SYNAPTICS_PROP_MAX_JERK, 1, > fvalues); > + > + fvalues[0] = para->max_accel; > + prop_max_accel = InitFloatAtom(pInfo->dev, SYNAPTICS_PROP_MAX_ACCEL, 1, > fvalues); > + > + fvalues[0] = para->max_error; > + prop_max_error = InitFloatAtom(pInfo->dev, SYNAPTICS_PROP_MAX_ERROR, 1, > fvalues); > } > > int > @@ -694,8 +709,37 @@ SetProperty(DeviceIntPtr dev, Atom property, > XIPropertyValuePtr prop, > return BadValue; > para->hyst_x = hyst[0]; > para->hyst_y = hyst[1]; > - } else if (property == prop_product_id || property == prop_device_node) > + } else if (property == prop_product_id || property == prop_device_node) { > return BadValue; /* read-only */ > + } else if (property == prop_max_distance) { > + float max_distance; > + if (prop->size != 1 || prop->format != 32 || prop->type != > float_type) > + return BadMatch; > + > + max_distance = *(float*)prop->data; > + para->max_distance = max_distance; > + } else if (property == prop_max_jerk) { > + float max_jerk; > + if (prop->size != 1 || prop->format != 32 || prop->type != > float_type) > + return BadMatch; > + > + max_jerk = *(float*)prop->data; > + para->max_jerk = max_jerk; > + } else if (property == prop_max_accel) { > + float max_accel; > + if (prop->size != 1 || prop->format != 32 || prop->type != > float_type) > + return BadMatch; > + > + max_accel = *(float*)prop->data; > + para->max_accel = max_accel; > + } else if (property == prop_max_error) { > + float max_error; > + if (prop->size != 1 || prop->format != 32 || prop->type != > float_type) > + return BadMatch; > + > + max_error = *(float*)prop->data; > + para->max_error = max_error; > + } > > return Success; > } > diff --git a/src/synaptics.c b/src/synaptics.c > index 560f166..4c408d9 100644 > --- a/src/synaptics.c > +++ b/src/synaptics.c > @@ -573,6 +573,11 @@ static void set_default_parameters(InputInfoPtr pInfo) > pars->resolution_horiz = xf86SetIntOption(opts, "HorizResolution", > horizResolution); > pars->resolution_vert = xf86SetIntOption(opts, "VertResolution", > vertResolution); > > + pars->max_jerk = xf86SetRealOption(opts, "MaxJerk", 0.0); > + pars->max_distance = xf86SetRealOption(opts, "MaxDistance", 0.0); > + pars->max_accel = xf86SetRealOption(opts, "MaxAccel", 0.0); > + pars->max_error = xf86SetRealOption(opts, "MaxError", 0.0); > + > /* Warn about (and fix) incorrectly configured TopEdge/BottomEdge > parameters */ > if (pars->top_edge > pars->bottom_edge) { > int tmp = pars->top_edge; > @@ -1801,6 +1806,33 @@ static void regress(SynapticsPrivate *priv, const > struct SynapticsHwState *hw, > double yb1n = 0, xb1n = 0, b1d = 0, xb1, yb1; > double dista, distb, distc, vela, velb, velc, acca, accb, jerk; > > + if (pars->max_distance && for consistency with the checks a few lines below, this should state > 0 as well > + hypot(hw->x - HIST(0).x, hw->y - HIST(0).y) > pars->max_distance) > + goto filtered; > + > + if (pars->max_accel > 0 || pars->max_jerk > 0) { > + if (priv->count_packet_finger < 3) { > + *dx = 0; > + *dy = 0; > + return; > + } > + for the poor buggers that may have to debug this one day, a comment on what's actually done here would be awesome. I've spent too much time on wikipedia's math sites lately, trying to figure out what a piece of code was supposed to do. Cheers, Peter > + dista = hypot(HIST(0).x - hw->x, HIST(0).y - hw->y); > + distb = hypot(HIST_DELTA(1, 0, x), HIST_DELTA(1, 0, y)); > + distc = hypot(HIST_DELTA(2, 1, x), HIST_DELTA(2, 1, y)); > + vela = dista / (HIST(0).millis - hw->millis); > + velb = distb / HIST_DELTA(1, 0, millis); > + velc = distc / HIST_DELTA(2, 1, millis); > + acca = (vela - velb) / (HIST(1).millis - hw->millis); > + if (pars->max_accel > 0 && fabs(acca) > pars->max_accel) > + goto filtered; > + > + accb = (velc - velb) / HIST_DELTA(2, 0, millis); > + jerk = (acca - accb) / (HIST(2).millis - hw->millis); > + if (pars->max_jerk > 0 && fabs(jerk) > pars->max_jerk) > + goto filtered; > + } > + > if (priv->count_packet_finger == 1) { > *dx = hw->x - HIST(0).x; > *dy = hw->y - HIST(0).y; > @@ -1826,6 +1858,18 @@ static void regress(SynapticsPrivate *priv, const > struct SynapticsHwState *hw, > xb1 = xb1n/b1d; > yb1 = yb1n/b1d; > > + if (pars->max_error > 0) { > + double X, Y, e, xb0, yb0; > + > + xb0 = xm - xb1*tm; > + yb0 = ym - yb1*tm; > + X = xb1*(hw->millis - HIST(0).millis) + xb0; > + Y = yb1*(hw->millis - HIST(0).millis) + yb0; > + e = hypot(hw->x - X, hw->y - Y); > + if (e > pars->max_error) > + goto filtered; > + } > + > *dx = xb1 * (hw->millis - start_time); > *dy = yb1 * (hw->millis - start_time); > return; > diff --git a/src/synapticsstr.h b/src/synapticsstr.h > index a496212..73893cf 100644 > --- a/src/synapticsstr.h > +++ b/src/synapticsstr.h > @@ -163,6 +163,12 @@ typedef struct _SynapticsParameters > Bool tap_and_drag_gesture; /* Switches the > tap-and-drag gesture on/off */ > unsigned int resolution_horiz; /* horizontal resolution of > touchpad in units/mm */ > unsigned int resolution_vert; /* vertical resolution of > touchpad in units/mm */ > + > + double max_distance; /* maximum distance in a single > report for valid input */ > + double max_jerk; /* maximum jerk for valid input > */ > + double max_accel; /* maximum acceleration for > valid input */ > + double max_error; /* maximum deviation from > estimated position for valid input */ > + > int area_left_edge, area_right_edge, area_top_edge, area_bottom_edge; /* > area coordinates absolute */ > int hyst_x, hyst_y; /* x and y width of hysteresis > box */ > } SynapticsParameters; > -- > 1.7.5.3 > > _______________________________________________ > [email protected]: X.Org development > Archives: http://lists.x.org/archives/xorg-devel > Info: http://lists.x.org/mailman/listinfo/xorg-devel > _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
