On Wed, Feb 03, 2016 at 03:28:10PM +1000, Peter Hutterer wrote: > From: Stephen Chandler Paul <thatsly...@gmail.com> > > Co-authored-by: Peter Hutterer <peter.hutte...@who-t.net> > Signed-off-by: Stephen Chandler Paul <thatsly...@gmail.com> > Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net>
Reviewed-by: Jonas Ådahl <jad...@gmail.com> with one comment inlined below. > --- > clients/window.c | 498 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > clients/window.h | 88 ++++++++++ > 2 files changed, 586 insertions(+) > > diff --git a/clients/window.c b/clients/window.c > index 35261b6..37c703b 100644 > --- a/clients/window.c > +++ b/clients/window.c > @@ -70,6 +70,7 @@ typedef void *EGLContext; > #include "shared/helpers.h" > #include "xdg-shell-unstable-v5-client-protocol.h" > #include "text-cursor-position-client-protocol.h" > +#include "tablet-unstable-v1-client-protocol.h" > #include "shared/os-compatibility.h" > > #include "window.h" > @@ -96,6 +97,7 @@ struct display { > struct wl_data_device_manager *data_device_manager; > struct text_cursor_position *text_cursor_position; > struct xdg_shell *xdg_shell; > + struct zwp_tablet_manager_v1 *tablet_manager; > struct ivi_application *ivi_application; /* ivi style shell */ > EGLDisplay dpy; > EGLConfig argb_config; > @@ -138,6 +140,33 @@ struct display { > int data_device_manager_version; > }; > > +struct tablet { > + struct zwp_tablet_v1 *tablet; > + char *name; > + int32_t vid; > + int32_t pid; > + > + void *user_data; > + > + struct wl_list link; > +}; > + > +struct tablet_tool { > + struct zwp_tablet_tool_v1 *tool; > + struct input *input; > + void *user_data; > + struct wl_list link; > + struct tablet *current_tablet; > + struct window *focus; > + struct widget *focus_widget; > + > + enum zwp_tablet_tool_v1_type type; > + uint64_t serial; > + uint64_t hwid; > + > + double sx, sy; > +}; > + > struct window_output { > struct output *output; > struct wl_list link; > @@ -286,6 +315,19 @@ struct widget { > widget_axis_source_handler_t axis_source_handler; > widget_axis_stop_handler_t axis_stop_handler; > widget_axis_discrete_handler_t axis_discrete_handler; > + widget_tablet_tool_motion_handler_t tablet_tool_motion_handler; > + widget_tablet_tool_up_handler_t tablet_tool_up_handler; > + widget_tablet_tool_down_handler_t tablet_tool_down_handler; > + widget_tablet_tool_pressure_handler_t tablet_tool_pressure_handler; > + widget_tablet_tool_distance_handler_t tablet_tool_distance_handler; > + widget_tablet_tool_tilt_handler_t tablet_tool_tilt_handler; > + widget_tablet_tool_rotation_handler_t tablet_tool_rotation_handler; > + widget_tablet_tool_slider_handler_t tablet_tool_slider_handler; > + widget_tablet_tool_wheel_handler_t tablet_tool_wheel_handler; > + widget_tablet_tool_proximity_in_handler_t tablet_tool_prox_in_handler; > + widget_tablet_tool_proximity_out_handler_t tablet_tool_prox_out_handler; > + widget_tablet_tool_button_handler_t tablet_tool_button_handler; > + widget_tablet_tool_frame_handler_t tablet_tool_frame_handler; > void *user_data; > int opaque; > int tooltip_count; > @@ -361,6 +403,10 @@ struct input { > uint32_t repeat_key; > uint32_t repeat_time; > int seat_version; > + > + struct zwp_tablet_seat_v1 *tablet_seat; > + struct wl_list tablet_list; > + struct wl_list tablet_tool_list; > }; > > struct output { > @@ -1970,6 +2016,62 @@ widget_set_axis_handlers(struct widget *widget, > widget->axis_discrete_handler = axis_discrete_handler; > } > > +void > +widget_set_tablet_tool_axis_handlers(struct widget *widget, > + widget_tablet_tool_motion_handler_t motion, > + widget_tablet_tool_pressure_handler_t > pressure, > + widget_tablet_tool_distance_handler_t > distance, > + widget_tablet_tool_tilt_handler_t tilt, > + widget_tablet_tool_rotation_handler_t > rotation, > + widget_tablet_tool_slider_handler_t slider, > + widget_tablet_tool_wheel_handler_t wheel) > +{ > + widget->tablet_tool_motion_handler = motion; > + widget->tablet_tool_pressure_handler = pressure; > + widget->tablet_tool_distance_handler = distance; > + widget->tablet_tool_tilt_handler = tilt; > + widget->tablet_tool_rotation_handler = rotation; > + widget->tablet_tool_slider_handler = slider; > + widget->tablet_tool_wheel_handler = wheel; > +} > + > +void > +widget_set_tablet_tool_up_handler(struct widget *widget, > + widget_tablet_tool_up_handler_t handler) > +{ > + widget->tablet_tool_up_handler = handler; > +} > + > +void > +widget_set_tablet_tool_down_handler(struct widget *widget, > + widget_tablet_tool_down_handler_t handler) > +{ > + widget->tablet_tool_down_handler = handler; > +} > + > +void > +widget_set_tablet_tool_proximity_handlers(struct widget *widget, > + > widget_tablet_tool_proximity_in_handler_t in_handler, > + > widget_tablet_tool_proximity_out_handler_t out_handler) > +{ > + widget->tablet_tool_prox_in_handler = in_handler; > + widget->tablet_tool_prox_out_handler = out_handler; > +} > + > +void > +widget_set_tablet_tool_button_handler(struct widget *widget, > + widget_tablet_tool_button_handler_t > handler) > +{ > + widget->tablet_tool_button_handler = handler; > +} > + > +void > +widget_set_tablet_tool_frame_handler(struct widget *widget, > + widget_tablet_tool_frame_handler_t handler) > +{ > + widget->tablet_tool_frame_handler = handler; > +} > + > static void > window_schedule_redraw_task(struct window *window); > > @@ -5335,6 +5437,9 @@ display_add_input(struct display *d, uint32_t id, int > display_seat_version) > wl_list_init(&input->touch_point_list); > wl_list_insert(d->input_list.prev, &input->link); > > + wl_list_init(&input->tablet_list); > + wl_list_init(&input->tablet_tool_list); > + > wl_seat_add_listener(input->seat, &seat_listener, input); > wl_seat_set_user_data(input->seat, input); > > @@ -5438,6 +5543,397 @@ static_assert(XDG_VERSION == > XDG_SHELL_VERSION_CURRENT, > #endif > > static void > +tablet_handle_name(void *data, struct zwp_tablet_v1 *zwp_tablet_v1, const > char *name) > +{ > + struct tablet *tablet = data; > + > + tablet->name = xstrdup(name); > +} > + > +static void > +tablet_handle_id(void *data, struct zwp_tablet_v1 *zwp_tablet_v1, > + uint32_t vid, uint32_t pid) > +{ > + struct tablet *tablet = data; > + > + tablet->vid = vid; > + tablet->pid = pid; > +} > + > +static void > +tablet_handle_path(void *data, struct zwp_tablet_v1 *zwp_tablet_v1, const > char *path) > +{ > +} > + > +static void > +tablet_handle_done(void *data, struct zwp_tablet_v1 *zwp_tablet_v1) > +{ > +} > + > +static void > +tablet_handle_removed(void *data, struct zwp_tablet_v1 *zwp_tablet_v1) > +{ > + struct tablet *tablet = data; > + > + zwp_tablet_v1_destroy(zwp_tablet_v1); > + > + wl_list_remove(&tablet->link); > + free(tablet->name); > + free(tablet); > +} > + > +static const struct zwp_tablet_v1_listener tablet_listener = { > + tablet_handle_name, > + tablet_handle_id, > + tablet_handle_path, > + tablet_handle_done, > + tablet_handle_removed, > +}; > + > +static void > +tablet_added(void *data, struct zwp_tablet_seat_v1 *zwp_tablet_seat1, > + struct zwp_tablet_v1 *id) > +{ > + struct input *input = data; > + struct tablet *tablet; > + > + tablet = zalloc(sizeof *tablet); > + > + zwp_tablet_v1_add_listener(id, &tablet_listener, tablet); > + wl_list_insert(&input->tablet_list, &tablet->link); > + zwp_tablet_v1_set_user_data(id, tablet); > +} > + > +enum zwp_tablet_tool_v1_type > +tablet_tool_get_type(struct tablet_tool *tool) > +{ > + return tool->type; > +} > + > +uint64_t > +tablet_tool_get_serial(struct tablet_tool *tool) > +{ > + return tool->serial; > +} > + > +uint64_t > +tablet_tool_get_hwid(struct tablet_tool *tool) > +{ > + return tool->hwid; > +} > + > +static void > +tablet_tool_handle_type(void *data, struct zwp_tablet_tool_v1 > *zwp_tablet_tool_v1, > + uint32_t tool_type) > +{ > + struct tablet_tool *tool = data; > + > + tool->type = tool_type; > +} > + > +static void > +tablet_tool_handle_serialid(void *data, struct zwp_tablet_tool_v1 > *zwp_tablet_tool_v1, > + uint32_t serial_msb, uint32_t serial_lsb) > +{ > + struct tablet_tool *tool = data; > + > + tool->serial = ((uint64_t)serial_msb << 32) | serial_lsb; > +} > + > +static void > +tablet_tool_handle_hardware_id_wacom(void *data, > + struct zwp_tablet_tool_v1 > *zwp_tablet_tool_v1, > + uint32_t hwid_msb, uint32_t hwid_lsb) > +{ > + struct tablet_tool *tool = data; > + > + tool->serial = ((uint64_t)hwid_msb << 32) | hwid_lsb; > +} > + > +static void > +tablet_tool_handle_capability(void *data, struct zwp_tablet_tool_v1 > *zwp_tablet_tool_v1, > + uint32_t capability) > +{ > +} > + > +static void > +tablet_tool_handle_done(void *data, struct zwp_tablet_tool_v1 > *zwp_tablet_tool_v1) > +{ > +} > + > +static void > +tablet_tool_handle_removed(void *data, struct zwp_tablet_tool_v1 > *zwp_tablet_tool_v1) > +{ > + zwp_tablet_tool_v1_destroy(zwp_tablet_tool_v1); > +} > + > +static void > +tablet_tool_set_focus_widget(struct tablet_tool *tool, struct window *window, > + wl_fixed_t sx, wl_fixed_t sy) > +{ > + struct widget *widget, *old; > + > + widget = window_find_widget(window, sx, sy); > + if (tool->focus_widget == widget) > + return; > + > + old = tool->focus_widget; > + if (old && old->tablet_tool_prox_out_handler) > + old->tablet_tool_prox_out_handler(old, tool, > + widget_get_user_data(old)); > + > + if (widget && widget->tablet_tool_prox_in_handler) > + widget->tablet_tool_prox_in_handler(widget, tool, > + tool->current_tablet, > + > widget_get_user_data(widget)); > + > + tool->focus_widget = widget; > +} > + > +static void > +tablet_tool_handle_proximity_in(void *data, > + struct zwp_tablet_tool_v1 *zwp_tablet_tool_v1, > + uint32_t serial, > + struct zwp_tablet_v1 *zwp_tablet_v1, > + struct wl_surface *surface) > +{ > + struct tablet_tool *tool = data; > + struct tablet *tablet = zwp_tablet_v1_get_user_data(zwp_tablet_v1); > + struct window *window; > + > + window = wl_surface_get_user_data(surface); > + if (surface != window->main_surface->surface) > + return; > + > + tool->focus = window; > + tool->current_tablet = tablet; > +} > + > +static void > +tablet_tool_handle_proximity_out(void *data, > + struct zwp_tablet_tool_v1 *zwp_tablet_tool_v1) > +{ > + struct tablet_tool *tool = data; > + > + tool->focus = NULL; > + tool->current_tablet = NULL; > +} > + > +static void > +tablet_tool_handle_down(void *data, struct zwp_tablet_tool_v1 > *zwp_tablet_tool_v1, > + uint32_t serial) > +{ > + struct tablet_tool *tool = data; > + struct widget *focus = tool->focus_widget; > + > + tool->input->display->serial = serial; > + > + if (focus && focus->tablet_tool_down_handler) > + focus->tablet_tool_down_handler(focus, tool, focus->user_data); > +} > + > +static void > +tablet_tool_handle_up(void *data, struct zwp_tablet_tool_v1 > *zwp_tablet_tool_v1) > +{ > + struct tablet_tool *tool = data; > + struct widget *focus = tool->focus_widget; > + > + if (focus && focus->tablet_tool_up_handler) > + focus->tablet_tool_up_handler(focus, tool, focus->user_data); > +} > + > +static void > +tablet_tool_handle_motion(void *data, struct zwp_tablet_tool_v1 > *zwp_tablet_tool_v1, > + wl_fixed_t x, wl_fixed_t y) > +{ > + struct tablet_tool *tool = data; > + double sx = wl_fixed_to_double(x); > + double sy = wl_fixed_to_double(y); > + struct window *window = tool->focus; > + struct widget *widget; > + > + if (!window) > + return; > + > + tool->sx = sx; > + tool->sy = sy; > + > + if (sx > window->main_surface->allocation.width || > + sy > window->main_surface->allocation.height) > + return; > + > + tablet_tool_set_focus_widget(tool, window, sx, sy); > + widget = tool->focus_widget; > + if (widget && widget->tablet_tool_motion_handler) { > + widget->tablet_tool_motion_handler(widget, tool, sx, sy, > + widget->user_data); > + } > +} > + > +static void > +tablet_tool_handle_pressure(void *data, struct zwp_tablet_tool_v1 > *zwp_tablet_tool_v1, > + uint32_t pressure) > +{ > + struct tablet_tool *tool = data; > + struct widget *widget = tool->focus_widget; > + > + if (widget && widget->tablet_tool_pressure_handler) > + widget->tablet_tool_pressure_handler(widget, tool, pressure, > + widget->user_data); > +} > + > +static void > +tablet_tool_handle_distance(void *data, struct zwp_tablet_tool_v1 > *zwp_tablet_tool_v1, > + uint32_t distance) > +{ > + struct tablet_tool *tool = data; > + struct widget *widget = tool->focus_widget; > + > + if (widget && widget->tablet_tool_distance_handler) > + widget->tablet_tool_distance_handler(widget, tool, > + distance, > + widget->user_data); > +} > + > +static void > +tablet_tool_handle_tilt(void *data, struct zwp_tablet_tool_v1 > *zwp_tablet_tool_v1, > + int32_t tilt_x, int32_t tilt_y) > +{ > + struct tablet_tool *tool = data; > + struct widget *widget = tool->focus_widget; > + > + if (widget && widget->tablet_tool_tilt_handler) > + widget->tablet_tool_tilt_handler(widget, tool, > + tilt_x, tilt_y, > + widget->user_data); > +} > + > +static void > +tablet_tool_handle_rotation(void *data, struct zwp_tablet_tool_v1 > *zwp_tablet_tool_v1, > + int32_t rotation) > +{ > + struct tablet_tool *tool = data; > + struct widget *widget = tool->focus_widget; > + > + if (widget && widget->tablet_tool_rotation_handler) > + widget->tablet_tool_rotation_handler(widget, tool, > + rotation, > + widget->user_data); > +} > + > +static void > +tablet_tool_handle_slider(void *data, struct zwp_tablet_tool_v1 > *zwp_tablet_tool_v1, > + int32_t slider) > +{ > + struct tablet_tool *tool = data; > + struct widget *widget = tool->focus_widget; > + > + if (widget && widget->tablet_tool_slider_handler) > + widget->tablet_tool_slider_handler(widget, tool, > + slider, > + widget->user_data); > +} > + > +static void > +tablet_tool_handle_wheel(void *data, struct zwp_tablet_tool_v1 > *zwp_tablet_tool_v1, > + int32_t degrees, int32_t clicks) > +{ > + struct tablet_tool *tool = data; > + struct widget *widget = tool->focus_widget; > + > + if (widget && widget->tablet_tool_wheel_handler) > + widget->tablet_tool_wheel_handler(widget, tool, > + degrees, clicks, > + widget->user_data); > +} > + > +static void > +tablet_tool_handle_button(void *data, struct zwp_tablet_tool_v1 > *zwp_tablet_tool_v1, > + uint32_t serial, uint32_t button, uint32_t state) > +{ > + struct tablet_tool *tool = data; > + struct widget *focus = tool->focus_widget; > + > + tool->input->display->serial = serial; > + > + if (focus && focus->tablet_tool_button_handler) > + focus->tablet_tool_button_handler(focus, tool, button, state, > + focus->user_data); > +} > + > +static void > +tablet_tool_handle_frame(void *data, struct zwp_tablet_tool_v1 > *zwp_tablet_tool_v1, > + uint32_t time) > +{ > + struct tablet_tool *tool = data; > + struct widget *widget = tool->focus_widget; > + > + if (widget && widget->tablet_tool_frame_handler) > + widget->tablet_tool_frame_handler(widget, tool, time, > + widget->user_data); > +} > + > +static const struct zwp_tablet_tool_v1_listener tablet_tool_listener = { > + tablet_tool_handle_type, > + tablet_tool_handle_serialid, > + tablet_tool_handle_hardware_id_wacom, > + tablet_tool_handle_capability, > + tablet_tool_handle_done, > + tablet_tool_handle_removed, > + tablet_tool_handle_proximity_in, > + tablet_tool_handle_proximity_out, > + tablet_tool_handle_down, > + tablet_tool_handle_up, > + tablet_tool_handle_motion, > + tablet_tool_handle_pressure, > + tablet_tool_handle_distance, > + tablet_tool_handle_tilt, > + tablet_tool_handle_rotation, > + tablet_tool_handle_slider, > + tablet_tool_handle_wheel, > + tablet_tool_handle_button, > + tablet_tool_handle_frame, > +}; > + > +static void > +tablet_tool_added(void *data, struct zwp_tablet_seat_v1 *zwp_tablet_seat1, > + struct zwp_tablet_tool_v1 *id) > +{ > + struct input *input = data; > + struct tablet_tool *tool; > + > + tool = zalloc(sizeof *tool); > + zwp_tablet_tool_v1_add_listener(id, &tablet_tool_listener, tool); > + wl_list_insert(&input->tablet_tool_list, &tool->link); > + > + tool->tool = id; > + tool->input = input; > +} > + > +static const struct zwp_tablet_seat_v1_listener tablet_seat_listener = { > + tablet_added, > + tablet_tool_added, > +}; > + > +static void > +display_bind_tablets(struct display *d, uint32_t id) > +{ > + struct input *input; > + > + d->tablet_manager = wl_registry_bind(d->registry, id, > + &zwp_tablet_manager_v1_interface, > 1); > + > + wl_list_for_each(input, &d->input_list, link) { > + input->tablet_seat = > + zwp_tablet_manager_v1_get_tablet_seat(d->tablet_manager, > + input->seat); > + zwp_tablet_seat_v1_add_listener(input->tablet_seat, > + &tablet_seat_listener, > + input); > + } > +} > + > +static void > registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, > const char *interface, uint32_t version) > { > @@ -5484,6 +5980,8 @@ registry_handle_global(void *data, struct wl_registry > *registry, uint32_t id, > d->ivi_application = > wl_registry_bind(registry, id, > &ivi_application_interface, 1); > + } else if (strcmp(interface, "zwp_tablet_manager_v1") == 0) { > + display_bind_tablets(d, id); > } > > if (d->global_handler) > diff --git a/clients/window.h b/clients/window.h > index 349dead..86f0366 100644 > --- a/clients/window.h > +++ b/clients/window.h > @@ -28,6 +28,7 @@ > > #include <xkbcommon/xkbcommon.h> > #include <wayland-client.h> > +#include <tablet-unstable-v1-client-protocol.h> This is not a system header. Jonas > #include <cairo.h> > #include "shared/config-parser.h" > #include "shared/zalloc.h" > @@ -38,6 +39,8 @@ struct widget; > struct display; > struct input; > struct output; > +struct tablet; > +struct tablet_tool; > > struct task { > void (*run)(struct task *task, uint32_t events); > @@ -272,6 +275,57 @@ typedef void (*widget_axis_handler_t)(struct widget > *widget, > uint32_t axis, > wl_fixed_t value, > void *data); > +typedef void (*widget_tablet_tool_motion_handler_t)(struct widget *widget, > + struct tablet_tool *tool, > + float x, float y, > + void *data); > +typedef void (*widget_tablet_tool_down_handler_t)(struct widget *widget, > + struct tablet_tool *tool, > + void *data); > +typedef void (*widget_tablet_tool_up_handler_t)(struct widget *widget, > + struct tablet_tool *tool, > + void *data); > +typedef void (*widget_tablet_tool_pressure_handler_t)(struct widget *widget, > + struct tablet_tool *tool, > + uint32_t pressure, > + void *data); > +typedef void (*widget_tablet_tool_distance_handler_t)(struct widget *widget, > + struct tablet_tool *tool, > + uint32_t distance, > + void *data); > +typedef void (*widget_tablet_tool_tilt_handler_t)(struct widget *widget, > + struct tablet_tool *tool, > + int32_t tilt_x, int32_t > tilt_y, > + void *data); > +typedef void (*widget_tablet_tool_rotation_handler_t)(struct widget *widget, > + struct tablet_tool *tool, > + int32_t rotation, > + void *data); > +typedef void (*widget_tablet_tool_slider_handler_t)(struct widget *widget, > + struct tablet_tool *tool, > + int32_t slider, > + void *data); > +typedef void (*widget_tablet_tool_wheel_handler_t)(struct widget *widget, > + struct tablet_tool *tool, > + int32_t degrees, > + int32_t clicks, > + void *data); > +typedef void (*widget_tablet_tool_proximity_in_handler_t)(struct widget > *widget, > + struct tablet_tool > *tool, > + struct tablet *tablet, > + void *data); > +typedef void (*widget_tablet_tool_proximity_out_handler_t)(struct widget > *widget, > + struct tablet_tool > *tool, > + void *data); > +typedef void (*widget_tablet_tool_button_handler_t)(struct widget *widget, > + struct tablet_tool *tool, > + uint32_t button, > + enum > zwp_tablet_tool_v1_button_state state, > + void *data); > +typedef void (*widget_tablet_tool_frame_handler_t)(struct widget *widget, > + struct tablet_tool *tool, > + uint32_t time, > + void *data); > > typedef void (*widget_pointer_frame_handler_t)(struct widget *widget, > struct input *input, > @@ -551,6 +605,31 @@ widget_set_axis_handlers(struct widget *widget, > widget_axis_source_handler_t axis_source_handler, > widget_axis_stop_handler_t axis_stop_handler, > widget_axis_discrete_handler_t axis_discrete_handler); > +void > +widget_set_tablet_tool_axis_handlers(struct widget *widget, > + widget_tablet_tool_motion_handler_t motion, > + widget_tablet_tool_pressure_handler_t > pressure, > + widget_tablet_tool_distance_handler_t > distance, > + widget_tablet_tool_tilt_handler_t tilt, > + widget_tablet_tool_rotation_handler_t > rotation, > + widget_tablet_tool_slider_handler_t slider, > + widget_tablet_tool_wheel_handler_t wheel); > +void > +widget_set_tablet_tool_up_handler(struct widget *widget, > + widget_tablet_tool_up_handler_t handler); > +void > +widget_set_tablet_tool_down_handler(struct widget *widget, > + widget_tablet_tool_down_handler_t handler); > +void > +widget_set_tablet_tool_proximity_handlers(struct widget *widget, > + > widget_tablet_tool_proximity_in_handler_t in_handler, > + > widget_tablet_tool_proximity_out_handler_t out_handler); > +void > +widget_set_tablet_tool_button_handler(struct widget *widget, > + widget_tablet_tool_button_handler_t > handler); > +void > +widget_set_tablet_tool_frame_handler(struct widget *widget, > + widget_tablet_tool_frame_handler_t > handler); > > void > widget_schedule_redraw(struct widget *widget); > @@ -662,4 +741,13 @@ xkb_mod_mask_t > keysym_modifiers_get_mask(struct wl_array *modifiers_map, > const char *name); > > +enum zwp_tablet_tool_v1_type > +tablet_tool_get_type(struct tablet_tool *tool); > + > +uint64_t > +tablet_tool_get_serial(struct tablet_tool *tool); > + > +uint64_t > +tablet_tool_get_hwid(struct tablet_tool *tool); > + > #endif > -- > 2.5.0 > > _______________________________________________ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel