Hi, On 08/27/2014 06:31 AM, Peter Hutterer wrote: > New configuration API: > libinput_device_config_calibration_has_matrix() > libinput_device_config_calibration_set_matrix() > libinput_device_config_calibration_get_matrix() > libinput_device_config_calibration_get_default_matrix() > > Deprecates libinput_device_calibrate(). > > For coordinate transformation, we're using a precalculated matrix. Thus, to > support ..._get_matrix() we need to store the original user-specified matrix > separately, in an unmangled state. > > Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net>
Looks good: Reviewed-by: Hans de Goede <hdego...@redhat.com> Regards, Hans > --- > src/evdev.c | 59 +++++++++++++++++++- > src/evdev.h | 2 + > src/libinput-private.h | 11 ++++ > src/libinput.c | 37 +++++++++++++ > src/libinput.h | 147 > +++++++++++++++++++++++++++++++++++++------------ > test/pointer.c | 24 ++++++++ > test/touch.c | 9 ++- > 7 files changed, 248 insertions(+), 41 deletions(-) > > diff --git a/src/evdev.c b/src/evdev.c > index 4cd3cfa..0059444 100644 > --- a/src/evdev.c > +++ b/src/evdev.c > @@ -578,19 +578,70 @@ fallback_destroy(struct evdev_dispatch *dispatch) > free(dispatch); > } > > +static int > +evdev_calibration_has_matrix(struct libinput_device *libinput_device) > +{ > + struct evdev_device *device = (struct evdev_device*)libinput_device; > + > + return device->abs.absinfo_x && device->abs.absinfo_y; > +} > + > +static enum libinput_config_status > +evdev_calibration_set_matrix(struct libinput_device *libinput_device, > + const float matrix[6]) > +{ > + struct evdev_device *device = (struct evdev_device*)libinput_device; > + > + evdev_device_calibrate(device, matrix); > + > + return LIBINPUT_CONFIG_STATUS_SUCCESS; > +} > + > +static int > +evdev_calibration_get_matrix(struct libinput_device *libinput_device, > + float matrix[6]) > +{ > + struct evdev_device *device = (struct evdev_device*)libinput_device; > + > + matrix_to_farray6(&device->abs.usermatrix, matrix); > + > + return !matrix_is_identity(&device->abs.usermatrix); > +} > + > +static int > +evdev_calibration_get_default_matrix(struct libinput_device *libinput_device, > + float matrix[6]) > +{ > + struct matrix m; > + > + /* Always return the identity matrix for now. In the future, this > + should return the WL_CALIBRATION matrix defined as default > + matrix for this device */ > + matrix_init_identity(&m); > + matrix_to_farray6(&m, matrix); > + > + return !matrix_is_identity(&m); > +} > + > struct evdev_dispatch_interface fallback_interface = { > fallback_process, > fallback_destroy > }; > > static struct evdev_dispatch * > -fallback_dispatch_create(void) > +fallback_dispatch_create(struct libinput_device *device) > { > struct evdev_dispatch *dispatch = malloc(sizeof *dispatch); > if (dispatch == NULL) > return NULL; > > dispatch->interface = &fallback_interface; > + device->config.calibration = &dispatch->calibration; > + > + dispatch->calibration.has_matrix = evdev_calibration_has_matrix; > + dispatch->calibration.set_matrix = evdev_calibration_set_matrix; > + dispatch->calibration.get_matrix = evdev_calibration_get_matrix; > + dispatch->calibration.get_default_matrix = > evdev_calibration_get_default_matrix; > > return dispatch; > } > @@ -904,6 +955,7 @@ evdev_device_create(struct libinput_seat *seat, > device->devname = libevdev_get_name(device->evdev); > > matrix_init_identity(&device->abs.calibration); > + matrix_init_identity(&device->abs.usermatrix); > > if (evdev_configure_device(device) == -1) > goto err; > @@ -915,7 +967,7 @@ evdev_device_create(struct libinput_seat *seat, > > /* If the dispatch was not set up use the fallback. */ > if (device->dispatch == NULL) > - device->dispatch = fallback_dispatch_create(); > + device->dispatch = fallback_dispatch_create(&device->base); > if (device->dispatch == NULL) > goto err; > > @@ -1014,6 +1066,9 @@ evdev_device_calibrate(struct evdev_device *device, > * order. > */ > > + /* back up the user matrix so we can return it on request */ > + matrix_from_farray6(&device->abs.usermatrix, calibration); > + > /* Un-Normalize */ > matrix_init_translate(&translate, > device->abs.absinfo_x->minimum, > diff --git a/src/evdev.h b/src/evdev.h > index 9196bd2..110ea74 100644 > --- a/src/evdev.h > +++ b/src/evdev.h > @@ -74,6 +74,7 @@ struct evdev_device { > > int apply_calibration; > struct matrix calibration; > + struct matrix usermatrix; /* as supplied by the caller */ > } abs; > > struct { > @@ -121,6 +122,7 @@ struct evdev_dispatch_interface { > > struct evdev_dispatch { > struct evdev_dispatch_interface *interface; > + struct libinput_device_config_calibration calibration; > }; > > struct evdev_device * > diff --git a/src/libinput-private.h b/src/libinput-private.h > index 94a3e07..9e084dd 100644 > --- a/src/libinput-private.h > +++ b/src/libinput-private.h > @@ -89,8 +89,19 @@ struct libinput_device_config_tap { > enum libinput_config_tap_state (*get_default)(struct libinput_device > *device); > }; > > +struct libinput_device_config_calibration { > + int (*has_matrix)(struct libinput_device *device); > + enum libinput_config_status (*set_matrix)(struct libinput_device > *device, > + const float matrix[6]); > + int (*get_matrix)(struct libinput_device *device, > + float matrix[6]); > + int (*get_default_matrix)(struct libinput_device *device, > + float matrix[6]); > +}; > + > struct libinput_device_config { > struct libinput_device_config_tap *tap; > + struct libinput_device_config_calibration *calibration; > }; > > struct libinput_device { > diff --git a/src/libinput.c b/src/libinput.c > index ed5eba1..20aa1cb 100644 > --- a/src/libinput.c > +++ b/src/libinput.c > @@ -1312,3 +1312,40 @@ libinput_device_config_tap_get_default_enabled(struct > libinput_device *device) > > return device->config.tap->get_default(device); > } > + > +LIBINPUT_EXPORT int > +libinput_device_config_calibration_has_matrix(struct libinput_device *device) > +{ > + return device->config.calibration ? > + device->config.calibration->has_matrix(device) : 0; > +} > + > +LIBINPUT_EXPORT enum libinput_config_status > +libinput_device_config_calibration_set_matrix(struct libinput_device *device, > + const float matrix[6]) > +{ > + if (!libinput_device_config_calibration_has_matrix(device)) > + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; > + > + return device->config.calibration->set_matrix(device, matrix); > +} > + > +LIBINPUT_EXPORT int > +libinput_device_config_calibration_get_matrix(struct libinput_device *device, > + float matrix[6]) > +{ > + if (!libinput_device_config_calibration_has_matrix(device)) > + return 0; > + > + return device->config.calibration->get_matrix(device, matrix); > +} > + > +LIBINPUT_EXPORT int > +libinput_device_config_calibration_get_default_matrix(struct libinput_device > *device, > + float matrix[6]) > +{ > + if (!libinput_device_config_calibration_has_matrix(device)) > + return 0; > + > + return device->config.calibration->get_default_matrix(device, matrix); > +} > diff --git a/src/libinput.h b/src/libinput.h > index 82970e2..5af0dde 100644 > --- a/src/libinput.h > +++ b/src/libinput.h > @@ -1365,45 +1365,12 @@ libinput_device_get_keys(struct libinput_device > *device, > /** > * @ingroup device > * > - * Apply the 3x3 transformation matrix to absolute device coordinates. This > - * matrix has no effect on relative events. > - * > - * Given a 6-element array [a, b, c, d, e, f], the matrix is applied as > - * @code > - * [ a b c ] [ x ] > - * [ d e f ] * [ y ] > - * [ 0 0 1 ] [ 1 ] > - * @endcode > - * > - * The translation component (c, f) is expected to be normalized to the > - * device coordinate range. For example, the matrix > - * @code > - * [ 1 0 1 ] > - * [ 0 1 -1 ] > - * [ 0 0 1 ] > - * @endcode > - * moves all coordinates by 1 device-width to the right and 1 device-height > - * up. > - * > - * The rotation matrix for rotation around the origin is defined as > - * @code > - * [ cos(a) -sin(a) 0 ] > - * [ sin(a) cos(a) 0 ] > - * [ 0 0 1 ] > - * @endcode > - * Note that any rotation requires an additional translation component to > - * translate the rotated coordinates back into the original device space. > - * The rotation matrixes for 90, 180 and 270 degrees clockwise are: > - * @code > - * 90 deg cw: 180 deg cw: 270 deg cw: > - * [ 0 -1 1] [ -1 0 1] [ 0 1 0 ] > - * [ 1 0 0] [ 0 -1 1] [ -1 0 1 ] > - * [ 0 0 1] [ 0 0 1] [ 0 0 1 ] > - * @endcode > + * @deprecated Use libinput_device_config_calibration_set_matrix() instead. > */ > void > libinput_device_calibrate(struct libinput_device *device, > - float calibration[6]); > + float calibration[6]) > + LIBINPUT_ATTRIBUTE_DEPRECATED; > > /** > * @ingroup device > @@ -1559,6 +1526,114 @@ libinput_device_config_tap_get_enabled(struct > libinput_device *device); > enum libinput_config_tap_state > libinput_device_config_tap_get_default_enabled(struct libinput_device > *device); > > +/** > + * @ingroup config > + * > + * Check if the device can be calibrated via a calibration matrix. > + * > + * @param device The device to check > + * @return non-zero if the device can be calibrated, zero otherwise. > + * > + * @see libinput_device_config_calibration_set_matrix > + * @see libinput_device_config_calibration_get_matrix > + * @see libinput_device_config_calibration_get_default_matrix > + */ > +int > +libinput_device_config_calibration_has_matrix(struct libinput_device > *device); > + > +/** > + * @ingroup config > + * > + * Apply the 3x3 transformation matrix to absolute device coordinates. This > + * matrix has no effect on relative events. > + * > + * Given a 6-element array [a, b, c, d, e, f], the matrix is applied as > + * @code > + * [ a b c ] [ x ] > + * [ d e f ] * [ y ] > + * [ 0 0 1 ] [ 1 ] > + * @endcode > + * > + * The translation component (c, f) is expected to be normalized to the > + * device coordinate range. For example, the matrix > + * @code > + * [ 1 0 1 ] > + * [ 0 1 -1 ] > + * [ 0 0 1 ] > + * @endcode > + * moves all coordinates by 1 device-width to the right and 1 device-height > + * up. > + * > + * The rotation matrix for rotation around the origin is defined as > + * @code > + * [ cos(a) -sin(a) 0 ] > + * [ sin(a) cos(a) 0 ] > + * [ 0 0 1 ] > + * @endcode > + * Note that any rotation requires an additional translation component to > + * translate the rotated coordinates back into the original device space. > + * The rotation matrixes for 90, 180 and 270 degrees clockwise are: > + * @code > + * 90 deg cw: 180 deg cw: 270 deg cw: > + * [ 0 -1 1] [ -1 0 1] [ 0 1 0 ] > + * [ 1 0 0] [ 0 -1 1] [ -1 0 1 ] > + * [ 0 0 1] [ 0 0 1] [ 0 0 1 ] > + * @endcode > + * > + * @param device The device to configure > + * @param matrix An array representing the first two rows of a 3x3 matrix as > + * described above. > + * > + * @return A config status code. > + * > + * @see libinput_device_config_calibration_has_matrix > + * @see libinput_device_config_calibration_get_matrix > + * @see libinput_device_config_calibration_get_default_matrix > + */ > +enum libinput_config_status > +libinput_device_config_calibration_set_matrix(struct libinput_device *device, > + const float matrix[6]); > + > +/** > + * @ingroup config > + * > + * Return the current calibration matrix for this device. > + * > + * @param device The device to configure > + * @param matrix Set to the array representing the first two rows of a 3x3 > matrix as > + * described in libinput_device_config_calibration_set_matrix(). > + * > + * @return 0 if no calibration is set and the returned matrix is the > + * identity matrix, 1 otherwise > + * > + * @see libinput_device_config_calibration_has_matrix > + * @see libinput_device_config_calibration_set_matrix > + * @see libinput_device_config_calibration_get_default_matrix > + */ > +int > +libinput_device_config_calibration_get_matrix(struct libinput_device *device, > + float matrix[6]); > + > +/** > + * @ingroup config > + * > + * Return the default calibration matrix for this device. > + * > + * @param device The device to configure > + * @param matrix Set to the array representing the first two rows of a 3x3 > matrix as > + * described in libinput_device_config_calibration_set_matrix(). > + * > + * @return 0 if no calibration is set and the returned matrix is the > + * identity matrix, 1 otherwise > + * > + * @see libinput_device_config_calibration_has_matrix > + * @see libinput_device_config_calibration_set_matrix > + * @see libinput_device_config_calibration_get_default_matrix > + */ > +int > +libinput_device_config_calibration_get_default_matrix(struct libinput_device > *device, > + float matrix[6]); > + > #ifdef __cplusplus > } > #endif > diff --git a/test/pointer.c b/test/pointer.c > index c0af460..861ab74 100644 > --- a/test/pointer.c > +++ b/test/pointer.c > @@ -385,6 +385,28 @@ START_TEST(pointer_seat_button_count) > } > END_TEST > > +START_TEST(pointer_no_calibration) > +{ > + struct litest_device *dev = litest_current_device(); > + struct libinput_device *d = dev->libinput_device; > + enum libinput_config_status status; > + int rc; > + float calibration[6] = {0}; > + > + rc = libinput_device_config_calibration_has_matrix(d); > + ck_assert_int_eq(rc, 0); > + rc = libinput_device_config_calibration_get_matrix(d, calibration); > + ck_assert_int_eq(rc, 0); > + rc = libinput_device_config_calibration_get_default_matrix(d, > + calibration); > + ck_assert_int_eq(rc, 0); > + > + status = libinput_device_config_calibration_set_matrix(d, > + calibration); > + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED); > +} > +END_TEST > + > int main (int argc, char **argv) { > > litest_add("pointer:motion", pointer_motion_relative, LITEST_POINTER, > LITEST_ANY); > @@ -393,5 +415,7 @@ int main (int argc, char **argv) { > litest_add("pointer:scroll", pointer_scroll_wheel, LITEST_WHEEL, > LITEST_ANY); > litest_add_no_device("pointer:seat button count", > pointer_seat_button_count); > > + litest_add("pointer:calibration", pointer_no_calibration, LITEST_ANY, > LITEST_TOUCH|LITEST_SINGLE_TOUCH); > + > return litest_run(argc, argv); > } > diff --git a/test/touch.c b/test/touch.c > index 0aab5c8..1c0a4b6 100644 > --- a/test/touch.c > +++ b/test/touch.c > @@ -232,7 +232,8 @@ START_TEST(touch_calibration_scale) > li = dev->libinput; > > for (calibration = 0.1; calibration < 1; calibration += 0.1) { > - libinput_device_calibrate(dev->libinput_device, matrix); > + > libinput_device_config_calibration_set_matrix(dev->libinput_device, > + matrix); > litest_drain_events(li); > > litest_touch_down(dev, 0, 100, 100); > @@ -303,7 +304,8 @@ START_TEST(touch_calibration_rotation) > break; > } > > - libinput_device_calibrate(dev->libinput_device, matrix); > + > libinput_device_config_calibration_set_matrix(dev->libinput_device, > + matrix); > litest_drain_events(li); > > litest_touch_down(dev, 0, 80, 20); > @@ -368,7 +370,8 @@ START_TEST(touch_calibration_translation) > > /* translating from 0 up to 1 device width/height */ > for (translate = 0.1; translate <= 1; translate += 0.1) { > - libinput_device_calibrate(dev->libinput_device, matrix); > + > libinput_device_config_calibration_set_matrix(dev->libinput_device, > + matrix); > litest_drain_events(li); > > litest_touch_down(dev, 0, 100, 100); > _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel