From: Peter Hutterer Date: Sun, 11 Jan 2015 22:39:47 +0000 (+1000) Subject: Parse the MOUSE_WHEEL_CLICK_ANGLE udev property if present X-Git-Tag: 0.8.0~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c35885e87dabdcba016cbfa124c384dd440411f1;p=platform%2Fupstream%2Flibinput.git Parse the MOUSE_WHEEL_CLICK_ANGLE udev property if present Signed-off-by: Peter Hutterer Reviewed-by: Jonas Ã…dahl --- diff --git a/doc/device-configuration-via-udev.dox b/doc/device-configuration-via-udev.dox index b8540351..bee36598 100644 --- a/doc/device-configuration-via-udev.dox +++ b/doc/device-configuration-via-udev.dox @@ -23,6 +23,10 @@ context. Defaults to "default".
HW resolution and sampling frequency of a relative pointer device. See @ref motion_normalization for details.
+
MOUSE_WHEEL_CLICK_ANGLE
+
The angle in degrees for each click on a mouse wheel. See +libinput_pointer_get_axis_source() for details. +
Below is an example udev rule to assign "seat1" to a device from vendor diff --git a/src/evdev.c b/src/evdev.c index d8b61299..d80594df 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -577,7 +577,7 @@ evdev_process_relative(struct evdev_device *device, time, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, - -1 * e->value * DEFAULT_WHEEL_CLICK_ANGLE); + -1 * e->value * device->scroll.wheel_click_angle); break; case REL_HWHEEL: evdev_flush_pending_event(device, time); @@ -586,7 +586,7 @@ evdev_process_relative(struct evdev_device *device, time, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, - e->value * DEFAULT_WHEEL_CLICK_ANGLE); + e->value * device->scroll.wheel_click_angle); break; } } @@ -1239,6 +1239,29 @@ evdev_tag_device(struct evdev_device *device) device->udev_device); } +static inline int +evdev_read_wheel_click_prop(struct evdev_device *device) +{ + struct libinput *libinput = device->base.seat->libinput; + const char *prop; + int angle = DEFAULT_WHEEL_CLICK_ANGLE; + + prop = udev_device_get_property_value(device->udev_device, + "MOUSE_WHEEL_CLICK_ANGLE"); + if (prop) { + angle = parse_mouse_wheel_click_angle_property(prop); + if (!angle) { + log_error(libinput, + "Mouse wheel click angle '%s' is present but invalid," + "using %d degrees instead\n", + device->devname, + DEFAULT_WHEEL_CLICK_ANGLE); + angle = DEFAULT_WHEEL_CLICK_ANGLE; + } + } + + return angle; +} static inline int evdev_read_dpi_prop(struct evdev_device *device) { @@ -1568,6 +1591,8 @@ evdev_device_create(struct libinput_seat *seat, device->devname = libevdev_get_name(device->evdev); device->scroll.threshold = 5.0; /* Default may be overridden */ device->scroll.direction = 0; + device->scroll.wheel_click_angle = + evdev_read_wheel_click_prop(device); device->dpi = evdev_read_dpi_prop(device); /* at most 5 SYN_DROPPED log-messages per 30s */ ratelimit_init(&device->syn_drop_limit, 30ULL * 1000, 5); diff --git a/src/evdev.h b/src/evdev.h index a75dd134..2171c5ad 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -119,6 +119,9 @@ struct evdev_device { /* set during device init if we want natural scrolling, * used at runtime to enable/disable the feature */ bool natural_scrolling_enabled; + + /* angle per REL_WHEEL click in degrees */ + int wheel_click_angle; } scroll; enum evdev_event_type pending_event; diff --git a/src/libinput-util.c b/src/libinput-util.c index c16de1bf..49e297af 100644 --- a/src/libinput-util.c +++ b/src/libinput-util.c @@ -171,3 +171,33 @@ parse_mouse_dpi_property(const char *prop) } return dpi; } + +/** + * Helper function to parse the MOUSE_WHEEL_CLICK_ANGLE property from udev. + * Property is of the form: + * MOUSE_WHEEL_CLICK_ANGLE= + * Where the number indicates the degrees travelled for each click. + * + * We skip preceding whitespaces and parse the first number seen. If + * multiple numbers are specified, we ignore those. + * + * @param prop The value of the udev property (without the MOUSE_WHEEL_CLICK_ANGLE=) + * @return The angle of the wheel (may be negative) or 0 on error. + */ +int +parse_mouse_wheel_click_angle_property(const char *prop) +{ + int angle = 0, + nread = 0; + + while(*prop != 0 && *prop == ' ') + prop++; + + sscanf(prop, "%d%n", &angle, &nread); + if (nread == 0 || angle == 0 || abs(angle) > 360) + return 0; + if (prop[nread] != ' ' && prop[nread] != '\0') + return 0; + + return angle; +} diff --git a/src/libinput-util.h b/src/libinput-util.h index 68258414..dc70bcd2 100644 --- a/src/libinput-util.h +++ b/src/libinput-util.h @@ -297,5 +297,6 @@ void ratelimit_init(struct ratelimit *r, uint64_t ival_ms, unsigned int burst); enum ratelimit_state ratelimit_test(struct ratelimit *r); int parse_mouse_dpi_property(const char *prop); +int parse_mouse_wheel_click_angle_property(const char *prop); #endif /* LIBINPUT_UTIL_H */ diff --git a/test/misc.c b/test/misc.c index c7d9ddf5..779b600f 100644 --- a/test/misc.c +++ b/test/misc.c @@ -531,7 +531,7 @@ END_TEST struct parser_test { char *tag; - int expected_dpi; + int expected_value; }; START_TEST(dpi_parser) @@ -565,7 +565,36 @@ START_TEST(dpi_parser) for (i = 0; tests[i].tag != NULL; i++) { dpi = parse_mouse_dpi_property(tests[i].tag); - ck_assert_int_eq(dpi, tests[i].expected_dpi); + ck_assert_int_eq(dpi, tests[i].expected_value); + } +} +END_TEST + +START_TEST(wheel_click_parser) +{ + struct parser_test tests[] = { + { "1", 1 }, + { "10", 10 }, + { "-12", -12 }, + { "360", 360 }, + { "66 ", 66 }, + { " 100 ", 100 }, + + { "0", 0 }, + { "-0", 0 }, + { "a", 0 }, + { "10a", 0 }, + { "10-", 0 }, + { "sadfasfd", 0 }, + { "361", 0 }, + { NULL, 0 } + }; + + int i, angle; + + for (i = 0; tests[i].tag != NULL; i++) { + angle = parse_mouse_wheel_click_angle_property(tests[i].tag); + ck_assert_int_eq(angle, tests[i].expected_value); } } END_TEST @@ -582,6 +611,7 @@ int main (int argc, char **argv) { litest_add_no_device("misc:matrix", matrix_helpers); 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); return litest_run(argc, argv); }