From bfc0e95d2cfeab96d771cb34e78ca92afee4464c Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 7 Mar 2018 20:57:55 -0500 Subject: [PATCH] Add mode support to libinput backend And extend tablet example with tilt and ring support --- backend/libinput/tablet_pad.c | 3 ++ backend/libinput/tablet_tool.c | 2 - examples/support/shared.c | 10 +++++ examples/support/shared.h | 3 ++ examples/tablet.c | 59 ++++++++++++++++++++++-------- include/wlr/types/wlr_tablet_pad.h | 3 ++ 6 files changed, 62 insertions(+), 18 deletions(-) diff --git a/backend/libinput/tablet_pad.c b/backend/libinput/tablet_pad.c index 70e4c677b..f71e1efa0 100644 --- a/backend/libinput/tablet_pad.c +++ b/backend/libinput/tablet_pad.c @@ -34,6 +34,7 @@ void handle_tablet_pad_button(struct libinput_event *event, wlr_event.time_msec = usec_to_msec(libinput_event_tablet_pad_get_time_usec(pevent)); wlr_event.button = libinput_event_tablet_pad_get_button_number(pevent); + wlr_event.mode = libinput_event_tablet_pad_get_mode(pevent); switch (libinput_event_tablet_pad_get_button_state(pevent)) { case LIBINPUT_BUTTON_STATE_PRESSED: wlr_event.state = WLR_BUTTON_PRESSED; @@ -60,6 +61,7 @@ void handle_tablet_pad_ring(struct libinput_event *event, usec_to_msec(libinput_event_tablet_pad_get_time_usec(pevent)); wlr_event.ring = libinput_event_tablet_pad_get_ring_number(pevent); wlr_event.position = libinput_event_tablet_pad_get_ring_position(pevent); + wlr_event.mode = libinput_event_tablet_pad_get_mode(pevent); switch (libinput_event_tablet_pad_get_ring_source(pevent)) { case LIBINPUT_TABLET_PAD_RING_SOURCE_UNKNOWN: wlr_event.source = WLR_TABLET_PAD_RING_SOURCE_UNKNOWN; @@ -86,6 +88,7 @@ void handle_tablet_pad_strip(struct libinput_event *event, usec_to_msec(libinput_event_tablet_pad_get_time_usec(pevent)); wlr_event.strip = libinput_event_tablet_pad_get_strip_number(pevent); wlr_event.position = libinput_event_tablet_pad_get_strip_position(pevent); + wlr_event.mode = libinput_event_tablet_pad_get_mode(pevent); switch (libinput_event_tablet_pad_get_strip_source(pevent)) { case LIBINPUT_TABLET_PAD_STRIP_SOURCE_UNKNOWN: wlr_event.source = WLR_TABLET_PAD_STRIP_SOURCE_UNKNOWN; diff --git a/backend/libinput/tablet_tool.c b/backend/libinput/tablet_tool.c index 4e60367fb..27cf7c818 100644 --- a/backend/libinput/tablet_tool.c +++ b/backend/libinput/tablet_tool.c @@ -71,8 +71,6 @@ void handle_tablet_tool_axis(struct libinput_event *event, wlr_event.updated_axes |= WLR_TABLET_TOOL_AXIS_WHEEL; wlr_event.wheel_delta = libinput_event_tablet_tool_get_wheel_delta(tevent); } - wlr_log(L_DEBUG, "Tablet tool axis event %d @ %f,%f", - wlr_event.updated_axes, wlr_event.x_mm, wlr_event.y_mm); wlr_signal_emit_safe(&wlr_dev->tablet_tool->events.axis, &wlr_event); } diff --git a/examples/support/shared.c b/examples/support/shared.c index c4f9288d0..e6233206f 100644 --- a/examples/support/shared.c +++ b/examples/support/shared.c @@ -294,6 +294,14 @@ static void tablet_pad_button_notify(struct wl_listener *listener, void *data) { } } +static void tablet_pad_ring_notify(struct wl_listener *listener, void *data) { + struct wlr_event_tablet_pad_ring *event = data; + struct tablet_pad_state *pstate = wl_container_of(listener, pstate, ring); + if (pstate->compositor->pad_ring_cb) { + pstate->compositor->pad_ring_cb(pstate, event->ring, event->position); + } +} + static void tablet_pad_destroy_notify(struct wl_listener *listener, void *data) { struct tablet_pad_state *pstate = wl_container_of(listener, pstate, destroy); struct compositor_state *state = pstate->compositor; @@ -315,6 +323,8 @@ static void tablet_pad_add(struct wlr_input_device *device, wl_signal_add(&device->events.destroy, &pstate->destroy); pstate->button.notify = tablet_pad_button_notify; wl_signal_add(&device->tablet_pad->events.button, &pstate->button); + pstate->ring.notify = tablet_pad_ring_notify; + wl_signal_add(&device->tablet_pad->events.ring, &pstate->ring); wl_list_insert(&state->tablet_pads, &pstate->link); } diff --git a/examples/support/shared.h b/examples/support/shared.h index 8cdea3013..d00e75b34 100644 --- a/examples/support/shared.h +++ b/examples/support/shared.h @@ -73,6 +73,7 @@ struct tablet_pad_state { struct wlr_input_device *device; struct wl_listener destroy; struct wl_listener button; + struct wl_listener ring; struct wl_list link; void *data; }; @@ -117,6 +118,8 @@ struct compositor_state { uint32_t button, enum wlr_button_state state); void (*pad_button_cb)(struct tablet_pad_state *s, uint32_t button, enum wlr_button_state state); + void (*pad_ring_cb)(struct tablet_pad_state *s, + uint32_t ring, double position); struct wl_display *display; struct wl_event_loop *event_loop; diff --git a/examples/tablet.c b/examples/tablet.c index ca76ec5ad..5bfa12717 100644 --- a/examples/tablet.c +++ b/examples/tablet.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -28,7 +29,9 @@ struct sample_state { double distance; double pressure; double x_mm, y_mm; + double x_tilt, y_tilt; double width_mm, height_mm; + double ring; struct wl_list link; float tool_color[4]; float pad_color[4]; @@ -46,7 +49,7 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts wlr_renderer_begin(sample->renderer, wlr_output); wlr_renderer_clear(sample->renderer, &(float[]){0.25f, 0.25f, 0.25f, 1}); - float matrix[16], view[16]; + float matrix[16]; float distance = 0.8f * (1 - sample->distance); float tool_color[4] = { distance, distance, distance, 1 }; for (size_t i = 0; sample->button && i < 4; ++i) { @@ -58,22 +61,31 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts float pad_height = sample->height_mm * scale; float left = width / 2.0f - pad_width / 2.0f; float top = height / 2.0f - pad_height / 2.0f; - wlr_matrix_translate(&matrix, left, top, 0); - wlr_matrix_scale(&view, pad_width, pad_height, 1); - wlr_matrix_mul(&matrix, &view, &view); - wlr_matrix_mul(&wlr_output->transform_matrix, &view, &matrix); + struct wlr_box box = { + .x = left, .y = top, + .width = pad_width, .height = pad_height, + }; + wlr_matrix_project_box(&matrix, &box, 0, 0, + &wlr_output->transform_matrix); wlr_render_colored_quad(sample->renderer, &sample->pad_color, &matrix); if (sample->proximity) { - wlr_matrix_translate(&matrix, - sample->x_mm * scale - 8 * (sample->pressure + 1) + left, - sample->y_mm * scale - 8 * (sample->pressure + 1) + top, 0); - wlr_matrix_scale(&view, - 16 * (sample->pressure + 1), - 16 * (sample->pressure + 1), 1); - wlr_matrix_mul(&matrix, &view, &view); - wlr_matrix_mul(&wlr_output->transform_matrix, &view, &matrix); - wlr_render_colored_ellipse(sample->renderer, &tool_color, &matrix); + struct wlr_box box = { + .x = sample->x_mm * scale - 8 * (sample->pressure + 1) + left, + .y = sample->y_mm * scale - 8 * (sample->pressure + 1) + top, + .width = 16 * (sample->pressure + 1), + .height = 16 * (sample->pressure + 1), + }; + wlr_matrix_project_box(&matrix, &box, 0, sample->ring, + &wlr_output->transform_matrix); + wlr_render_colored_quad(sample->renderer, &tool_color, &matrix); + box.x += sample->x_tilt; + box.y += sample->y_tilt; + box.width /= 2; + box.height /= 2; + wlr_matrix_project_box(&matrix, &box, 0, 0, + &wlr_output->transform_matrix); + wlr_render_colored_quad(sample->renderer, &tool_color, &matrix); } wlr_renderer_end(sample->renderer); @@ -97,6 +109,12 @@ static void handle_tool_axis(struct tablet_tool_state *tstate, if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_PRESSURE)) { sample->pressure = event->pressure; } + if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_TILT_X)) { + sample->x_tilt = event->tilt_x; + } + if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_TILT_Y)) { + sample->y_tilt = event->tilt_y; + } } static void handle_tool_proximity(struct tablet_tool_state *tstate, @@ -125,7 +143,7 @@ static void handle_tool_button(struct tablet_tool_state *tstate, static void handle_pad_button(struct tablet_pad_state *pstate, uint32_t button, enum wlr_button_state state) { struct sample_state *sample = pstate->compositor->data; - float default_color[4] = { 0.75, 0.75, 0.75, 1.0 }; + float default_color[4] = { 0.5, 0.5, 0.5, 1.0 }; if (state == WLR_BUTTON_RELEASED) { memcpy(sample->pad_color, default_color, sizeof(default_color)); } else { @@ -139,11 +157,19 @@ static void handle_pad_button(struct tablet_pad_state *pstate, } } +static void handle_pad_ring(struct tablet_pad_state *pstate, + uint32_t ring, double position) { + struct sample_state *sample = pstate->compositor->data; + if (position != -1) { + sample->ring = -(position * (M_PI / 180.0)); + } +} + int main(int argc, char *argv[]) { wlr_log_init(L_DEBUG, NULL); struct sample_state state = { .tool_color = { 1, 1, 1, 1 }, - .pad_color = { 0.75, 0.75, 0.75, 1.0 } + .pad_color = { 0.5, 0.5, 0.5, 1.0 } }; struct compositor_state compositor = { 0, .data = &state, @@ -152,6 +178,7 @@ int main(int argc, char *argv[]) { .tool_proximity_cb = handle_tool_proximity, .tool_button_cb = handle_tool_button, .pad_button_cb = handle_pad_button, + .pad_ring_cb = handle_pad_ring, }; compositor_init(&compositor); diff --git a/include/wlr/types/wlr_tablet_pad.h b/include/wlr/types/wlr_tablet_pad.h index e70db516f..73082c56a 100644 --- a/include/wlr/types/wlr_tablet_pad.h +++ b/include/wlr/types/wlr_tablet_pad.h @@ -29,6 +29,7 @@ struct wlr_event_tablet_pad_button { uint32_t time_msec; uint32_t button; enum wlr_button_state state; + unsigned int mode; }; enum wlr_tablet_pad_ring_source { @@ -41,6 +42,7 @@ struct wlr_event_tablet_pad_ring { enum wlr_tablet_pad_ring_source source; uint32_t ring; double position; + unsigned int mode; }; enum wlr_tablet_pad_strip_source { @@ -53,6 +55,7 @@ struct wlr_event_tablet_pad_strip { enum wlr_tablet_pad_strip_source source; uint32_t strip; double position; + unsigned int mode; }; #endif