tablet: add tablet tool scroll

This commit is contained in:
Louis Goyard 2024-03-12 00:09:43 +09:00
parent 50eae512d9
commit 5225a4ccce
9 changed files with 133 additions and 0 deletions

View file

@ -218,6 +218,9 @@ void handle_libinput_event(struct wlr_libinput_backend *backend,
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
handle_tablet_tool_button(event, &dev->tablet); handle_tablet_tool_button(event, &dev->tablet);
break; break;
case LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS:
handle_tablet_tool_scroll_continuous(event, &dev->tablet);
break;
case LIBINPUT_EVENT_TABLET_PAD_BUTTON: case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
handle_tablet_pad_button(event, &dev->tablet_pad); handle_tablet_pad_button(event, &dev->tablet_pad);
break; break;

View file

@ -275,3 +275,53 @@ void handle_tablet_tool_button(struct libinput_event *event,
} }
wl_signal_emit_mutable(&wlr_tablet->events.button, &wlr_event); wl_signal_emit_mutable(&wlr_tablet->events.button, &wlr_event);
} }
void handle_tablet_tool_scroll_continuous(struct libinput_event *event,
struct wlr_tablet *wlr_tablet) {
struct libinput_event_tablet_tool *tevent =
libinput_event_get_tablet_tool_event(event);
struct wlr_libinput_input_device *dev = device_from_tablet(wlr_tablet);
struct tablet_tool *tool =
get_tablet_tool(dev, libinput_event_tablet_tool_get_tool(tevent));
struct wlr_tablet_tool_axis_scroll_event wlr_event = {
.tablet = wlr_tablet,
.tool = &tool->wlr_tool,
.time_msec = usec_to_msec(libinput_event_tablet_tool_get_time_usec(tevent)),
};
switch (libinput_event_tablet_tool_get_axis_source(tevent)) {
case LIBINPUT_TABLET_TOOL_AXIS_SOURCE_CONTINUOUS:
wlr_event.source = WL_POINTER_AXIS_SOURCE_CONTINUOUS;
break;
default:
// FIXME
return;
}
const enum libinput_pointer_axis axes[] = {
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
};
for (size_t i = 0; i < sizeof(axes) / sizeof(axes[0]); ++i) {
if (!libinput_event_tablet_tool_has_axis(tevent, axes[i])) {
continue;
}
switch (axes[i]) {
case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
wlr_event.orientation = WL_POINTER_AXIS_VERTICAL_SCROLL;
break;
case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
wlr_event.orientation = WL_POINTER_AXIS_HORIZONTAL_SCROLL;
break;
}
wlr_event.delta =
libinput_event_tablet_tool_get_scroll_value(tevent, axes[i]);
wlr_event.relative_direction = WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL;
if (libinput_device_config_scroll_get_natural_scroll_enabled(libinput_event_get_device(event))) {
wlr_event.relative_direction = WL_POINTER_AXIS_RELATIVE_DIRECTION_INVERTED;
}
wl_signal_emit_mutable(&wlr_tablet->events.axis_scroll, &wlr_event);
}
}

View file

@ -124,6 +124,8 @@ void handle_tablet_tool_tip(struct libinput_event *event,
struct wlr_tablet *tablet); struct wlr_tablet *tablet);
void handle_tablet_tool_button(struct libinput_event *event, void handle_tablet_tool_button(struct libinput_event *event,
struct wlr_tablet *tablet); struct wlr_tablet *tablet);
void handle_tablet_tool_scroll_continuous(struct libinput_event *event,
struct wlr_tablet *tablet);
void init_device_tablet_pad(struct wlr_libinput_input_device *dev); void init_device_tablet_pad(struct wlr_libinput_input_device *dev);
void finish_device_tablet_pad(struct wlr_libinput_input_device *dev); void finish_device_tablet_pad(struct wlr_libinput_input_device *dev);

View file

@ -73,6 +73,7 @@ struct wlr_cursor {
struct wl_signal tablet_tool_proximity; struct wl_signal tablet_tool_proximity;
struct wl_signal tablet_tool_tip; struct wl_signal tablet_tool_tip;
struct wl_signal tablet_tool_button; struct wl_signal tablet_tool_button;
struct wl_signal tablet_tool_axis_scroll;
} events; } events;
void *data; void *data;

View file

@ -12,6 +12,7 @@
#include <stdint.h> #include <stdint.h>
#include <wayland-server-core.h> #include <wayland-server-core.h>
#include <wlr/types/wlr_input_device.h> #include <wlr/types/wlr_input_device.h>
#include <wlr/types/wlr_seat.h>
/* /*
* Copy+Paste from libinput, but this should neither use libinput, nor * Copy+Paste from libinput, but this should neither use libinput, nor
@ -72,6 +73,7 @@ struct wlr_tablet {
struct wl_signal proximity; struct wl_signal proximity;
struct wl_signal tip; struct wl_signal tip;
struct wl_signal button; struct wl_signal button;
struct wl_signal axis_scroll;
} events; } events;
struct wl_array paths; // char * struct wl_array paths; // char *
@ -145,6 +147,16 @@ struct wlr_tablet_tool_button_event {
enum wlr_button_state state; enum wlr_button_state state;
}; };
struct wlr_tablet_tool_axis_scroll_event {
struct wlr_tablet *tablet;
struct wlr_tablet_tool *tool;
uint32_t time_msec;
enum wl_pointer_axis_source source;
enum wl_pointer_axis orientation;
enum wl_pointer_axis_relative_direction relative_direction;
double delta;
};
/** /**
* Get a struct wlr_tablet from a struct wlr_input_device. * Get a struct wlr_tablet from a struct wlr_input_device.
* *

View file

@ -179,6 +179,11 @@ void wlr_send_tablet_v2_tablet_tool_button(
struct wlr_tablet_v2_tablet_tool *tool, uint32_t button, struct wlr_tablet_v2_tablet_tool *tool, uint32_t button,
enum zwp_tablet_pad_v2_button_state state); enum zwp_tablet_pad_v2_button_state state);
void wlr_send_tablet_v2_tablet_tool_axis_scroll(
struct wlr_tablet_v2_tablet_tool *tool, uint32_t time_msec,
enum wl_pointer_axis orientation, double value,
enum wl_pointer_axis_source source,
enum wl_pointer_axis_relative_direction relative_direction);
void wlr_tablet_v2_tablet_tool_notify_proximity_in( void wlr_tablet_v2_tablet_tool_notify_proximity_in(
@ -217,6 +222,12 @@ void wlr_tablet_v2_tablet_tool_notify_button(
struct wlr_tablet_v2_tablet_tool *tool, uint32_t button, struct wlr_tablet_v2_tablet_tool *tool, uint32_t button,
enum zwp_tablet_pad_v2_button_state state); enum zwp_tablet_pad_v2_button_state state);
void wlr_tablet_v2_tablet_tool_notify_scroll(
struct wlr_tablet_v2_tablet_tool *tool, uint32_t time_msec,
enum wl_pointer_axis orientation, double value,
enum wl_pointer_axis_source source,
enum wl_pointer_axis_relative_direction relative_direction);
struct wlr_tablet_tool_v2_grab_interface { struct wlr_tablet_tool_v2_grab_interface {
void (*proximity_in)( void (*proximity_in)(
@ -246,6 +257,13 @@ struct wlr_tablet_tool_v2_grab_interface {
void (*button)( void (*button)(
struct wlr_tablet_tool_v2_grab *grab, uint32_t button, struct wlr_tablet_tool_v2_grab *grab, uint32_t button,
enum zwp_tablet_pad_v2_button_state state); enum zwp_tablet_pad_v2_button_state state);
void (*axis_scroll)(
struct wlr_tablet_tool_v2_grab *grab, uint32_t time_msec,
enum wl_pointer_axis orientation, double value,
enum wl_pointer_axis_source source,
enum wl_pointer_axis_relative_direction relative_direction);
void (*cancel)(struct wlr_tablet_tool_v2_grab *grab); void (*cancel)(struct wlr_tablet_tool_v2_grab *grab);
}; };

View file

@ -490,6 +490,17 @@ void wlr_send_tablet_v2_tablet_tool_button(
} }
} }
void wlr_send_tablet_v2_tablet_tool_axis_scroll(
struct wlr_tablet_v2_tablet_tool *tool, uint32_t time_msec,
enum wl_pointer_axis orientation, double value,
enum wl_pointer_axis_source source,
enum wl_pointer_axis_relative_direction relative_direction) {
if (tool->current_client) {
zwp_tablet_tool_v2_send_axis_scroll(tool->current_client->resource, time_msec, orientation, value);
queue_tool_frame(tool->current_client);
}
}
void wlr_send_tablet_v2_tablet_tool_wheel( void wlr_send_tablet_v2_tablet_tool_wheel(
struct wlr_tablet_v2_tablet_tool *tool, double degrees, int32_t clicks) { struct wlr_tablet_v2_tablet_tool *tool, double degrees, int32_t clicks) {
if (tool->current_client) { if (tool->current_client) {
@ -616,6 +627,16 @@ void wlr_tablet_v2_tablet_tool_notify_button(
} }
} }
void wlr_tablet_v2_tablet_tool_notify_scroll(
struct wlr_tablet_v2_tablet_tool *tool, uint32_t time_msec,
enum wl_pointer_axis orientation, double value,
enum wl_pointer_axis_source source,
enum wl_pointer_axis_relative_direction relative_direction) {
if (tool->grab->interface->axis_scroll) {
tool->grab->interface->axis_scroll(tool->grab, time_msec, orientation, value, source, relative_direction);
}
}
void wlr_tablet_tool_v2_start_grab(struct wlr_tablet_v2_tablet_tool *tool, void wlr_tablet_tool_v2_start_grab(struct wlr_tablet_v2_tablet_tool *tool,
struct wlr_tablet_tool_v2_grab *grab) { struct wlr_tablet_tool_v2_grab *grab) {
wlr_tablet_tool_v2_end_grab(tool); wlr_tablet_tool_v2_end_grab(tool);
@ -689,6 +710,14 @@ static void default_tool_button(
wlr_send_tablet_v2_tablet_tool_button(grab->tool, button, state); wlr_send_tablet_v2_tablet_tool_button(grab->tool, button, state);
} }
static void default_tool_axis_scroll(struct wlr_tablet_tool_v2_grab *grab,
uint32_t time_msec,
enum wl_pointer_axis orientation, double value,
enum wl_pointer_axis_source source,
enum wl_pointer_axis_relative_direction relative_direction) {
wlr_send_tablet_v2_tablet_tool_axis_scroll(grab->tool, time_msec, orientation, value, source, relative_direction);
}
static void default_tool_cancel(struct wlr_tablet_tool_v2_grab *grab) { static void default_tool_cancel(struct wlr_tablet_tool_v2_grab *grab) {
/* Do nothing. Default grab can't be canceled */ /* Do nothing. Default grab can't be canceled */
} }
@ -707,6 +736,7 @@ static const struct wlr_tablet_tool_v2_grab_interface
.wheel = default_tool_wheel, .wheel = default_tool_wheel,
.proximity_out = default_tool_proximity_out, .proximity_out = default_tool_proximity_out,
.button = default_tool_button, .button = default_tool_button,
.axis_scroll = default_tool_axis_scroll,
.cancel = default_tool_cancel, .cancel = default_tool_cancel,
}; };

View file

@ -50,6 +50,7 @@ struct wlr_cursor_device {
struct wl_listener tablet_tool_proximity; struct wl_listener tablet_tool_proximity;
struct wl_listener tablet_tool_tip; struct wl_listener tablet_tool_tip;
struct wl_listener tablet_tool_button; struct wl_listener tablet_tool_button;
struct wl_listener tablet_tool_axis_scroll;
struct wl_listener destroy; struct wl_listener destroy;
}; };
@ -142,6 +143,7 @@ struct wlr_cursor *wlr_cursor_create(void) {
wl_signal_init(&cur->events.tablet_tool_tip); wl_signal_init(&cur->events.tablet_tool_tip);
wl_signal_init(&cur->events.tablet_tool_axis); wl_signal_init(&cur->events.tablet_tool_axis);
wl_signal_init(&cur->events.tablet_tool_button); wl_signal_init(&cur->events.tablet_tool_button);
wl_signal_init(&cur->events.tablet_tool_axis_scroll);
wl_signal_init(&cur->events.tablet_tool_proximity); wl_signal_init(&cur->events.tablet_tool_proximity);
wl_list_init(&cur->state->surface_destroy.link); wl_list_init(&cur->state->surface_destroy.link);
@ -212,6 +214,7 @@ static void cursor_device_destroy(struct wlr_cursor_device *c_device) {
wl_list_remove(&c_device->tablet_tool_proximity.link); wl_list_remove(&c_device->tablet_tool_proximity.link);
wl_list_remove(&c_device->tablet_tool_tip.link); wl_list_remove(&c_device->tablet_tool_tip.link);
wl_list_remove(&c_device->tablet_tool_button.link); wl_list_remove(&c_device->tablet_tool_button.link);
wl_list_remove(&c_device->tablet_tool_axis_scroll.link);
break; break;
default: default:
abort(); // unreachable abort(); // unreachable
@ -921,6 +924,15 @@ static void handle_tablet_tool_button(struct wl_listener *listener,
wl_signal_emit_mutable(&device->cursor->events.tablet_tool_button, event); wl_signal_emit_mutable(&device->cursor->events.tablet_tool_button, event);
} }
static void handle_tablet_tool_axis_scroll(struct wl_listener *listener,
void *data) {
struct wlr_tablet_tool_axis_scroll_event *event = data;
struct wlr_cursor_device *device;
device = wl_container_of(listener, device, tablet_tool_axis_scroll);
wl_signal_emit_mutable(&device->cursor->events.tablet_tool_axis_scroll, event);
}
static void handle_tablet_tool_proximity(struct wl_listener *listener, static void handle_tablet_tool_proximity(struct wl_listener *listener,
void *data) { void *data) {
struct wlr_tablet_tool_proximity_event *event = data; struct wlr_tablet_tool_proximity_event *event = data;
@ -1036,6 +1048,10 @@ static struct wlr_cursor_device *cursor_device_create(
wl_signal_add(&tablet->events.button, &c_device->tablet_tool_button); wl_signal_add(&tablet->events.button, &c_device->tablet_tool_button);
c_device->tablet_tool_button.notify = handle_tablet_tool_button; c_device->tablet_tool_button.notify = handle_tablet_tool_button;
wl_signal_add(&tablet->events.axis_scroll,
&c_device->tablet_tool_axis_scroll);
c_device->tablet_tool_axis_scroll.notify = handle_tablet_tool_axis_scroll;
break; break;
default: default:

View file

@ -24,6 +24,7 @@ void wlr_tablet_init(struct wlr_tablet *tablet,
wl_signal_init(&tablet->events.proximity); wl_signal_init(&tablet->events.proximity);
wl_signal_init(&tablet->events.tip); wl_signal_init(&tablet->events.tip);
wl_signal_init(&tablet->events.button); wl_signal_init(&tablet->events.button);
wl_signal_init(&tablet->events.axis_scroll);
wl_array_init(&tablet->paths); wl_array_init(&tablet->paths);
} }