On Mon, Jan 12, 2015 at 09:12:36AM +1000, Peter Hutterer wrote: > Signed-off-by: Peter Hutterer <[email protected]>
Reviewed-by: Jonas Ådahl <[email protected]> > --- > doc/device-configuration-via-udev.dox | 4 ++++ > src/evdev.c | 29 +++++++++++++++++++++++++++-- > src/evdev.h | 3 +++ > src/libinput-util.c | 30 ++++++++++++++++++++++++++++++ > src/libinput-util.h | 1 + > test/misc.c | 34 ++++++++++++++++++++++++++++++++-- > 6 files changed, 97 insertions(+), 4 deletions(-) > > diff --git a/doc/device-configuration-via-udev.dox > b/doc/device-configuration-via-udev.dox > index b854035..bee3659 100644 > --- a/doc/device-configuration-via-udev.dox > +++ b/doc/device-configuration-via-udev.dox > @@ -23,6 +23,10 @@ context. Defaults to "default".</dd> > <dd>HW resolution and sampling frequency of a relative pointer device. > See @ref motion_normalization for details. > </dd> > +<dt>MOUSE_WHEEL_CLICK_ANGLE</dt> > +<dd>The angle in degrees for each click on a mouse wheel. See > +libinput_pointer_get_axis_source() for details. > +</dd> > </dl> > > 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 4fb37d6..f35ee34 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_AXIS_STEP_DISTANCE); > + -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_AXIS_STEP_DISTANCE); > + e->value * device->scroll.wheel_click_angle); > break; > } > } > @@ -1240,6 +1240,29 @@ evdev_tag_device(struct evdev_device *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_AXIS_STEP_DISTANCE; > + > + 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_AXIS_STEP_DISTANCE); > + angle = DEFAULT_AXIS_STEP_DISTANCE; > + } > + } > + > + return angle; > +} > +static inline int > evdev_read_dpi_prop(struct evdev_device *device) > { > struct libinput *libinput = device->base.seat->libinput; > @@ -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 a75dd13..2171c5a 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 c16de1b..49e297a 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=<integer> > + * 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 6825841..dc70bcd 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 c7d9ddf..779b600 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); > } > -- > 2.1.0 > > _______________________________________________ > wayland-devel mailing list > [email protected] > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
