From: Stephen Chandler Paul <thatsly...@gmail.com>

Changing the pointer to the appropriate image while moving the stylus
around isn't supported yet.

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>
---
 clients/window.c      |  32 ++++++
 desktop-shell/shell.c | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/compositor.h      |   6 ++
 src/input.c           |  11 +++
 4 files changed, 316 insertions(+)

diff --git a/clients/window.c b/clients/window.c
index abfc223..d5454b5 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -2598,6 +2598,36 @@ frame_tablet_tool_motion_handler(struct widget *widget,
        return CURSOR_DEFAULT;
 }
 
+static void
+frame_tablet_tool_down_handler(struct widget *widget,
+                              struct tablet_tool *tool,
+                              void *data)
+{
+       struct window_frame *frame = data;
+       enum theme_location location;
+       uint32_t time = 0; /* FIXME: we should be doing this in the frame
+                             handler where we have the timestamp  */
+
+       /* Map a stylus touch to the left mouse button */
+       location = frame_pointer_button(frame->frame, tool, BTN_LEFT, 1);
+       frame_handle_status(frame, tool->input, time, location);
+}
+
+static void
+frame_tablet_tool_up_handler(struct widget *widget, struct tablet_tool *tool,
+                            void *data)
+{
+       struct window_frame *frame = data;
+       enum theme_location location;
+       uint32_t time = 0; /* FIXME: we should be doing this in the frame
+                             handler where we have the timestamp  */
+
+       /* Map the stylus leaving contact with the tablet as releasing the left
+        * mouse button */
+       location = frame_pointer_button(frame->frame, tool, BTN_LEFT, 0);
+       frame_handle_status(frame, tool->input, time, location);
+}
+
 struct widget *
 window_frame_create(struct window *window, void *data)
 {
@@ -2627,6 +2657,8 @@ window_frame_create(struct window *window, void *data)
        widget_set_touch_up_handler(frame->widget, frame_touch_up_handler);
        widget_set_tablet_tool_motion_handler(frame->widget,
                                              frame_tablet_tool_motion_handler);
+       widget_set_tablet_tool_down_handler(frame->widget, 
frame_tablet_tool_down_handler);
+       widget_set_tablet_tool_up_handler(frame->widget, 
frame_tablet_tool_up_handler);
 
        window->frame = frame;
 
diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index 352ab23..5b604a5 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -195,6 +195,13 @@ struct shell_touch_grab {
        struct weston_touch *touch;
 };
 
+struct shell_tablet_tool_grab {
+       struct weston_tablet_tool_grab grab;
+       struct shell_surface *shsurf;
+       struct wl_listener shsurf_destroy_listener;
+       struct weston_tablet_tool *tool;
+};
+
 struct weston_move_grab {
        struct shell_grab base;
        wl_fixed_t dx, dy;
@@ -207,6 +214,11 @@ struct weston_touch_move_grab {
        wl_fixed_t dx, dy;
 };
 
+struct weston_tablet_tool_move_grab {
+       struct shell_tablet_tool_grab base;
+       wl_fixed_t dx, dy;
+};
+
 struct rotate_grab {
        struct shell_grab base;
        struct weston_matrix rotation;
@@ -224,6 +236,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_tool_added_listener;
 
        struct {
                struct weston_pointer_grab grab;
@@ -235,6 +248,11 @@ struct shell_seat {
        } popup_grab;
 };
 
+struct tablet_tool_listener {
+       struct wl_listener base;
+       struct wl_listener removed_listener;
+};
+
 struct shell_client {
        struct wl_resource *resource;
        struct wl_client *client;
@@ -595,6 +613,43 @@ shell_touch_grab_end(struct shell_touch_grab *grab)
 }
 
 static void
+shell_tablet_tool_grab_start(struct shell_tablet_tool_grab *grab,
+                            const struct weston_tablet_tool_grab_interface 
*interface,
+                            struct shell_surface *shsurf,
+                            struct weston_tablet_tool *tool)
+{
+       struct desktop_shell *shell = shsurf->shell;
+
+       if (tool->seat->pointer_state)
+               popup_grab_end(tool->seat->pointer_state);
+
+       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->tool = tool;
+       shsurf->grabbed = 1;
+
+       weston_tablet_tool_start_grab(tool, &grab->grab);
+       if (shell->child.desktop_shell)
+               weston_tablet_tool_set_focus(tool,
+                                            
get_default_view(shell->grab_surface),
+                                            0);
+}
+
+static void
+shell_tablet_tool_grab_end(struct shell_tablet_tool_grab *grab)
+{
+       if (grab->shsurf) {
+               wl_list_remove(&grab->shsurf_destroy_listener.link);
+               grab->shsurf->grabbed = 0;
+       }
+
+       weston_tablet_tool_end_grab(grab->tool);
+}
+
+static void
 center_on_output(struct weston_view *view,
                 struct weston_output *output);
 
@@ -1716,6 +1771,138 @@ surface_move(struct shell_surface *shsurf, struct 
weston_pointer *pointer,
 }
 
 static void
+tablet_tool_noop_grab_proximity_in(struct weston_tablet_tool_grab *grab,
+                                  uint32_t time,
+                                  struct weston_tablet *tablet)
+{
+}
+
+static void
+tablet_tool_move_grab_proximity_out(struct weston_tablet_tool_grab *grab, 
uint32_t time)
+{
+       struct weston_tablet_tool_move_grab *move =
+               (struct weston_tablet_tool_move_grab *)grab;
+
+       shell_tablet_tool_grab_end(&move->base);
+       free(grab);
+}
+
+static void
+tablet_tool_move_grab_up(struct weston_tablet_tool_grab *grab, uint32_t time)
+{
+       struct weston_tablet_tool_move_grab *move =
+               (struct weston_tablet_tool_move_grab *)grab;
+
+       shell_tablet_tool_grab_end(&move->base);
+       free(grab);
+}
+
+static void
+tablet_tool_noop_grab_down(struct weston_tablet_tool_grab *grab, uint32_t time)
+{
+}
+
+static void
+tablet_tool_move_grab_motion(struct weston_tablet_tool_grab *grab, uint32_t 
time,
+                       wl_fixed_t x, wl_fixed_t y)
+{
+       struct weston_tablet_tool_move_grab *move =
+               (struct weston_tablet_tool_move_grab *)grab;
+       struct shell_surface *shsurf = move->base.shsurf;
+
+       if (!shsurf)
+               return;
+
+       weston_tablet_tool_cursor_move(grab->tool, 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_tool_noop_grab_pressure(struct weston_tablet_tool_grab *grab,
+                              uint32_t time,
+                              uint32_t pressure)
+{
+}
+
+static void
+tablet_tool_noop_grab_distance(struct weston_tablet_tool_grab *grab,
+                              uint32_t time,
+                              uint32_t distance)
+{
+}
+
+static void
+tablet_tool_noop_grab_tilt(struct weston_tablet_tool_grab *grab,
+                          uint32_t time,
+                          int32_t tilt_x, int32_t tilt_y)
+{
+}
+
+static void tablet_tool_noop_grab_button(struct weston_tablet_tool_grab *grab,
+                                        uint32_t time, uint32_t button,
+                                        enum zwp_tablet_tool1_button_state 
state)
+{
+}
+
+static void
+tablet_tool_noop_grab_frame(struct weston_tablet_tool_grab *grab,
+                           uint32_t time)
+{
+}
+
+static void
+tablet_tool_move_grab_cancel(struct weston_tablet_tool_grab *grab)
+{
+       struct weston_tablet_tool_move_grab *move =
+               (struct weston_tablet_tool_move_grab *)grab;
+
+       shell_tablet_tool_grab_end(&move->base);
+       free(grab);
+}
+
+static struct weston_tablet_tool_grab_interface 
tablet_tool_move_grab_interface = {
+       tablet_tool_noop_grab_proximity_in,
+       tablet_tool_move_grab_proximity_out,
+       tablet_tool_move_grab_motion,
+       tablet_tool_noop_grab_down,
+       tablet_tool_move_grab_up,
+       tablet_tool_noop_grab_pressure,
+       tablet_tool_noop_grab_distance,
+       tablet_tool_noop_grab_tilt,
+       tablet_tool_noop_grab_button,
+       tablet_tool_noop_grab_frame,
+       tablet_tool_move_grab_cancel,
+};
+
+static int
+surface_tablet_tool_move(struct shell_surface *shsurf, struct 
weston_tablet_tool *tool)
+{
+       struct weston_tablet_tool_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) - 
tool->grab_x;
+       move->dy = wl_fixed_from_double(shsurf->view->geometry.y) - 
tool->grab_y;
+
+       shell_tablet_tool_grab_start(&move->base, 
&tablet_tool_move_grab_interface,
+                                    shsurf, tool);
+
+       return 0;
+}
+
+
+static void
 common_surface_move(struct wl_resource *resource,
                    struct wl_resource *seat_resource, uint32_t serial)
 {
@@ -1740,6 +1927,18 @@ common_surface_move(struct wl_resource *resource,
                if ((surface == shsurf->surface) &&
                    (surface_touch_move(shsurf, touch) < 0))
                        wl_resource_post_no_memory(resource);
+       } else if (!wl_list_empty(&seat->tablet_tool_list)) {
+               struct weston_tablet_tool *tool;
+
+               wl_list_for_each(tool, &seat->tablet_tool_list, link) {
+                       if (tool->focus && tool->grab_serial == serial) {
+                               surface = weston_surface_get_main_surface(
+                                                         tool->focus->surface);
+                               if (surface == shsurf->surface &&
+                                   surface_tablet_tool_move(shsurf, tool) < 0)
+                                       wl_resource_post_no_memory(resource);
+                       }
+               }
        }
 }
 
@@ -2146,6 +2345,22 @@ handle_pointer_focus(struct wl_listener *listener, void 
*data)
 }
 
 static void
+handle_tablet_tool_focus(struct wl_listener *listener, void *data)
+{
+       struct weston_tablet_tool *tool = data;
+       struct weston_view *view = tool->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)
@@ -3020,6 +3235,37 @@ shell_interface_resize(struct shell_surface *shsurf,
 static const struct weston_pointer_grab_interface popup_grab_interface;
 
 static void
+destroy_tablet_tool_listener(struct wl_listener *listener, void *data)
+{
+       struct tablet_tool_listener *tool_listener =
+               container_of(listener, struct tablet_tool_listener, 
removed_listener);
+
+       wl_list_remove(&tool_listener->removed_listener.link);
+       wl_list_remove(&tool_listener->base.link);
+       free(tool_listener);
+}
+
+static void
+handle_tablet_tool_added(struct wl_listener *listener, void *data)
+{
+       struct weston_tablet_tool *tool = data;
+       struct tablet_tool_listener *tool_listener;
+
+       tool_listener = malloc(sizeof *tool_listener);
+       if (!tool_listener) {
+               weston_log("no memory to allocate to shell seat tablet 
listener\n");
+               return;
+       }
+
+       tool_listener->removed_listener.notify = destroy_tablet_tool_listener;
+       wl_signal_add(&tool->removed_signal,
+                     &tool_listener->removed_listener);
+
+       tool_listener->base.notify = handle_tablet_tool_focus;
+       wl_signal_add(&tool->focus_signal, &tool_listener->base);
+}
+
+static void
 destroy_shell_seat(struct wl_listener *listener, void *data)
 {
        struct shell_seat *shseat =
@@ -3040,6 +3286,7 @@ destroy_shell_seat(struct wl_listener *listener, void 
*data)
        }
 
        wl_list_remove(&shseat->seat_destroy_listener.link);
+       wl_list_remove(&shseat->tablet_tool_added_listener.link);
        free(shseat);
 }
 
@@ -3077,6 +3324,7 @@ static struct shell_seat *
 create_shell_seat(struct weston_seat *seat)
 {
        struct shell_seat *shseat;
+       struct weston_tablet_tool *tool;
 
        shseat = calloc(1, sizeof *shseat);
        if (!shseat) {
@@ -3097,6 +3345,25 @@ 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_tool_added_listener.notify = handle_tablet_tool_added;
+       wl_list_init(&shseat->tablet_tool_added_listener.link);
+
+       wl_list_for_each(tool, &seat->tablet_tool_list, link) {
+               struct tablet_tool_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_tool_listener;
+               wl_signal_add(&tool->removed_signal,
+                             &listener->removed_listener);
+
+               listener->base.notify = handle_tablet_tool_focus;
+               wl_signal_add(&tool->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 2eaadf4..4da6bc5 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -438,6 +438,11 @@ struct weston_tablet_tool {
        struct wl_listener sprite_destroy_listener;
 
        wl_fixed_t x, y;
+
+       struct wl_signal focus_signal;
+       struct wl_signal removed_signal;
+
+       wl_fixed_t grab_x, grab_y;
 };
 
 struct weston_tablet {
@@ -659,6 +664,7 @@ struct weston_seat {
        char *seat_name;
 
        struct wl_list tablet_seat_resource_list;
+       struct wl_signal tablet_tool_added_signal;
 };
 
 enum {
diff --git a/src/input.c b/src/input.c
index 69806e2..145defd 100644
--- a/src/input.c
+++ b/src/input.c
@@ -751,6 +751,8 @@ weston_tablet_tool_set_focus(struct weston_tablet_tool 
*tool,
                                                 
&tool->focus_resource_listener);
        tool->focus = view;
        tool->focus_view_listener.notify = tablet_tool_focus_view_destroyed;
+
+       wl_signal_emit(&tool->focus_signal, tool);
 }
 
 WL_EXPORT void
@@ -989,6 +991,9 @@ weston_tablet_tool_create(void)
        tool->default_grab.tool = tool;
        tool->grab = &tool->default_grab;
 
+       wl_signal_init(&tool->focus_signal);
+       wl_signal_init(&tool->removed_signal);
+
        return tool;
 }
 
@@ -2354,6 +2359,8 @@ notify_tablet_tool_down(struct weston_tablet_tool *tool,
 
         tool->tip_is_down = true;
         tool->grab_serial = wl_display_get_serial(compositor->wl_display);
+        tool->grab_x = tool->x;
+        tool->grab_y = tool->y;
 
         grab->interface->down(grab, time);
 }
@@ -3068,6 +3075,7 @@ weston_seat_release_tablet_tool(struct weston_tablet_tool 
*tool)
 {
        /* FIXME: nothing is calling this function yet, tools are only
           released on shutdown when the seat goes away */
+       wl_signal_emit(&tool->removed_signal, tool);
 }
 
 WL_EXPORT void
@@ -3126,6 +3134,8 @@ weston_seat_add_tablet_tool(struct weston_seat *seat)
        if (tool == NULL)
                return NULL;
 
+       wl_signal_emit(&seat->tablet_tool_added_signal, tool);
+
        wl_list_init(&tool->resource_list);
        tool->seat = seat;
 
@@ -3159,6 +3169,7 @@ weston_seat_init(struct weston_seat *seat, struct 
weston_compositor *ec,
        wl_list_init(&seat->tablet_seat_resource_list);
        wl_list_init(&seat->tablet_list);
        wl_list_init(&seat->tablet_tool_list);
+       wl_signal_init(&seat->tablet_tool_added_signal);
 
        seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 4,
                                        seat, bind_seat);
-- 
2.4.3

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to