[PATCH libinput 6/6] pad: add support for left-handed configurations
Peter Hutterer
peter.hutterer at who-t.net
Wed Feb 10 06:17:34 UTC 2016
Signed-off-by: Peter Hutterer <peter.hutterer at 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
More information about the wayland-devel
mailing list