Instead of using a hard coded mouse DPI value, we query it from udev. If it's not present or the property is obviously broken we fall back to default.
Signed-off-by: Derek Foreman <der...@osg.samsung.com> --- src/evdev.c | 18 ++++++++++++++++++ src/libinput-util.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/libinput-util.h | 2 ++ 3 files changed, 61 insertions(+) diff --git a/src/evdev.c b/src/evdev.c index 36c6859..a2547c7 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -1218,8 +1218,11 @@ evdev_need_mtdev(struct evdev_device *device) static void evdev_tag_device(struct evdev_device *device) { + struct libinput *libinput = device->base.seat->libinput; + const char *mouse_dpi; struct udev *udev; struct udev_device *udev_device = NULL; + int dpi; udev = udev_new(); if (!udev) @@ -1229,6 +1232,21 @@ evdev_tag_device(struct evdev_device *device) if (udev_device) { if (device->dispatch->interface->tag_device) device->dispatch->interface->tag_device(device, udev_device); + mouse_dpi = udev_device_get_property_value(udev_device, "MOUSE_DPI"); + if (mouse_dpi) { + dpi = udev_parse_mouse_dpi_property(mouse_dpi); + if (dpi) + device->dpi = dpi; + else { + log_error(libinput, "Mouse DPI property for" + " '%s' is present but " + "invalid, using %d DPI " + "instead\n", + device->devname, + DEFAULT_MOUSE_DPI); + device->dpi = DEFAULT_MOUSE_DPI; + } + } udev_device_unref(udev_device); } udev_unref(udev); diff --git a/src/libinput-util.c b/src/libinput-util.c index 34d5549..5600424 100644 --- a/src/libinput-util.c +++ b/src/libinput-util.c @@ -28,7 +28,9 @@ #include "config.h" +#include <ctype.h> #include <stdarg.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -113,3 +115,42 @@ ratelimit_test(struct ratelimit *r) return RATELIMIT_EXCEEDED; } + +int +udev_parse_mouse_dpi_property(const char *prop) +{ + bool is_default = false; + int rd, dpi; + + /* When parsing the mouse DPI property, if we find an error we + * just return 0 since it's obviously invalid, the caller will + * treat that as an error and use a reasonable default instead. + * If the property contains multiple DPI settings but none flagged + * as default, we return the last because we're lazy and that's + * a silly way to set the property anyway. + */ + while (*prop != 0) { + if (*prop == ' ') { + prop++; + continue; + } + if (*prop == '*') { + prop++; + is_default = true; + if (!isdigit(prop[0])) + return 0; + } + + rd = 0; + sscanf(prop, "%d@%*d%n", &dpi, &rd); + if (!rd) + sscanf(prop, "%d%n", &dpi, &rd); + if (!rd || dpi == 0 || prop[rd] == '@') + return 0; + + if (is_default) + break; + prop += rd; + } + return dpi; +} diff --git a/src/libinput-util.h b/src/libinput-util.h index 909c9db..62d7ac1 100644 --- a/src/libinput-util.h +++ b/src/libinput-util.h @@ -296,4 +296,6 @@ struct ratelimit { void ratelimit_init(struct ratelimit *r, uint64_t ival_ms, unsigned int burst); enum ratelimit_state ratelimit_test(struct ratelimit *r); +int udev_parse_mouse_dpi_property(const char *prop); + #endif /* LIBINPUT_UTIL_H */ -- 2.1.3 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel