From: Peter Hutterer Date: Tue, 26 Aug 2014 01:41:19 +0000 (+1000) Subject: Change calibration into a configuration option X-Git-Tag: 0.6.0~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ea00ff9114c100e83689dfdc143ddb3891efc26d;p=platform%2Fupstream%2Flibinput.git Change calibration into a configuration option 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 Reviewed-by: Hans de Goede --- diff --git a/src/evdev.c b/src/evdev.c index 4cd3cfaa..00594440 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 9196bd20..110ea745 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 94a3e07c..9e084dd7 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 ed5eba17..20aa1cb3 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 82970e25..5af0ddec 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 c0af460c..861ab741 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 0aab5c8e..1c0a4b6e 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);