From 99015345065eae0858a051fe4c5ef82a0b1f65ff Mon Sep 17 00:00:00 2001 From: Louis Goyard Date: Tue, 12 Mar 2024 00:08:19 +0900 Subject: [PATCH 1/7] tablet: Add LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS --- src/libinput.c | 104 +++++++++++++++++++++++----------- src/libinput.h | 7 +++ test/litest.c | 3 + tools/libinput-debug-events.c | 13 +++++ tools/libinput-debug-gui.c | 22 ++++++- 5 files changed, 114 insertions(+), 35 deletions(-) diff --git a/src/libinput.c b/src/libinput.c index 5bebe56b..c5d9ea5d 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -100,6 +100,7 @@ event_type_to_str(enum libinput_event_type type) CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_TIP); CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_BUTTON); + CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_BUTTON); CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_RING); CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_STRIP); @@ -436,7 +437,8 @@ libinput_event_get_tablet_tool_event(struct libinput_event *event) LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, LIBINPUT_EVENT_TABLET_TOOL_TIP, - LIBINPUT_EVENT_TABLET_TOOL_BUTTON); + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return (struct libinput_event_tablet_tool *) event; } @@ -1133,7 +1135,8 @@ libinput_event_tablet_tool_x_has_changed( LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return bit_is_set(event->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_X); @@ -1149,7 +1152,8 @@ libinput_event_tablet_tool_y_has_changed( LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return bit_is_set(event->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_Y); @@ -1165,7 +1169,8 @@ libinput_event_tablet_tool_pressure_has_changed( LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return bit_is_set(event->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_PRESSURE); @@ -1181,7 +1186,8 @@ libinput_event_tablet_tool_distance_has_changed( LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return bit_is_set(event->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_DISTANCE); @@ -1197,7 +1203,8 @@ libinput_event_tablet_tool_tilt_x_has_changed( LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return bit_is_set(event->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_TILT_X); @@ -1213,7 +1220,8 @@ libinput_event_tablet_tool_tilt_y_has_changed( LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return bit_is_set(event->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_TILT_Y); @@ -1229,7 +1237,8 @@ libinput_event_tablet_tool_rotation_has_changed( LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return bit_is_set(event->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z); @@ -1245,7 +1254,8 @@ libinput_event_tablet_tool_slider_has_changed( LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return bit_is_set(event->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_SLIDER); @@ -1261,7 +1271,8 @@ libinput_event_tablet_tool_size_major_has_changed( LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return bit_is_set(event->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_SIZE_MAJOR); @@ -1277,7 +1288,8 @@ libinput_event_tablet_tool_size_minor_has_changed( LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return bit_is_set(event->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_SIZE_MINOR); @@ -1293,7 +1305,8 @@ libinput_event_tablet_tool_wheel_has_changed( LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return bit_is_set(event->changed_axes, LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL); @@ -1310,7 +1323,8 @@ libinput_event_tablet_tool_get_x(struct libinput_event_tablet_tool *event) LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return evdev_convert_to_mm(device->abs.absinfo_x, event->axes.point.x); @@ -1327,7 +1341,8 @@ libinput_event_tablet_tool_get_y(struct libinput_event_tablet_tool *event) LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return evdev_convert_to_mm(device->abs.absinfo_y, event->axes.point.y); @@ -1342,7 +1357,8 @@ libinput_event_tablet_tool_get_dx(struct libinput_event_tablet_tool *event) LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return event->axes.delta.x; } @@ -1356,7 +1372,8 @@ libinput_event_tablet_tool_get_dy(struct libinput_event_tablet_tool *event) LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return event->axes.delta.y; } @@ -1370,7 +1387,8 @@ libinput_event_tablet_tool_get_pressure(struct libinput_event_tablet_tool *event LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return event->axes.pressure; } @@ -1384,7 +1402,8 @@ libinput_event_tablet_tool_get_distance(struct libinput_event_tablet_tool *event LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return event->axes.distance; } @@ -1398,7 +1417,8 @@ libinput_event_tablet_tool_get_tilt_x(struct libinput_event_tablet_tool *event) LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return event->axes.tilt.x; } @@ -1412,7 +1432,8 @@ libinput_event_tablet_tool_get_tilt_y(struct libinput_event_tablet_tool *event) LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return event->axes.tilt.y; } @@ -1426,7 +1447,8 @@ libinput_event_tablet_tool_get_rotation(struct libinput_event_tablet_tool *event LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return event->axes.rotation; } @@ -1440,7 +1462,8 @@ libinput_event_tablet_tool_get_slider_position(struct libinput_event_tablet_tool LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return event->axes.slider; } @@ -1454,7 +1477,8 @@ libinput_event_tablet_tool_get_size_major(struct libinput_event_tablet_tool *eve LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return event->axes.size.major; } @@ -1468,7 +1492,8 @@ libinput_event_tablet_tool_get_size_minor(struct libinput_event_tablet_tool *eve LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return event->axes.size.minor; } @@ -1482,7 +1507,8 @@ libinput_event_tablet_tool_get_wheel_delta(struct libinput_event_tablet_tool *ev LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return event->axes.wheel; } @@ -1497,7 +1523,8 @@ libinput_event_tablet_tool_get_wheel_delta_discrete( LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return event->axes.wheel_discrete; } @@ -1514,7 +1541,8 @@ libinput_event_tablet_tool_get_x_transformed(struct libinput_event_tablet_tool * LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return evdev_device_transform_x(device, event->axes.point.x, @@ -1533,7 +1561,8 @@ libinput_event_tablet_tool_get_y_transformed(struct libinput_event_tablet_tool * LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return evdev_device_transform_y(device, event->axes.point.y, @@ -1549,7 +1578,8 @@ libinput_event_tablet_tool_get_tool(struct libinput_event_tablet_tool *event) LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return event->tool; } @@ -1563,7 +1593,8 @@ libinput_event_tablet_tool_get_proximity_state(struct libinput_event_tablet_tool LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return event->proximity_state; } @@ -1577,7 +1608,8 @@ libinput_event_tablet_tool_get_tip_state(struct libinput_event_tablet_tool *even LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return event->tip_state; } @@ -1591,7 +1623,8 @@ libinput_event_tablet_tool_get_time(struct libinput_event_tablet_tool *event) LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return us2ms(event->time); } @@ -1605,7 +1638,8 @@ libinput_event_tablet_tool_get_time_usec(struct libinput_event_tablet_tool *even LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, - LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); + LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return event->time; } @@ -2026,6 +2060,7 @@ libinput_event_destroy(struct libinput_event *event) case LIBINPUT_EVENT_TABLET_TOOL_AXIS: case LIBINPUT_EVENT_TABLET_TOOL_TIP: case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: + case LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS: libinput_event_tablet_tool_destroy( libinput_event_get_tablet_tool_event(event)); break; @@ -3642,7 +3677,8 @@ libinput_event_tablet_tool_get_base_event(struct libinput_event_tablet_tool *eve LIBINPUT_EVENT_TABLET_TOOL_AXIS, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, - LIBINPUT_EVENT_TABLET_TOOL_BUTTON); + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); return &event->base; } diff --git a/src/libinput.h b/src/libinput.h index 85403be5..21e35710 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -941,6 +941,13 @@ enum libinput_event_type { */ LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + /** + * A scroll event caused by the movement of tablet tool while scroll button is holded + * + * @since FIXME + */ + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS, + /** * A button pressed on a device with the @ref * LIBINPUT_DEVICE_CAP_TABLET_PAD capability. diff --git a/test/litest.c b/test/litest.c index 792b0a54..81a3cf72 100644 --- a/test/litest.c +++ b/test/litest.c @@ -3214,6 +3214,9 @@ litest_event_type_str(enum libinput_event_type type) case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: str = "TABLET TOOL BUTTON"; break; + case LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS: + str = "TABLET TOOL SCROLL CONTINOUS"; + break; case LIBINPUT_EVENT_TABLET_PAD_BUTTON: str = "TABLET PAD BUTTON"; break; diff --git a/tools/libinput-debug-events.c b/tools/libinput-debug-events.c index 6230b18f..287d792e 100644 --- a/tools/libinput-debug-events.c +++ b/tools/libinput-debug-events.c @@ -146,6 +146,9 @@ print_event_header(struct libinput_event *ev) case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: type = "TABLET_TOOL_BUTTON"; break; + case LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS: + type = "TABLET_TOOL_SCROLL_CONTINOUS"; + break; case LIBINPUT_EVENT_TABLET_PAD_BUTTON: type = "TABLET_PAD_BUTTON"; break; @@ -490,6 +493,13 @@ print_tablet_button_event(struct libinput_event *ev) libinput_event_tablet_tool_get_seat_button_count(p)); } +static void +print_tablet_tool_scroll_event(struct libinput_event *ev) +{ + // FIXME: done in a later commit + printq("FIXME"); +} + static void print_pointer_axis_event(struct libinput_event *ev) { @@ -949,6 +959,9 @@ handle_and_print_events(struct libinput *li) case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: print_tablet_button_event(ev); break; + case LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS: + print_tablet_tool_scroll_event(ev); + break; case LIBINPUT_EVENT_TABLET_PAD_BUTTON: print_tablet_pad_button_event(ev); break; diff --git a/tools/libinput-debug-gui.c b/tools/libinput-debug-gui.c index a1300c64..503b7a7d 100644 --- a/tools/libinput-debug-gui.c +++ b/tools/libinput-debug-gui.c @@ -1476,7 +1476,7 @@ handle_event_touch(struct libinput_event *ev, struct window *w) } static void -handle_event_axis(struct libinput_event *ev, struct window *w) +handle_event_pointer_axis(struct libinput_event *ev, struct window *w) { struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev); double value; @@ -1510,6 +1510,25 @@ handle_event_axis(struct libinput_event *ev, struct window *w) } } +static void +handle_event_tablet_tool_axis(struct libinput_event *ev, struct window *w) +{ + // FIXME: done in a later commit +} + +static void +handle_event_axis(struct libinput_event *ev, struct window *w) +{ + switch (libinput_event_get_type(ev)){ + case LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS: + handle_event_tablet_tool_axis(ev, w); + break; + default: + handle_event_pointer_axis(ev, w); + break; + } +} + static int handle_event_keyboard(struct libinput_event *ev, struct window *w) { @@ -1816,6 +1835,7 @@ handle_event_libinput(GIOChannel *source, GIOCondition condition, gpointer data) case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL: case LIBINPUT_EVENT_POINTER_SCROLL_FINGER: case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS: + case LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS: handle_event_axis(ev, w); break; case LIBINPUT_EVENT_POINTER_BUTTON: From e335f4397172548c9d0ad3f8b3a7cbd69cb97f70 Mon Sep 17 00:00:00 2001 From: Louis Goyard Date: Tue, 12 Mar 2024 00:08:20 +0900 Subject: [PATCH 2/7] tablet: enable tablet change button scroll method --- src/evdev-tablet.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c index c2dce5bf..c028da9b 100644 --- a/src/evdev-tablet.c +++ b/src/evdev-tablet.c @@ -2734,6 +2734,27 @@ tablet_fix_tilt(struct tablet_dispatch *tablet, } } +static void +tablet_change_scroll_method(struct evdev_device *device) +{ + // FIXME + //struct tablet_dispatch *dispatch = tablet_dispatch(device->dispatch); + + if (device->scroll.want_method == device->scroll.method && + device->scroll.want_button == device->scroll.button && + device->scroll.want_lock_enabled == device->scroll.lock_enabled) + return; + + // FIXME + //if (tablet_any_button_down(dispatch, device)) + // return; + + device->scroll.method = device->scroll.want_method; + device->scroll.button = device->scroll.want_button; + device->scroll.lock_enabled = device->scroll.want_lock_enabled; + evdev_set_button_scroll_lock_enabled(device, device->scroll.lock_enabled); +} + static int tablet_init(struct tablet_dispatch *tablet, struct evdev_device *device) @@ -2747,6 +2768,9 @@ tablet_init(struct tablet_dispatch *tablet, tablet->device = device; tablet->status = TABLET_NONE; tablet->current_tool.type = LIBINPUT_TOOL_NONE; + + evdev_init_button_scroll(device, tablet_change_scroll_method); + list_init(&tablet->tool_list); if (tablet_reject_device(device)) From 27a66310fc0651022e0de7fbb8a64b2e97340344 Mon Sep 17 00:00:00 2001 From: Louis Goyard Date: Tue, 12 Mar 2024 00:08:21 +0900 Subject: [PATCH 3/7] tablet: add evdev/libinput functions for tablet scroll --- src/evdev.c | 129 +++++++++++++++++++++++++++++++++++++++++ src/evdev.h | 24 ++++++++ src/libinput-private.h | 16 +++++ src/libinput.c | 125 +++++++++++++++++++++++++++++++++++++++ src/libinput.h | 29 +++++++++ src/libinput.sym | 3 + 6 files changed, 326 insertions(+) diff --git a/src/evdev.c b/src/evdev.c index da538df7..9ff26d7f 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -499,6 +499,27 @@ evdev_notify_axis_continous(struct evdev_device *device, &delta); } +void +evdev_notify_axis_tablet_tool_continous(struct evdev_device *device, + uint64_t time, + struct libinput_tablet_tool *tool, + uint32_t scroll_axes, + const struct normalized_coords *delta_in) +{ + struct normalized_coords delta = *delta_in; + + if (device->scroll.natural_scrolling_enabled) { + delta.x *= -1; + delta.y *= -1; + } + + tablet_tool_notify_axis_continuous(&device->base, + time, + tool, + scroll_axes, + &delta); +} + static void evdev_tag_external_mouse(struct evdev_device *device, struct udev_device *udev_device) @@ -2932,6 +2953,114 @@ evdev_stop_scroll(struct evdev_device *device, device->scroll.direction = 0; } +void +evdev_post_tablet_tool_scroll(struct evdev_device *device, + uint64_t time, + struct libinput_tablet_tool *tool, + enum libinput_tablet_tool_axis_source source, + const struct normalized_coords *delta) +{ + const struct normalized_coords *trigger; + struct normalized_coords event; + + if (!evdev_is_scrolling(device, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) + device->scroll.buildup.y += delta->y; + if (!evdev_is_scrolling(device, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) + device->scroll.buildup.x += delta->x; + + trigger = &device->scroll.buildup; + + /* If we're not scrolling yet, use a distance trigger: moving + past a certain distance starts scrolling */ + if (!evdev_is_scrolling(device, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL) && + !evdev_is_scrolling(device, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) { + if (fabs(trigger->y) >= device->scroll.threshold) + evdev_start_scrolling(device, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); + if (fabs(trigger->x) >= device->scroll.threshold) + evdev_start_scrolling(device, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); + /* We're already scrolling in one direction. Require some + trigger speed to start scrolling in the other direction */ + } else if (!evdev_is_scrolling(device, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) { + if (fabs(delta->y) >= device->scroll.direction_lock_threshold) + evdev_start_scrolling(device, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); + } else if (!evdev_is_scrolling(device, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) { + if (fabs(delta->x) >= device->scroll.direction_lock_threshold) + evdev_start_scrolling(device, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); + } + + event = *delta; + + /* We use the trigger to enable, but the delta from this event for + * the actual scroll movement. Otherwise we get a jump once + * scrolling engages */ + if (!evdev_is_scrolling(device, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) + event.y = 0.0; + + if (!evdev_is_scrolling(device, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) + event.x = 0.0; + + if (!normalized_is_zero(event)) { + uint32_t scroll_axes = device->scroll.direction; + + if (event.y == 0.0) + scroll_axes &= ~bit(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); + if (event.x == 0.0) + scroll_axes &= ~bit(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); + + switch (source) { + case LIBINPUT_TABLET_TOOL_AXIS_SOURCE_CONTINUOUS: + evdev_notify_axis_tablet_tool_continous(device, time, tool, scroll_axes, &event); + break; + default: + evdev_log_bug_libinput(device, + "Posting invalid scroll source %d\n", + source); + break; + } + } +} + +void +evdev_stop_tablet_tool_scroll(struct evdev_device *device, + uint64_t time, + enum libinput_tablet_tool_axis_source source) +{ + const struct normalized_coords zero = { 0.0, 0.0 }; + + /* terminate scrolling with a zero scroll event */ + if (device->scroll.direction != 0) { + switch (source) { + case LIBINPUT_TABLET_TOOL_AXIS_SOURCE_CONTINUOUS: + pointer_notify_axis_continuous(&device->base, + time, + device->scroll.direction, + &zero); + break; + default: + evdev_log_bug_libinput(device, + "Stopping invalid scroll source %d\n", + source); + break; + } + } + + device->scroll.buildup.x = 0; + device->scroll.buildup.y = 0; + device->scroll.direction = 0; +} + void evdev_notify_suspended_device(struct evdev_device *device) { diff --git a/src/evdev.h b/src/evdev.h index f954938c..43e8c300 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -568,6 +568,11 @@ evdev_pointer_notify_button(struct evdev_device *device, unsigned int button, enum libinput_button_state state); void +evdev_tablet_tool_notify_button(struct evdev_device *device, + uint64_t time, + unsigned int button, + enum libinput_button_state state); +void evdev_pointer_notify_physical_button(struct evdev_device *device, uint64_t time, int button, @@ -612,6 +617,13 @@ evdev_notify_axis_continous(struct evdev_device *device, uint32_t axes, const struct normalized_coords *delta_in); +void +evdev_notify_axis_tablet_tool_continous(struct evdev_device *device, + uint64_t time, + struct libinput_tablet_tool *tool, + uint32_t scroll_axes, + const struct normalized_coords *delta_in); + void evdev_post_scroll(struct evdev_device *device, uint64_t time, @@ -623,6 +635,18 @@ evdev_stop_scroll(struct evdev_device *device, uint64_t time, enum libinput_pointer_axis_source source); +void +evdev_post_tablet_tool_scroll(struct evdev_device *device, + uint64_t time, + struct libinput_tablet_tool *tool, + enum libinput_tablet_tool_axis_source source, + const struct normalized_coords *delta); + +void +evdev_stop_tablet_tool_scroll(struct evdev_device *device, + uint64_t time, + enum libinput_tablet_tool_axis_source source); + void evdev_device_remove(struct evdev_device *device); diff --git a/src/libinput-private.h b/src/libinput-private.h index de1d7d64..fc48728b 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -672,6 +672,13 @@ pointer_notify_axis_continuous(struct libinput_device *device, uint32_t axes, const struct normalized_coords *delta); +void +tablet_tool_notify_axis_continuous(struct libinput_device *device, + uint64_t time, + struct libinput_tablet_tool *tool, + uint32_t scroll_axes, + const struct normalized_coords *delta); + void pointer_notify_axis_legacy_wheel(struct libinput_device *device, uint64_t time, @@ -782,6 +789,15 @@ tablet_notify_tip(struct libinput_device *device, unsigned char *changed_axes, const struct tablet_axes *axes); +void +tablet_tool_notify_button(struct libinput_device *device, + uint64_t time, + struct libinput_tablet_tool *tool, + enum libinput_tablet_tool_tip_state tip_state, + const struct tablet_axes *axes, + int32_t button, + enum libinput_button_state state); + void tablet_notify_button(struct libinput_device *device, uint64_t time, diff --git a/src/libinput.c b/src/libinput.c index c5d9ea5d..dccc1043 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -58,6 +58,7 @@ ASSERT_INT_SIZE(enum libinput_pointer_axis); ASSERT_INT_SIZE(enum libinput_pointer_axis_source); ASSERT_INT_SIZE(enum libinput_tablet_pad_ring_axis_source); ASSERT_INT_SIZE(enum libinput_tablet_pad_strip_axis_source); +ASSERT_INT_SIZE(enum libinput_tablet_tool_axis_source); ASSERT_INT_SIZE(enum libinput_tablet_tool_type); ASSERT_INT_SIZE(enum libinput_tablet_tool_proximity_state); ASSERT_INT_SIZE(enum libinput_tablet_tool_tip_state); @@ -214,11 +215,15 @@ struct libinput_event_tablet_tool { enum libinput_button_state state; uint32_t seat_button_count; uint64_t time; + struct normalized_coords delta; struct tablet_axes axes; unsigned char changed_axes[NCHARS(LIBINPUT_TABLET_TOOL_AXIS_MAX + 1)]; struct libinput_tablet_tool *tool; enum libinput_tablet_tool_proximity_state proximity_state; enum libinput_tablet_tool_tip_state tip_state; + + enum libinput_tablet_tool_axis_source source; + uint32_t scroll_axes; }; struct libinput_event_tablet_pad { @@ -728,6 +733,24 @@ libinput_event_pointer_has_axis(struct libinput_event_pointer *event, return 0; } +LIBINPUT_EXPORT int +libinput_event_tablet_tool_has_axis(struct libinput_event_tablet_tool *event, + enum libinput_pointer_axis axis) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); + + switch (axis) { + case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: + case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: + return !!(event->scroll_axes & bit(axis)); + } + + return 0; +} + LIBINPUT_EXPORT double libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event, enum libinput_pointer_axis axis) @@ -812,6 +835,33 @@ libinput_event_pointer_get_scroll_value(struct libinput_event_pointer *event, return value; } +LIBINPUT_EXPORT double +libinput_event_tablet_tool_get_scroll_value(struct libinput_event_tablet_tool *event, + enum libinput_pointer_axis axis) +{ + struct libinput *libinput = event->base.device->seat->libinput; + double value = 0; + + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + 0.0, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); + + if (!libinput_event_tablet_tool_has_axis(event, axis)) { + log_bug_client(libinput, "value requested for unset axis\n"); + } else { + switch (axis) { + case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: + value = event->delta.x; + break; + case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: + value = event->delta.y; + break; + } + } + return value; +} + LIBINPUT_EXPORT double libinput_event_pointer_get_scroll_value_v120(struct libinput_event_pointer *event, enum libinput_pointer_axis axis) @@ -2552,6 +2602,43 @@ pointer_notify_button(struct libinput_device *device, &button_event->base); } +void +tablet_tool_notify_button(struct libinput_device *device, + uint64_t time, + struct libinput_tablet_tool *tool, + enum libinput_tablet_tool_tip_state tip_state, + const struct tablet_axes *axes, + int32_t button, + enum libinput_button_state state) +{ + struct libinput_event_tablet_tool *button_event; + int32_t seat_button_count; + + if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_TABLET_TOOL)) + return; + + button_event = zalloc(sizeof *button_event); + + seat_button_count = update_seat_button_count(device->seat, + button, + state); + + *button_event = (struct libinput_event_tablet_tool) { + .time = time, + .tool = libinput_tablet_tool_ref(tool), + .button = button, + .state = state, + .seat_button_count = seat_button_count, + .proximity_state = LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN, + .tip_state = tip_state, + .axes = *axes, + }; + + post_device_event(device, time, + LIBINPUT_EVENT_TABLET_TOOL_BUTTON, + &button_event->base); +} + void pointer_notify_axis_finger(struct libinput_device *device, uint64_t time, @@ -2620,6 +2707,33 @@ pointer_notify_axis_continuous(struct libinput_device *device, &axis_event_legacy->base); } +void +tablet_tool_notify_axis_continuous(struct libinput_device *device, + uint64_t time, + struct libinput_tablet_tool *tool, + uint32_t scroll_axes, + const struct normalized_coords *delta) +{ + struct libinput_event_tablet_tool *axis_event; + + if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_TABLET_TOOL)) + return; + + axis_event = zalloc(sizeof *axis_event); + + *axis_event = (struct libinput_event_tablet_tool) { + .time = time, + .tool = libinput_tablet_tool_ref(tool), + .delta = *delta, + .source = LIBINPUT_TABLET_TOOL_AXIS_SOURCE_CONTINUOUS, + .scroll_axes = scroll_axes, + }; + + post_device_event(device, time, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS, + &axis_event->base); +} + void pointer_notify_axis_legacy_wheel(struct libinput_device *device, uint64_t time, @@ -3771,6 +3885,17 @@ libinput_event_tablet_pad_get_strip_source(struct libinput_event_tablet_pad *eve return event->strip.source; } +LIBINPUT_EXPORT enum libinput_tablet_tool_axis_source +libinput_event_tablet_tool_get_axis_source(struct libinput_event_tablet_tool *event) +{ + require_event_type(libinput_event_get_context(&event->base), + event->base.type, + LIBINPUT_TABLET_TOOL_AXIS_SOURCE_CONTINUOUS, + LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS); + + return event->source; +} + LIBINPUT_EXPORT uint32_t libinput_event_tablet_pad_get_button_number(struct libinput_event_tablet_pad *event) { diff --git a/src/libinput.h b/src/libinput.h index 21e35710..782f2fad 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -321,6 +321,24 @@ enum libinput_tablet_pad_strip_axis_source { LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER, }; +/** + * @ingroup event_tablet_pad + * + * The source for a @ref LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS event. + * See libinput_event_tablet_tool_get_axis_source() for details. + * + * @since 1.3 + */ +enum libinput_tablet_tool_axis_source { + LIBINPUT_TABLET_TOOL_AXIS_SOURCE_UNKNOWN = 1, + + /** + * The event is caused by the movement of the tool + * while the scroll button is being held down + */ + LIBINPUT_TABLET_TOOL_AXIS_SOURCE_CONTINUOUS, +}; + /** * @ingroup device * @@ -1542,6 +1560,10 @@ int libinput_event_pointer_has_axis(struct libinput_event_pointer *event, enum libinput_pointer_axis axis); +int +libinput_event_tablet_tool_has_axis(struct libinput_event_tablet_tool *event, + enum libinput_pointer_axis axis); + /** * @ingroup event_pointer * @@ -1700,6 +1722,10 @@ double libinput_event_pointer_get_scroll_value(struct libinput_event_pointer *event, enum libinput_pointer_axis axis); +double +libinput_event_tablet_tool_get_scroll_value(struct libinput_event_tablet_tool *event, + enum libinput_pointer_axis axis); + /** * @ingroup event_pointer * @@ -3269,6 +3295,9 @@ libinput_event_tablet_pad_get_strip_number(struct libinput_event_tablet_pad *eve enum libinput_tablet_pad_strip_axis_source libinput_event_tablet_pad_get_strip_source(struct libinput_event_tablet_pad *event); +enum libinput_tablet_tool_axis_source +libinput_event_tablet_tool_get_axis_source(struct libinput_event_tablet_tool *event); + /** * @ingroup event_tablet_pad * diff --git a/src/libinput.sym b/src/libinput.sym index 3624401c..1930e350 100644 --- a/src/libinput.sym +++ b/src/libinput.sym @@ -346,4 +346,7 @@ LIBINPUT_1.26 { libinput_tablet_tool_config_pressure_range_get_maximum; libinput_tablet_tool_config_pressure_range_get_default_minimum; libinput_tablet_tool_config_pressure_range_get_default_maximum; + libinput_event_tablet_tool_has_axis; + libinput_event_tablet_tool_get_scroll_value; + libinput_event_tablet_tool_get_axis_source; } LIBINPUT_1.23; From a18bb8e411487ce70cecb3e8956c6409f0219e8c Mon Sep 17 00:00:00 2001 From: Louis Goyard Date: Tue, 12 Mar 2024 00:08:21 +0900 Subject: [PATCH 4/7] tablet: move tablet_get_current_tool up for future needs --- src/evdev-tablet.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c index c028da9b..75ca81ea 100644 --- a/src/evdev-tablet.c +++ b/src/evdev-tablet.c @@ -1312,6 +1312,18 @@ tablet_get_tool(struct tablet_dispatch *tablet, return tool; } +static struct libinput_tablet_tool * +tablet_get_current_tool(struct tablet_dispatch *tablet) +{ + if (tablet->current_tool.type == LIBINPUT_TOOL_NONE) + return NULL; + + return tablet_get_tool(tablet, + tablet->current_tool.type, + tablet->current_tool.id, + tablet->current_tool.serial); +} + static void tablet_notify_button_mask(struct tablet_dispatch *tablet, struct evdev_device *device, @@ -2061,18 +2073,6 @@ tablet_update_tool_state(struct tablet_dispatch *tablet, return false; } -static struct libinput_tablet_tool * -tablet_get_current_tool(struct tablet_dispatch *tablet) -{ - if (tablet->current_tool.type == LIBINPUT_TOOL_NONE) - return NULL; - - return tablet_get_tool(tablet, - tablet->current_tool.type, - tablet->current_tool.id, - tablet->current_tool.serial); -} - static void tablet_flush(struct tablet_dispatch *tablet, struct evdev_device *device, From 0ae8e69ca8f868c00977bf02971c3d881b42d225 Mon Sep 17 00:00:00 2001 From: Louis Goyard Date: Tue, 12 Mar 2024 00:08:21 +0900 Subject: [PATCH 5/7] tablet: add tablet tool main functions --- src/evdev-tablet.c | 160 +++++++++++++++++++++++++++++++++++++++++++++ src/evdev-tablet.h | 1 + 2 files changed, 161 insertions(+) diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c index 75ca81ea..be10ce6d 100644 --- a/src/evdev-tablet.c +++ b/src/evdev-tablet.c @@ -1324,6 +1324,159 @@ tablet_get_current_tool(struct tablet_dispatch *tablet) tablet->current_tool.serial); } +static void +evdev_tablet_stop_scroll(struct evdev_device *device, + struct libinput_tablet_tool* tool, + uint64_t time, + enum libinput_tablet_tool_axis_source source) +{ + const struct normalized_coords zero = { 0.0, 0.0 }; + + /* terminate scrolling with a zero scroll event */ + if (device->scroll.direction != 0) { + switch (source) { + case LIBINPUT_TABLET_TOOL_AXIS_SOURCE_CONTINUOUS: + evdev_notify_axis_tablet_tool_continous(device, + time, + tool, + device->scroll.direction, + &zero); + break; + default: + evdev_log_bug_libinput(device, + "Stopping invalid scroll source %d\n", + source); + break; + } + } + + device->scroll.buildup.x = 0; + device->scroll.buildup.y = 0; + device->scroll.direction = 0; +} + +#define DEFAULT_BUTTON_SCROLL_TIMEOUT ms2us(200) +static inline void +tablet_notify_button_scroll(struct evdev_device *device, + struct tablet_dispatch *tablet, + uint64_t time, + bool is_press) +{ + if (is_press) { + device->scroll.button_scroll_state = BUTTONSCROLL_BUTTON_DOWN; + + enum timer_flags flags = TIMER_FLAG_NONE; + libinput_timer_set_flags(&device->scroll.timer, + time + DEFAULT_BUTTON_SCROLL_TIMEOUT, + flags); + device->scroll.button_down_time = time; + evdev_log_debug(device, "btnscroll: down\n"); + } else { + struct libinput_tablet_tool *tool; + tool = tablet_get_current_tool(tablet); + if (!tool) + return; /* OOM */ + + libinput_timer_cancel(&device->scroll.timer); + switch(device->scroll.button_scroll_state) { + case BUTTONSCROLL_IDLE: + evdev_log_bug_libinput(device, + "invalid state IDLE for button up\n"); + break; + case BUTTONSCROLL_BUTTON_DOWN: + case BUTTONSCROLL_READY: + evdev_log_debug(device, "btnscroll: cancel\n"); + + enum libinput_tablet_tool_tip_state tip_state; + if (tablet_has_status(tablet, TABLET_TOOL_IN_CONTACT)) + tip_state = LIBINPUT_TABLET_TOOL_TIP_DOWN; + else + tip_state = LIBINPUT_TABLET_TOOL_TIP_UP; + + /* If the button is released quickly enough or + * without scroll events, emit the + * button press/release events. */ + tablet_notify_button(&device->base, + device->scroll.button_down_time, + tool, + tip_state, + &tablet->axes, + device->scroll.button, + LIBINPUT_BUTTON_STATE_PRESSED); + tablet_notify_button(&device->base, + time, + tool, + tip_state, + &tablet->axes, + device->scroll.button, + LIBINPUT_BUTTON_STATE_RELEASED); + break; + case BUTTONSCROLL_SCROLLING: + evdev_log_debug(device, "btnscroll: up\n"); + evdev_tablet_stop_scroll(device, tool, time, + LIBINPUT_TABLET_TOOL_AXIS_SOURCE_CONTINUOUS); + break; + } + + device->scroll.button_scroll_state = BUTTONSCROLL_IDLE; + } +} +#undef DEFAULT_BUTTON_SCROLL_TIMEOUT + +#define __SIGN(x) ((x > 0) - (x < 0)) +#define TABLET_TOOL_SCROLL_MINIMUM 2 +#define TABLET_TOOL_SCROLL_REDUCER 8 +static inline bool +post_button_scroll(struct evdev_device *device, + struct tablet_dispatch *tablet, + uint64_t time) +{ + if (device->scroll.method != LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) + return false; + + switch(device->scroll.button_scroll_state) { + case BUTTONSCROLL_IDLE: + return false; + case BUTTONSCROLL_BUTTON_DOWN: + /* if the button is down but scroll is not active, we're within the + timeout where we swallow motion events but don't post + scroll buttons */ + evdev_log_debug(device, "btnscroll: discarding\n"); + return true; + case BUTTONSCROLL_READY: + device->scroll.button_scroll_state = BUTTONSCROLL_SCROLLING; + _fallthrough_; + case BUTTONSCROLL_SCROLLING: + { + struct normalized_coords normalized = { tablet->current_value[1] - tablet->prev_value[1] , tablet->current_value[2] - tablet->prev_value[2] }; + + normalized.x = normalized.x / TABLET_TOOL_SCROLL_REDUCER; + normalized.y = normalized.y / TABLET_TOOL_SCROLL_REDUCER; + + if (fabs(normalized.x) < TABLET_TOOL_SCROLL_MINIMUM) + normalized.x = 0; + else + normalized.x -= __SIGN(normalized.x)*(TABLET_TOOL_SCROLL_MINIMUM-1); + + if (fabs(normalized.y) < TABLET_TOOL_SCROLL_MINIMUM) + normalized.y = 0; + else + normalized.y -= __SIGN(normalized.y)*(TABLET_TOOL_SCROLL_MINIMUM-1); + + evdev_post_tablet_tool_scroll(device, time, + tablet_get_current_tool(tablet), + LIBINPUT_TABLET_TOOL_AXIS_SOURCE_CONTINUOUS, + &normalized); + } + return true; + } + + assert(!"invalid scroll button state"); +} +#undef TABLET_TOOL_SCROLL_REDUCER +#undef TABLET_TOOL_SCROLL_MINIMUM +#undef __SIGN + static void tablet_notify_button_mask(struct tablet_dispatch *tablet, struct evdev_device *device, @@ -1346,6 +1499,11 @@ tablet_notify_button_mask(struct tablet_dispatch *tablet, if (!bit_is_set(buttons->bits, i)) continue; + if (device->scroll.method == LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN && i == device->scroll.button){ + tablet_notify_button_scroll(device, tablet, time, state == LIBINPUT_BUTTON_STATE_PRESSED); + continue; + } + tablet_notify_button(base, time, tool, @@ -2117,6 +2275,8 @@ reprocess: sanitize_tablet_axes(tablet, tool); } + post_button_scroll(device, tablet, time); + tablet_send_events(tablet, tool, device, time); if (process_tool_twice) diff --git a/src/evdev-tablet.h b/src/evdev-tablet.h index 48469a2b..64f0242b 100644 --- a/src/evdev-tablet.h +++ b/src/evdev-tablet.h @@ -47,6 +47,7 @@ enum tablet_status { TABLET_TOOL_ENTERING_CONTACT = bit(9), TABLET_TOOL_LEAVING_CONTACT = bit(10), TABLET_TOOL_OUT_OF_RANGE = bit(11), + TABLET_IN_SCROLL = bit(12), }; struct button_state { From 78d2bd9dad714c7d4d47f24fd320e33681c2e190 Mon Sep 17 00:00:00 2001 From: Louis Goyard Date: Tue, 12 Mar 2024 00:08:31 +0900 Subject: [PATCH 6/7] tablet: add tablet tool scrolling to debug tools --- tools/libinput-debug-events.c | 35 +++++++++++++++++++++++++++++++++-- tools/libinput-debug-gui.c | 20 +++++++++++++++++++- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/tools/libinput-debug-events.c b/tools/libinput-debug-events.c index 287d792e..301df11b 100644 --- a/tools/libinput-debug-events.c +++ b/tools/libinput-debug-events.c @@ -496,8 +496,39 @@ print_tablet_button_event(struct libinput_event *ev) static void print_tablet_tool_scroll_event(struct libinput_event *ev) { - // FIXME: done in a later commit - printq("FIXME"); + struct libinput_event_tablet_tool *t = libinput_event_get_tablet_tool_event(ev); + double v = 0, h = 0; + const char *have_vert = "", + *have_horiz = ""; + const char *source = NULL; + enum libinput_pointer_axis axis; + enum libinput_event_type type; + + type = libinput_event_get_type(ev); + + switch (type) { + case LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS: + source = "continuous"; + break; + default: + abort(); + break; + } + + axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL; + if (libinput_event_tablet_tool_has_axis(t, axis)) { + v = libinput_event_tablet_tool_get_scroll_value(t, axis); + have_vert = "*"; + } + axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL; + if (libinput_event_tablet_tool_has_axis(t, axis)) { + h = libinput_event_tablet_tool_get_scroll_value(t, axis); + have_horiz = "*"; + } + + printq("vert %.2f%s horiz %.2f%s (%s)\n", + v, have_vert, + h, have_horiz, source); } static void diff --git a/tools/libinput-debug-gui.c b/tools/libinput-debug-gui.c index 503b7a7d..2c232b8c 100644 --- a/tools/libinput-debug-gui.c +++ b/tools/libinput-debug-gui.c @@ -1513,7 +1513,25 @@ handle_event_pointer_axis(struct libinput_event *ev, struct window *w) static void handle_event_tablet_tool_axis(struct libinput_event *ev, struct window *w) { - // FIXME: done in a later commit + struct libinput_event_tablet_tool *p = libinput_event_get_tablet_tool_event(ev); + double value; + enum libinput_pointer_axis axis; + + assert(p != NULL); + + axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL; + if (libinput_event_tablet_tool_has_axis(p, axis)) { + value = libinput_event_tablet_tool_get_scroll_value(p, axis); + w->scroll.vy += value; + w->scroll.vy = clip(w->scroll.vy, 0, w->height); + } + + axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL; + if (libinput_event_tablet_tool_has_axis(p, axis)) { + value = libinput_event_tablet_tool_get_scroll_value(p, axis); + w->scroll.hx += value; + w->scroll.hx = clip(w->scroll.hx, 0, w->width); + } } static void From d1dd08b3b00e37417f85a39728c84ad0d041a0ea Mon Sep 17 00:00:00 2001 From: Louis Goyard Date: Tue, 12 Mar 2024 23:03:39 +0900 Subject: [PATCH 7/7] test: expect tablets to support scroll button --- test/test-pointer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test-pointer.c b/test/test-pointer.c index 7a80c57b..5f9086bd 100644 --- a/test/test-pointer.c +++ b/test/test-pointer.c @@ -3771,8 +3771,8 @@ TEST_COLLECTION(pointer) litest_add(pointer_scroll_wheel_inhibit_dir_change, LITEST_WHEEL, LITEST_TABLET); litest_add_for_device(pointer_scroll_wheel_lenovo_scrollpoint, LITEST_LENOVO_SCROLLPOINT); litest_add(pointer_scroll_button, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY); - litest_add(pointer_scroll_button_noscroll, LITEST_ABSOLUTE|LITEST_BUTTON, LITEST_RELATIVE); - litest_add(pointer_scroll_button_noscroll, LITEST_ANY, LITEST_RELATIVE|LITEST_BUTTON); + litest_add(pointer_scroll_button_noscroll, LITEST_ABSOLUTE|LITEST_BUTTON, LITEST_RELATIVE|LITEST_TABLET); + litest_add(pointer_scroll_button_noscroll, LITEST_ANY, LITEST_RELATIVE|LITEST_BUTTON|LITEST_TABLET); litest_add(pointer_scroll_button_no_event_before_timeout, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY); litest_add(pointer_scroll_button_middle_emulation, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY); litest_add_no_device(pointer_scroll_button_device_remove_while_down);