Allow rotation on all mice and for any angle

Previously we restricted rotation to trackballs only and to multiples 
of 90 degrees. Update rotation allow angles other than multiples of 90.

Also enable rotation on all mice. The only devices without rotation
are now pointing sticks.

Fixes #827

Signed-off-by: Lucas Zampieri <lzampier@redhat.com>
This commit is contained in:
Lucas Zampieri 2022-12-05 22:57:51 +00:00 committed by Peter Hutterer
parent 38dbfe41a1
commit fb8d285566
5 changed files with 22 additions and 24 deletions

View file

@ -151,20 +151,18 @@ fallback_filter_defuzz_touch(struct fallback_dispatch *dispatch,
return false;
}
static inline void
static inline struct device_float_coords
fallback_rotate_relative(struct fallback_dispatch *dispatch,
struct evdev_device *device)
{
struct device_coords rel = dispatch->rel;
struct device_float_coords rel = { dispatch->rel.x, dispatch->rel.y };
if (!device->base.config.rotation)
return;
return rel;
/* loss of precision for non-90 degrees, but we only support 90 deg
* right now anyway */
matrix_mult_vec(&dispatch->rotation.matrix, &rel.x, &rel.y);
matrix_mult_vec_double(&dispatch->rotation.matrix, &rel.x, &rel.y);
dispatch->rel = rel;
return rel;
}
static void
@ -174,15 +172,12 @@ fallback_flush_relative_motion(struct fallback_dispatch *dispatch,
{
struct libinput_device *base = &device->base;
struct normalized_coords accel;
struct device_float_coords raw;
if (!(device->seat_caps & EVDEV_DEVICE_POINTER))
return;
fallback_rotate_relative(dispatch, device);
struct device_float_coords raw = fallback_rotate_relative(dispatch, device);
raw.x = dispatch->rel.x;
raw.y = dispatch->rel.y;
dispatch->rel.x = 0;
dispatch->rel.y = 0;
@ -1488,7 +1483,7 @@ static void
fallback_init_rotation(struct fallback_dispatch *dispatch,
struct evdev_device *device)
{
if ((device->model_flags & EVDEV_MODEL_TRACKBALL) == 0)
if (device->tags & EVDEV_TAG_TRACKPOINT)
return;
dispatch->rotation.config.is_available = fallback_rotation_config_is_available;

View file

@ -4576,7 +4576,7 @@ libinput_device_config_rotation_set_angle(struct libinput_device *device,
return degrees_cw ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED :
LIBINPUT_CONFIG_STATUS_SUCCESS;
if (degrees_cw >= 360 || degrees_cw % 90)
if (degrees_cw >= 360)
return LIBINPUT_CONFIG_STATUS_INVALID;
return device->config.rotation->set_angle(device, degrees_cw);

View file

@ -6162,11 +6162,6 @@ libinput_device_config_rotation_is_available(struct libinput_device *device);
* multiple of 360 or negative, the caller must ensure the correct ranging
* before calling this function.
*
* libinput guarantees that this function accepts multiples of 90 degrees.
* If a value is within the [0, 360[ range but not a multiple of 90 degrees,
* this function may return LIBINPUT_CONFIG_STATUS_INVALID if the underlying
* device or implementation does not support finer-grained rotation angles.
*
* The rotation angle is applied to all motion events emitted by the device.
* Thus, rotating the device also changes the angle required or presented by
* scrolling, gestures, etc.

View file

@ -139,6 +139,18 @@ matrix_mult_vec(const struct matrix *m, int *x, int *y)
*y = ty;
}
static inline void
matrix_mult_vec_double(const struct matrix *m, double *x, double *y)
{
double tx, ty;
tx = *x * m->val[0][0] + *y * m->val[0][1] + m->val[0][2];
ty = *x * m->val[1][0] + *y * m->val[1][1] + m->val[1][2];
*x = tx;
*y = ty;
}
static inline void
matrix_to_farray6(const struct matrix *m, float out[6])
{

View file

@ -81,8 +81,6 @@ START_TEST(trackball_rotation_config_no_rotation)
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
for (angle = 1; angle < 360; angle++) {
if (angle % 90 == 0)
continue;
status = libinput_device_config_rotation_set_angle(device,
angle);
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
@ -117,11 +115,9 @@ START_TEST(trackball_rotation_config_odd_angle)
ck_assert(libinput_device_config_rotation_is_available(device));
for (angle = 0; angle < 360; angle++) {
if (angle % 90 == 0)
continue;
status = libinput_device_config_rotation_set_angle(device,
angle);
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
}
}
END_TEST
@ -263,7 +259,7 @@ TEST_COLLECTION(trackball)
{
litest_add(trackball_rotation_config_defaults, LITEST_TRACKBALL, LITEST_ANY);
litest_add(trackball_rotation_config_invalid_range, LITEST_TRACKBALL, LITEST_ANY);
litest_add(trackball_rotation_config_no_rotation, LITEST_ANY, LITEST_TRACKBALL);
litest_add(trackball_rotation_config_no_rotation, LITEST_POINTINGSTICK, LITEST_ANY);
litest_add(trackball_rotation_config_right_angle, LITEST_TRACKBALL, LITEST_ANY);
litest_add(trackball_rotation_config_odd_angle, LITEST_TRACKBALL, LITEST_ANY);
litest_add(trackball_rotation_x, LITEST_TRACKBALL, LITEST_ANY);