Changing the pointer to the appropriate image while moving the stylus around isn't supported yet.
Signed-off-by: Stephen Chandler Paul <[email protected]> --- clients/window.c | 27 +++++ desktop-shell/shell.c | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/compositor.h | 5 + src/input.c | 23 +++++ 4 files changed, 323 insertions(+) diff --git a/clients/window.c b/clients/window.c index 83459eb..7b844f8 100644 --- a/clients/window.c +++ b/clients/window.c @@ -2483,6 +2483,31 @@ frame_tablet_motion_handler(struct widget *widget, struct tablet *tablet, return frame_get_pointer_image_for_location(data, location); } +static void +frame_tablet_down_handler(struct widget *widget, struct tablet *tablet, + uint32_t time, void *data) +{ + struct window_frame *frame = data; + enum theme_location location; + + /* Map a stylus touch to the left mouse button */ + location = frame_pointer_button(frame->frame, tablet, BTN_LEFT, 1); + frame_handle_status(frame, tablet->input, time, location); +} + +static void +frame_tablet_up_handler(struct widget *widget, struct tablet *tablet, + uint32_t time, void *data) +{ + struct window_frame *frame = data; + enum theme_location location; + + /* Map the stylus leaving contact with the tablet as releasing the left + * mouse button */ + location = frame_pointer_button(frame->frame, tablet, BTN_LEFT, 0); + frame_handle_status(frame, tablet->input, time, location); +} + struct widget * window_frame_create(struct window *window, void *data) { @@ -2511,6 +2536,8 @@ window_frame_create(struct window *window, void *data) widget_set_touch_down_handler(frame->widget, frame_touch_down_handler); widget_set_touch_up_handler(frame->widget, frame_touch_up_handler); widget_set_tablet_motion_handler(frame->widget, frame_tablet_motion_handler); + widget_set_tablet_down_handler(frame->widget, frame_tablet_down_handler); + widget_set_tablet_up_handler(frame->widget, frame_tablet_up_handler); window->frame = frame; diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 3c3649c..679d011 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -191,6 +191,13 @@ struct shell_touch_grab { struct weston_touch *touch; }; +struct shell_tablet_grab { + struct weston_tablet_grab grab; + struct shell_surface *shsurf; + struct wl_listener shsurf_destroy_listener; + struct weston_tablet *tablet; +}; + struct weston_move_grab { struct shell_grab base; wl_fixed_t dx, dy; @@ -203,6 +210,11 @@ struct weston_touch_move_grab { wl_fixed_t dx, dy; }; +struct weston_tablet_move_grab { + struct shell_tablet_grab base; + wl_fixed_t dx, dy; +}; + struct rotate_grab { struct shell_grab base; struct weston_matrix rotation; @@ -220,6 +232,7 @@ struct shell_seat { struct wl_listener caps_changed_listener; struct wl_listener pointer_focus_listener; struct wl_listener keyboard_focus_listener; + struct wl_listener tablet_added_listener; struct { struct weston_pointer_grab grab; @@ -229,6 +242,11 @@ struct shell_seat { } popup_grab; }; +struct tablet_listener { + struct wl_listener base; + struct wl_listener removed_listener; +}; + struct shell_client { struct wl_resource *resource; struct wl_client *client; @@ -465,6 +483,43 @@ shell_touch_grab_end(struct shell_touch_grab *grab) } static void +shell_tablet_grab_start(struct shell_tablet_grab *grab, + const struct weston_tablet_grab_interface *interface, + struct shell_surface *shsurf, + struct weston_tablet *tablet) +{ + struct desktop_shell *shell = shsurf->shell; + + if (tablet->seat->pointer) + popup_grab_end(tablet->seat->pointer); + + grab->grab.interface = interface; + grab->shsurf = shsurf; + grab->shsurf_destroy_listener.notify = destroy_shell_grab_shsurf; + wl_signal_add(&shsurf->destroy_signal, &grab->shsurf_destroy_listener); + + grab->tablet = tablet; + shsurf->grabbed = 1; + + weston_tablet_start_grab(tablet, &grab->grab); + if (shell->child.desktop_shell) + weston_tablet_set_focus(tablet, + get_default_view(shell->grab_surface), + 0); +} + +static void +shell_tablet_grab_end(struct shell_tablet_grab *grab) +{ + if (grab->shsurf) { + wl_list_remove(&grab->shsurf_destroy_listener.link); + grab->shsurf->grabbed = 0; + } + + weston_tablet_end_grab(grab->tablet); +} + +static void center_on_output(struct weston_view *view, struct weston_output *output); @@ -1649,6 +1704,135 @@ surface_move(struct shell_surface *shsurf, struct weston_seat *seat, } static void +tablet_noop_grab_proximity_in(struct weston_tablet_grab *grab, + uint32_t time, + struct weston_tablet_tool *tool) +{ +} + +static void +tablet_move_grab_proximity_out(struct weston_tablet_grab *grab, uint32_t time) +{ + struct weston_tablet_move_grab *move = + (struct weston_tablet_move_grab *)grab; + + shell_tablet_grab_end(&move->base); + free(grab); +} + +static void +tablet_move_grab_up(struct weston_tablet_grab *grab, uint32_t time) +{ + struct weston_tablet_move_grab *move = + (struct weston_tablet_move_grab *)grab; + + shell_tablet_grab_end(&move->base); + free(grab); +} + +static void +tablet_noop_grab_down(struct weston_tablet_grab *grab, uint32_t time) +{ +} + +static void +tablet_move_grab_motion(struct weston_tablet_grab *grab, uint32_t time, + wl_fixed_t x, wl_fixed_t y) +{ + struct weston_tablet_move_grab *move = + (struct weston_tablet_move_grab *)grab; + struct shell_surface *shsurf = move->base.shsurf; + + if (!shsurf) + return; + + weston_tablet_cursor_move(grab->tablet, x, y); + weston_view_set_position(shsurf->view, + wl_fixed_to_double(x + move->dx), + wl_fixed_to_double(y + move->dy)); + weston_compositor_schedule_repaint(shsurf->surface->compositor); +} + +static void +tablet_noop_grab_pressure(struct weston_tablet_grab *grab, uint32_t time, + wl_fixed_t pressure) +{ +} + +static void +tablet_noop_grab_distance(struct weston_tablet_grab *grab, uint32_t time, + wl_fixed_t distance) +{ +} + +static void +tablet_noop_grab_tilt(struct weston_tablet_grab *grab, uint32_t time, + wl_fixed_t tilt_x, wl_fixed_t tilt_y) +{ +} + +static void tablet_noop_grab_button(struct weston_tablet_grab *grab, + uint32_t time, uint32_t button, + enum wl_tablet_button_state state) +{ +} + +static void +tablet_noop_grab_frame(struct weston_tablet_grab *grab) +{ +} + +static void +tablet_move_grab_cancel(struct weston_tablet_grab *grab) +{ + struct weston_tablet_move_grab *move = + (struct weston_tablet_move_grab *)grab; + + shell_tablet_grab_end(&move->base); + free(grab); +} + +static struct weston_tablet_grab_interface tablet_move_grab_interface = { + tablet_noop_grab_proximity_in, + tablet_move_grab_proximity_out, + tablet_move_grab_motion, + tablet_noop_grab_down, + tablet_move_grab_up, + tablet_noop_grab_pressure, + tablet_noop_grab_distance, + tablet_noop_grab_tilt, + tablet_noop_grab_button, + tablet_noop_grab_frame, + tablet_move_grab_cancel, +}; + +static int +surface_tablet_move(struct shell_surface *shsurf, struct weston_tablet *tablet) +{ + struct weston_tablet_move_grab *move; + + if (!shsurf) + return -1; + + if (shsurf->state.fullscreen || shsurf->state.maximized) + return 0; + + move = malloc(sizeof(*move)); + if (!move) + return -1; + + move->dx = wl_fixed_from_double(shsurf->view->geometry.x) - + tablet->grab_x; + move->dy = wl_fixed_from_double(shsurf->view->geometry.y) - + tablet->grab_y; + + shell_tablet_grab_start(&move->base, &tablet_move_grab_interface, + shsurf, tablet); + + return 0; +} + +static void common_surface_move(struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial) { @@ -1671,6 +1855,20 @@ common_surface_move(struct wl_resource *resource, if ((surface == shsurf->surface) && (surface_touch_move(shsurf, seat) < 0)) wl_resource_post_no_memory(resource); + } else if (!wl_list_empty(&seat->tablet_list)) { + struct weston_tablet *tablet; + + wl_list_for_each(tablet, &seat->tablet_list, link) { + if (tablet->focus && + tablet->grab_serial == serial) { + surface = weston_surface_get_main_surface( + tablet->focus->surface); + + if ((surface == shsurf->surface) && + (surface_tablet_move(shsurf, tablet) < 0)) + wl_resource_post_no_memory(resource); + } + } } } @@ -2057,6 +2255,22 @@ handle_pointer_focus(struct wl_listener *listener, void *data) } static void +handle_tablet_focus(struct wl_listener *listener, void *data) +{ + struct weston_tablet *tablet = data; + struct weston_view *view = tablet->focus; + struct weston_compositor *compositor; + uint32_t serial; + + if (!view) + return; + + compositor = view->surface->compositor; + serial = wl_display_next_serial(compositor->wl_display); + ping_handler(view->surface, serial); +} + +static void shell_surface_lose_keyboard_focus(struct shell_surface *shsurf) { if (--shsurf->focus_count == 0) @@ -2854,6 +3068,38 @@ shell_interface_move(struct shell_surface *shsurf, struct weston_seat *ws) static const struct weston_pointer_grab_interface popup_grab_interface; static void +destroy_tablet_listener(struct wl_listener *listener, void *data) +{ + struct tablet_listener *tablet_listener = + container_of(listener, struct tablet_listener, removed_listener); + + wl_list_remove(&tablet_listener->removed_listener.link); + wl_list_remove(&tablet_listener->base.link); + free(tablet_listener); +} + +static void +handle_tablet_added(struct wl_listener *listener, void *data) +{ + struct weston_tablet *tablet = data; + struct tablet_listener *tablet_listener; + + tablet_listener = malloc(sizeof *tablet_listener); + if (!tablet_listener) { + weston_log("no memory to allocate to shell seat tablet " + "listener\n"); + return; + } + + tablet_listener->removed_listener.notify = destroy_tablet_listener; + wl_signal_add(&tablet->removed_signal, + &tablet_listener->removed_listener); + + tablet_listener->base.notify = handle_tablet_focus; + wl_signal_add(&tablet->focus_signal, &tablet_listener->base); +} + +static void destroy_shell_seat(struct wl_listener *listener, void *data) { struct shell_seat *shseat = @@ -2876,6 +3122,7 @@ destroy_shell_seat(struct wl_listener *listener, void *data) } wl_list_remove(&shseat->seat_destroy_listener.link); + wl_list_remove(&shseat->tablet_added_listener.link); free(shseat); } @@ -2907,6 +3154,7 @@ static struct shell_seat * create_shell_seat(struct weston_seat *seat) { struct shell_seat *shseat; + struct weston_tablet *tablet; shseat = calloc(1, sizeof *shseat); if (!shseat) { @@ -2927,6 +3175,26 @@ create_shell_seat(struct weston_seat *seat) shseat->pointer_focus_listener.notify = handle_pointer_focus; wl_list_init(&shseat->pointer_focus_listener.link); + shseat->tablet_added_listener.notify = handle_tablet_added; + wl_list_init(&shseat->tablet_added_listener.link); + + wl_list_for_each(tablet, &seat->tablet_list, link) { + struct tablet_listener *listener = malloc(sizeof *listener); + + if (!listener) { + weston_log("no memory to allocate to shell seat tablet " + "listener\n"); + break; + } + + listener->removed_listener.notify = destroy_tablet_listener; + wl_signal_add(&tablet->removed_signal, + &listener->removed_listener); + + listener->base.notify = handle_tablet_focus; + wl_signal_add(&tablet->focus_signal, &listener->base); + } + shseat->caps_changed_listener.notify = shell_seat_caps_changed; wl_signal_add(&seat->updated_caps_signal, &shseat->caps_changed_listener); diff --git a/src/compositor.h b/src/compositor.h index 91ce7b7..081be57 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -420,6 +420,9 @@ struct weston_tablet { uint32_t focus_serial; uint32_t grab_serial; + struct wl_signal focus_signal; + struct wl_signal removed_signal; + struct weston_tablet_tool *current_tool; int32_t hotspot_x, hotspot_y; @@ -436,6 +439,7 @@ struct weston_tablet { struct weston_tablet_grab *grab; struct weston_tablet_grab default_grab; + wl_fixed_t grab_x, grab_y; struct wl_list link; @@ -623,6 +627,7 @@ struct weston_seat { struct wl_global *tablet_manager; struct wl_list tablet_manager_resource_list; + struct wl_signal tablet_added_signal; void (*led_update)(struct weston_seat *ws, enum weston_led leds); diff --git a/src/input.c b/src/input.c index 62b49ed..baafd70 100644 --- a/src/input.c +++ b/src/input.c @@ -750,6 +750,8 @@ weston_tablet_create(void) tablet->default_grab.interface = &default_tablet_grab_interface; tablet->default_grab.tablet = tablet; tablet->grab = &tablet->default_grab; + wl_signal_init(&tablet->focus_signal); + wl_signal_init(&tablet->removed_signal); return tablet; } @@ -873,6 +875,8 @@ weston_tablet_set_focus(struct weston_tablet *tablet, struct weston_view *view, tablet->focus = view; tablet->focus_view_listener.notify = tablet_focus_view_destroyed; + + wl_signal_emit(&tablet->focus_signal, tablet); } WL_EXPORT void @@ -1136,6 +1140,19 @@ weston_touch_cancel_grab(struct weston_touch *touch) touch->grab->interface->cancel(touch->grab); } +WL_EXPORT void +weston_tablet_start_grab(struct weston_tablet *tablet, struct weston_tablet_grab *grab) +{ + tablet->grab = grab; + grab->tablet = tablet; +} + +WL_EXPORT void +weston_tablet_end_grab(struct weston_tablet *tablet) +{ + tablet->grab = &tablet->default_grab; +} + static void weston_pointer_clamp_for_output(struct weston_pointer *pointer, struct weston_output *output, @@ -1946,6 +1963,9 @@ notify_tablet_down(struct weston_tablet *tablet, uint32_t time) weston_compositor_idle_inhibit(compositor); tablet->tool_contact_status = WESTON_TOOL_DOWN; + tablet->grab_serial = wl_display_get_serial(compositor->wl_display); + tablet->grab_x = tablet->x; + tablet->grab_y = tablet->y; grab->interface->down(grab, time); } @@ -2786,6 +2806,7 @@ weston_seat_add_tablet(struct weston_seat *seat) if (tablet == NULL) return NULL; + wl_signal_emit(&seat->tablet_added_signal, tablet); tablet->seat = seat; return tablet; @@ -2796,6 +2817,7 @@ weston_seat_release_tablet(struct weston_tablet *tablet) { struct wl_resource *resource; + wl_signal_emit(&tablet->removed_signal, tablet); weston_tablet_set_focus(tablet, NULL, 0); wl_resource_for_each(resource, &tablet->resource_list) wl_tablet_send_removed(resource); @@ -2836,6 +2858,7 @@ weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec, wl_list_init(&seat->tablet_list); wl_list_init(&seat->tablet_manager_resource_list); wl_list_init(&seat->tablet_tool_list); + wl_signal_init(&seat->tablet_added_signal); seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 4, seat, bind_seat); -- 1.8.5.5 _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
