filter: add scroll movement type to the custom acceleration profile
authorYinon Burgansky <yinonburgansky@gmail.com>
Sat, 18 Feb 2023 19:12:13 +0000 (21:12 +0200)
committerJihoon Kim <jihoon48.kim@samsung.com>
Mon, 4 Dec 2023 10:21:12 +0000 (19:21 +0900)
Adds a dedicated scroll movement type to the custom acceleration profile.
Supported by physical mouse and touchpad.
Other profiles remain the same by using the same unaccelerated filter for the scroll filter.

Signed-off-by: Yinon Burgansky <51504-Yinon@users.noreply.gitlab.freedesktop.org>
25 files changed:
doc/user/pointer-acceleration.rst
src/evdev-fallback.c
src/evdev-mt-touchpad-gestures.c
src/evdev-mt-touchpad.c
src/evdev-mt-touchpad.h
src/evdev-wheel.c
src/filter-custom.c
src/filter-flat.c
src/filter-low-dpi.c
src/filter-mouse.c
src/filter-private.h
src/filter-tablet.c
src/filter-touchpad-flat.c
src/filter-touchpad-x230.c
src/filter-touchpad.c
src/filter-trackpoint-flat.c
src/filter-trackpoint.c
src/filter.c
src/filter.h
src/libinput-private.h
src/libinput.c
src/libinput.h
test/test-pointer.c
tools/libinput-debug-events.man
tools/shared.c

index 1d60702a27c6911da2ce77a13cec91ed2d8310e8..211bd4696cca5b6775085fcfc662af3cf537fd21 100644 (file)
@@ -252,6 +252,8 @@ Supported Movement types:
 +---------------+---------------------------------+----------------------+
 | Motion        | Used for pointer motion         | All devices          |
 +---------------+---------------------------------+----------------------+
+| Scroll        | Used for scroll movement        | Mouse, Touchpad      |
++---------------+---------------------------------+----------------------+
 
 If a user does not provide the fallback custom acceleration function, a
 flat acceleration function is used, i.e. no acceleration.
@@ -259,11 +261,12 @@ flat acceleration function is used, i.e. no acceleration.
 The fallback acceleration may be used for different types of movements, it is
 strongly recommended that this acceleration function is a constant function.
 
-For example, a physical mouse usually has two movement types: pointer
-movement and scroll (wheel) movement. As there is no separate movement
-type for scroll yet, scroll movement is be accelerated using the Fallback
-acceleration function. Pointer movements is accelerated using the Motion
-acceleration function. If no Motion acceleration function is set, the
+For example, a touchpad has multiple movement types: pointer
+movement, scroll movement, zoom movement (pinch), etc. As there is no separate
+movement type for zoom yet, zoom movement is accelerated using the Fallback
+acceleration function. Pointer movement is accelerated using the Motion
+acceleration function, and Scroll movement is accelerated using the Scroll
+acceleration function. If no Motion/Scroll acceleration function is set, the
 Fallback acceleration function is used.
 
 When using custom acceleration profile, any calls to set the speed have no
index d591928af4ac59f1c5935784c44172df16409125..ae33d45a65cffbf85d0198361f2bfe8915f8c379 100644 (file)
@@ -113,10 +113,10 @@ post_button_scroll(struct evdev_device *device,
        case BUTTONSCROLL_SCROLLING:
                {
                const struct normalized_coords normalized =
-                               filter_dispatch_constant(device->pointer.filter,
-                                                        &raw,
-                                                        device,
-                                                        time);
+                               filter_dispatch_scroll(device->pointer.filter,
+                                                      &raw,
+                                                      device,
+                                                      time);
                evdev_post_scroll(device, time,
                                  LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
                                  &normalized);
index 08c936163e1ca12d7798eb60e5d683f17c037bcd..ad11c2627252a7a353ec1a1e4c22c38952dbf40c 100644 (file)
@@ -1176,8 +1176,8 @@ tp_gesture_handle_state_scroll(struct tp_dispatch *tp, uint64_t time)
 
        raw = tp_get_average_touches_delta(tp);
 
-       /* scroll is not accelerated */
-       delta = tp_filter_motion_unaccelerated(tp, &raw, time);
+       /* scroll is not accelerated by default */
+       delta = tp_filter_scroll(tp, &raw, time);
 
        if (normalized_is_zero(delta))
                return;
index 40c5696ef8e568a3050ff18423a8efac06d55a21..a72b9095899b5c2b86afd6c2b3e556deeb6257f4 100644 (file)
@@ -93,6 +93,24 @@ tp_filter_motion_unaccelerated(struct tp_dispatch *tp,
                                        &raw, tp, time);
 }
 
+struct normalized_coords
+tp_filter_scroll(struct tp_dispatch *tp,
+                const struct device_float_coords *unaccelerated,
+                uint64_t time)
+{
+       struct device_float_coords raw;
+       const struct normalized_coords zero = { 0.0, 0.0 };
+
+       if (device_float_is_zero(*unaccelerated))
+               return zero;
+
+       /* Convert to device units with x/y in the same resolution */
+       raw = tp_scale_to_xaxis(tp, *unaccelerated);
+
+       return filter_dispatch_scroll(tp->device->pointer.filter,
+                                     &raw, tp, time);
+}
+
 static inline void
 tp_calculate_motion_speed(struct tp_dispatch *tp,
                          struct tp_touch *t,
index a95bdd4c286ac33962e6b11a66cf9d9e6c92196d..c99b190f4bb226d2253cbf4ba6851c87cad898cd 100644 (file)
@@ -607,6 +607,11 @@ tp_filter_motion_unaccelerated(struct tp_dispatch *tp,
                               const struct device_float_coords *unaccelerated,
                               uint64_t time);
 
+struct normalized_coords
+tp_filter_scroll(struct tp_dispatch *tp,
+                const struct device_float_coords *unaccelerated,
+                uint64_t time);
+
 bool
 tp_touch_active(const struct tp_dispatch *tp, const struct tp_touch *t);
 
index 7276ec1a2ca4a426189e31f6a2683de8e1ec3bf6..2381cb772241346eacb79dc60680dfcb344291bd 100644 (file)
@@ -196,10 +196,10 @@ wheel_flush_scroll(struct fallback_dispatch *dispatch,
                        .y = dispatch->wheel.lo_res.y * -1,
                };
                const struct normalized_coords normalized =
-                               filter_dispatch_constant(device->pointer.filter,
-                                                        &raw,
-                                                        device,
-                                                        time);
+                               filter_dispatch_scroll(device->pointer.filter,
+                                                      &raw,
+                                                      device,
+                                                      time);
                evdev_post_scroll(device,
                                  time,
                                  LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
index 0172f7c0505379eebd01cf94e2a202b7e60607bf..b2eb75c8ccecdd962dcfae12775d3844b1ef1c12 100644 (file)
@@ -201,6 +201,7 @@ struct custom_accelerator {
        struct {
                struct custom_accel_function *fallback;
                struct custom_accel_function *motion;
+               struct custom_accel_function *scroll;
        } funcs;
 };
 
@@ -213,6 +214,8 @@ custom_accelerator_get_custom_function(struct custom_accelerator *f,
                return f->funcs.fallback;
        case LIBINPUT_ACCEL_TYPE_MOTION:
                return f->funcs.motion ? f->funcs.motion : f->funcs.fallback;
+       case LIBINPUT_ACCEL_TYPE_SCROLL:
+               return f->funcs.scroll ? f->funcs.scroll : f->funcs.fallback;
        }
 
        return f->funcs.fallback;
@@ -262,6 +265,7 @@ custom_accelerator_destroy(struct motion_filter *filter)
        /* destroy all custom movement functions */
        custom_accel_function_destroy(f->funcs.fallback);
        custom_accel_function_destroy(f->funcs.motion);
+       custom_accel_function_destroy(f->funcs.scroll);
        free(f);
 }
 
@@ -284,7 +288,8 @@ custom_accelerator_set_accel_config(struct motion_filter *filter,
                (struct custom_accelerator *)filter;
 
        struct custom_accel_function *fallback = NULL,
-                                    *motion = NULL;
+                                    *motion = NULL,
+                                    *scroll = NULL;
 
        if (config->custom.fallback) {
                fallback = create_custom_accel_function(config->custom.fallback->step,
@@ -302,17 +307,28 @@ custom_accelerator_set_accel_config(struct motion_filter *filter,
                        goto out;
        }
 
+       if (config->custom.scroll) {
+               scroll = create_custom_accel_function(config->custom.scroll->step,
+                                                     config->custom.scroll->points,
+                                                     config->custom.scroll->npoints);
+               if (!scroll)
+                       goto out;
+       }
+
        custom_accel_function_destroy(f->funcs.fallback);
        custom_accel_function_destroy(f->funcs.motion);
+       custom_accel_function_destroy(f->funcs.scroll);
 
        f->funcs.fallback = fallback;
        f->funcs.motion = motion;
+       f->funcs.scroll = scroll;
 
        return true;
 
 out:
        custom_accel_function_destroy(fallback);
        custom_accel_function_destroy(motion);
+       custom_accel_function_destroy(scroll);
 
        return false;
 }
@@ -365,10 +381,34 @@ custom_accelerator_filter_motion(struct motion_filter *filter,
                                         time);
 }
 
+double
+custom_accel_profile_scroll(struct motion_filter *filter,
+                           void *data,
+                           double speed_in,
+                           uint64_t time)
+{
+       return custom_accelerator_profile(LIBINPUT_ACCEL_TYPE_SCROLL,
+                                         filter,
+                                         speed_in);
+}
+
+static struct normalized_coords
+custom_accelerator_filter_scroll(struct motion_filter *filter,
+                                const struct device_float_coords *unaccelerated,
+                                void *data,
+                                uint64_t time)
+{
+       return custom_accelerator_filter(LIBINPUT_ACCEL_TYPE_SCROLL,
+                                        filter,
+                                        unaccelerated,
+                                        time);
+}
+
 struct motion_filter_interface custom_accelerator_interface = {
        .type = LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM,
        .filter = custom_accelerator_filter_motion,
        .filter_constant = custom_accelerator_filter_fallback,
+       .filter_scroll = custom_accelerator_filter_scroll,
        .restart = custom_accelerator_restart,
        .destroy = custom_accelerator_destroy,
        .set_speed = custom_accelerator_set_speed,
index 3f5d9bd9935a217fdc720abeb04684c8e6e97475..4781476743c1be9c8fe5bbd6fa33117f9cefed95 100644 (file)
@@ -112,6 +112,7 @@ static const struct motion_filter_interface accelerator_interface_flat = {
        .type = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
        .filter = accelerator_filter_flat,
        .filter_constant = accelerator_filter_noop_flat,
+       .filter_scroll = accelerator_filter_noop_flat,
        .restart = NULL,
        .destroy = accelerator_destroy_flat,
        .set_speed = accelerator_set_speed_flat,
index 51793b5cba25e6ef3f0994eddac36e938746f6b7..a52bb3ca422e60a186c931ec724d2f176e889f5c 100644 (file)
@@ -210,6 +210,7 @@ static const struct motion_filter_interface accelerator_interface_low_dpi = {
        .type = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
        .filter = accelerator_filter_low_dpi,
        .filter_constant = accelerator_filter_noop,
+       .filter_scroll = accelerator_filter_noop,
        .restart = accelerator_restart,
        .destroy = accelerator_destroy,
        .set_speed = accelerator_set_speed,
index a2284c00c90ee3184791742c34e14f0a02d9810c..f7d4d20c5688b92aadbcac20851759a4ea41cca1 100644 (file)
@@ -270,6 +270,7 @@ static const struct motion_filter_interface accelerator_interface = {
        .type = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
        .filter = accelerator_filter_linear,
        .filter_constant = accelerator_filter_noop,
+       .filter_scroll = accelerator_filter_noop,
        .restart = accelerator_restart,
        .destroy = accelerator_destroy,
        .set_speed = accelerator_set_speed,
index ed969f04ee49fe39588af14e8467cfe1aff2fc6e..e7f8dc24b8a753b172accf6fdc7ab7900249a7e9 100644 (file)
@@ -38,6 +38,10 @@ struct motion_filter_interface {
                           struct motion_filter *filter,
                           const struct device_float_coords *unaccelerated,
                           void *data, uint64_t time);
+       struct normalized_coords (*filter_scroll)(
+                          struct motion_filter *filter,
+                          const struct device_float_coords *unaccelerated,
+                          void *data, uint64_t time);
        void (*restart)(struct motion_filter *filter,
                        void *data,
                        uint64_t time);
index 4415b9ea51eca1ca572944894ca308de6b0eb6ef..abc687d27f8c92b8a981fc5d550ef2dd233231c8 100644 (file)
@@ -147,6 +147,7 @@ static const struct motion_filter_interface accelerator_interface_tablet = {
        .type = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
        .filter = tablet_accelerator_filter_flat,
        .filter_constant = NULL,
+       .filter_scroll = NULL,
        .restart = NULL,
        .destroy = tablet_accelerator_destroy,
        .set_speed = tablet_accelerator_set_speed,
index ac1a15c1f5dfb34ab41caf4cd05868e7c3980117..846d096bfe0a6336ca7ec813c9a8248a380261eb 100644 (file)
@@ -110,6 +110,7 @@ static const struct motion_filter_interface accelerator_interface_touchpad_flat
        .type = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
        .filter = accelerator_filter_touchpad_flat,
        .filter_constant = accelerator_filter_noop_touchpad_flat,
+       .filter_scroll = accelerator_filter_noop_touchpad_flat,
        .restart = NULL,
        .destroy = accelerator_destroy_touchpad_flat,
        .set_speed = accelerator_set_speed_touchpad_flat,
index 90c42140aa08289556f9ff3a8b1f5ad4c5f34c48..6d1fb282c85f8182fa92949e1d65dda8a62f3f5f 100644 (file)
@@ -287,6 +287,7 @@ static const struct motion_filter_interface accelerator_interface_x230 = {
        .type = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
        .filter = accelerator_filter_x230,
        .filter_constant = accelerator_filter_constant_x230,
+       .filter_scroll = accelerator_filter_constant_x230,
        .restart = accelerator_restart_x230,
        .destroy = accelerator_destroy_x230,
        .set_speed = accelerator_set_speed_x230,
index dcc2450d8072625a216546513bd97ad35dd8ff48..ec6731c395a21b82d5662256adeafdac490035ff 100644 (file)
@@ -278,6 +278,7 @@ static const struct motion_filter_interface accelerator_interface_touchpad = {
        .type = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
        .filter = accelerator_filter_touchpad,
        .filter_constant = touchpad_constant_filter,
+       .filter_scroll = touchpad_constant_filter,
        .restart = touchpad_accelerator_restart,
        .destroy = touchpad_accelerator_destroy,
        .set_speed = touchpad_accelerator_set_speed,
index 7f63a0e3e2b4fcfc513dcd37774f142b1c2e8e90..786913abecdffde564517a02b9958195c91d3e0d 100644 (file)
@@ -129,6 +129,7 @@ static struct motion_filter_interface accelerator_interface_flat = {
        .type = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
        .filter = trackpoint_flat_filter,
        .filter_constant = trackpoint_flat_filter_noop,
+       .filter_scroll = trackpoint_flat_filter_noop,
        .restart = NULL,
        .destroy = trackpoint_flat_destroy,
        .set_speed = trackpoint_flat_set_speed,
index 742674639895ea3c2229f45ad79f2298d07d2318..0083db3a371e920b5ba2e2432a141aee0ac831a6 100644 (file)
@@ -174,6 +174,7 @@ static const struct motion_filter_interface accelerator_interface_trackpoint = {
        .type = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
        .filter = trackpoint_accelerator_filter,
        .filter_constant = trackpoint_accelerator_filter_noop,
+       .filter_scroll = trackpoint_accelerator_filter_noop,
        .restart = trackpoint_accelerator_restart,
        .destroy = trackpoint_accelerator_destroy,
        .set_speed = trackpoint_accelerator_set_speed,
index aa60540a5ba8671bae3308a402c2b18c84961a21..4c28bd9dd5229d77b3b8ecbdb0decc266cee85ee 100644 (file)
@@ -53,6 +53,14 @@ filter_dispatch_constant(struct motion_filter *filter,
        return filter->interface->filter_constant(filter, unaccelerated, data, time);
 }
 
+struct normalized_coords
+filter_dispatch_scroll(struct motion_filter *filter,
+                      const struct device_float_coords *unaccelerated,
+                      void *data, uint64_t time)
+{
+       return filter->interface->filter_scroll(filter, unaccelerated, data, time);
+}
+
 void
 filter_restart(struct motion_filter *filter,
               void *data, uint64_t time)
index a293e5a64c5e353d8116cb3c4de8aab723413a77..f42a0c63dcb1e4caa3307cca4066b673c1ff2c0e 100644 (file)
@@ -82,6 +82,28 @@ filter_dispatch_constant(struct motion_filter *filter,
                         const struct device_float_coords *unaccelerated,
                         void *data, uint64_t time);
 
+/**
+ * Apply a scroll filter.
+ * Depending on the device, and the acceleration profile,
+ * this filter allows the user to accelerate the scroll movement.
+ *
+ * Takes a set of unaccelerated deltas and applies the scroll filter to it.
+ *
+ * @param filter The device's motion filter
+ * @param unaccelerated The unaccelerated delta in the device's dpi
+ * resolution as specified during filter creation. If a device has uneven
+ * resolution for x and y, one axis needs to be scaled to match the
+ * originally provided resolution.
+ * @param data Custom data
+ * @param time The time of the delta
+ *
+ * @see filter_dispatch
+ */
+struct normalized_coords
+filter_dispatch_scroll(struct motion_filter *filter,
+                      const struct device_float_coords *unaccelerated,
+                      void *data, uint64_t time);
+
 void
 filter_restart(struct motion_filter *filter,
               void *data, uint64_t time);
@@ -180,4 +202,9 @@ custom_accel_profile_motion(struct motion_filter *filter,
                            void *data,
                            double speed_in,
                            uint64_t time);
+double
+custom_accel_profile_scroll(struct motion_filter *filter,
+                           void *data,
+                           double speed_in,
+                           uint64_t time);
 #endif /* FILTER_H */
index b9981ec00114940c9aca50b4d427eed55e70b057..b97107565e487a51ffccc826aeb9c6e317633da7 100644 (file)
@@ -271,6 +271,7 @@ struct libinput_config_accel {
        struct  {
                struct libinput_config_accel_custom_func *fallback;
                struct libinput_config_accel_custom_func *motion;
+               struct libinput_config_accel_custom_func *scroll;
        } custom;
 };
 
index c40266d7c4c37e33154472d19e30b4130a73c38d..f656dd9c76b7145020f17d9645d9966b0daab3b6 100644 (file)
@@ -4218,6 +4218,7 @@ libinput_config_accel_destroy(struct libinput_config_accel *accel_config)
 {
        libinput_config_accel_custom_func_destroy(accel_config->custom.fallback);
        libinput_config_accel_custom_func_destroy(accel_config->custom.motion);
+       libinput_config_accel_custom_func_destroy(accel_config->custom.scroll);
        free(accel_config);
 }
 
@@ -4256,6 +4257,7 @@ libinput_config_accel_set_points(struct libinput_config_accel *config,
        switch (accel_type) {
        case LIBINPUT_ACCEL_TYPE_FALLBACK:
        case LIBINPUT_ACCEL_TYPE_MOTION:
+       case LIBINPUT_ACCEL_TYPE_SCROLL:
                break;
        default:
                return LIBINPUT_CONFIG_STATUS_INVALID;
@@ -4288,6 +4290,10 @@ libinput_config_accel_set_points(struct libinput_config_accel *config,
                libinput_config_accel_custom_func_destroy(config->custom.motion);
                config->custom.motion = func;
                break;
+       case LIBINPUT_ACCEL_TYPE_SCROLL:
+               libinput_config_accel_custom_func_destroy(config->custom.scroll);
+               config->custom.scroll = func;
+               break;
        }
 
        return LIBINPUT_CONFIG_STATUS_SUCCESS;
index 1d477b680f0d901f3377e96b678fda73886c6205..7c0a9a757e09d8232acbf9d4df6d73f132930e5d 100644 (file)
@@ -5364,6 +5364,11 @@ enum libinput_config_accel_type {
         * type is always supported.
         */
        LIBINPUT_ACCEL_TYPE_MOTION,
+       /**
+        * Acceleration type for scroll movement.
+        * This type is supported by mouse and touchpad.
+        */
+       LIBINPUT_ACCEL_TYPE_SCROLL,
 };
 
 /**
index f8eb1eff2367641d8381f68bf3e581714e8091ce..945e490b1ee4afd34748b8e8ec9abc3eb523a8b6 100644 (file)
@@ -2283,22 +2283,24 @@ START_TEST(pointer_accel_config)
        enum libinput_config_accel_profile profile;
        enum libinput_config_status valid = LIBINPUT_CONFIG_STATUS_SUCCESS,
                                    invalid = LIBINPUT_CONFIG_STATUS_INVALID;
-       enum libinput_config_accel_type fallback = LIBINPUT_ACCEL_TYPE_FALLBACK,
-                                       motion = LIBINPUT_ACCEL_TYPE_MOTION;
+       enum libinput_config_accel_type accel_types[] = {
+               LIBINPUT_ACCEL_TYPE_FALLBACK,
+               LIBINPUT_ACCEL_TYPE_MOTION,
+               LIBINPUT_ACCEL_TYPE_SCROLL,
+       };
        struct custom_config_test {
-               enum libinput_config_accel_type accel_type;
                double step;
                double points[4];
                enum libinput_config_status expected_status;
        } tests[] = {
-               { fallback,  0.5, { 1.0, 2.0, 2.5, 2.6 },  valid },
-               { motion,  0.003, { 0.1, 0.3, 0.4, 0.45 }, valid },
-               { fallback,  2.7, { 1.0, 3.0, 4.5, 4.5 },  valid },
-               { motion,      0, { 1.0, 2.0, 2.5, 2.6 },  invalid },
-               { fallback,   -1, { 1.0, 2.0, 2.5, 2.6 },  invalid },
-               { motion,   1e10, { 1.0, 2.0, 2.5, 2.6 },  invalid },
-               { fallback,    1, { 1.0, 2.0, -2.5, 2.6 }, invalid },
-               { motion,      1, { 1.0, 2.0, 1e10, 2.6 }, invalid },
+               { 0.5,   { 1.0, 2.0, 2.5, 2.6 },  valid },
+               { 0.003, { 0.1, 0.3, 0.4, 0.45 }, valid },
+               { 2.7,   { 1.0, 3.0, 4.5, 4.5 },  valid },
+               { 0,     { 1.0, 2.0, 2.5, 2.6 },  invalid },
+               { -1,    { 1.0, 2.0, 2.5, 2.6 },  invalid },
+               { 1e10,  { 1.0, 2.0, 2.5, 2.6 },  invalid },
+               { 1,     { 1.0, 2.0, -2.5, 2.6 }, invalid },
+               { 1,     { 1.0, 2.0, 1e10, 2.6 }, invalid },
        };
 
        ck_assert(libinput_device_config_accel_is_available(device));
@@ -2312,22 +2314,24 @@ START_TEST(pointer_accel_config)
        ck_assert_ptr_nonnull(config_custom_changed);
 
        ARRAY_FOR_EACH(tests, t) {
-               status = libinput_config_accel_set_points(config_custom_changed,
-                                                         t->accel_type,
-                                                         t->step,
-                                                         ARRAY_LENGTH(t->points),
-                                                         t->points);
-               ck_assert_int_eq(status, t->expected_status);
-
-               status = libinput_device_config_accel_apply(device, config_custom_changed);
-               ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
-               profile = libinput_device_config_accel_get_profile(device);
-               ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM);
-
-               status = libinput_device_config_accel_apply(device, config_custom_default);
-               ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
-               profile = libinput_device_config_accel_get_profile(device);
-               ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM);
+               ARRAY_FOR_EACH(accel_types, accel_type) {
+                       status = libinput_config_accel_set_points(config_custom_changed,
+                                                                 *accel_type,
+                                                                 t->step,
+                                                                 ARRAY_LENGTH(t->points),
+                                                                 t->points);
+                       ck_assert_int_eq(status, t->expected_status);
+
+                       status = libinput_device_config_accel_apply(device, config_custom_changed);
+                       ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+                       profile = libinput_device_config_accel_get_profile(device);
+                       ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM);
+
+                       status = libinput_device_config_accel_apply(device, config_custom_default);
+                       ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+                       profile = libinput_device_config_accel_get_profile(device);
+                       ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM);
+               }
        }
 
        libinput_config_accel_destroy(config_custom_default);
index 628d87162c8ec01ead1c7980b93fe938dfea71f6..849765d1cca48a18299cec1de6cc62c29c56045a 100644 (file)
@@ -112,7 +112,7 @@ Sets the distance along the x-axis between each point, starting from 0.
 Defaults to 1.0.
 This only applies to the custom profile.
 .TP 8
-.B \-\-set\-custom\-type=[fallback|motion]
+.B \-\-set\-custom\-type=[fallback|motion|scroll]
 Sets the type of the custom acceleration function.
 Defaults to fallback.
 This only applies to the custom profile.
index ee80eb93e9db41e0b1145ee2759eb5772b116b26..7a7302789599907998fd976aa748dc34dd357ec3 100644 (file)
@@ -307,9 +307,11 @@ tools_parse_option(int option,
                        options->custom_type = LIBINPUT_ACCEL_TYPE_FALLBACK;
                else if (streq(optarg, "motion"))
                        options->custom_type = LIBINPUT_ACCEL_TYPE_MOTION;
+               else if (streq(optarg, "scroll"))
+                       options->custom_type = LIBINPUT_ACCEL_TYPE_SCROLL;
                else {
                        fprintf(stderr, "Invalid --set-custom-type\n"
-                                       "Valid custom types: fallback|motion\n");
+                                       "Valid custom types: fallback|motion|scroll\n");
                        return 1;
                }
                break;