provide an overview for developers and is not necessarily useful for
users.
+@section ptraccel-profiles Pointer acceleration profiles
+
+The profile decides the general method of pointer acceleration.
+libinput currently supports two profiles: "adaptive" and "flat". The aptive
+profile is the default profile for all devices and takes the current speed
+of the device into account when deciding on acceleration. The flat profile
+is simply a constant factor applied to all device deltas, regardless of the
+speed of motion (see @ref ptraccel-profile-flat). Most of this document
+describes the adaptive pointer acceleration.
+
@section ptraccel-velocity Velocity calculation
The device's speed of movement is measured across multiple input events
@ref ptraccel-linear. The constant acceleration factor, usually applied by
udev, shapes the acceleration profile.
+@section ptraccel-profile-flat The flat pointer acceleration profile
+
+In a flat profile, the acceleration factor is constant regardless of the
+velocity of the pointer and each delta (dx, dy) results in an accelerated delta
+(dx * factor, dy * factor). This provides 1:1 movement between the device
+and the pointer on-screen.
+
*/
return 0;
}
+static uint32_t
+tp_accel_config_get_profiles(struct libinput_device *libinput_device)
+{
+ return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
+}
+
+static enum libinput_config_status
+tp_accel_config_set_profile(struct libinput_device *libinput_device,
+ enum libinput_config_accel_profile profile)
+{
+ return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
+}
+
+static enum libinput_config_accel_profile
+tp_accel_config_get_profile(struct libinput_device *libinput_device)
+{
+ return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
+}
+
+static enum libinput_config_accel_profile
+tp_accel_config_get_default_profile(struct libinput_device *libinput_device)
+{
+ return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
+}
+
static int
tp_init_accel(struct tp_dispatch *tp, double diagonal)
{
+ struct evdev_device *device = tp->device;
int res_x, res_y;
struct motion_filter *filter;
+ int rc;
res_x = tp->device->abs.absinfo_x->resolution;
res_y = tp->device->abs.absinfo_y->resolution;
if (!filter)
return -1;
- return evdev_device_init_pointer_acceleration(tp->device, filter);
+ rc = evdev_device_init_pointer_acceleration(tp->device, filter);
+ if (rc != 0)
+ return rc;
+
+ /* we override the profile hooks for accel configuration with hooks
+ * that don't allow selection of profiles */
+ device->pointer.config.get_profiles = tp_accel_config_get_profiles;
+ device->pointer.config.set_profile = tp_accel_config_set_profile;
+ device->pointer.config.get_profile = tp_accel_config_get_profile;
+ device->pointer.config.get_default_profile = tp_accel_config_get_default_profile;
+
+ return 0;
}
static uint32_t
}
}
+static inline int
+evdev_init_accel(struct evdev_device *device,
+ enum libinput_config_accel_profile which)
+{
+ struct motion_filter *filter;
+
+ if (which == LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT)
+ filter = create_pointer_accelerator_filter_flat(device->dpi);
+ else 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);
+
+ if (!filter)
+ return -1;
+
+ return evdev_device_init_pointer_acceleration(device, filter);
+}
+
static int
evdev_accel_config_available(struct libinput_device *device)
{
return 0.0;
}
+static uint32_t
+evdev_accel_config_get_profiles(struct libinput_device *libinput_device)
+{
+ struct evdev_device *device = (struct evdev_device*)libinput_device;
+
+ if (!device->pointer.filter)
+ return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
+
+ return LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE |
+ LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT;
+}
+
+static enum libinput_config_status
+evdev_accel_config_set_profile(struct libinput_device *libinput_device,
+ enum libinput_config_accel_profile profile)
+{
+ struct evdev_device *device = (struct evdev_device*)libinput_device;
+ struct motion_filter *filter;
+ double speed;
+
+ filter = device->pointer.filter;
+ if (filter_get_type(filter) == profile)
+ return LIBINPUT_CONFIG_STATUS_SUCCESS;
+
+ speed = filter_get_speed(filter);
+ device->pointer.filter = NULL;
+
+ if (evdev_init_accel(device, profile) == 0) {
+ evdev_accel_config_set_speed(libinput_device, speed);
+ filter_destroy(filter);
+ } else {
+ device->pointer.filter = filter;
+ }
+
+ return LIBINPUT_CONFIG_STATUS_SUCCESS;
+}
+
+static enum libinput_config_accel_profile
+evdev_accel_config_get_profile(struct libinput_device *libinput_device)
+{
+ struct evdev_device *device = (struct evdev_device*)libinput_device;
+
+ return filter_get_type(device->pointer.filter);
+}
+
+static enum libinput_config_accel_profile
+evdev_accel_config_get_default_profile(struct libinput_device *libinput_device)
+{
+ struct evdev_device *device = (struct evdev_device*)libinput_device;
+
+ if (!device->pointer.filter)
+ return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
+
+ /* No device has a flat profile as default */
+ return LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
+}
+
int
evdev_device_init_pointer_acceleration(struct evdev_device *device,
struct motion_filter *filter)
{
device->pointer.filter = filter;
- device->pointer.config.available = evdev_accel_config_available;
- device->pointer.config.set_speed = evdev_accel_config_set_speed;
- device->pointer.config.get_speed = evdev_accel_config_get_speed;
- device->pointer.config.get_default_speed = evdev_accel_config_get_default_speed;
- device->base.config.accel = &device->pointer.config;
+ if (device->base.config.accel == NULL) {
+ device->pointer.config.available = evdev_accel_config_available;
+ device->pointer.config.set_speed = evdev_accel_config_set_speed;
+ device->pointer.config.get_speed = evdev_accel_config_get_speed;
+ device->pointer.config.get_default_speed = evdev_accel_config_get_default_speed;
+ device->pointer.config.get_profiles = evdev_accel_config_get_profiles;
+ device->pointer.config.set_profile = evdev_accel_config_set_profile;
+ device->pointer.config.get_profile = evdev_accel_config_get_profile;
+ device->pointer.config.get_default_profile = evdev_accel_config_get_default_profile;
+ device->base.config.accel = &device->pointer.config;
- evdev_accel_config_set_speed(&device->base,
- evdev_accel_config_get_default_speed(&device->base));
+ evdev_accel_config_set_speed(&device->base,
+ evdev_accel_config_get_default_speed(&device->base));
+ }
return 0;
}
return 0;
}
-static inline int
-evdev_init_accel(struct evdev_device *device)
-{
- struct motion_filter *filter;
-
- 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);
-
- if (!filter)
- return -1;
-
- return evdev_device_init_pointer_acceleration(device, filter);
-}
-
static int
evdev_configure_device(struct evdev_device *device)
{
if (libevdev_has_event_code(evdev, EV_REL, REL_X) &&
libevdev_has_event_code(evdev, EV_REL, REL_Y) &&
- evdev_init_accel(device) == -1)
+ evdev_init_accel(device, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE) == -1)
return -1;
device->seat_caps |= EVDEV_DEVICE_POINTER;
#include "filter.h"
struct motion_filter_interface {
+ enum libinput_config_accel_profile type;
struct normalized_coords (*filter)(
struct motion_filter *filter,
const struct normalized_coords *unaccelerated,
filter_restart(struct motion_filter *filter,
void *data, uint64_t time)
{
- filter->interface->restart(filter, data, time);
+ if (filter->interface->restart)
+ filter->interface->restart(filter, data, time);
}
void
filter_destroy(struct motion_filter *filter)
{
- if (!filter)
+ if (!filter || !filter->interface->destroy)
return;
filter->interface->destroy(filter);
return filter->speed_adjustment;
}
+enum libinput_config_accel_profile
+filter_get_type(struct motion_filter *filter)
+{
+ return filter->interface->type;
+}
+
/*
* Default parameters for pointer acceleration profiles.
*/
double dpi_factor;
};
+struct pointer_accelerator_flat {
+ struct motion_filter base;
+
+ double factor;
+ double dpi_factor;
+};
+
static void
feed_trackers(struct pointer_accelerator *accel,
const struct normalized_coords *delta,
}
struct motion_filter_interface accelerator_interface = {
+ .type = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
.filter = accelerator_filter,
.filter_constant = accelerator_filter_noop,
.restart = accelerator_restart,
}
struct motion_filter_interface accelerator_interface_low_dpi = {
+ .type = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
.filter = accelerator_filter_low_dpi,
.filter_constant = accelerator_filter_noop,
.restart = accelerator_restart,
}
struct motion_filter_interface accelerator_interface_touchpad = {
+ .type = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
.filter = accelerator_filter,
.filter_constant = touchpad_constant_filter,
.restart = accelerator_restart,
}
struct motion_filter_interface accelerator_interface_x230 = {
+ .type = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
.filter = accelerator_filter_x230,
.filter_constant = accelerator_filter_constant_x230,
.restart = accelerator_restart,
}
struct motion_filter_interface accelerator_interface_trackpoint = {
+ .type = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE,
.filter = accelerator_filter_trackpoint,
.filter_constant = accelerator_filter_noop,
.restart = accelerator_restart,
return &filter->base;
}
+
+static struct normalized_coords
+accelerator_filter_flat(struct motion_filter *filter,
+ const struct normalized_coords *unaccelerated,
+ void *data, uint64_t time)
+{
+ struct pointer_accelerator_flat *accel_filter =
+ (struct pointer_accelerator_flat *)filter;
+ double factor; /* unitless factor */
+ struct normalized_coords accelerated;
+ struct normalized_coords unnormalized;
+
+ /* You want flat acceleration, you get flat acceleration for the
+ * device */
+ unnormalized.x = unaccelerated->x * accel_filter->dpi_factor;
+ unnormalized.y = unaccelerated->y * accel_filter->dpi_factor;
+ factor = accel_filter->factor;
+
+ accelerated.x = factor * unnormalized.x;
+ accelerated.y = factor * unnormalized.y;
+
+ return accelerated;
+}
+
+static bool
+accelerator_set_speed_flat(struct motion_filter *filter,
+ double speed_adjustment)
+{
+ struct pointer_accelerator_flat *accel_filter =
+ (struct pointer_accelerator_flat *)filter;
+
+ assert(speed_adjustment >= -1.0 && speed_adjustment <= 1.0);
+
+ /* Speed rage is 0-200% of the nominal speed, with 0 mapping to the
+ * nominal speed. Anything above 200 is pointless, we're already
+ * skipping over ever second pixel at 200% speed.
+ */
+
+ accel_filter->factor = 1 + speed_adjustment;
+ filter->speed_adjustment = speed_adjustment;
+
+ return true;
+}
+
+static void
+accelerator_destroy_flat(struct motion_filter *filter)
+{
+ struct pointer_accelerator_flat *accel =
+ (struct pointer_accelerator_flat *) filter;
+
+ free(accel);
+}
+
+struct motion_filter_interface accelerator_interface_flat = {
+ .type = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
+ .filter = accelerator_filter_flat,
+ .filter_constant = accelerator_filter_noop,
+ .restart = NULL,
+ .destroy = accelerator_destroy_flat,
+ .set_speed = accelerator_set_speed_flat,
+};
+
+struct motion_filter *
+create_pointer_accelerator_filter_flat(int dpi)
+{
+ struct pointer_accelerator_flat *filter;
+
+ filter = zalloc(sizeof *filter);
+ if (filter == NULL)
+ return NULL;
+
+ filter->base.interface = &accelerator_interface_flat;
+ filter->dpi_factor = dpi/(double)DEFAULT_MOUSE_DPI;
+
+ return &filter->base;
+}
double
filter_get_speed(struct motion_filter *filter);
+enum libinput_config_accel_profile
+filter_get_type(struct motion_filter *filter);
+
typedef double (*accel_profile_func_t)(struct motion_filter *filter,
void *data,
double velocity,
uint64_t time);
/* Pointer acceleration types */
+struct motion_filter *
+create_pointer_accelerator_filter_flat(int dpi);
struct motion_filter *
create_pointer_accelerator_filter_linear(int dpi);
double speed);
double (*get_speed)(struct libinput_device *device);
double (*get_default_speed)(struct libinput_device *device);
+
+ uint32_t (*get_profiles)(struct libinput_device *device);
+ enum libinput_config_status (*set_profile)(struct libinput_device *device,
+ enum libinput_config_accel_profile);
+ enum libinput_config_accel_profile (*get_profile)(struct libinput_device *device);
+ enum libinput_config_accel_profile (*get_default_profile)(struct libinput_device *device);
};
struct libinput_device_config_natural_scroll {
return device->config.accel->set_speed(device, speed);
}
-
LIBINPUT_EXPORT double
libinput_device_config_accel_get_speed(struct libinput_device *device)
{
return device->config.accel->get_default_speed(device);
}
+LIBINPUT_EXPORT uint32_t
+libinput_device_config_accel_get_profiles(struct libinput_device *device)
+{
+ if (!libinput_device_config_accel_is_available(device))
+ return 0;
+
+ return device->config.accel->get_profiles(device);
+}
+
+LIBINPUT_EXPORT enum libinput_config_accel_profile
+libinput_device_config_accel_get_profile(struct libinput_device *device)
+{
+ if (!libinput_device_config_accel_is_available(device))
+ return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
+
+ return device->config.accel->get_profile(device);
+}
+
+LIBINPUT_EXPORT enum libinput_config_accel_profile
+libinput_device_config_accel_get_default_profile(struct libinput_device *device)
+{
+ if (!libinput_device_config_accel_is_available(device))
+ return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
+
+ return device->config.accel->get_profile(device);
+}
+
+LIBINPUT_EXPORT enum libinput_config_status
+libinput_device_config_accel_set_profile(struct libinput_device *device,
+ enum libinput_config_accel_profile profile)
+{
+ switch (profile) {
+ case LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT:
+ case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE:
+ break;
+ default:
+ return LIBINPUT_CONFIG_STATUS_INVALID;
+ }
+
+ if (!libinput_device_config_accel_is_available(device) ||
+ (libinput_device_config_accel_get_profiles(device) & profile) == 0)
+ return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
+
+ return device->config.accel->set_profile(device, profile);
+}
+
LIBINPUT_EXPORT int
libinput_device_config_scroll_has_natural_scroll(struct libinput_device *device)
{
double
libinput_device_config_accel_get_default_speed(struct libinput_device *device);
+enum libinput_config_accel_profile {
+ /**
+ * Placeholder for devices that don't have a configurable pointer
+ * acceleration profile.
+ */
+ LIBINPUT_CONFIG_ACCEL_PROFILE_NONE = 0,
+ /**
+ * A flat acceleration profile. Pointer motion is accelerated by a
+ * constant (device-specific) factor, depending on the current
+ * speed.
+ *
+ * @see libinput_device_config_accel_set_speed
+ */
+ LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT = (1 << 0),
+
+ /**
+ * An adaptive acceleration profile. Pointer acceleration depends
+ * on the input speed. This is the default profile for most devices.
+ */
+ LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE = (1 << 1),
+};
+
+/**
+ * @ingroup config
+ *
+ * Returns a bitmask of the configurable acceleration modes available on
+ * this device.
+ *
+ * @param device The device to configure
+ *
+ * @return A bitmask of all configurable modes availble on this device.
+ */
+uint32_t
+libinput_device_config_accel_get_profiles(struct libinput_device *device);
+
+/**
+ * @ingroup config
+ *
+ * Set the pointer acceleration profile of this pointer device to the given
+ * mode.
+ *
+ * @param device The device to configure
+ * @param mode The mode to set the device to.
+ *
+ * @return A config status code
+ */
+enum libinput_config_status
+libinput_device_config_accel_set_profile(struct libinput_device *device,
+ enum libinput_config_accel_profile mode);
+
+/**
+ * @ingroup config
+ *
+ * Get the current pointer acceleration profile for this pointer device.
+ *
+ * @param device The device to configure
+ *
+ * @return The currently configured pointer acceleration profile.
+ */
+enum libinput_config_accel_profile
+libinput_device_config_accel_get_profile(struct libinput_device *device);
+
+/**
+ * @ingroup config
+ *
+ * Return the default pointer acceleration profile for this pointer device.
+ *
+ * @param device The device to configure
+ *
+ * @return The default acceleration profile for this device.
+ */
+enum libinput_config_accel_profile
+libinput_device_config_accel_get_default_profile(struct libinput_device *device);
+
/**
* @ingroup config
*
libinput_event_pointer_get_time_usec;
libinput_event_touch_get_time_usec;
} LIBINPUT_0.20.0;
+
+LIBINPUT_1.1 {
+ libinput_device_config_accel_get_profile;
+ libinput_device_config_accel_get_profiles;
+ libinput_device_config_accel_get_default_profile;
+ libinput_device_config_accel_set_profile;
+} LIBINPUT_0.21.0;
}
END_TEST
+START_TEST(pointer_accel_profile_defaults)
+{
+ 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;
+ uint32_t profiles;
+
+ ck_assert(libinput_device_config_accel_is_available(device));
+
+ profile = libinput_device_config_accel_get_default_profile(device);
+ ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
+
+ profile = libinput_device_config_accel_get_profile(device);
+ ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
+
+ profiles = libinput_device_config_accel_get_profiles(device);
+ ck_assert(profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
+ ck_assert(profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
+
+ status = libinput_device_config_accel_set_profile(device,
+ LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
+ 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_FLAT);
+
+ status = libinput_device_config_accel_set_profile(device,
+ LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
+ 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);
+}
+END_TEST
+
+START_TEST(pointer_accel_profile_defaults_noprofile)
+{
+ 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;
+ uint32_t profiles;
+
+ ck_assert(libinput_device_config_accel_is_available(device));
+
+ profile = libinput_device_config_accel_get_default_profile(device);
+ ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
+
+ profile = libinput_device_config_accel_get_profile(device);
+ ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
+
+ profiles = libinput_device_config_accel_get_profiles(device);
+ ck_assert_int_eq(profiles, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
+
+ status = libinput_device_config_accel_set_profile(device,
+ LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
+ profile = libinput_device_config_accel_get_profile(device);
+ ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
+
+ status = libinput_device_config_accel_set_profile(device,
+ LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
+ profile = libinput_device_config_accel_get_profile(device);
+ ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
+}
+END_TEST
+
+START_TEST(pointer_accel_profile_invalid)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput_device *device = dev->libinput_device;
+ enum libinput_config_status status;
+
+ ck_assert(libinput_device_config_accel_is_available(device));
+
+ status = libinput_device_config_accel_set_profile(device,
+ LIBINPUT_CONFIG_ACCEL_PROFILE_NONE);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
+
+ status = libinput_device_config_accel_set_profile(device,
+ LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE + 1);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_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);
+}
+END_TEST
+
+START_TEST(pointer_accel_profile_flat_motion_relative)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput_device *device = dev->libinput_device;
+
+ libinput_device_config_accel_set_profile(device,
+ LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT);
+ litest_drain_events(dev->libinput);
+
+ test_relative_event(dev, 1, 0);
+ test_relative_event(dev, 1, 1);
+ test_relative_event(dev, 1, -1);
+ test_relative_event(dev, 0, 1);
+
+ test_relative_event(dev, -1, 0);
+ test_relative_event(dev, -1, 1);
+ test_relative_event(dev, -1, -1);
+ test_relative_event(dev, 0, -1);
+}
+END_TEST
+
START_TEST(middlebutton)
{
struct litest_device *device = litest_current_device();
litest_add("pointer:accel", pointer_accel_defaults_absolute, LITEST_ABSOLUTE, LITEST_RELATIVE);
litest_add("pointer:accel", pointer_accel_defaults_absolute_relative, LITEST_ABSOLUTE|LITEST_RELATIVE, LITEST_ANY);
litest_add("pointer:accel", pointer_accel_direction_change, LITEST_RELATIVE, LITEST_ANY);
+ litest_add("pointer:accel", pointer_accel_profile_defaults, LITEST_RELATIVE, LITEST_TOUCHPAD);
+ litest_add("pointer:accel", pointer_accel_profile_defaults_noprofile, LITEST_TOUCHPAD, LITEST_ANY);
+ litest_add("pointer:accel", pointer_accel_profile_invalid, LITEST_RELATIVE, LITEST_ANY);
+ litest_add("pointer:accel", pointer_accel_profile_flat_motion_relative, LITEST_RELATIVE, LITEST_TOUCHPAD);
litest_add("pointer:middlebutton", middlebutton, LITEST_BUTTON, LITEST_ANY);
litest_add("pointer:middlebutton", middlebutton_timeout, LITEST_BUTTON, LITEST_ANY);
return str;
}
+static char*
+accel_profiles(struct libinput_device *device)
+{
+ uint32_t profiles;
+ char *str;
+ enum libinput_config_accel_profile profile;
+
+ if (!libinput_device_config_accel_is_available(device)) {
+ xasprintf(&str, "n/a");
+ return str;
+ }
+
+ profiles = libinput_device_config_accel_get_profiles(device);
+ if (profiles == LIBINPUT_CONFIG_ACCEL_PROFILE_NONE) {
+ xasprintf(&str, "none");
+ return str;
+ }
+
+ profile = libinput_device_config_accel_get_default_profile(device);
+ xasprintf(&str,
+ "%s%s%s%s",
+ (profile == LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT) ? "*" : "",
+ (profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT) ? "flat" : "",
+ (profile == LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE) ? "*" : "",
+ (profiles & LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE) ? "adaptive" : "");
+
+ return str;
+}
+
static const char *
dwt_default(struct libinput_device *device)
{
printf("Disable-w-typing: %s\n", dwt_default(dev));
+ str = accel_profiles(dev);
+ printf("Accel profiles: %s\n", str);
+ free(str);
+
printf("\n");
}
OPT_SCROLL_METHOD,
OPT_SCROLL_BUTTON,
OPT_SPEED,
+ OPT_PROFILE,
};
static void
"--set-click-method=[none|clickfinger|buttonareas] .... set the desired click method\n"
"--set-scroll-method=[none|twofinger|edge|button] ... set the desired scroll method\n"
"--set-scroll-button=BTN_MIDDLE ... set the button to the given button code\n"
+ "--set-profile=[adaptive|flat].... set pointer acceleration profile\n"
"--set-speed=<value>.... set pointer acceleration speed\n"
"\n"
"These options apply to all applicable devices, if a feature\n"
options->backend = BACKEND_UDEV;
options->seat = "seat0";
options->speed = 0.0;
+ options->profile = LIBINPUT_CONFIG_ACCEL_PROFILE_NONE;
}
int
{ "set-click-method", 1, 0, OPT_CLICK_METHOD },
{ "set-scroll-method", 1, 0, OPT_SCROLL_METHOD },
{ "set-scroll-button", 1, 0, OPT_SCROLL_BUTTON },
+ { "set-profile", 1, 0, OPT_PROFILE },
{ "speed", 1, 0, OPT_SPEED },
{ 0, 0, 0, 0}
};
}
options->speed = atof(optarg);
break;
+ case OPT_PROFILE:
+ if (!optarg) {
+ tools_usage();
+ return 1;
+ }
+ if (streq(optarg, "adaptive")) {
+ options->profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
+ } else if (streq(optarg, "flat")) {
+ options->profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT;
+ } else {
+ tools_usage();
+ return 1;
+ }
+ break;
default:
tools_usage();
return 1;
libinput_device_config_scroll_set_button(device,
options->scroll_button);
- if (libinput_device_config_accel_is_available(device))
+ if (libinput_device_config_accel_is_available(device)) {
libinput_device_config_accel_set_speed(device,
options->speed);
+ if (options->profile != LIBINPUT_CONFIG_ACCEL_PROFILE_NONE)
+ libinput_device_config_accel_set_profile(device,
+ options->profile);
+ }
}
int scroll_button;
double speed;
int dwt;
+ enum libinput_config_accel_profile profile;
};
struct tools_context {