<dd>The angle in degrees for each click on a mouse wheel. See
libinput_pointer_get_axis_source() for details.
</dd>
+<dt>POINTINGSTICK_CONST_ACCEL</dt>
+<dd>A constant (linear) acceleration factor to apply to pointingstick deltas
+to normalize them.
+</dd>
</dl>
Below is an example udev rule to assign "seat1" to a device from vendor
return angle;
}
+
+static inline int
+evdev_get_trackpoint_dpi(struct evdev_device *device)
+{
+ struct libinput *libinput = device->base.seat->libinput;
+ const char *trackpoint_accel;
+ double accel = DEFAULT_TRACKPOINT_ACCEL;
+
+ trackpoint_accel = udev_device_get_property_value(
+ device->udev_device, "POINTINGSTICK_CONST_ACCEL");
+ if (trackpoint_accel) {
+ accel = parse_trackpoint_accel_property(trackpoint_accel);
+ if (accel == 0.0) {
+ log_error(libinput, "Trackpoint accel property for "
+ "'%s' is present but invalid, "
+ "using %.2f instead\n",
+ device->devname,
+ DEFAULT_TRACKPOINT_ACCEL);
+ accel = DEFAULT_TRACKPOINT_ACCEL;
+ }
+ }
+
+ return DEFAULT_MOUSE_DPI / accel;
+}
+
static inline int
evdev_read_dpi_prop(struct evdev_device *device)
{
const char *mouse_dpi;
int dpi = DEFAULT_MOUSE_DPI;
+ /*
+ * Trackpoints do not have dpi, instead hwdb may contain a
+ * POINTINGSTICK_CONST_ACCEL value to compensate for sensitivity
+ * differences between models, we translate this to a fake dpi.
+ */
+ if (libevdev_has_property(device->evdev, INPUT_PROP_POINTING_STICK))
+ return evdev_get_trackpoint_dpi(device);
+
mouse_dpi = udev_device_get_property_value(device->udev_device,
"MOUSE_DPI");
if (mouse_dpi) {
/* The HW DPI rate we normalize to before calculating pointer acceleration */
#define DEFAULT_MOUSE_DPI 1000
+
+/*
+ * The constant (linear) acceleration factor we use to normalize trackpoint
+ * deltas before calculating pointer acceleration.
+ */
+#define DEFAULT_TRACKPOINT_ACCEL 1.0
+
/* The fake resolution value for abs devices without resolution */
#define EVDEV_FAKE_RESOLUTION 1
#include "config.h"
#include <ctype.h>
+#include <locale.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
return angle;
}
+
+/**
+ * Helper function to parse the TRACKPOINT_CONST_ACCEL property from udev.
+ * Property is of the form:
+ * TRACKPOINT_CONST_ACCEL=<float>
+ *
+ * @param prop The value of the udev property (without the TRACKPOINT_CONST_ACCEL=)
+ * @return The acceleration, or 0.0 on error.
+ */
+double
+parse_trackpoint_accel_property(const char *prop)
+{
+ locale_t c_locale;
+ double accel;
+ char *endp;
+
+ /* Create a "C" locale to force strtod to use '.' as separator */
+ c_locale = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0);
+ if (c_locale == (locale_t)0)
+ return 0.0;
+
+ accel = strtod_l(prop, &endp, c_locale);
+
+ freelocale(c_locale);
+
+ if (*endp != '\0')
+ return 0.0;
+
+ return accel;
+}
int parse_mouse_dpi_property(const char *prop);
int parse_mouse_wheel_click_angle_property(const char *prop);
+double parse_trackpoint_accel_property(const char *prop);
#endif /* LIBINPUT_UTIL_H */
}
END_TEST
+struct parser_test_float {
+ char *tag;
+ double expected_value;
+};
+
+START_TEST(trackpoint_accel_parser)
+{
+ struct parser_test_float tests[] = {
+ { "0.5", 0.5 },
+ { "1.0", 1.0 },
+ { "2.0", 2.0 },
+ { "fail1.0", 0.0 },
+ { "1.0fail", 0.0 },
+ { "0,5", 0.0 },
+ { NULL, 0.0 }
+ };
+ int i;
+ double accel;
+
+ for (i = 0; tests[i].tag != NULL; i++) {
+ accel = parse_trackpoint_accel_property(tests[i].tag);
+ ck_assert(accel == tests[i].expected_value);
+ }
+}
+END_TEST
+
int main (int argc, char **argv) {
litest_add_no_device("events:conversion", event_conversion_device_notify);
litest_add_for_device("events:conversion", event_conversion_pointer, LITEST_MOUSE);
litest_add_no_device("misc:ratelimit", ratelimit_helpers);
litest_add_no_device("misc:dpi parser", dpi_parser);
litest_add_no_device("misc:wheel click parser", wheel_click_parser);
+ litest_add_no_device("misc:trackpoint accel parser", trackpoint_accel_parser);
return litest_run(argc, argv);
}