diff --git a/doc/device-configuration-via-udev.dox b/doc/device-configuration-via-udev.dox
index e38b93f6..85c5c9c9 100644
--- a/doc/device-configuration-via-udev.dox
+++ b/doc/device-configuration-via-udev.dox
@@ -67,6 +67,10 @@ to normalize them.
This prefix is reserved as private API, do not use.. See @ref
model_specific_configuration for details.
+LIBINPUT_ATTR_*
+This prefix is reserved as private API, do not use.. See @ref
+model_specific_configuration for details.
+
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 LIBINPUT_MODEL_ for
-model-specific configuration. This prefix is reserved as private API, do
-not use.
+libinput reserves the property prefixes LIBINPUT_MODEL_ and
+LIBINPUT_ATTR_* for model-specific configuration. These prefixes
+are reserved as private API, do not use.
-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 29bed728..3d19ee73 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1551,6 +1551,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,
@@ -1559,6 +1576,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;
@@ -1570,15 +1589,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