Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> --- src/evdev-tablet-pad.c | 55 ++++++++++++++++++++++- test/pad.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+), 2 deletions(-)
diff --git a/src/evdev-tablet-pad.c b/src/evdev-tablet-pad.c index 810b241..c2fe379 100644 --- a/src/evdev-tablet-pad.c +++ b/src/evdev-tablet-pad.c @@ -62,6 +62,19 @@ pad_button_is_down(const struct pad_dispatch *pad, return bit_is_set(pad->button_state.bits, button); } +static inline bool +pad_any_button_down(const struct pad_dispatch *pad) +{ + const struct button_state *state = &pad->button_state; + unsigned int i; + + for (i = 0; i < sizeof(state->bits); i++) + if (state->bits[i] != 0) + return true; + + return false; +} + static inline void pad_button_set_down(struct pad_dispatch *pad, uint32_t button, @@ -161,11 +174,17 @@ pad_handle_ring(struct pad_dispatch *pad, unsigned int code) { const struct input_absinfo *absinfo; + double degrees; absinfo = libevdev_get_abs_info(device->evdev, code); assert(absinfo); - return normalize_ring(absinfo) * 360; + degrees = normalize_ring(absinfo) * 360; + + if (device->left_handed.enabled) + degrees = fmod(degrees + 180, 360); + + return degrees; } static inline double @@ -174,6 +193,7 @@ pad_handle_strip(struct pad_dispatch *pad, unsigned int code) { const struct input_absinfo *absinfo; + double pos; absinfo = libevdev_get_abs_info(device->evdev, code); assert(absinfo); @@ -181,7 +201,12 @@ pad_handle_strip(struct pad_dispatch *pad, if (absinfo->value == 0) return 0.0; - return normalize_strip(absinfo); + pos = normalize_strip(absinfo); + + if (device->left_handed.enabled) + pos = 1.0 - pos; + + return pos; } static void @@ -313,6 +338,20 @@ pad_notify_buttons(struct pad_dispatch *pad, } static void +pad_change_to_left_handed(struct evdev_device *device) +{ + struct pad_dispatch *pad = (struct pad_dispatch*)device->dispatch; + + if (device->left_handed.enabled == device->left_handed.want_enabled) + return; + + if (pad_any_button_down(pad)) + return; + + device->left_handed.enabled = device->left_handed.want_enabled; +} + +static void pad_flush(struct pad_dispatch *pad, struct evdev_device *device, uint64_t time) @@ -328,6 +367,8 @@ pad_flush(struct pad_dispatch *pad, time, LIBINPUT_BUTTON_STATE_RELEASED); pad_unset_status(pad, PAD_BUTTONS_RELEASED); + + pad_change_to_left_handed(device); } if (pad_has_status(pad, PAD_BUTTONS_PRESSED)) { @@ -407,6 +448,14 @@ static struct evdev_dispatch_interface pad_interface = { NULL, /* post_added */ }; +static void +pad_init_left_handed(struct evdev_device *device) +{ + if (evdev_tablet_has_left_handed(device)) + evdev_init_left_handed(device, + pad_change_to_left_handed); +} + static int pad_init(struct pad_dispatch *pad, struct evdev_device *device) { @@ -415,6 +464,8 @@ pad_init(struct pad_dispatch *pad, struct evdev_device *device) pad->status = PAD_NONE; pad->changed_axes = PAD_AXIS_NONE; + pad_init_left_handed(device); + return 0; } diff --git a/test/pad.c b/test/pad.c index 0286bd0..53a907f 100644 --- a/test/pad.c +++ b/test/pad.c @@ -359,6 +359,117 @@ START_TEST(pad_strip_finger_up) } END_TEST +START_TEST(pad_left_handed_default) +{ +#if HAVE_LIBWACOM + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + enum libinput_config_status status; + + ck_assert(libinput_device_config_left_handed_is_available(device)); + + ck_assert_int_eq(libinput_device_config_left_handed_get_default(device), + 0); + ck_assert_int_eq(libinput_device_config_left_handed_get(device), + 0); + + status = libinput_device_config_left_handed_set(dev->libinput_device, 1); + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); + + ck_assert_int_eq(libinput_device_config_left_handed_get(device), + 1); + ck_assert_int_eq(libinput_device_config_left_handed_get_default(device), + 0); + + status = libinput_device_config_left_handed_set(dev->libinput_device, 0); + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS); + + ck_assert_int_eq(libinput_device_config_left_handed_get(device), + 0); + ck_assert_int_eq(libinput_device_config_left_handed_get_default(device), + 0); + +#endif +} +END_TEST + +START_TEST(pad_no_left_handed) +{ + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + enum libinput_config_status status; + + ck_assert(!libinput_device_config_left_handed_is_available(device)); + + ck_assert_int_eq(libinput_device_config_left_handed_get_default(device), + 0); + ck_assert_int_eq(libinput_device_config_left_handed_get(device), + 0); + + status = libinput_device_config_left_handed_set(dev->libinput_device, 1); + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED); + + ck_assert_int_eq(libinput_device_config_left_handed_get(device), + 0); + ck_assert_int_eq(libinput_device_config_left_handed_get_default(device), + 0); + + status = libinput_device_config_left_handed_set(dev->libinput_device, 0); + ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED); + + ck_assert_int_eq(libinput_device_config_left_handed_get(device), + 0); + ck_assert_int_eq(libinput_device_config_left_handed_get_default(device), + 0); +} +END_TEST + +START_TEST(pad_left_handed_ring) +{ +#if HAVE_LIBWACOM + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *ev; + struct libinput_event_tablet_pad *pev; + int val; + double degrees, expected; + + libinput_device_config_left_handed_set(dev->libinput_device, 1); + + litest_pad_ring_start(dev, 10); + + litest_drain_events(li); + + /* Wacom's 0 value is at 275 degrees -> 90 in left-handed mode*/ + expected = 90; + + for (val = 0; val < 100; val += 10) { + litest_pad_ring_change(dev, val); + libinput_dispatch(li); + + ev = libinput_get_event(li); + pev = litest_is_pad_ring_event(ev, + 0, + LIBINPUT_TABLET_PAD_RING_SOURCE_FINGER); + + degrees = libinput_event_tablet_pad_get_ring_position(pev); + ck_assert_double_ge(degrees, 0.0); + ck_assert_double_lt(degrees, 360.0); + + /* rounding errors, mostly caused by small physical range */ + ck_assert_double_ge(degrees, expected - 2); + ck_assert_double_le(degrees, expected + 2); + + libinput_event_destroy(ev); + + expected = fmod(degrees + 36, 360); + } + + litest_pad_ring_end(dev); +#endif +} +END_TEST + void litest_setup_tests(void) { @@ -378,4 +489,8 @@ litest_setup_tests(void) litest_add("pad:strip", pad_strip, LITEST_STRIP, LITEST_ANY); litest_add("pad:strip", pad_strip_finger_up, LITEST_STRIP, LITEST_ANY); + litest_add_for_device("pad:left_handed", pad_left_handed_default, LITEST_WACOM_INTUOS5_PAD); + litest_add_for_device("pad:left_handed", pad_no_left_handed, LITEST_WACOM_INTUOS3_PAD); + litest_add_for_device("pad:left_handed", pad_left_handed_ring, LITEST_WACOM_INTUOS5_PAD); + /* None of the current strip tablets are left-handed */ } -- 2.5.0 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel