[PATCH libinput 1/2] evdev: Query mouse DPI from udev

Derek Foreman derekf at osg.samsung.com
Mon Nov 24 13:53:36 PST 2014


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 <derekf at 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



More information about the wayland-devel mailing list