[PATCH weston 03/16] tablet: add weston grab interfaces for tablet tools

Bastian Farkas bfarkas at de.adit-jv.com
Wed Oct 25 11:13:06 UTC 2017


From: Lyude Paul <thatslyude at gmail.com>

Co-authored-by: Peter Hutterer <peter.hutterer at who-t.net>
Signed-off-by: Lyude Paul <thatslyude at gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
Signed-off-by: Bastian Farkas <bfarkas at de.adit-jv.com>
---
 libweston/compositor.h |  53 +++++++++++
 libweston/input.c      | 253 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 306 insertions(+)

diff --git a/libweston/compositor.h b/libweston/compositor.h
index 6a17a92..49a0b56 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -310,6 +310,47 @@ struct weston_touch_grab {
 	struct weston_touch *touch;
 };
 
+struct weston_tablet;
+struct weston_tablet_tool;
+struct weston_tablet_tool_grab;
+struct weston_tablet_tool_grab_interface {
+	void (*proximity_in)(struct weston_tablet_tool_grab *grab,
+			     uint32_t time,
+			     struct weston_tablet *tablet);
+	void (*proximity_out)(struct weston_tablet_tool_grab *grab,
+			     uint32_t time);
+	void (*motion)(struct weston_tablet_tool_grab *grab,
+		       uint32_t time,
+		       wl_fixed_t x,
+		       wl_fixed_t y);
+	void (*down)(struct weston_tablet_tool_grab *grab,
+		     uint32_t time);
+	void (*up)(struct weston_tablet_tool_grab *grab,
+		   uint32_t time);
+	void (*pressure)(struct weston_tablet_tool_grab *grab,
+			 uint32_t time,
+			 uint32_t pressure);
+	void (*distance)(struct weston_tablet_tool_grab *grab,
+			 uint32_t time,
+			 uint32_t distance);
+	void (*tilt)(struct weston_tablet_tool_grab *grab,
+		     uint32_t time,
+		     int32_t tilt_x,
+		     int32_t tilt_y);
+	void (*button)(struct weston_tablet_tool_grab *grab,
+		       uint32_t time,
+		       uint32_t button,
+		       enum zwp_tablet_tool_v1_button_state state);
+	void (*frame)(struct weston_tablet_tool_grab *grab,
+		      uint32_t time);
+	void (*cancel)(struct weston_tablet_tool_grab *grab);
+};
+
+struct weston_tablet_tool_grab {
+	const struct weston_tablet_tool_grab_interface *interface;
+	struct weston_tablet_tool *tool;
+};
+
 struct weston_data_offer {
 	struct wl_resource *resource;
 	struct weston_data_source *source;
@@ -410,12 +451,19 @@ struct weston_tablet_tool {
 	struct wl_listener focus_view_listener;
 	struct wl_listener focus_resource_listener;
 	uint32_t focus_serial;
+	uint32_t grab_serial;
 
 	struct wl_list link;
 
 	uint64_t serial;
 	uint64_t hwid;
 	uint32_t capabilities;
+
+	struct weston_tablet_tool_grab *grab;
+	struct weston_tablet_tool_grab default_grab;
+
+	int button_count;
+	bool tip_is_down;
 };
 
 struct weston_tablet {
@@ -542,6 +590,11 @@ void
 weston_tablet_tool_set_focus(struct weston_tablet_tool *tool,
 			     struct weston_view *view,
 			     uint32_t time);
+void
+weston_tablet_tool_start_grab(struct weston_tablet_tool *tool,
+			      struct weston_tablet_tool_grab *grab);
+void
+weston_tablet_tool_end_grab(struct weston_tablet_tool *tool);
 
 bool
 weston_touch_has_focus_resource(struct weston_touch *touch);
diff --git a/libweston/input.c b/libweston/input.c
index 808e08e..1d863df 100644
--- a/libweston/input.c
+++ b/libweston/input.c
@@ -1243,6 +1243,9 @@ weston_tablet_tool_set_focus(struct weston_tablet_tool *tool,
 	focus_resource_list = &tool->focus_resource_list;
 	if (tool->focus && !wl_list_empty(focus_resource_list)) {
 		wl_resource_for_each(resource, focus_resource_list) {
+			if (tool->tip_is_down)
+				zwp_tablet_tool_v1_send_up(resource);
+
 			zwp_tablet_tool_v1_send_proximity_out(resource);
 			zwp_tablet_tool_v1_send_frame(resource, time);
 		}
@@ -1267,6 +1270,11 @@ weston_tablet_tool_set_focus(struct weston_tablet_tool *tool,
 
 			zwp_tablet_tool_v1_send_proximity_in(resource, tool->focus_serial,
 							   tr, view->surface->resource);
+
+			if (tool->tip_is_down)
+				zwp_tablet_tool_v1_send_down(resource,
+							   tool->focus_serial);
+
 			zwp_tablet_tool_v1_send_frame(resource, time);
 		}
 	}
@@ -1286,6 +1294,186 @@ weston_tablet_tool_set_focus(struct weston_tablet_tool *tool,
 	tool->focus_view_listener.notify = tablet_tool_focus_view_destroyed;
 }
 
+WL_EXPORT void
+weston_tablet_tool_start_grab(struct weston_tablet_tool *tool,
+			      struct weston_tablet_tool_grab *grab)
+{
+	tool->grab = grab;
+	grab->tool = tool;
+}
+
+WL_EXPORT void
+weston_tablet_tool_end_grab(struct weston_tablet_tool *tool)
+{
+	tool->grab = &tool->default_grab;
+}
+
+static void
+default_grab_tablet_tool_proximity_in(struct weston_tablet_tool_grab *grab,
+				      uint32_t time,
+				      struct weston_tablet *tablet)
+{
+	struct weston_tablet_tool *tool = grab->tool;
+
+	tool->current_tablet = tablet;
+}
+
+static void
+default_grab_tablet_tool_proximity_out(struct weston_tablet_tool_grab *grab,
+				       uint32_t time)
+{
+	weston_tablet_tool_set_focus(grab->tool, NULL, time);
+}
+
+static void
+default_grab_tablet_tool_motion(struct weston_tablet_tool_grab *grab,
+				uint32_t time,
+				wl_fixed_t x,
+				wl_fixed_t y)
+{
+	struct weston_tablet_tool *tool = grab->tool;
+	struct weston_view *current_view;
+	wl_fixed_t sx, sy;
+	struct wl_resource *resource;
+	struct wl_list *resource_list = &tool->focus_resource_list;
+
+	current_view = weston_compositor_pick_view(tool->seat->compositor,
+						   x, y, &sx, &sy);
+	if (current_view != tool->focus)
+		weston_tablet_tool_set_focus(tool, current_view, time);
+
+	if (!wl_list_empty(resource_list)) {
+		wl_resource_for_each(resource, resource_list)
+			zwp_tablet_tool_v1_send_motion(resource, sx, sy);
+	}
+}
+
+static void
+default_grab_tablet_tool_down(struct weston_tablet_tool_grab *grab,
+			      uint32_t time)
+{
+	struct weston_tablet_tool *tool = grab->tool;
+	struct wl_resource *resource;
+	struct wl_list *resource_list = &tool->focus_resource_list;
+
+	if (!wl_list_empty(resource_list)) {
+		wl_resource_for_each(resource, resource_list)
+			zwp_tablet_tool_v1_send_down(resource, tool->grab_serial);
+	}
+}
+
+static void
+default_grab_tablet_tool_up(struct weston_tablet_tool_grab *grab,
+			    uint32_t time)
+{
+	struct weston_tablet_tool *tool = grab->tool;
+	struct wl_resource *resource;
+	struct wl_list *resource_list = &tool->focus_resource_list;
+
+	if (!wl_list_empty(resource_list)) {
+		wl_resource_for_each(resource, resource_list)
+			zwp_tablet_tool_v1_send_up(resource);
+	}
+}
+
+static void
+default_grab_tablet_tool_pressure(struct weston_tablet_tool_grab *grab,
+				  uint32_t time,
+				  uint32_t pressure)
+{
+	struct weston_tablet_tool *tool = grab->tool;
+	struct wl_resource *resource;
+	struct wl_list *resource_list = &tool->focus_resource_list;
+
+	if (!wl_list_empty(resource_list)) {
+		wl_resource_for_each(resource, resource_list)
+			zwp_tablet_tool_v1_send_pressure(resource, pressure);
+	}
+}
+
+static void
+default_grab_tablet_tool_distance(struct weston_tablet_tool_grab *grab,
+				  uint32_t time,
+				  uint32_t distance)
+{
+	struct weston_tablet_tool *tool = grab->tool;
+	struct wl_resource *resource;
+	struct wl_list *resource_list = &tool->focus_resource_list;
+
+	if (!wl_list_empty(resource_list)) {
+		wl_resource_for_each(resource, resource_list)
+			zwp_tablet_tool_v1_send_pressure(resource, distance);
+	}
+}
+
+static void
+default_grab_tablet_tool_tilt(struct weston_tablet_tool_grab *grab,
+			      uint32_t time,
+			      int32_t tilt_x,
+			      int32_t tilt_y)
+{
+	struct weston_tablet_tool *tool = grab->tool;
+	struct wl_resource *resource;
+	struct wl_list *resource_list = &tool->focus_resource_list;
+
+	if (!wl_list_empty(resource_list)) {
+		wl_resource_for_each(resource, resource_list)
+			zwp_tablet_tool_v1_send_tilt(resource, tilt_x, tilt_y);
+	}
+}
+
+static void
+default_grab_tablet_tool_button(struct weston_tablet_tool_grab *grab,
+				uint32_t time,
+				uint32_t button,
+				enum zwp_tablet_tool_v1_button_state state)
+{
+	struct weston_tablet_tool *tool = grab->tool;
+	struct wl_resource *resource;
+	struct wl_list *resource_list = &tool->focus_resource_list;
+
+	if (!wl_list_empty(resource_list)) {
+		wl_resource_for_each(resource, resource_list) {
+			zwp_tablet_tool_v1_send_button(resource, tool->grab_serial,
+						   button, state);
+		}
+	}
+}
+
+static void
+default_grab_tablet_tool_frame(struct weston_tablet_tool_grab *grab,
+			       uint32_t time)
+{
+	struct wl_resource *resource;
+	struct wl_list *resource_list = &grab->tool->focus_resource_list;
+
+	if (!wl_list_empty(resource_list)) {
+		wl_resource_for_each(resource, resource_list)
+			zwp_tablet_tool_v1_send_frame(resource, time);
+	}
+}
+
+
+static void
+default_grab_tablet_tool_cancel(struct weston_tablet_tool_grab *grab)
+{
+}
+
+
+static struct weston_tablet_tool_grab_interface default_tablet_tool_grab_interface = {
+	default_grab_tablet_tool_proximity_in,
+	default_grab_tablet_tool_proximity_out,
+	default_grab_tablet_tool_motion,
+	default_grab_tablet_tool_down,
+	default_grab_tablet_tool_up,
+	default_grab_tablet_tool_pressure,
+	default_grab_tablet_tool_distance,
+	default_grab_tablet_tool_tilt,
+	default_grab_tablet_tool_button,
+	default_grab_tablet_tool_frame,
+	default_grab_tablet_tool_cancel,
+};
+
 WL_EXPORT struct weston_tablet_tool *
 weston_tablet_tool_create(void)
 {
@@ -1304,6 +1492,10 @@ weston_tablet_tool_create(void)
 	wl_list_init(&tool->focus_resource_listener.link);
 	tool->focus_resource_listener.notify = tablet_tool_focus_resource_destroyed;
 
+	tool->default_grab.interface = &default_tablet_tool_grab_interface;
+	tool->default_grab.tool = tool;
+	tool->grab = &tool->default_grab;
+
 	return tool;
 }
 
@@ -2574,12 +2766,18 @@ notify_tablet_tool_proximity_in(struct weston_tablet_tool *tool,
 				 uint32_t time,
 				 struct weston_tablet *tablet)
 {
+	struct weston_tablet_tool_grab *grab = tool->grab;
+
+	grab->interface->proximity_in(grab, time, tablet);
 }
 
 WL_EXPORT void
 notify_tablet_tool_proximity_out(struct weston_tablet_tool *tool,
 				 uint32_t time)
 {
+	struct weston_tablet_tool_grab *grab = tool->grab;
+
+	grab->interface->proximity_out(grab, time);
 }
 
 WL_EXPORT void
@@ -2587,24 +2785,44 @@ notify_tablet_tool_motion(struct weston_tablet_tool *tool,
 			  uint32_t time,
 			  wl_fixed_t x, wl_fixed_t y)
 {
+	struct weston_tablet_tool_grab *grab = tool->grab;
+
+	weston_compositor_wake(tool->seat->compositor);
+
+	grab->interface->motion(grab, time, x, y);
 }
 
 WL_EXPORT void
 notify_tablet_tool_pressure(struct weston_tablet_tool *tool,
 			    uint32_t time, uint32_t pressure)
 {
+	struct weston_tablet_tool_grab *grab = tool->grab;
+
+	weston_compositor_wake(tool->seat->compositor);
+
+	grab->interface->pressure(grab, time, pressure);
 }
 
 WL_EXPORT void
 notify_tablet_tool_distance(struct weston_tablet_tool *tool,
 			    uint32_t time, uint32_t distance)
 {
+	struct weston_tablet_tool_grab *grab = tool->grab;
+
+	weston_compositor_wake(tool->seat->compositor);
+
+	grab->interface->distance(grab, time, distance);
 }
 
 WL_EXPORT void
 notify_tablet_tool_tilt(struct weston_tablet_tool *tool,
 			uint32_t time, int32_t tilt_x, int32_t tilt_y)
 {
+	struct weston_tablet_tool_grab *grab = tool->grab;
+
+	weston_compositor_wake(tool->seat->compositor);
+
+	grab->interface->tilt(grab, time, tilt_x, tilt_y);
 }
 
 WL_EXPORT void
@@ -2613,24 +2831,59 @@ notify_tablet_tool_button(struct weston_tablet_tool *tool,
 			  uint32_t button,
 			  enum zwp_tablet_tool_v1_button_state state)
 {
+	struct weston_tablet_tool_grab *grab = tool->grab;
+	struct weston_compositor *compositor = tool->seat->compositor;
+
+	if (state == ZWP_TABLET_TOOL_V1_BUTTON_STATE_PRESSED) {
+		tool->button_count++;
+		if (tool->button_count == 1)
+			weston_compositor_idle_inhibit(compositor);
+	} else {
+		tool->button_count--;
+		if (tool->button_count == 1)
+			weston_compositor_idle_release(compositor);
+	}
+
+	tool->grab_serial = wl_display_next_serial(compositor->wl_display);
+	grab->interface->button(grab, time, button, state);
 }
 
 WL_EXPORT void
 notify_tablet_tool_down(struct weston_tablet_tool *tool,
 			uint32_t time)
 {
+	 struct weston_tablet_tool_grab *grab = tool->grab;
+	 struct weston_compositor *compositor = tool->seat->compositor;
+
+	 weston_compositor_idle_inhibit(compositor);
+
+	 tool->tip_is_down = true;
+	 tool->grab_serial = wl_display_get_serial(compositor->wl_display);
+
+	 grab->interface->down(grab, time);
 }
 
 WL_EXPORT void
 notify_tablet_tool_up(struct weston_tablet_tool *tool,
 		      uint32_t time)
 {
+	 struct weston_tablet_tool_grab *grab = tool->grab;
+	 struct weston_compositor *compositor = tool->seat->compositor;
+
+	 weston_compositor_idle_release(compositor);
+
+	 tool->tip_is_down = false;
+
+	 grab->interface->up(grab, time);
 }
 
 WL_EXPORT void
 notify_tablet_tool_frame(struct weston_tablet_tool *tool,
 			 uint32_t time)
 {
+	struct weston_tablet_tool_grab *grab = tool->grab;
+
+	grab->interface->frame(grab, time);
 }
 
 
-- 
2.7.4



More information about the wayland-devel mailing list