[PATCH libinput 2/2] Parse the MOUSE_WHEEL_CLICK_ANGLE udev property if present
Jonas Ådahl
jadahl at gmail.com
Sun Jan 11 17:43:59 PST 2015
On Mon, Jan 12, 2015 at 09:12:36AM +1000, Peter Hutterer wrote:
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
Reviewed-by: Jonas Ådahl <jadahl at gmail.com>
> ---
> 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
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list