diff options
| author | Peter Hutterer <peter.hutterer@who-t.net> | 2015-06-30 12:15:12 +1000 |
|---|---|---|
| committer | Peter Hutterer <peter.hutterer@who-t.net> | 2015-07-14 10:12:12 +1000 |
| commit | a4f5abd18e4e6c98d4c467016bbe9b13a8a8b05d (patch) | |
| tree | 4c0c2b9610a699fb6145fce60c756f08c172ef0d /src | |
| parent | 5bebd4aea487203dedca985e7c8333261bdb677f (diff) | |
| download | libinput-a4f5abd18e4e6c98d4c467016bbe9b13a8a8b05d.tar.gz | |
evdev: use LIBINPUT_ATTR_SIZE_HINT for resolutions
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@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/evdev.c | 36 |
1 files changed, 34 insertions, 2 deletions
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 |
