From 7835e7460498d57ea7cab13089fa3b939d474428 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 12 Nov 2015 08:01:43 +1000 Subject: [PATCH] tablet: allow fetching the tip state from any tablet event Signed-off-by: Peter Hutterer Reviewed-by: Hans de Goede --- src/evdev-tablet.c | 13 +++- src/libinput-private.h | 2 + src/libinput.c | 9 ++- test/tablet.c | 170 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 192 insertions(+), 2 deletions(-) diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c index 476dee2b..ed64d552 100644 --- a/src/evdev-tablet.c +++ b/src/evdev-tablet.c @@ -406,14 +406,20 @@ tablet_check_notify_axes(struct tablet_dispatch *tablet, LIBINPUT_TOOL_PROXIMITY_IN, tablet->changed_axes, axes); - else + else { + enum libinput_tool_tip_state tip_state; + + tip_state = tablet_has_status(tablet, TABLET_TOOL_IN_CONTACT) ? + LIBINPUT_TOOL_TIP_DOWN : LIBINPUT_TOOL_TIP_UP; tablet_notify_axis(base, time, tool, + tip_state, tablet->changed_axes, axes, deltas, deltas_discrete); + } } memset(tablet->changed_axes, 0, sizeof(tablet->changed_axes)); @@ -786,6 +792,10 @@ tablet_notify_button_mask(struct tablet_dispatch *tablet, struct libinput_device *base = &device->base; size_t i; size_t nbits = 8 * sizeof(buttons[0]) * buttons_len; + enum libinput_tool_tip_state tip_state; + + tip_state = tablet_has_status(tablet, TABLET_TOOL_IN_CONTACT) ? + LIBINPUT_TOOL_TIP_DOWN : LIBINPUT_TOOL_TIP_UP; for (i = 0; i < nbits; i++) { if (!bit_is_set(buttons, i)) @@ -794,6 +804,7 @@ tablet_notify_button_mask(struct tablet_dispatch *tablet, tablet_notify_button(base, time, tool, + tip_state, tablet->axes, i, state); diff --git a/src/libinput-private.h b/src/libinput-private.h index 0e7ddff3..702bf6e8 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -463,6 +463,7 @@ void tablet_notify_axis(struct libinput_device *device, uint64_t time, struct libinput_tool *tool, + enum libinput_tool_tip_state tip_state, unsigned char *changed_axes, double *axes, double *deltas, @@ -487,6 +488,7 @@ void tablet_notify_button(struct libinput_device *device, uint64_t time, struct libinput_tool *tool, + enum libinput_tool_tip_state tip_state, double *axes, int32_t button, enum libinput_button_state state); diff --git a/src/libinput.c b/src/libinput.c index a2a98cc6..479418e2 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -1095,7 +1095,10 @@ libinput_event_tablet_get_tip_state(struct libinput_event_tablet *event) require_event_type(libinput_event_get_context(&event->base), event->base.type, 0, - LIBINPUT_EVENT_TABLET_TIP); + LIBINPUT_EVENT_TABLET_AXIS, + LIBINPUT_EVENT_TABLET_TIP, + LIBINPUT_EVENT_TABLET_BUTTON, + LIBINPUT_EVENT_TABLET_PROXIMITY); return event->tip_state; } @@ -1970,6 +1973,7 @@ void tablet_notify_axis(struct libinput_device *device, uint64_t time, struct libinput_tool *tool, + enum libinput_tool_tip_state tip_state, unsigned char *changed_axes, double *axes, double *deltas, @@ -1985,6 +1989,7 @@ tablet_notify_axis(struct libinput_device *device, .time = time, .tool = tool, .proximity_state = LIBINPUT_TOOL_PROXIMITY_IN, + .tip_state = tip_state, }; memcpy(axis_event->changed_axes, @@ -2069,6 +2074,7 @@ void tablet_notify_button(struct libinput_device *device, uint64_t time, struct libinput_tool *tool, + enum libinput_tool_tip_state tip_state, double *axes, int32_t button, enum libinput_button_state state) @@ -2091,6 +2097,7 @@ tablet_notify_button(struct libinput_device *device, .state = state, .seat_button_count = seat_button_count, .proximity_state = LIBINPUT_TOOL_PROXIMITY_IN, + .tip_state = tip_state, }; memcpy(button_event->axes, axes, sizeof(button_event->axes)); diff --git a/test/tablet.c b/test/tablet.c index 1f3c9471..1bd3f13c 100644 --- a/test/tablet.c +++ b/test/tablet.c @@ -398,6 +398,173 @@ START_TEST(tip_up_motion) } END_TEST +START_TEST(tip_state_proximity) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_tablet *tablet_event; + struct axis_replacement axes[] = { + { ABS_DISTANCE, 10 }, + { -1, -1 } + }; + + litest_drain_events(li); + + litest_tablet_proximity_in(dev, 10, 10, axes); + libinput_dispatch(li); + + event = libinput_get_event(li); + tablet_event = litest_is_tablet_event(event, + LIBINPUT_EVENT_TABLET_PROXIMITY); + ck_assert_int_eq(libinput_event_tablet_get_tip_state(tablet_event), + LIBINPUT_TOOL_TIP_UP); + libinput_event_destroy(event); + + litest_event(dev, EV_KEY, BTN_TOUCH, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_event(dev, EV_KEY, BTN_TOUCH, 0); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_drain_events(li); + + litest_tablet_proximity_out(dev); + libinput_dispatch(li); + + event = libinput_get_event(li); + tablet_event = litest_is_tablet_event(event, + LIBINPUT_EVENT_TABLET_PROXIMITY); + ck_assert_int_eq(libinput_event_tablet_get_tip_state(tablet_event), + LIBINPUT_TOOL_TIP_UP); + libinput_event_destroy(event); +} +END_TEST + +START_TEST(tip_state_axis) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_tablet *tablet_event; + struct axis_replacement axes[] = { + { ABS_DISTANCE, 10 }, + { -1, -1 } + }; + + litest_tablet_proximity_in(dev, 10, 10, axes); + litest_drain_events(li); + + litest_tablet_motion(dev, 70, 70, axes); + libinput_dispatch(li); + + event = libinput_get_event(li); + tablet_event = litest_is_tablet_event(event, + LIBINPUT_EVENT_TABLET_AXIS); + ck_assert_int_eq(libinput_event_tablet_get_tip_state(tablet_event), + LIBINPUT_TOOL_TIP_UP); + libinput_event_destroy(event); + + litest_event(dev, EV_KEY, BTN_TOUCH, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_drain_events(li); + + litest_tablet_motion(dev, 30, 30, axes); + libinput_dispatch(li); + + event = libinput_get_event(li); + tablet_event = litest_is_tablet_event(event, + LIBINPUT_EVENT_TABLET_AXIS); + ck_assert_int_eq(libinput_event_tablet_get_tip_state(tablet_event), + LIBINPUT_TOOL_TIP_DOWN); + libinput_event_destroy(event); + + litest_event(dev, EV_KEY, BTN_TOUCH, 0); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_drain_events(li); + + litest_tablet_motion(dev, 40, 80, axes); + libinput_dispatch(li); + + event = libinput_get_event(li); + tablet_event = litest_is_tablet_event(event, + LIBINPUT_EVENT_TABLET_AXIS); + ck_assert_int_eq(libinput_event_tablet_get_tip_state(tablet_event), + LIBINPUT_TOOL_TIP_UP); + libinput_event_destroy(event); + + litest_assert_empty_queue(li); +} +END_TEST + +START_TEST(tip_state_button) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + struct libinput_event_tablet *tablet_event; + struct axis_replacement axes[] = { + { ABS_DISTANCE, 10 }, + { -1, -1 } + }; + + litest_tablet_proximity_in(dev, 10, 10, axes); + litest_drain_events(li); + + litest_event(dev, EV_KEY, BTN_STYLUS, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + libinput_dispatch(li); + + event = libinput_get_event(li); + tablet_event = litest_is_tablet_event(event, + LIBINPUT_EVENT_TABLET_BUTTON); + ck_assert_int_eq(libinput_event_tablet_get_tip_state(tablet_event), + LIBINPUT_TOOL_TIP_UP); + libinput_event_destroy(event); + + litest_event(dev, EV_KEY, BTN_TOUCH, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_drain_events(li); + + litest_event(dev, EV_KEY, BTN_STYLUS, 0); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + libinput_dispatch(li); + + event = libinput_get_event(li); + tablet_event = litest_is_tablet_event(event, + LIBINPUT_EVENT_TABLET_BUTTON); + ck_assert_int_eq(libinput_event_tablet_get_tip_state(tablet_event), + LIBINPUT_TOOL_TIP_DOWN); + libinput_event_destroy(event); + + litest_event(dev, EV_KEY, BTN_TOUCH, 0); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_drain_events(li); + + litest_event(dev, EV_KEY, BTN_STYLUS, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + libinput_dispatch(li); + + event = libinput_get_event(li); + tablet_event = litest_is_tablet_event(event, + LIBINPUT_EVENT_TABLET_BUTTON); + ck_assert_int_eq(libinput_event_tablet_get_tip_state(tablet_event), + LIBINPUT_TOOL_TIP_UP); + libinput_event_destroy(event); + + litest_event(dev, EV_KEY, BTN_STYLUS, 0); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + libinput_dispatch(li); + + event = libinput_get_event(li); + tablet_event = litest_is_tablet_event(event, + LIBINPUT_EVENT_TABLET_BUTTON); + ck_assert_int_eq(libinput_event_tablet_get_tip_state(tablet_event), + LIBINPUT_TOOL_TIP_UP); + libinput_event_destroy(event); + + litest_assert_empty_queue(li); +} +END_TEST + START_TEST(proximity_in_out) { struct litest_device *dev = litest_current_device(); @@ -2160,6 +2327,9 @@ litest_setup_tests(void) litest_add("tablet:tip", tip_up_btn_change, LITEST_TABLET, LITEST_ANY); litest_add("tablet:tip", tip_down_motion, LITEST_TABLET, LITEST_ANY); litest_add("tablet:tip", tip_up_motion, LITEST_TABLET, LITEST_ANY); + litest_add("tablet:tip", tip_state_proximity, LITEST_TABLET, LITEST_ANY); + litest_add("tablet:tip", tip_state_axis, LITEST_TABLET, LITEST_ANY); + litest_add("tablet:tip", tip_state_button, LITEST_TABLET, LITEST_ANY); litest_add("tablet:motion", motion, LITEST_TABLET, LITEST_ANY); litest_add("tablet:motion", motion_delta, LITEST_TABLET, LITEST_ANY); litest_add("tablet:motion", motion_delta_partial, LITEST_TABLET, LITEST_ANY);