summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorYinon Burgansky <yinonburgansky@gmail.com>2022-12-13 00:23:59 +0200
committerPeter Hutterer <peter.hutterer@who-t.net>2023-01-17 01:46:17 +0000
commit5324f425a1635fb95356461c34e43d72590c9023 (patch)
tree3179a0ec9904e1d8eae11e5fa638fbadeea0d6e4 /test
parentee3330491d368096a36043661466e6a911af3576 (diff)
downloadlibinput-5324f425a1635fb95356461c34e43d72590c9023.tar.gz
Introduce custom acceleration profile
The custom acceleration profile allow the user to define custom acceleration functions for each movement type per device, giving full control over accelerations behavior at different speeds. This commit introduces 2 movement types which corresponds to the 2 profiles currently in use by libinput. regular filter is Motion type. constant filter is Fallback type. This allows possible expansion of new movement types for the different devices. The custom pointer acceleration profile gives the user full control over the acceleration behavior at different speeds. The user needs to provide a custom acceleration function f(x) where the x-axis is the device speed and the y-axis is the pointer speed. The user should take into account the native device dpi and screen dpi in order to achieve the desired behavior/feel of the acceleration. The custom acceleration function is defined using n points which are spaced uniformly along the x-axis, starting from 0 and continuing in constant steps. There by the points defining the custom function are: (0 * step, f[0]), (1 * step, f[1]), ..., ((n-1) * step, f[n-1]) where f is a list of n unitless values defining the acceleration factor for each velocity. When a velocity value does not lie exactly on those points, a linear interpolation of the two closest points will be calculated. When a velocity value is greater than the max point defined, a linear extrapolation of the two biggest points will be calculated. Signed-off-by: Yinon Burgansky <51504-Yinon@users.noreply.gitlab.freedesktop.org> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'test')
-rw-r--r--test/test-pointer.c91
-rw-r--r--test/test-utils.c45
2 files changed, 136 insertions, 0 deletions
diff --git a/test/test-pointer.c b/test/test-pointer.c
index ee675f39..c9f2e344 100644
--- a/test/test-pointer.c
+++ b/test/test-pointer.c
@@ -2220,6 +2220,7 @@ START_TEST(pointer_accel_profile_defaults)
profiles = libinput_device_config_accel_get_profiles(device);
ck_assert(profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
ck_assert(profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
+ ck_assert(profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM);
status = libinput_device_config_accel_set_profile(device,
LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
@@ -2235,6 +2236,90 @@ START_TEST(pointer_accel_profile_defaults)
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_ADAPTIVE);
+
+ status = libinput_device_config_accel_set_profile(device,
+ LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM);
+ 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);
+}
+END_TEST
+
+START_TEST(pointer_accel_config_reset_to_defaults)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput_device *device = dev->libinput_device;
+ double default_speed = libinput_device_config_accel_get_default_speed(device);
+
+ /* There are no settings for these profiles to toggle, so we expect it
+ * to simply reset to defaults */
+ enum libinput_config_accel_profile profiles[] = {
+ LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
+ LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
+ };
+
+ ARRAY_FOR_EACH(profiles, profile) {
+ ck_assert_int_eq(libinput_device_config_accel_set_speed(device, 1.0),
+ LIBINPUT_CONFIG_STATUS_SUCCESS);
+
+ ck_assert_double_eq(libinput_device_config_accel_get_speed(device), 1.0);
+
+ struct libinput_config_accel *config =
+ libinput_config_accel_create(LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
+ ck_assert_int_eq(libinput_device_config_accel_apply(device, config),
+ LIBINPUT_CONFIG_STATUS_SUCCESS);
+ ck_assert_double_eq(libinput_device_config_accel_get_speed(device),
+ default_speed);
+ libinput_config_accel_destroy(config);
+ }
+}
+END_TEST
+
+START_TEST(pointer_accel_config)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput_device *device = dev->libinput_device;
+ enum libinput_config_status status;
+ enum libinput_config_accel_profile profile;
+ double custom_speed[] = {0.1234, -0.567, 0.89};
+ double custom_step[] = {0.5, 0.003, 2.7};
+ double custom_npoints = 4;
+ double custom_points[3][4] = {{1.0, 2.0, 2.5, 2.6},
+ {0.1, 0.3, 0.4, 0.45},
+ {1.0, 3.0, 4.5, 4.5}};
+
+ ck_assert(libinput_device_config_accel_is_available(device));
+
+ struct libinput_config_accel *config_custom_default =
+ libinput_config_accel_create(LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM);
+ struct libinput_config_accel *config_custom_changed =
+ libinput_config_accel_create(LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM);
+
+ ck_assert_ptr_nonnull(config_custom_default);
+ ck_assert_ptr_nonnull(config_custom_changed);
+
+
+ for (size_t idx = 0; idx < ARRAY_LENGTH(custom_speed); idx++) {
+ status = libinput_config_accel_set_points(config_custom_changed,
+ LIBINPUT_ACCEL_TYPE_FALLBACK,
+ custom_step[idx],
+ custom_npoints,
+ custom_points[idx]);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+
+ 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);
+ libinput_config_accel_destroy(config_custom_changed);
}
END_TEST
@@ -2257,6 +2342,10 @@ START_TEST(pointer_accel_profile_invalid)
status = libinput_device_config_accel_set_profile(device,
LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE |LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
+
+ status = libinput_device_config_accel_set_profile(device,
+ LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM |LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
}
END_TEST
@@ -3633,6 +3722,8 @@ TEST_COLLECTION(pointer)
litest_add(pointer_accel_direction_change, LITEST_RELATIVE, LITEST_POINTINGSTICK);
litest_add(pointer_accel_profile_defaults, LITEST_RELATIVE, LITEST_TOUCHPAD);
litest_add(pointer_accel_profile_defaults, LITEST_TOUCHPAD, LITEST_ANY);
+ litest_add(pointer_accel_config_reset_to_defaults, LITEST_RELATIVE, LITEST_ANY);
+ litest_add(pointer_accel_config, LITEST_RELATIVE, LITEST_ANY);
litest_add(pointer_accel_profile_invalid, LITEST_RELATIVE, LITEST_ANY);
litest_add(pointer_accel_profile_noaccel, LITEST_ANY, LITEST_TOUCHPAD|LITEST_RELATIVE|LITEST_TABLET);
litest_add(pointer_accel_profile_flat_motion_relative, LITEST_RELATIVE, LITEST_TOUCHPAD);
diff --git a/test/test-utils.c b/test/test-utils.c
index a5248147..fa307031 100644
--- a/test/test-utils.c
+++ b/test/test-utils.c
@@ -1119,6 +1119,50 @@ START_TEST(strsplit_test)
}
END_TEST
+START_TEST(double_array_from_string_test)
+{
+ struct double_array_from_string_test {
+ const char *string;
+ const char *delim;
+ const double array[10];
+ const size_t len;
+ const bool result;
+ } tests[] = {
+ { "1 2 3", " ", { 1, 2, 3 }, 3 },
+ { "1", " ", { 1 }, 1 },
+ { "1,2.5,", ",", { 1, 2.5 }, 2 },
+ { "1.0 2", " ", { 1, 2.0 }, 2 },
+ { " 1 2", " ", { 1, 2 }, 2 },
+ { " ; 1;2 3.5 ;;4.1", "; ", { 1, 2, 3.5, 4.1 }, 4 },
+ /* special cases */
+ { "1 two", " ", { 0 }, 0 },
+ { "one two", " ", { 0 }, 0 },
+ { "one 2", " ", { 0 }, 0 },
+ { "", " ", { 0 }, 0 },
+ { " ", " ", { 0 }, 0 },
+ { " ", " ", { 0 }, 0 },
+ { "", " ", { 0 }, 0 },
+ { "oneoneone", "one", { 0 }, 0 },
+ { NULL, NULL, { 0 }, 0 }
+ };
+ struct double_array_from_string_test *t = tests;
+
+ while (t->string) {
+ size_t len;
+ double *array = double_array_from_string(t->string,
+ t->delim,
+ &len);
+ ck_assert_int_eq(len, t->len);
+
+ for (size_t idx = 0; idx < len; idx++)
+ ck_assert_double_eq(array[idx], t->array[idx]);
+
+ free(array);
+ t++;
+ }
+}
+END_TEST
+
START_TEST(strargv_test)
{
struct argv_test {
@@ -1571,6 +1615,7 @@ litest_utils_suite(void)
tcase_add_test(tc, safe_atou_base_8_test);
tcase_add_test(tc, safe_atod_test);
tcase_add_test(tc, strsplit_test);
+ tcase_add_test(tc, double_array_from_string_test);
tcase_add_test(tc, strargv_test);
tcase_add_test(tc, kvsplit_double_test);
tcase_add_test(tc, strjoin_test);