filter: split trackpoint acceleration out
authorPeter Hutterer <peter.hutterer@who-t.net>
Tue, 28 Jul 2015 06:02:05 +0000 (16:02 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Wed, 12 Aug 2015 04:06:00 +0000 (14:06 +1000)
This is step one to fixing trackpoint acceleration, separating it from the
other acceleration code. No functional changes yet, it still uses the low-dpi
accel method.

https://bugs.freedesktop.org/show_bug.cgi?id=91369

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Jonas Ã…dahl <jadahl@gmail.com>
src/evdev.c
src/filter.c
src/filter.h

index bb31724889d7178527d5b42afd4bf385e5251c57..22d51dcbefc94f2d82b95cc7e9a4ed1dd1505aed 100644 (file)
@@ -1861,7 +1861,9 @@ evdev_init_accel(struct evdev_device *device)
 {
        struct motion_filter *filter;
 
-       if (device->dpi < DEFAULT_MOUSE_DPI)
+       if (device->tags & EVDEV_TAG_TRACKPOINT)
+               filter = create_pointer_accelerator_filter_trackpoint(device->dpi);
+       else if (device->dpi < DEFAULT_MOUSE_DPI)
                filter = create_pointer_accelerator_filter_linear_low_dpi(device->dpi);
        else
                filter = create_pointer_accelerator_filter_linear(device->dpi);
index 0c3e1de249795e712886f586cff9840053149bf4..7054fafa14e63bb8fc300c0e10fd7858266edb70 100644 (file)
@@ -342,6 +342,36 @@ accelerator_filter_low_dpi(struct motion_filter *filter,
        return accelerated;
 }
 
+static struct normalized_coords
+accelerator_filter_trackpoint(struct motion_filter *filter,
+                             const struct normalized_coords *unaccelerated,
+                             void *data, uint64_t time)
+{
+       struct pointer_accelerator *accel =
+               (struct pointer_accelerator *) filter;
+       double accel_value; /* unitless factor */
+       struct normalized_coords accelerated;
+       struct normalized_coords unnormalized;
+       double dpi_factor = accel->dpi_factor;
+
+       /* trackpoints with a dpi factor have a const accel set, remove that
+        * and restore device units. The accel profile takes const accel
+        * into account */
+       dpi_factor = min(1.0, dpi_factor);
+       unnormalized.x = unaccelerated->x * dpi_factor;
+       unnormalized.y = unaccelerated->y * dpi_factor;
+
+       accel_value = calculate_acceleration_factor(accel,
+                                                   &unnormalized,
+                                                   data,
+                                                   time);
+
+       accelerated.x = accel_value * unnormalized.x;
+       accelerated.y = accel_value * unnormalized.y;
+
+       return accelerated;
+}
+
 static struct normalized_coords
 accelerator_filter_x230(struct motion_filter *filter,
                        const struct normalized_coords *unaccelerated,
@@ -609,6 +639,38 @@ touchpad_lenovo_x230_accel_profile(struct motion_filter *filter,
        return factor * TP_MAGIC_SLOWDOWN / TP_MAGIC_LOW_RES_FACTOR;
 }
 
+double
+trackpoint_accel_profile(struct motion_filter *filter,
+                               void *data,
+                               double speed_in, /* 1000-dpi normalized */
+                               uint64_t time)
+{
+       struct pointer_accelerator *accel_filter =
+               (struct pointer_accelerator *)filter;
+       double max_accel = accel_filter->accel; /* unitless factor */
+       double threshold = accel_filter->threshold; /* units/ms */
+       const double incline = accel_filter->incline;
+       double factor;
+       double dpi_factor = accel_filter->dpi_factor;
+
+       /* dpi_factor is always < 1.0, increase max_accel, reduce
+          the threshold so it kicks in earlier */
+       max_accel /= dpi_factor;
+       threshold *= dpi_factor;
+
+       /* see pointer_accel_profile_linear for a long description */
+       if (v_us2ms(speed_in) < 0.07)
+               factor = 10 * v_us2ms(speed_in) + 0.3;
+       else if (speed_in < threshold)
+               factor = 1;
+       else
+               factor = incline * v_us2ms(speed_in - threshold) + 1;
+
+       factor = min(max_accel, factor);
+
+       return factor;
+}
+
 struct motion_filter_interface accelerator_interface = {
        accelerator_filter,
        accelerator_restart,
@@ -728,3 +790,28 @@ create_pointer_accelerator_filter_lenovo_x230(int dpi)
 
        return &filter->base;
 }
+
+struct motion_filter_interface accelerator_interface_trackpoint = {
+       accelerator_filter_trackpoint,
+       accelerator_restart,
+       accelerator_destroy,
+       accelerator_set_speed,
+};
+
+struct motion_filter *
+create_pointer_accelerator_filter_trackpoint(int dpi)
+{
+       struct pointer_accelerator *filter;
+
+       filter = create_default_filter(dpi);
+       if (!filter)
+               return NULL;
+
+       filter->base.interface = &accelerator_interface_trackpoint;
+       filter->profile = trackpoint_accel_profile;
+       filter->threshold = DEFAULT_THRESHOLD;
+       filter->accel = DEFAULT_ACCELERATION;
+       filter->incline = DEFAULT_INCLINE;
+
+       return &filter->base;
+}
index 76fc147688a6be0bd36c83dcbc1d1471b308cda8..fd36da49f2151aced490918e37c1dd5456ad8607 100644 (file)
@@ -71,6 +71,9 @@ create_pointer_accelerator_filter_touchpad(int dpi);
 struct motion_filter *
 create_pointer_accelerator_filter_lenovo_x230(int dpi);
 
+struct motion_filter *
+create_pointer_accelerator_filter_trackpoint(int dpi);
+
 /*
  * Pointer acceleration profiles.
  */
@@ -95,4 +98,9 @@ touchpad_lenovo_x230_accel_profile(struct motion_filter *filter,
                                      void *data,
                                      double speed_in,
                                      uint64_t time);
+double
+trackpoint_accel_profile(struct motion_filter *filter,
+                        void *data,
+                        double speed_in,
+                        uint64_t time);
 #endif /* FILTER_H */