[PATCH libinput 4/9] evdev: use LIBINPUT_ATTR_SIZE_HINT for resolutions

Peter Hutterer peter.hutterer at who-t.net
Tue Jun 30 23:08:48 PDT 2015


Touchpads, notably Elantech, ALPS and bcm5974 don't provide x/y resolution
until recent generations.
Add a new property, LIBINPUT_ATTR_SIZE_HINT, that provides size information to
libinput. Note that this property *does not* override true resolution values,
it is only used when the resolution is missing. It is used merely as an
approximate size hint.

If the resolution for a specific device is known it should be added to the
udev hwdb so it can be set globally. See the bcm5974 entries here:
http://cgit.freedesktop.org/systemd/systemd/tree/hwdb/60-evdev.hwdb.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 doc/device-configuration-via-udev.dox | 14 +++++++++-----
 src/evdev.c                           | 36 +++++++++++++++++++++++++++++++++--
 2 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/doc/device-configuration-via-udev.dox b/doc/device-configuration-via-udev.dox
index e38b93f..85c5c9c 100644
--- a/doc/device-configuration-via-udev.dox
+++ b/doc/device-configuration-via-udev.dox
@@ -67,6 +67,10 @@ to normalize them.
 <dd><b>This prefix is reserved as private API, do not use.</b>. See @ref
 model_specific_configuration for details.
 </dd>
+<dt>LIBINPUT_ATTR_*</dt>
+<dd><b>This prefix is reserved as private API, do not use.</b>. See @ref
+model_specific_configuration for details.
+</dd>
 </dl>
 
 Below is an example udev rule to assign "seat1" to a device from vendor
@@ -103,13 +107,13 @@ ENV{ID_MODEL_ID}=="034b", ENV{ID_INPUT_TOUCHPAD}="", ENV{ID_INPUT_TABLET}="1"
 
 @section model_specific_configuration Model-specific configuration
 
-libinput reserves the property prefix <b>LIBINPUT_MODEL_</b> for
-model-specific configuration. <b>This prefix is reserved as private API, do
-not use.</b>
+libinput reserves the property prefixes <b>LIBINPUT_MODEL_</b> and
+<b>LIBINPUT_ATTR_*</b> for model-specific configuration. <b>These prefixes
+are reserved as private API, do not use.</b>
 
-The effect of this property may be to enable or disable certain
+The effect of these properties may be to enable or disable certain
 features on a specific device or set of devices, to change configuration
-defaults or any other reason. The effects of setting this property, the
+defaults or any other reason. The effects of setting these properties, the
 format of the property and the value of the property are subject to change
 at any time.
 
diff --git a/src/evdev.c b/src/evdev.c
index 5d9b9d0..26bcf41 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1547,6 +1547,23 @@ evdev_read_model(struct evdev_device *device)
 	return m->model;
 }
 
+static inline int
+evdev_read_attr_size_prop(struct evdev_device *device,
+			  size_t *size_x,
+			  size_t *size_y)
+{
+	struct udev_device *udev;
+	const char *size_prop;
+
+	udev = device->udev_device;
+	size_prop = udev_device_get_property_value(udev,
+						   "LIBINPUT_ATTR_SIZE_HINT");
+	if (!size_prop)
+		return false;
+
+	return parse_dimension_property(size_prop, size_x, size_y);
+}
+
 /* Return 1 if the device is set to the fake resolution or 0 otherwise */
 static inline int
 evdev_fix_abs_resolution(struct evdev_device *device,
@@ -1555,6 +1572,8 @@ evdev_fix_abs_resolution(struct evdev_device *device,
 {
 	struct libinput *libinput = device->base.seat->libinput;
 	struct libevdev *evdev = device->evdev;
+	const struct input_absinfo *absx, *absy;
+	size_t widthmm = 0, heightmm = 0;
 	int xres = EVDEV_FAKE_RESOLUTION,
 	    yres = EVDEV_FAKE_RESOLUTION;
 
@@ -1566,15 +1585,28 @@ evdev_fix_abs_resolution(struct evdev_device *device,
 		return 0;
 	}
 
-	if (libevdev_get_abs_resolution(evdev, xcode) != 0)
+	absx = libevdev_get_abs_info(evdev, xcode);
+	absy = libevdev_get_abs_info(evdev, ycode);
+
+	if (absx->resolution != 0 || absy->resolution != 0)
 		return 0;
 
+	/* Note: we *do not* override resolutions if provided by the kernel.
+	 * If a device needs this, add it to 60-evdev.hwdb. The libinput
+	 * property is only for general size hints where we can make
+	 * educated guesses but don't know better.
+	 */
+	if (evdev_read_attr_size_prop(device, &widthmm, &heightmm)) {
+		xres = (absx->maximum - absx->minimum)/widthmm;
+		yres = (absy->maximum - absy->minimum)/heightmm;
+	}
+
 	/* libevdev_set_abs_resolution() changes the absinfo we already
 	   have a pointer to, no need to fetch it again */
 	libevdev_set_abs_resolution(evdev, xcode, xres);
 	libevdev_set_abs_resolution(evdev, ycode, yres);
 
-	return 1;
+	return xres == EVDEV_FAKE_RESOLUTION;
 }
 
 static enum evdev_device_udev_tags
-- 
2.4.3



More information about the wayland-devel mailing list