Signed-off-by: Stephen Chandler Paul <thatsly...@gmail.com> --- clients/window.c | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ clients/window.h | 19 ++++++ 2 files changed, 220 insertions(+)
diff --git a/clients/window.c b/clients/window.c index 85e5de8..90a2e28 100644 --- a/clients/window.c +++ b/clients/window.c @@ -67,6 +67,7 @@ typedef void *EGLContext; #include "../shared/cairo-util.h" #include "xdg-shell-client-protocol.h" #include "text-cursor-position-client-protocol.h" +#include "wayland-tablet-client-protocol.h" #include "workspaces-client-protocol.h" #include "../shared/os-compatibility.h" @@ -135,6 +136,24 @@ struct display { int seat_version; }; +struct tablet { + struct wl_tablet *tablet; + double sx, sy; + struct input *input; + + struct window *focus; + struct widget *focus_widget; + + char *name; + int32_t vid; + int32_t pid; + enum wl_tablet_manager_tablet_type type; + + void *user_data; + + struct wl_list link; +}; + struct window_output { struct output *output; struct wl_list link; @@ -275,6 +294,7 @@ struct widget { widget_touch_frame_handler_t touch_frame_handler; widget_touch_cancel_handler_t touch_cancel_handler; widget_axis_handler_t axis_handler; + widget_tablet_motion_handler_t tablet_motion_handler; void *user_data; int opaque; int tooltip_count; @@ -300,6 +320,8 @@ struct input { struct wl_keyboard *keyboard; struct wl_touch *touch; struct wl_list touch_point_list; + struct wl_tablet_manager *tablet_manager; + struct wl_list tablet_list; struct window *pointer_focus; struct window *keyboard_focus; struct window *touch_focus; @@ -1895,6 +1917,13 @@ widget_set_axis_handler(struct widget *widget, widget->axis_handler = handler; } +void +widget_set_tablet_motion_handler(struct widget *widget, + widget_tablet_motion_handler_t handler) +{ + widget->tablet_motion_handler = handler; +} + static void window_schedule_redraw_task(struct window *window); @@ -2521,6 +2550,25 @@ input_ungrab(struct input *input) } } +void +tablet_get_position(struct tablet *tablet, int32_t *x, int32_t *y) +{ + *x = tablet->sx; + *y = tablet->sy; +} + +void +tablet_set_user_data(struct tablet *tablet, void *data) +{ + tablet->user_data = data; +} + +void * +tablet_get_user_data(struct tablet *tablet) +{ + return tablet->user_data; +} + static void input_remove_pointer_focus(struct input *input) { @@ -3064,6 +3112,136 @@ static const struct wl_touch_listener touch_listener = { }; static void +tablet_handle_proximity_in(void *data, struct wl_tablet *wl_tablet, + uint32_t serial, uint32_t time, + struct wl_tablet_tool *tool, + struct wl_surface *surface) +{ + struct tablet *tablet = data; + struct window *window; + + DBG("tablet_handle_proximity_in\n"); + + window = wl_surface_get_user_data(surface); + if (surface != window->main_surface->surface) { + DBG("Ignoring input event from subsurface %p\n", surface); + return; + } + tablet->focus = window; +} + +static void +tablet_handle_proximity_out(void *data, struct wl_tablet *wl_tablet, + uint32_t time) +{ + struct tablet *tablet = data; + + tablet->focus = NULL; +} + +static void +tablet_handle_motion(void *data, struct wl_tablet *wl_tablet, uint32_t time, + wl_fixed_t w_sx, wl_fixed_t w_sy) +{ + struct tablet *tablet = data; + double sx = wl_fixed_to_double(w_sx); + double sy = wl_fixed_to_double(w_sy); + struct window *window = tablet->focus; + struct widget *widget; + + DBG("tablet_handle_motion"); + + if (!window) + return; + + tablet->sx = sx; + tablet->sy = sy; + + if (sx > window->main_surface->allocation.width || + sy > window->main_surface->allocation.height) + return; + + widget = window_find_widget(window, sx, sy); + if (widget && widget->tablet_motion_handler) { + widget->tablet_motion_handler(widget, tablet, sx, sy, time, + widget->user_data); + } +} + +static void +tablet_handle_removed(void *data, struct wl_tablet *wl_tablet) +{ + struct tablet *tablet = data; + + wl_list_remove(&tablet->link); + free(tablet->name); + free(tablet); + + wl_tablet_release(wl_tablet); +} + +static void +tablet_handle_frame(void *data, struct wl_tablet *wl_tablet) +{ + +} + +static const struct wl_tablet_listener tablet_listener = { + tablet_handle_proximity_in, + tablet_handle_proximity_out, + tablet_handle_motion, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + tablet_handle_frame, + tablet_handle_removed, +}; + +static void +tablet_manager_handle_device_added(void *data, + struct wl_tablet_manager *wl_tablet_manager, + struct wl_tablet *wl_tablet, + const char *name, uint32_t vid, uint32_t pid, + uint32_t type, uint32_t extra_axes) +{ + struct input *input = data; + struct tablet *tablet = xzalloc(sizeof(*tablet)); + + *tablet = (struct tablet) { + .name = strdup(name), + .vid = vid, + .pid = pid, + .type = type, + .input = input, + .tablet = wl_tablet, + }; + wl_list_insert(&input->tablet_list, &tablet->link); + + DBG("tablet_manager_handle_device_added"); + + wl_tablet_add_listener(wl_tablet, &tablet_listener, tablet); +} + +static void +tablet_manager_handle_seat(void *data, + struct wl_tablet_manager *wl_tablet_manager, + struct wl_seat *seat) +{ + struct input *input = wl_seat_get_user_data(seat); + + wl_tablet_manager_set_user_data(wl_tablet_manager, input); +} + +static const struct wl_tablet_manager_listener tablet_manager_listener = { + tablet_manager_handle_device_added, + NULL, + tablet_manager_handle_seat, +}; + +static void seat_handle_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps) { @@ -4975,6 +5153,7 @@ display_add_input(struct display *d, uint32_t id) input->keyboard_focus = NULL; wl_list_init(&input->touch_point_list); wl_list_insert(d->input_list.prev, &input->link); + wl_list_init(&input->tablet_list); wl_seat_add_listener(input->seat, &seat_listener, input); wl_seat_set_user_data(input->seat, input); @@ -4998,10 +5177,22 @@ display_add_input(struct display *d, uint32_t id) } static void +input_destroy_tablets(struct input *input) +{ + struct tablet *tablet, *tmp; + + wl_list_for_each_safe(tablet, tmp, &input->tablet_list, link) { + free(tablet->name); + free(tablet); + } +} + +static void input_destroy(struct input *input) { input_remove_keyboard_focus(input); input_remove_pointer_focus(input); + input_destroy_tablets(input); if (input->drag_offer) data_offer_destroy(input->drag_offer); @@ -5098,6 +5289,16 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, d->data_device_manager = wl_registry_bind(registry, id, &wl_data_device_manager_interface, 1); + } else if (strcmp(interface, "wl_tablet_manager") == 0) { + struct wl_tablet_manager *tablet_manager = + wl_registry_bind(registry, id, + &wl_tablet_manager_interface, 1); + + /* We can't do anything more with this tablet manager until we + * get the seat it's associated with */ + wl_tablet_manager_add_listener(tablet_manager, + &tablet_manager_listener, + NULL); } else if (strcmp(interface, "xdg_shell") == 0) { d->xdg_shell = wl_registry_bind(registry, id, &xdg_shell_interface, 1); diff --git a/clients/window.h b/clients/window.h index 5247f19..e4bec84 100644 --- a/clients/window.h +++ b/clients/window.h @@ -42,6 +42,7 @@ struct widget; struct display; struct input; struct output; +struct tablet; struct task { void (*run)(struct task *task, uint32_t events); @@ -270,6 +271,12 @@ typedef void (*widget_axis_handler_t)(struct widget *widget, uint32_t axis, wl_fixed_t value, void *data); +typedef void (*widget_tablet_motion_handler_t)(struct widget *widget, + struct tablet *tablet, + float x, + float y, + uint32_t time, + void *data); struct window * window_create(struct display *display); @@ -524,6 +531,9 @@ void widget_set_axis_handler(struct widget *widget, widget_axis_handler_t handler); void +widget_set_tablet_motion_handler(struct widget *widget, + widget_tablet_motion_handler_t handler); +void widget_schedule_redraw(struct widget *widget); void widget_set_use_cairo(struct widget *widget, int use_cairo); @@ -626,6 +636,15 @@ const char * output_get_model(struct output *output); void +tablet_get_position(struct tablet *tablet, int32_t *x, int32_t *y); + +void +tablet_set_user_data(struct tablet *tablet, void *data); + +void * +tablet_get_user_data(struct tablet *tablet); + +void keysym_modifiers_add(struct wl_array *modifiers_map, const char *name); -- 1.8.5.5 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel