[PATCH v2 weston] libinput: normalize WL_CALIBRATION before passing it to libinput
Peter Hutterer
peter.hutterer at who-t.net
Mon Sep 8 20:15:42 PDT 2014
On Mon, Sep 08, 2014 at 08:16:07PM +0200, Jonas Ådahl wrote:
> On Fri, Sep 05, 2014 at 11:25:25AM +1000, Peter Hutterer wrote:
> > WL_CALIBRATION, introduced in weston-1.1, requires the translation component
> > of the calibration matrix to be in screen coordinates. libinput does not have
> > access to this and it's not a very generic way to do this anyway. So with
> > the libinput backend, WL_CALIBRATION support is currently broken (#82742).
> > This cannot be fixed in libinput without changing its API for this specific
> > use-case.
> >
> > This patch lets weston take care of WL_CALIBRATION. It takes the original
> > format and normalizes it before passing it to libinput. This way libinput
> > still does the coordinate transformation, weston just needs to provide the
> > initial configuration.
> >
> > Note that this needs an updated libinput, otherwise libinput will try to
> > transform coordinates as well.
>
> Should we also deprecate the WL_CALIBRATION udev parameter and warn
> about when using it, as well as having weston-calibrator output the
> normalized calibration matrix?
tbh, I'd rather leave it as-is. I'm not a big fan of the configuration
back-channel in libinput, I'd prefer this to be set by the compositor as
required. with WL_CALIBRATION as-is that works fine, having a weston tool
spit out a udev configuration that is then read by libinput to give weston
calibrated values seems a bit all over the place to me.
> We could also move weston-calibrator to
> libinput, but then we'd need to port it to something else than toytoolkit
> (or by not using a toolkit), which naturally is less trivial. Keeping
> weston-calibrator that outputs the non-normalized matrix, at least after
> the release, is probably not a good idea.
>
> In anyway, this patch can be considered
> Reviewed-by: Jonas Ådahl <jadahl at gmail.com> with some minor style nits
> below.
thanks for the review, updated patch is on the list.
Cheers,
Peter
>
>
> Jonas
>
> > ---
> > Changes to v1:
> > - fix copy/paste error assigning height to the screen width
> >
> > https://bugs.freedesktop.org/show_bug.cgi?id=82742 has positive test results
> > so we don't break exisint setups with WL_CALIBRATION set.
> >
> > Can be merged once libinput 0.6 is released.
> >
> > configure.ac | 2 +-
> > src/libinput-device.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 88 insertions(+), 1 deletion(-)
> >
> > diff --git a/configure.ac b/configure.ac
> > index bc5c88a..fb19fb2 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -160,7 +160,7 @@ AC_ARG_ENABLE(libinput-backend, [ --disable-libinput-backend],,
> > AM_CONDITIONAL([ENABLE_LIBINPUT_BACKEND], [test x$enable_libinput_backend = xyes])
> > if test x$enable_libinput_backend = xyes; then
> > AC_DEFINE([BUILD_LIBINPUT_BACKEND], [1], [Build the libinput input device backend])
> > - PKG_CHECK_MODULES(LIBINPUT_BACKEND, [libinput >= 0.5.0])
> > + PKG_CHECK_MODULES(LIBINPUT_BACKEND, [libinput >= 0.6.0])
> > fi
> >
> >
> > diff --git a/src/libinput-device.c b/src/libinput-device.c
> > index 6e50eeb..fded34c 100644
> > --- a/src/libinput-device.c
> > +++ b/src/libinput-device.c
> > @@ -282,6 +282,90 @@ notify_output_destroy(struct wl_listener *listener, void *data)
> > }
> > }
> >
> > +/**
> > + * The WL_CALIBRATION property requires a pixel-specific matrix to be
> > + * applied after scaling device coordinates to screen coordinates. libinput
> > + * can't do that, so we need to convert the calibration to the normalized
> > + * format libinput expects.
> > + */
> > +static void
> > +evdev_device_set_calibration(struct evdev_device *device)
> > +{
> > + struct udev *udev;
> > + struct udev_device *udev_device = NULL;
> > + const char *sysname = libinput_device_get_sysname(device->device);
> > + const char *calibration_values;
> > + uint32_t width, height;
> > + float calibration[6];
> > + enum libinput_config_status status;
> > +
> > + if (!device->output)
> > + return;
> > +
> > + width = device->output->width;
> > + height = device->output->height;
> > + if (width == 0 || height == 0)
> > + return;
> > +
> > + /* If libinput has a pre-set calibration matrix, don't override it */
> > + if (!libinput_device_config_calibration_has_matrix(device->device) ||
> > + libinput_device_config_calibration_get_default_matrix(
> > + device->device,
> > + calibration) != 0)
> > + return;
> > +
> > + udev = udev_new();
> > + if (!udev)
> > + return;
> > +
> > + udev_device = udev_device_new_from_subsystem_sysname(udev,
> > + "input",
> > + sysname);
> > + if (!udev_device)
> > + goto out;
> > +
> > + calibration_values =
> > + udev_device_get_property_value(udev_device,
> > + "WL_CALIBRATION");
>
> These two lines should be indented.
>
> > +
> > + if (!calibration_values || sscanf(calibration_values,
> > + "%f %f %f %f %f %f",
> > + &calibration[0],
> > + &calibration[1],
> > + &calibration[2],
> > + &calibration[3],
> > + &calibration[4],
> > + &calibration[5]) != 6)
> > + goto out;
> > +
> > + weston_log("Applying calibration: %f %f %f %f %f %f "
> > + "(normalized %f %f)\n",
> > + calibration[0],
> > + calibration[1],
> > + calibration[2],
> > + calibration[3],
> > + calibration[4],
> > + calibration[5],
> > + calibration[2]/width,
> > + calibration[5]/height);
>
> There should be spaces between the binary operators.
>
> > +
> > + /* normalize to a format libinput can use. There is a chance of
> > + this being wrong if the width/height don't match the device
> > + width/height but I'm not sure how to fix that */
> > + calibration[2] /= width;
> > + calibration[5] /= height;
> > +
> > + status = libinput_device_config_calibration_set_matrix(device->device,
> > + calibration);
> > + if (status != LIBINPUT_CONFIG_STATUS_SUCCESS)
> > + weston_log("Failed to apply calibration.\n");
> > +
> > +out:
> > + if (udev_device)
> > + udev_device_unref(udev_device);
> > + udev_unref(udev);
> > +}
> > +
> > void
> > evdev_device_set_output(struct evdev_device *device,
> > struct weston_output *output)
> > @@ -295,6 +379,7 @@ evdev_device_set_output(struct evdev_device *device,
> > device->output_destroy_listener.notify = notify_output_destroy;
> > wl_signal_add(&output->destroy_signal,
> > &device->output_destroy_listener);
> > + evdev_device_set_calibration(device);
> > }
> >
> > static void
> > @@ -318,6 +403,8 @@ configure_device(struct evdev_device *device)
> > libinput_device_config_tap_set_enabled(device->device,
> > enable_tap);
> > }
> > +
> > + evdev_device_set_calibration(device);
> > }
> >
> > struct evdev_device *
> > --
> > 1.9.3
> >
> > _______________________________________________
> > wayland-devel mailing list
> > wayland-devel at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list