[1/2] Restore zoom-follows-text-cursor functionality

Submitted by Scott Moreau on April 28, 2017, 6:51 p.m.

Details

Message ID 1493405507-16769-1-git-send-email-oreaus@gmail.com
State New
Headers show
Series "Series without cover letter" ( rev: 1 ) in Wayland

Not browsing as part of any series.

Commit Message

Scott Moreau April 28, 2017, 6:51 p.m.
This restores the functionality removed by a7af70436. It demonstrates
text-cursor-position protocol that can be seen when typing in
weston-terminal while zoomed in.
---
 desktop-shell/shell.c  |   3 +-
 libweston/compositor.c |   2 +-
 libweston/compositor.h |  18 +++++++-
 libweston/zoom.c       | 118 +++++++++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 134 insertions(+), 7 deletions(-)

Patch hide | download patch | download mbox

diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index f1577c1..429360a 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -3404,7 +3404,7 @@  do_zoom(struct weston_seat *seat, uint32_t time, uint32_t key, uint32_t axis,
 
 			output->zoom.spring_z.target = output->zoom.level;
 
-			weston_output_update_zoom(output);
+			weston_output_update_zoom(output, ZOOM_FOCUS_POINTER);
 		}
 	}
 }
@@ -5032,6 +5032,7 @@  wet_shell_init(struct weston_compositor *ec,
 	wl_signal_add(&ec->output_resized_signal, &shell->resized_listener);
 
 	screenshooter_create(ec);
+	text_cursor_position_notifier_create(ec);
 
 	shell_add_bindings(ec, shell);
 
diff --git a/libweston/compositor.c b/libweston/compositor.c
index 2bca19c..fa82e60 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -4349,7 +4349,7 @@  weston_output_update_matrix(struct weston_output *output)
 
 	if (output->zoom.active) {
 		magnification = 1 / (1 - output->zoom.spring_z.current);
-		weston_output_update_zoom(output);
+		weston_output_update_zoom(output, ZOOM_FOCUS_CURRENT);
 		weston_matrix_translate(&output->matrix, -output->zoom.trans_x,
 					-output->zoom.trans_y, 0);
 		weston_matrix_scale(&output->matrix, magnification,
diff --git a/libweston/compositor.h b/libweston/compositor.h
index 6070c77..07ab616 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -123,8 +123,15 @@  struct weston_spring {
 	uint32_t clip;
 };
 
+enum {
+	ZOOM_FOCUS_CURRENT,
+	ZOOM_FOCUS_POINTER,
+	ZOOM_FOCUS_TEXT
+};
+
 struct weston_output_zoom {
 	bool active;
+	uint32_t type;
 	float increment;
 	float level;
 	float max_level;
@@ -132,6 +139,9 @@  struct weston_output_zoom {
 	struct {
 		double x, y;
 	} current;
+	struct {
+		double x, y;
+	} text_cursor;
 	struct weston_seat *seat;
 	struct weston_animation animation_z;
 	struct weston_spring spring_z;
@@ -1705,11 +1715,14 @@  weston_compositor_exit_with_code(struct weston_compositor *compositor,
 void
 weston_output_init_zoom(struct weston_output *output);
 void
-weston_output_update_zoom(struct weston_output *output);
+weston_output_update_zoom(struct weston_output *output, uint32_t type);
 void
 weston_output_activate_zoom(struct weston_output *output,
 			    struct weston_seat *seat);
 void
+weston_text_cursor_position_notify(struct weston_surface *surface,
+						wl_fixed_t x, wl_fixed_t y);
+void
 weston_output_update_matrix(struct weston_output *output);
 void
 weston_output_move(struct weston_output *output, int x, int y);
@@ -1805,6 +1818,9 @@  weston_recorder_stop(struct weston_recorder *recorder);
 struct clipboard *
 clipboard_create(struct weston_seat *seat);
 
+void
+text_cursor_position_notifier_create(struct weston_compositor *ec);
+
 struct weston_view_animation;
 typedef	void (*weston_view_animation_done_func_t)(struct weston_view_animation *animation, void *data);
 
diff --git a/libweston/zoom.c b/libweston/zoom.c
index a1a1ab2..d3a2f55 100644
--- a/libweston/zoom.c
+++ b/libweston/zoom.c
@@ -34,6 +34,106 @@ 
 #include "text-cursor-position-server-protocol.h"
 #include "shared/helpers.h"
 
+
+struct text_cursor_position {
+	struct weston_compositor *ec;
+	struct wl_global *global;
+	struct wl_listener destroy_listener;
+};
+
+static void
+text_cursor_position_notify(struct wl_client *client,
+			    struct wl_resource *resource,
+			    struct wl_resource *surface_resource,
+			    wl_fixed_t x, wl_fixed_t y)
+{
+	struct weston_surface *surface =
+		wl_resource_get_user_data(surface_resource);
+
+	weston_text_cursor_position_notify(surface, x, y);
+}
+
+struct text_cursor_position_interface text_cursor_position_implementation = {
+	text_cursor_position_notify
+};
+
+static void
+bind_text_cursor_position(struct wl_client *client,
+	     void *data, uint32_t version, uint32_t id)
+{
+	struct wl_resource *resource;
+
+	resource = wl_resource_create(client,
+				      &text_cursor_position_interface, 1, id);
+	if (resource)
+		wl_resource_set_implementation(resource,
+					       &text_cursor_position_implementation,
+					       data, NULL);
+}
+
+static void
+text_cursor_position_notifier_destroy(struct wl_listener *listener, void *data)
+{
+	struct text_cursor_position *text_cursor_position =
+		container_of(listener, struct text_cursor_position, destroy_listener);
+
+	wl_global_destroy(text_cursor_position->global);
+	free(text_cursor_position);
+}
+
+WL_EXPORT void
+text_cursor_position_notifier_create(struct weston_compositor *ec)
+{
+	struct text_cursor_position *text_cursor_position;
+
+	text_cursor_position = malloc(sizeof *text_cursor_position);
+	if (text_cursor_position == NULL)
+		return;
+
+	text_cursor_position->ec = ec;
+
+	text_cursor_position->global =
+		wl_global_create(ec->wl_display,
+				 &text_cursor_position_interface, 1,
+				 text_cursor_position,
+				 bind_text_cursor_position);
+
+	text_cursor_position->destroy_listener.notify =
+		text_cursor_position_notifier_destroy;
+	wl_signal_add(&ec->destroy_signal, &text_cursor_position->destroy_listener);
+}
+
+WL_EXPORT void
+weston_text_cursor_position_notify(struct weston_surface *surface,
+						wl_fixed_t cur_pos_x,
+						wl_fixed_t cur_pos_y)
+{
+	struct weston_output *output;
+	struct weston_view *view;
+	wl_fixed_t global_x, global_y;
+
+	if (wl_list_empty(&surface->views))
+		return;
+
+	/* Use first view in list */
+	view = container_of(surface->views.next,
+					    struct weston_view, link);
+	weston_view_to_global_fixed(view, cur_pos_x, cur_pos_y,
+										&global_x, &global_y);
+
+	wl_list_for_each(output, &surface->compositor->output_list, link)
+		if (output->zoom.active &&
+		    pixman_region32_contains_point(&output->region,
+						wl_fixed_to_int(global_x),
+						wl_fixed_to_int(global_y),
+						NULL)) {
+			output->zoom.text_cursor.x = global_x;
+			output->zoom.text_cursor.y = global_y;
+			weston_output_update_zoom(output, ZOOM_FOCUS_TEXT);
+		}
+}
+
+
 static void
 weston_zoom_frame_z(struct weston_animation *animation,
 		struct weston_output *output, uint32_t msecs)
@@ -119,15 +219,25 @@  weston_zoom_transition(struct weston_output *output)
 }
 
 WL_EXPORT void
-weston_output_update_zoom(struct weston_output *output)
+weston_output_update_zoom(struct weston_output *output, uint32_t type)
 {
 	struct weston_seat *seat = output->zoom.seat;
 	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
 
 	assert(output->zoom.active);
 
-	output->zoom.current.x = wl_fixed_to_double(pointer->x);
-	output->zoom.current.y = wl_fixed_to_double(pointer->y);
+	switch(type) {
+	case ZOOM_FOCUS_POINTER:
+		output->zoom.current.x = wl_fixed_to_double(pointer->x);
+		output->zoom.current.y = wl_fixed_to_double(pointer->y);
+		break;
+	case ZOOM_FOCUS_TEXT:
+		output->zoom.current.x = wl_fixed_to_double(output->zoom.text_cursor.x);
+		output->zoom.current.y = wl_fixed_to_double(output->zoom.text_cursor.y);
+		break;
+	default:
+		break;
+	}
 
 	weston_zoom_transition(output);
 	weston_output_update_zoom_transform(output);
@@ -141,7 +251,7 @@  motion(struct wl_listener *listener, void *data)
 	struct weston_output *output =
 		container_of(zoom, struct weston_output, zoom);
 
-	weston_output_update_zoom(output);
+	weston_output_update_zoom(output, ZOOM_FOCUS_POINTER);
 }
 
 WL_EXPORT void