xref: /OK3568_Linux_fs/buildroot/package/weston/0076-HACK-Honour-cursor-size-config.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1From e0e7931ad4b829298e2c9e8cfd8e6a51e66bc41a Mon Sep 17 00:00:00 2001
2From: Jeffy Chen <jeffy.chen@rock-chips.com>
3Date: Fri, 23 Sep 2022 17:24:12 +0800
4Subject: [PATCH 76/95] HACK: Honour cursor-size config
5
6By scaling the cursor surface.
7
8Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
9---
10 compositor/main.c             |  4 +++
11 include/libweston/libweston.h |  6 +++-
12 libweston/backend-drm/drm.c   |  5 +++
13 libweston/compositor.c        | 66 +++++++++++++++++++++++------------
14 libweston/input.c             | 37 +++++++++++++++++---
15 5 files changed, 90 insertions(+), 28 deletions(-)
16
17diff --git a/compositor/main.c b/compositor/main.c
18index 314ccf1..a9ad103 100644
19--- a/compositor/main.c
20+++ b/compositor/main.c
21@@ -3802,6 +3802,10 @@ wet_main(int argc, char *argv[], const struct weston_testsuite_data *test_data)
22 	wet.compositor->exit = handle_exit;
23 	wet.compositor->warm_up = warm_up;
24
25+	section = weston_config_get_section(config, "shell", NULL, NULL);
26+	weston_config_section_get_int(section, "cursor-size",
27+				      &wet.compositor->cursor_size, 0);
28+
29 	weston_compositor_log_capabilities(wet.compositor);
30
31 	server_socket = getenv("WAYLAND_SERVER_SOCKET");
32diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h
33index 9d9c5c6..f6f4ecc 100644
34--- a/include/libweston/libweston.h
35+++ b/include/libweston/libweston.h
36@@ -738,6 +738,8 @@ struct weston_pointer {
37 	struct wl_listener output_destroy_listener;
38
39 	struct wl_list timestamps_list;
40+
41+	float scale;
42 };
43
44 /** libinput style calibration matrix
45@@ -1343,6 +1345,8 @@ struct weston_compositor {
46
47 	bool warm_up;
48 	uint32_t pending_fade_out;
49+
50+	int cursor_size;
51 };
52
53 struct weston_solid_buffer_values {
54@@ -1401,7 +1405,7 @@ struct weston_buffer_viewport {
55 		uint32_t transform;
56
57 		/* wl_surface.set_scaling_factor */
58-		int32_t scale;
59+		float scale;
60
61 		/*
62 		 * If src_width != wl_fixed_from_int(-1),
63diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c
64index 05ae2c1..658e2c3 100644
65--- a/libweston/backend-drm/drm.c
66+++ b/libweston/backend-drm/drm.c
67@@ -4369,6 +4369,11 @@ drm_backend_create(struct weston_compositor *compositor,
68 		goto err_udev_dev;
69 	}
70
71+	if (compositor->cursor_size) {
72+		device->cursor_width = compositor->cursor_size;
73+		device->cursor_height = compositor->cursor_size;
74+	}
75+
76 	res = drmModeGetResources(b->drm->drm.fd);
77 	if (!res) {
78 		weston_log("Failed to get drmModeRes\n");
79diff --git a/libweston/compositor.c b/libweston/compositor.c
80index ca5e405..ddd2180 100644
81--- a/libweston/compositor.c
82+++ b/libweston/compositor.c
83@@ -710,11 +710,11 @@ weston_view_to_global_float(struct weston_view *view,
84  * The given width and height must be the result of inverse scaled and
85  * inverse transformed buffer size.
86  */
87-WL_EXPORT void
88-weston_transformed_coord(int width, int height,
89-			 enum wl_output_transform transform,
90-			 int32_t scale,
91-			 float sx, float sy, float *bx, float *by)
92+static void
93+weston_transformed_coord_float(int width, int height,
94+			       enum wl_output_transform transform,
95+			       float scale,
96+			       float sx, float sy, float *bx, float *by)
97 {
98 	switch (transform) {
99 	case WL_OUTPUT_TRANSFORM_NORMAL:
100@@ -756,6 +756,16 @@ weston_transformed_coord(int width, int height,
101 	*by *= scale;
102 }
103
104+WL_EXPORT void
105+weston_transformed_coord(int width, int height,
106+			 enum wl_output_transform transform,
107+			 int32_t scale,
108+			 float sx, float sy, float *bx, float *by)
109+{
110+	weston_transformed_coord_float(width, height, transform,
111+				       scale, sx, sy, bx, by);
112+}
113+
114 /** Transform a rectangle to buffer coordinates
115  *
116  * \param width Surface width.
117@@ -773,20 +783,20 @@ weston_transformed_coord(int width, int height,
118  * The given width and height must be the result of inverse scaled and
119  * inverse transformed buffer size.
120  */
121-WL_EXPORT pixman_box32_t
122-weston_transformed_rect(int width, int height,
123-			enum wl_output_transform transform,
124-			int32_t scale,
125-			pixman_box32_t rect)
126+static pixman_box32_t
127+weston_transformed_rect_float(int width, int height,
128+			      enum wl_output_transform transform,
129+			      float scale,
130+			      pixman_box32_t rect)
131 {
132 	float x1, x2, y1, y2;
133
134 	pixman_box32_t ret;
135
136-	weston_transformed_coord(width, height, transform, scale,
137-				 rect.x1, rect.y1, &x1, &y1);
138-	weston_transformed_coord(width, height, transform, scale,
139-				 rect.x2, rect.y2, &x2, &y2);
140+	weston_transformed_coord_float(width, height, transform, scale,
141+				       rect.x1, rect.y1, &x1, &y1);
142+	weston_transformed_coord_float(width, height, transform, scale,
143+				       rect.x2, rect.y2, &x2, &y2);
144
145 	if (x1 <= x2) {
146 		ret.x1 = x1;
147@@ -807,6 +817,16 @@ weston_transformed_rect(int width, int height,
148 	return ret;
149 }
150
151+WL_EXPORT pixman_box32_t
152+weston_transformed_rect(int width, int height,
153+			enum wl_output_transform transform,
154+			int32_t scale,
155+			pixman_box32_t rect)
156+{
157+	return weston_transformed_rect_float(width, height, transform,
158+					     scale, rect);
159+}
160+
161 /** Transform a region by a matrix, restricted to axis-aligned transformations
162  *
163  * Warning: This function does not work for projective, affine, or matrices
164@@ -1012,10 +1032,10 @@ weston_surface_to_buffer_float(struct weston_surface *surface,
165 	/* first transform coordinates if the viewport is set */
166 	viewport_surface_to_buffer(surface, sx, sy, bx, by);
167
168-	weston_transformed_coord(surface->width_from_buffer,
169-				 surface->height_from_buffer,
170-				 vp->buffer.transform, vp->buffer.scale,
171-				 *bx, *by, bx, by);
172+	weston_transformed_coord_float(surface->width_from_buffer,
173+				       surface->height_from_buffer,
174+				       vp->buffer.transform, vp->buffer.scale,
175+				       *bx, *by, bx, by);
176 }
177
178 /** Transform a rectangle from surface coordinates to buffer coordinates
179@@ -1052,10 +1072,10 @@ weston_surface_to_buffer_rect(struct weston_surface *surface,
180 	rect.x2 = ceilf(xf);
181 	rect.y2 = ceilf(yf);
182
183-	return weston_transformed_rect(surface->width_from_buffer,
184-				       surface->height_from_buffer,
185-				       vp->buffer.transform, vp->buffer.scale,
186-				       rect);
187+	return weston_transformed_rect_float(surface->width_from_buffer,
188+					     surface->height_from_buffer,
189+					     vp->buffer.transform,
190+					     vp->buffer.scale, rect);
191 }
192
193 /** Transform a region from surface coordinates to buffer coordinates
194@@ -2163,7 +2183,7 @@ static void
195 convert_size_by_transform_scale(int32_t *width_out, int32_t *height_out,
196 				int32_t width, int32_t height,
197 				uint32_t transform,
198-				int32_t scale)
199+				float scale)
200 {
201 	assert(scale > 0);
202
203diff --git a/libweston/input.c b/libweston/input.c
204index 352aab6..2482168 100644
205--- a/libweston/input.c
206+++ b/libweston/input.c
207@@ -1768,8 +1768,8 @@ weston_pointer_move_to(struct weston_pointer *pointer,
208
209 	if (pointer->sprite) {
210 		weston_view_set_position(pointer->sprite,
211-					 ix - pointer->hotspot_x,
212-					 iy - pointer->hotspot_y);
213+					 ix - pointer->hotspot_x * pointer->scale,
214+					 iy - pointer->hotspot_y * pointer->scale);
215 		weston_view_schedule_repaint(pointer->sprite);
216 	}
217
218@@ -2735,6 +2735,29 @@ pointer_cursor_surface_get_label(struct weston_surface *surface,
219 	return snprintf(buf, len, "cursor");
220 }
221
222+static void
223+pointer_cursor_scale(struct weston_pointer *pointer,
224+		     struct weston_surface *surface)
225+{
226+	struct weston_compositor *compositor = surface->compositor;
227+	float scale;
228+
229+	if (!compositor->cursor_size || !surface->width ||
230+	    surface->width == compositor->cursor_size)
231+		return;
232+
233+	scale = 1.0 * compositor->cursor_size / surface->width;
234+	surface->buffer_viewport.buffer.scale = 1 / scale;
235+	pointer->scale = scale;
236+	surface->width *= scale;
237+	surface->height *= scale;
238+
239+	weston_matrix_scale(&surface->surface_to_buffer_matrix,
240+			    1 / scale, 1 / scale, 1);
241+	weston_matrix_invert(&surface->buffer_to_surface_matrix,
242+			     &surface->surface_to_buffer_matrix);
243+}
244+
245 static void
246 pointer_cursor_surface_committed(struct weston_surface *es,
247 				 int32_t dx, int32_t dy)
248@@ -2747,11 +2770,13 @@ pointer_cursor_surface_committed(struct weston_surface *es,
249
250 	assert(es == pointer->sprite->surface);
251
252+	pointer_cursor_scale(pointer, es);
253+
254 	pointer->hotspot_x -= dx;
255 	pointer->hotspot_y -= dy;
256
257-	x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
258-	y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
259+	x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x * pointer->scale;
260+	y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y * pointer->scale;
261
262 	weston_view_set_position(pointer->sprite, x, y);
263
264@@ -2822,6 +2847,8 @@ pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
265 		pointer->sprite = weston_view_create(surface);
266 	}
267
268+	pointer_cursor_scale(pointer, surface);
269+
270 	pointer->hotspot_x = x;
271 	pointer->hotspot_y = y;
272
273@@ -3432,6 +3459,8 @@ weston_seat_init_pointer(struct weston_seat *seat)
274
275 	seat_send_updated_caps(seat);
276
277+	pointer->scale = 1.0;
278+
279 	return 0;
280 }
281
282--
2832.20.1
284
285