• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2010-2011 Benjamin Franzke
3  * Copyright © 2013 Jason Ekstrand
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial
15  * portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26 
27 #include "config.h"
28 
29 #include <assert.h>
30 #include <stddef.h>
31 #include <stdint.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <fcntl.h>
36 #include <unistd.h>
37 #include <errno.h>
38 #include <sys/mman.h>
39 #include <linux/input.h>
40 
41 #include <drm_fourcc.h>
42 #include <wayland-client.h>
43 #include <wayland-cursor.h>
44 
45 #ifdef ENABLE_EGL
46 #include <wayland-egl.h>
47 #endif
48 
49 #include <libweston/libweston.h>
50 #include <libweston/backend-wayland.h>
51 #include "renderer-gl/gl-renderer.h"
52 #include "shared/weston-egl-ext.h"
53 #include "pixman-renderer.h"
54 #include "shared/helpers.h"
55 #include "shared/image-loader.h"
56 #include "shared/os-compatibility.h"
57 #include "shared/cairo-util.h"
58 #include "shared/timespec-util.h"
59 #include "fullscreen-shell-unstable-v1-client-protocol.h"
60 #include "xdg-shell-client-protocol.h"
61 #include "presentation-time-server-protocol.h"
62 #include "linux-dmabuf.h"
63 #include <libweston/windowed-output-api.h>
64 
65 #define WINDOW_TITLE "Weston Compositor"
66 
67 static const uint32_t wayland_formats[] = {
68 	DRM_FORMAT_ARGB8888,
69 };
70 
71 struct wayland_backend {
72 	struct weston_backend base;
73 	struct weston_compositor *compositor;
74 
75 	struct {
76 		struct wl_display *wl_display;
77 		struct wl_registry *registry;
78 		struct wl_compositor *compositor;
79 		struct wl_shell *shell;
80 		struct xdg_wm_base *xdg_wm_base;
81 		struct zwp_fullscreen_shell_v1 *fshell;
82 		struct wl_shm *shm;
83 
84 		struct wl_list output_list;
85 
86 		struct wl_event_source *wl_source;
87 		uint32_t event_mask;
88 	} parent;
89 
90 	bool use_pixman;
91 	bool sprawl_across_outputs;
92 	bool fullscreen;
93 
94 	struct theme *theme;
95 	cairo_device_t *frame_device;
96 	struct wl_cursor_theme *cursor_theme;
97 	struct wl_cursor *cursor;
98 
99 	struct wl_list input_list;
100 };
101 
102 struct wayland_output {
103 	struct weston_output base;
104 
105 	struct {
106 		bool draw_initial_frame;
107 		struct wl_surface *surface;
108 
109 		struct wl_output *output;
110 		uint32_t global_id;
111 
112 		struct wl_shell_surface *shell_surface;
113 		struct xdg_surface *xdg_surface;
114 		struct xdg_toplevel *xdg_toplevel;
115 		int configure_width, configure_height;
116 		bool wait_for_configure;
117 	} parent;
118 
119 	int keyboard_count;
120 
121 	char *title;
122 	struct frame *frame;
123 
124 	struct {
125 		struct wl_egl_window *egl_window;
126 		struct {
127 			cairo_surface_t *top;
128 			cairo_surface_t *left;
129 			cairo_surface_t *right;
130 			cairo_surface_t *bottom;
131 		} border;
132 	} gl;
133 
134 	struct {
135 		struct wl_list buffers;
136 		struct wl_list free_buffers;
137 	} shm;
138 
139 	struct weston_mode mode;
140 
141 	struct wl_callback *frame_cb;
142 };
143 
144 struct wayland_parent_output {
145 	struct wayland_backend *backend;	/**< convenience */
146 	struct wayland_head *head;
147 	struct wl_list link;
148 
149 	struct wl_output *global;
150 	uint32_t id;
151 
152 	struct {
153 		char *make;
154 		char *model;
155 		int32_t width, height;
156 		uint32_t subpixel;
157 	} physical;
158 
159 	int32_t x, y;
160 	uint32_t transform;
161 	uint32_t scale;
162 
163 	struct wl_callback *sync_cb;	/**< wl_output < 2 done replacement */
164 
165 	struct wl_list mode_list;
166 	struct weston_mode *preferred_mode;
167 	struct weston_mode *current_mode;
168 };
169 
170 struct wayland_head {
171 	struct weston_head base;
172 	struct wayland_parent_output *parent_output;
173 };
174 
175 struct wayland_shm_buffer {
176 	struct wayland_output *output;
177 	struct wl_list link;
178 	struct wl_list free_link;
179 
180 	struct wl_buffer *buffer;
181 	void *data;
182 	size_t size;
183 	int width;
184 	int height;
185 	pixman_region32_t damage;		/**< in global coords */
186 	int frame_damaged;
187 
188 	pixman_image_t *pm_image;
189 	cairo_surface_t *c_surface;
190 };
191 
192 struct wayland_input {
193 	struct weston_seat base;
194 	struct wayland_backend *backend;
195 	struct wl_list link;
196 
197 	struct {
198 		struct wl_seat *seat;
199 		struct wl_pointer *pointer;
200 		struct wl_keyboard *keyboard;
201 		struct wl_touch *touch;
202 
203 		struct {
204 			struct wl_surface *surface;
205 			int32_t hx, hy;
206 		} cursor;
207 	} parent;
208 
209 	struct weston_touch_device *touch_device;
210 
211 	enum weston_key_state_update keyboard_state_update;
212 	uint32_t key_serial;
213 	uint32_t enter_serial;
214 	uint32_t touch_points;
215 	bool touch_active;
216 	bool has_focus;
217 	int seat_version;
218 
219 	struct wayland_output *output;
220 	struct wayland_output *touch_focus;
221 	struct wayland_output *keyboard_focus;
222 
223 	struct weston_pointer_axis_event vert, horiz;
224 };
225 
226 struct gl_renderer_interface *gl_renderer;
227 
228 static inline struct wayland_head *
to_wayland_head(struct weston_head * base)229 to_wayland_head(struct weston_head *base)
230 {
231 	return container_of(base, struct wayland_head, base);
232 }
233 
234 static inline struct wayland_output *
to_wayland_output(struct weston_output * base)235 to_wayland_output(struct weston_output *base)
236 {
237 	return container_of(base, struct wayland_output, base);
238 }
239 
240 static inline struct wayland_backend *
to_wayland_backend(struct weston_compositor * base)241 to_wayland_backend(struct weston_compositor *base)
242 {
243 	return container_of(base->backend, struct wayland_backend, base);
244 }
245 
246 static void
wayland_shm_buffer_destroy(struct wayland_shm_buffer * buffer)247 wayland_shm_buffer_destroy(struct wayland_shm_buffer *buffer)
248 {
249 	cairo_surface_destroy(buffer->c_surface);
250 	pixman_image_unref(buffer->pm_image);
251 
252 	wl_buffer_destroy(buffer->buffer);
253 	munmap(buffer->data, buffer->size);
254 
255 	pixman_region32_fini(&buffer->damage);
256 
257 	wl_list_remove(&buffer->link);
258 	wl_list_remove(&buffer->free_link);
259 	free(buffer);
260 }
261 
262 static void
buffer_release(void * data,struct wl_buffer * buffer)263 buffer_release(void *data, struct wl_buffer *buffer)
264 {
265 	struct wayland_shm_buffer *sb = data;
266 
267 	if (sb->output) {
268 		wl_list_insert(&sb->output->shm.free_buffers, &sb->free_link);
269 	} else {
270 		wayland_shm_buffer_destroy(sb);
271 	}
272 }
273 
274 static const struct wl_buffer_listener buffer_listener = {
275 	buffer_release
276 };
277 
278 static struct wayland_shm_buffer *
wayland_output_get_shm_buffer(struct wayland_output * output)279 wayland_output_get_shm_buffer(struct wayland_output *output)
280 {
281 	struct wayland_backend *b =
282 		to_wayland_backend(output->base.compositor);
283 	struct wl_shm *shm = b->parent.shm;
284 	struct wayland_shm_buffer *sb;
285 
286 	struct wl_shm_pool *pool;
287 	int width, height, stride;
288 	int32_t fx, fy;
289 	int fd;
290 	unsigned char *data;
291 
292 	if (!wl_list_empty(&output->shm.free_buffers)) {
293 		sb = container_of(output->shm.free_buffers.next,
294 				  struct wayland_shm_buffer, free_link);
295 		wl_list_remove(&sb->free_link);
296 		wl_list_init(&sb->free_link);
297 
298 		return sb;
299 	}
300 
301 	if (output->frame) {
302 		width = frame_width(output->frame);
303 		height = frame_height(output->frame);
304 	} else {
305 		width = output->base.current_mode->width;
306 		height = output->base.current_mode->height;
307 	}
308 
309 	stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
310 
311 	fd = os_create_anonymous_file(height * stride);
312 	if (fd < 0) {
313 		weston_log("could not create an anonymous file buffer: %s\n",
314 			   strerror(errno));
315 		return NULL;
316 	}
317 
318 	data = mmap(NULL, height * stride, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
319 	if (data == MAP_FAILED) {
320 		weston_log("could not mmap %d memory for data: %s\n", height * stride,
321 			   strerror(errno));
322 		close(fd);
323 		return NULL;
324 	}
325 
326 	sb = zalloc(sizeof *sb);
327 	if (sb == NULL) {
328 		weston_log("could not zalloc %zu memory for sb: %s\n", sizeof *sb,
329 			   strerror(errno));
330 		close(fd);
331 		munmap(data, height * stride);
332 		return NULL;
333 	}
334 
335 	sb->output = output;
336 	wl_list_init(&sb->free_link);
337 	wl_list_insert(&output->shm.buffers, &sb->link);
338 
339 	pixman_region32_init(&sb->damage);
340 	pixman_region32_copy(&sb->damage, &output->base.region);
341 	sb->frame_damaged = 1;
342 
343 	sb->data = data;
344 	sb->width = width;
345 	sb->height = height;
346 	sb->size = height * stride;
347 
348 	pool = wl_shm_create_pool(shm, fd, sb->size);
349 
350 	sb->buffer = wl_shm_pool_create_buffer(pool, 0,
351 					       width, height,
352 					       stride,
353 					       WL_SHM_FORMAT_ARGB8888);
354 	wl_buffer_add_listener(sb->buffer, &buffer_listener, sb);
355 	wl_shm_pool_destroy(pool);
356 	close(fd);
357 
358 	memset(data, 0, sb->size);
359 
360 	sb->c_surface =
361 		cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32,
362 						    width, height, stride);
363 
364 	fx = 0;
365 	fy = 0;
366 	if (output->frame)
367 		frame_interior(output->frame, &fx, &fy, 0, 0);
368 	sb->pm_image =
369 		pixman_image_create_bits(PIXMAN_a8r8g8b8, width, height,
370 					 (uint32_t *)(data + fy * stride) + fx,
371 					 stride);
372 
373 	return sb;
374 }
375 
376 static void
frame_done(void * data,struct wl_callback * callback,uint32_t time)377 frame_done(void *data, struct wl_callback *callback, uint32_t time)
378 {
379 	struct wayland_output *output = data;
380 	struct timespec ts;
381 
382 	assert(callback == output->frame_cb);
383 	wl_callback_destroy(callback);
384 	output->frame_cb = NULL;
385 
386 	/* XXX: use the presentation extension for proper timings */
387 
388 	/*
389 	 * This is the fallback case, where Presentation extension is not
390 	 * available from the parent compositor. We do not know the base for
391 	 * 'time', so we cannot feed it to finish_frame(). Do the only thing
392 	 * we can, and pretend finish_frame time is when we process this
393 	 * event.
394 	 */
395 	weston_compositor_read_presentation_clock(output->base.compositor, &ts);
396 	weston_output_finish_frame(&output->base, &ts, 0);
397 }
398 
399 static const struct wl_callback_listener frame_listener = {
400 	frame_done
401 };
402 
403 static void
draw_initial_frame(struct wayland_output * output)404 draw_initial_frame(struct wayland_output *output)
405 {
406 	struct wayland_shm_buffer *sb;
407 
408 	sb = wayland_output_get_shm_buffer(output);
409 
410 	/* If we are rendering with GL, then orphan it so that it gets
411 	 * destroyed immediately */
412 	if (output->gl.egl_window)
413 		sb->output = NULL;
414 
415 	wl_surface_attach(output->parent.surface, sb->buffer, 0, 0);
416 	wl_surface_damage(output->parent.surface, 0, 0,
417 			  sb->width, sb->height);
418 }
419 
420 #ifdef ENABLE_EGL
421 static void
wayland_output_update_gl_border(struct wayland_output * output)422 wayland_output_update_gl_border(struct wayland_output *output)
423 {
424 	int32_t ix, iy, iwidth, iheight, fwidth, fheight;
425 	cairo_t *cr;
426 
427 	if (!output->frame)
428 		return;
429 	if (!(frame_status(output->frame) & FRAME_STATUS_REPAINT))
430 		return;
431 
432 	fwidth = frame_width(output->frame);
433 	fheight = frame_height(output->frame);
434 	frame_interior(output->frame, &ix, &iy, &iwidth, &iheight);
435 
436 	if (!output->gl.border.top)
437 		output->gl.border.top =
438 			cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
439 						   fwidth, iy);
440 	cr = cairo_create(output->gl.border.top);
441 	frame_repaint(output->frame, cr);
442 	cairo_destroy(cr);
443 	gl_renderer->output_set_border(&output->base, GL_RENDERER_BORDER_TOP,
444 				       fwidth, iy,
445 				       cairo_image_surface_get_stride(output->gl.border.top) / 4,
446 				       cairo_image_surface_get_data(output->gl.border.top));
447 
448 
449 	if (!output->gl.border.left)
450 		output->gl.border.left =
451 			cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
452 						   ix, 1);
453 	cr = cairo_create(output->gl.border.left);
454 	cairo_translate(cr, 0, -iy);
455 	frame_repaint(output->frame, cr);
456 	cairo_destroy(cr);
457 	gl_renderer->output_set_border(&output->base, GL_RENDERER_BORDER_LEFT,
458 				       ix, 1,
459 				       cairo_image_surface_get_stride(output->gl.border.left) / 4,
460 				       cairo_image_surface_get_data(output->gl.border.left));
461 
462 
463 	if (!output->gl.border.right)
464 		output->gl.border.right =
465 			cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
466 						   fwidth - (ix + iwidth), 1);
467 	cr = cairo_create(output->gl.border.right);
468 	cairo_translate(cr, -(iwidth + ix), -iy);
469 	frame_repaint(output->frame, cr);
470 	cairo_destroy(cr);
471 	gl_renderer->output_set_border(&output->base, GL_RENDERER_BORDER_RIGHT,
472 				       fwidth - (ix + iwidth), 1,
473 				       cairo_image_surface_get_stride(output->gl.border.right) / 4,
474 				       cairo_image_surface_get_data(output->gl.border.right));
475 
476 
477 	if (!output->gl.border.bottom)
478 		output->gl.border.bottom =
479 			cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
480 						   fwidth, fheight - (iy + iheight));
481 	cr = cairo_create(output->gl.border.bottom);
482 	cairo_translate(cr, 0, -(iy + iheight));
483 	frame_repaint(output->frame, cr);
484 	cairo_destroy(cr);
485 	gl_renderer->output_set_border(&output->base, GL_RENDERER_BORDER_BOTTOM,
486 				       fwidth, fheight - (iy + iheight),
487 				       cairo_image_surface_get_stride(output->gl.border.bottom) / 4,
488 				       cairo_image_surface_get_data(output->gl.border.bottom));
489 }
490 #endif
491 
492 static int
wayland_output_start_repaint_loop(struct weston_output * output_base)493 wayland_output_start_repaint_loop(struct weston_output *output_base)
494 {
495 	struct wayland_output *output = to_wayland_output(output_base);
496 	struct wayland_backend *wb =
497 		to_wayland_backend(output->base.compositor);
498 
499 	/* If this is the initial frame, we need to attach a buffer so that
500 	 * the compositor can map the surface and include it in its render
501 	 * loop. If the surface doesn't end up in the render loop, the frame
502 	 * callback won't be invoked. The buffer is transparent and of the
503 	 * same size as the future real output buffer. */
504 	if (output->parent.draw_initial_frame) {
505 		output->parent.draw_initial_frame = false;
506 
507 		draw_initial_frame(output);
508 	}
509 
510 	output->frame_cb = wl_surface_frame(output->parent.surface);
511 	wl_callback_add_listener(output->frame_cb, &frame_listener, output);
512 	wl_surface_commit(output->parent.surface);
513 	wl_display_flush(wb->parent.wl_display);
514 
515 	return 0;
516 }
517 
518 #ifdef ENABLE_EGL
519 static int
wayland_output_repaint_gl(struct weston_output * output_base,pixman_region32_t * damage,void * repaint_data)520 wayland_output_repaint_gl(struct weston_output *output_base,
521 			  pixman_region32_t *damage,
522 			  void *repaint_data)
523 {
524 	struct wayland_output *output = to_wayland_output(output_base);
525 	struct weston_compositor *ec = output->base.compositor;
526 
527 	output->frame_cb = wl_surface_frame(output->parent.surface);
528 	wl_callback_add_listener(output->frame_cb, &frame_listener, output);
529 
530 	wayland_output_update_gl_border(output);
531 
532 	ec->renderer->repaint_output(&output->base, damage);
533 
534 	pixman_region32_subtract(&ec->primary_plane.damage,
535 				 &ec->primary_plane.damage, damage);
536 	return 0;
537 }
538 #endif
539 
540 static void
wayland_output_update_shm_border(struct wayland_shm_buffer * buffer)541 wayland_output_update_shm_border(struct wayland_shm_buffer *buffer)
542 {
543 	int32_t ix, iy, iwidth, iheight, fwidth, fheight;
544 	cairo_t *cr;
545 
546 	if (!buffer->output->frame || !buffer->frame_damaged)
547 		return;
548 
549 	cr = cairo_create(buffer->c_surface);
550 
551 	frame_interior(buffer->output->frame, &ix, &iy, &iwidth, &iheight);
552 	fwidth = frame_width(buffer->output->frame);
553 	fheight = frame_height(buffer->output->frame);
554 
555 	/* Set the clip so we don't unnecisaraly damage the surface */
556 	cairo_move_to(cr, ix, iy);
557 	cairo_rel_line_to(cr, iwidth, 0);
558 	cairo_rel_line_to(cr, 0, iheight);
559 	cairo_rel_line_to(cr, -iwidth, 0);
560 	cairo_line_to(cr, ix, iy);
561 	cairo_line_to(cr, 0, iy);
562 	cairo_line_to(cr, 0, fheight);
563 	cairo_line_to(cr, fwidth, fheight);
564 	cairo_line_to(cr, fwidth, 0);
565 	cairo_line_to(cr, 0, 0);
566 	cairo_line_to(cr, 0, iy);
567 	cairo_close_path(cr);
568 	cairo_clip(cr);
569 
570 	/* Draw using a pattern so that the final result gets clipped */
571 	cairo_push_group(cr);
572 	frame_repaint(buffer->output->frame, cr);
573 	cairo_pop_group_to_source(cr);
574 	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
575 	cairo_paint(cr);
576 
577 	cairo_destroy(cr);
578 }
579 
580 static void
wayland_shm_buffer_attach(struct wayland_shm_buffer * sb)581 wayland_shm_buffer_attach(struct wayland_shm_buffer *sb)
582 {
583 	pixman_region32_t damage;
584 	pixman_box32_t *rects;
585 	int32_t ix, iy, iwidth, iheight, fwidth, fheight;
586 	int i, n;
587 
588 	pixman_region32_init(&damage);
589 	pixman_region32_copy(&damage, &sb->damage);
590 	pixman_region32_translate(&damage, -sb->output->base.x,
591 				  -sb->output->base.y);
592 
593 	weston_transformed_region(sb->output->base.width,
594 				  sb->output->base.height,
595 				  sb->output->base.transform,
596 				  sb->output->base.current_scale,
597 				  &damage, &damage);
598 
599 	if (sb->output->frame) {
600 		frame_interior(sb->output->frame, &ix, &iy, &iwidth, &iheight);
601 		fwidth = frame_width(sb->output->frame);
602 		fheight = frame_height(sb->output->frame);
603 
604 		pixman_region32_translate(&damage, ix, iy);
605 
606 		if (sb->frame_damaged) {
607 			pixman_region32_union_rect(&damage, &damage,
608 						   0, 0, fwidth, iy);
609 			pixman_region32_union_rect(&damage, &damage,
610 						   0, iy, ix, iheight);
611 			pixman_region32_union_rect(&damage, &damage,
612 						   ix + iwidth, iy,
613 						   fwidth - (ix + iwidth), iheight);
614 			pixman_region32_union_rect(&damage, &damage,
615 						   0, iy + iheight,
616 						   fwidth, fheight - (iy + iheight));
617 		}
618 	}
619 
620 	rects = pixman_region32_rectangles(&damage, &n);
621 	wl_surface_attach(sb->output->parent.surface, sb->buffer, 0, 0);
622 	for (i = 0; i < n; ++i)
623 		wl_surface_damage(sb->output->parent.surface, rects[i].x1,
624 				  rects[i].y1, rects[i].x2 - rects[i].x1,
625 				  rects[i].y2 - rects[i].y1);
626 
627 	if (sb->output->frame)
628 		pixman_region32_fini(&damage);
629 }
630 
631 static int
wayland_output_repaint_pixman(struct weston_output * output_base,pixman_region32_t * damage,void * repaint_data)632 wayland_output_repaint_pixman(struct weston_output *output_base,
633 			      pixman_region32_t *damage,
634 			      void *repaint_data)
635 {
636 	struct wayland_output *output = to_wayland_output(output_base);
637 	struct wayland_backend *b =
638 		to_wayland_backend(output->base.compositor);
639 	struct wayland_shm_buffer *sb;
640 
641 	if (output->frame) {
642 		if (frame_status(output->frame) & FRAME_STATUS_REPAINT)
643 			wl_list_for_each(sb, &output->shm.buffers, link)
644 				sb->frame_damaged = 1;
645 	}
646 
647 	wl_list_for_each(sb, &output->shm.buffers, link)
648 		pixman_region32_union(&sb->damage, &sb->damage, damage);
649 
650 	sb = wayland_output_get_shm_buffer(output);
651 
652 	wayland_output_update_shm_border(sb);
653 	pixman_renderer_output_set_buffer(output_base, sb->pm_image);
654 	b->compositor->renderer->repaint_output(output_base, &sb->damage);
655 
656 	wayland_shm_buffer_attach(sb);
657 
658 	output->frame_cb = wl_surface_frame(output->parent.surface);
659 	wl_callback_add_listener(output->frame_cb, &frame_listener, output);
660 	wl_surface_commit(output->parent.surface);
661 	wl_display_flush(b->parent.wl_display);
662 
663 	pixman_region32_fini(&sb->damage);
664 	pixman_region32_init(&sb->damage);
665 	sb->frame_damaged = 0;
666 
667 	pixman_region32_subtract(&b->compositor->primary_plane.damage,
668 				 &b->compositor->primary_plane.damage, damage);
669 	return 0;
670 }
671 
672 static void
wayland_backend_destroy_output_surface(struct wayland_output * output)673 wayland_backend_destroy_output_surface(struct wayland_output *output)
674 {
675 	assert(output->parent.surface);
676 
677 	if (output->parent.xdg_toplevel) {
678 		xdg_toplevel_destroy(output->parent.xdg_toplevel);
679 		output->parent.xdg_toplevel = NULL;
680 	}
681 
682 	if (output->parent.xdg_surface) {
683 		xdg_surface_destroy(output->parent.xdg_surface);
684 		output->parent.xdg_surface = NULL;
685 	}
686 
687 	if (output->parent.shell_surface) {
688 		wl_shell_surface_destroy(output->parent.shell_surface);
689 		output->parent.shell_surface = NULL;
690 	}
691 
692 	wl_surface_destroy(output->parent.surface);
693 	output->parent.surface = NULL;
694 }
695 
696 static void
wayland_output_destroy_shm_buffers(struct wayland_output * output)697 wayland_output_destroy_shm_buffers(struct wayland_output *output)
698 {
699 	struct wayland_shm_buffer *buffer, *next;
700 
701 	/* Throw away any remaining SHM buffers */
702 	wl_list_for_each_safe(buffer, next, &output->shm.free_buffers, free_link)
703 		wayland_shm_buffer_destroy(buffer);
704 	/* These will get thrown away when they get released */
705 	wl_list_for_each(buffer, &output->shm.buffers, link)
706 		buffer->output = NULL;
707 }
708 
709 static int
wayland_output_disable(struct weston_output * base)710 wayland_output_disable(struct weston_output *base)
711 {
712 	struct wayland_output *output = to_wayland_output(base);
713 	struct wayland_backend *b = to_wayland_backend(base->compositor);
714 
715 	if (!output->base.enabled)
716 		return 0;
717 
718 	if (b->use_pixman) {
719 		pixman_renderer_output_destroy(&output->base);
720 #ifdef ENABLE_EGL
721 	} else {
722 		gl_renderer->output_destroy(&output->base);
723 		wl_egl_window_destroy(output->gl.egl_window);
724 #endif
725 	}
726 
727 	wayland_output_destroy_shm_buffers(output);
728 
729 	wayland_backend_destroy_output_surface(output);
730 
731 	if (output->frame)
732 		frame_destroy(output->frame);
733 
734 	cairo_surface_destroy(output->gl.border.top);
735 	cairo_surface_destroy(output->gl.border.left);
736 	cairo_surface_destroy(output->gl.border.right);
737 	cairo_surface_destroy(output->gl.border.bottom);
738 
739 	return 0;
740 }
741 
742 static void
wayland_output_destroy(struct weston_output * base)743 wayland_output_destroy(struct weston_output *base)
744 {
745 	struct wayland_output *output = to_wayland_output(base);
746 
747 	wayland_output_disable(&output->base);
748 
749 	weston_output_release(&output->base);
750 
751 	if (output->frame_cb)
752 		wl_callback_destroy(output->frame_cb);
753 
754 	free(output->title);
755 	free(output);
756 }
757 
758 static const struct wl_shell_surface_listener shell_surface_listener;
759 
760 #ifdef ENABLE_EGL
761 static int
wayland_output_init_gl_renderer(struct wayland_output * output)762 wayland_output_init_gl_renderer(struct wayland_output *output)
763 {
764 	int32_t fwidth = 0, fheight = 0;
765 	struct gl_renderer_output_options options = {
766 		.drm_formats = wayland_formats,
767 		.drm_formats_count = ARRAY_LENGTH(wayland_formats),
768 	};
769 
770 	if (output->frame) {
771 		fwidth = frame_width(output->frame);
772 		fheight = frame_height(output->frame);
773 	} else {
774 		fwidth = output->base.current_mode->width;
775 		fheight = output->base.current_mode->height;
776 	}
777 
778 	output->gl.egl_window =
779 		wl_egl_window_create(output->parent.surface,
780 				     fwidth, fheight);
781 	if (!output->gl.egl_window) {
782 		weston_log("failure to create wl_egl_window\n");
783 		return -1;
784 	}
785 	options.window_for_legacy = output->gl.egl_window;
786 	options.window_for_platform = output->gl.egl_window;
787 
788 	if (gl_renderer->output_window_create(&output->base, &options) < 0)
789 		goto cleanup_window;
790 
791 	return 0;
792 
793 cleanup_window:
794 	wl_egl_window_destroy(output->gl.egl_window);
795 	return -1;
796 }
797 #endif
798 
799 static int
wayland_output_init_pixman_renderer(struct wayland_output * output)800 wayland_output_init_pixman_renderer(struct wayland_output *output)
801 {
802 	const struct pixman_renderer_output_options options = {
803 		.use_shadow = true,
804 	};
805 	return pixman_renderer_output_create(&output->base, &options);
806 }
807 
808 static void
wayland_output_resize_surface(struct wayland_output * output)809 wayland_output_resize_surface(struct wayland_output *output)
810 {
811 	struct wayland_backend *b =
812 		to_wayland_backend(output->base.compositor);
813 	int32_t ix, iy, iwidth, iheight;
814 	int32_t width, height;
815 	struct wl_region *region;
816 
817 	width = output->base.current_mode->width;
818 	height = output->base.current_mode->height;
819 
820 	if (output->frame) {
821 		frame_resize_inside(output->frame, width, height);
822 
823 		frame_input_rect(output->frame, &ix, &iy, &iwidth, &iheight);
824 		region = wl_compositor_create_region(b->parent.compositor);
825 		wl_region_add(region, ix, iy, iwidth, iheight);
826 		wl_surface_set_input_region(output->parent.surface, region);
827 		wl_region_destroy(region);
828 
829 		if (output->parent.xdg_surface) {
830 			xdg_surface_set_window_geometry(output->parent.xdg_surface,
831 							ix,
832 							iy,
833 							iwidth,
834 							iheight);
835 		}
836 
837 		frame_opaque_rect(output->frame, &ix, &iy, &iwidth, &iheight);
838 		region = wl_compositor_create_region(b->parent.compositor);
839 		wl_region_add(region, ix, iy, iwidth, iheight);
840 		wl_surface_set_opaque_region(output->parent.surface, region);
841 		wl_region_destroy(region);
842 
843 		width = frame_width(output->frame);
844 		height = frame_height(output->frame);
845 	} else {
846 		region = wl_compositor_create_region(b->parent.compositor);
847 		wl_region_add(region, 0, 0, width, height);
848 		wl_surface_set_input_region(output->parent.surface, region);
849 		wl_region_destroy(region);
850 
851 		region = wl_compositor_create_region(b->parent.compositor);
852 		wl_region_add(region, 0, 0, width, height);
853 		wl_surface_set_opaque_region(output->parent.surface, region);
854 		wl_region_destroy(region);
855 
856 		if (output->parent.xdg_surface) {
857 			xdg_surface_set_window_geometry(output->parent.xdg_surface,
858 							0,
859 							0,
860 							width,
861 							height);
862 		}
863 	}
864 
865 #ifdef ENABLE_EGL
866 	if (output->gl.egl_window) {
867 		wl_egl_window_resize(output->gl.egl_window,
868 				     width, height, 0, 0);
869 
870 		/* These will need to be re-created due to the resize */
871 		gl_renderer->output_set_border(&output->base,
872 					       GL_RENDERER_BORDER_TOP,
873 					       0, 0, 0, NULL);
874 		cairo_surface_destroy(output->gl.border.top);
875 		output->gl.border.top = NULL;
876 		gl_renderer->output_set_border(&output->base,
877 					       GL_RENDERER_BORDER_LEFT,
878 					       0, 0, 0, NULL);
879 		cairo_surface_destroy(output->gl.border.left);
880 		output->gl.border.left = NULL;
881 		gl_renderer->output_set_border(&output->base,
882 					       GL_RENDERER_BORDER_RIGHT,
883 					       0, 0, 0, NULL);
884 		cairo_surface_destroy(output->gl.border.right);
885 		output->gl.border.right = NULL;
886 		gl_renderer->output_set_border(&output->base,
887 					       GL_RENDERER_BORDER_BOTTOM,
888 					       0, 0, 0, NULL);
889 		cairo_surface_destroy(output->gl.border.bottom);
890 		output->gl.border.bottom = NULL;
891 	}
892 #endif
893 
894 	wayland_output_destroy_shm_buffers(output);
895 }
896 
897 static int
wayland_output_set_windowed(struct wayland_output * output)898 wayland_output_set_windowed(struct wayland_output *output)
899 {
900 	struct wayland_backend *b =
901 		to_wayland_backend(output->base.compositor);
902 
903 	if (output->frame)
904 		return 0;
905 
906 	if (!b->theme) {
907 		b->theme = theme_create();
908 		if (!b->theme)
909 			return -1;
910 	}
911 	output->frame = frame_create(b->theme, 100, 100,
912 	                             FRAME_BUTTON_CLOSE, output->title, NULL);
913 	if (!output->frame)
914 		return -1;
915 
916 	if (output->keyboard_count)
917 		frame_set_flag(output->frame, FRAME_FLAG_ACTIVE);
918 
919 	wayland_output_resize_surface(output);
920 
921 	if (output->parent.xdg_toplevel) {
922 		xdg_toplevel_unset_fullscreen(output->parent.xdg_toplevel);
923 	} else if (output->parent.shell_surface) {
924 		wl_shell_surface_set_toplevel(output->parent.shell_surface);
925 	} else {
926 		abort();
927 	}
928 
929 	return 0;
930 }
931 
932 static void
wayland_output_set_fullscreen(struct wayland_output * output,enum wl_shell_surface_fullscreen_method method,uint32_t framerate,struct wl_output * target)933 wayland_output_set_fullscreen(struct wayland_output *output,
934 			      enum wl_shell_surface_fullscreen_method method,
935 			      uint32_t framerate, struct wl_output *target)
936 {
937 	if (output->frame) {
938 		frame_destroy(output->frame);
939 		output->frame = NULL;
940 	}
941 
942 	wayland_output_resize_surface(output);
943 
944 	if (output->parent.xdg_toplevel) {
945 		xdg_toplevel_set_fullscreen(output->parent.xdg_toplevel, target);
946 	} else if (output->parent.shell_surface) {
947 		wl_shell_surface_set_fullscreen(output->parent.shell_surface,
948 						method, framerate, target);
949 	} else {
950 		abort();
951 	}
952 }
953 
954 static struct weston_mode *
wayland_output_choose_mode(struct wayland_output * output,struct weston_mode * ref_mode)955 wayland_output_choose_mode(struct wayland_output *output,
956 			   struct weston_mode *ref_mode)
957 {
958 	struct weston_mode *mode;
959 
960 	/* First look for an exact match */
961 	wl_list_for_each(mode, &output->base.mode_list, link)
962 		if (mode->width == ref_mode->width &&
963 		    mode->height == ref_mode->height &&
964 		    mode->refresh == ref_mode->refresh)
965 			return mode;
966 
967 	/* If we can't find an exact match, ignore refresh and try again */
968 	wl_list_for_each(mode, &output->base.mode_list, link)
969 		if (mode->width == ref_mode->width &&
970 		    mode->height == ref_mode->height)
971 			return mode;
972 
973 	/* Yeah, we failed */
974 	return NULL;
975 }
976 
977 enum mode_status {
978 	MODE_STATUS_UNKNOWN,
979 	MODE_STATUS_SUCCESS,
980 	MODE_STATUS_FAIL,
981 	MODE_STATUS_CANCEL,
982 };
983 
984 static void
mode_feedback_successful(void * data,struct zwp_fullscreen_shell_mode_feedback_v1 * fb)985 mode_feedback_successful(void *data,
986 			 struct zwp_fullscreen_shell_mode_feedback_v1 *fb)
987 {
988 	enum mode_status *value = data;
989 
990 	printf("Mode switch successful\n");
991 
992 	*value = MODE_STATUS_SUCCESS;
993 }
994 
995 static void
mode_feedback_failed(void * data,struct zwp_fullscreen_shell_mode_feedback_v1 * fb)996 mode_feedback_failed(void *data, struct zwp_fullscreen_shell_mode_feedback_v1 *fb)
997 {
998 	enum mode_status *value = data;
999 
1000 	printf("Mode switch failed\n");
1001 
1002 	*value = MODE_STATUS_FAIL;
1003 }
1004 
1005 static void
mode_feedback_cancelled(void * data,struct zwp_fullscreen_shell_mode_feedback_v1 * fb)1006 mode_feedback_cancelled(void *data, struct zwp_fullscreen_shell_mode_feedback_v1 *fb)
1007 {
1008 	enum mode_status *value = data;
1009 
1010 	printf("Mode switch cancelled\n");
1011 
1012 	*value = MODE_STATUS_CANCEL;
1013 }
1014 
1015 struct zwp_fullscreen_shell_mode_feedback_v1_listener mode_feedback_listener = {
1016 	mode_feedback_successful,
1017 	mode_feedback_failed,
1018 	mode_feedback_cancelled,
1019 };
1020 
1021 static enum mode_status
wayland_output_fullscreen_shell_mode_feedback(struct wayland_output * output,struct weston_mode * mode)1022 wayland_output_fullscreen_shell_mode_feedback(struct wayland_output *output,
1023 					      struct weston_mode *mode)
1024 {
1025 	struct wayland_backend *b = to_wayland_backend(output->base.compositor);
1026 	struct zwp_fullscreen_shell_mode_feedback_v1 *mode_feedback;
1027 	enum mode_status mode_status;
1028 	int ret = 0;
1029 
1030 	mode_feedback =
1031 		zwp_fullscreen_shell_v1_present_surface_for_mode(b->parent.fshell,
1032 								 output->parent.surface,
1033 								 output->parent.output,
1034 								 mode->refresh);
1035 
1036 	zwp_fullscreen_shell_mode_feedback_v1_add_listener(mode_feedback,
1037 							   &mode_feedback_listener,
1038 							   &mode_status);
1039 
1040 	output->parent.draw_initial_frame = false;
1041 	draw_initial_frame(output);
1042 	wl_surface_commit(output->parent.surface);
1043 
1044 	mode_status = MODE_STATUS_UNKNOWN;
1045 	while (mode_status == MODE_STATUS_UNKNOWN && ret >= 0)
1046 		ret = wl_display_dispatch(b->parent.wl_display);
1047 
1048 	zwp_fullscreen_shell_mode_feedback_v1_destroy(mode_feedback);
1049 
1050 	return mode_status;
1051 }
1052 
1053 static int
wayland_output_switch_mode(struct weston_output * output_base,struct weston_mode * mode)1054 wayland_output_switch_mode(struct weston_output *output_base,
1055 			   struct weston_mode *mode)
1056 {
1057 	struct wayland_output *output = to_wayland_output(output_base);
1058 	struct wayland_backend *b;
1059 	struct wl_surface *old_surface;
1060 	struct weston_mode *old_mode;
1061 	enum mode_status mode_status;
1062 
1063 	if (output_base == NULL) {
1064 		weston_log("output is NULL.\n");
1065 		return -1;
1066 	}
1067 
1068 	if (mode == NULL) {
1069 		weston_log("mode is NULL.\n");
1070 		return -1;
1071 	}
1072 
1073 	b = to_wayland_backend(output_base->compositor);
1074 
1075 	if (output->parent.xdg_surface || output->parent.shell_surface || !b->parent.fshell)
1076 		return -1;
1077 
1078 	mode = wayland_output_choose_mode(output, mode);
1079 	if (mode == NULL)
1080 		return -1;
1081 
1082 	if (output->base.current_mode == mode)
1083 		return 0;
1084 
1085 	old_mode = output->base.current_mode;
1086 	old_surface = output->parent.surface;
1087 	output->base.current_mode = mode;
1088 	output->parent.surface =
1089 		wl_compositor_create_surface(b->parent.compositor);
1090 	wl_surface_set_user_data(output->parent.surface, output);
1091 
1092 	/* Blow the old buffers because we changed size/surfaces */
1093 	wayland_output_resize_surface(output);
1094 
1095 	mode_status = wayland_output_fullscreen_shell_mode_feedback(output, mode);
1096 
1097 	/* This should kick-start things again */
1098 	wayland_output_start_repaint_loop(&output->base);
1099 
1100 	if (mode_status == MODE_STATUS_FAIL) {
1101 		output->base.current_mode = old_mode;
1102 		wl_surface_destroy(output->parent.surface);
1103 		output->parent.surface = old_surface;
1104 		wayland_output_resize_surface(output);
1105 
1106 		return -1;
1107 	}
1108 
1109 	old_mode->flags &= ~WL_OUTPUT_MODE_CURRENT;
1110 	output->base.current_mode->flags |= WL_OUTPUT_MODE_CURRENT;
1111 
1112 	if (b->use_pixman) {
1113 		pixman_renderer_output_destroy(output_base);
1114 		if (wayland_output_init_pixman_renderer(output) < 0)
1115 			goto err_output;
1116 #ifdef ENABLE_EGL
1117 	} else {
1118 		gl_renderer->output_destroy(output_base);
1119 		wl_egl_window_destroy(output->gl.egl_window);
1120 		if (wayland_output_init_gl_renderer(output) < 0)
1121 			goto err_output;
1122 #endif
1123 	}
1124 	wl_surface_destroy(old_surface);
1125 
1126 	weston_output_schedule_repaint(&output->base);
1127 
1128 	return 0;
1129 
1130 err_output:
1131 	/* XXX */
1132 	return -1;
1133 }
1134 
1135 static void
handle_xdg_surface_configure(void * data,struct xdg_surface * surface,uint32_t serial)1136 handle_xdg_surface_configure(void *data, struct xdg_surface *surface,
1137 			 uint32_t serial)
1138 {
1139 	xdg_surface_ack_configure(surface, serial);
1140 }
1141 
1142 static const struct xdg_surface_listener xdg_surface_listener = {
1143 	handle_xdg_surface_configure
1144 };
1145 
1146 static void
handle_xdg_toplevel_configure(void * data,struct xdg_toplevel * toplevel,int32_t width,int32_t height,struct wl_array * states)1147 handle_xdg_toplevel_configure(void *data, struct xdg_toplevel *toplevel,
1148 			  int32_t width, int32_t height,
1149 			  struct wl_array *states)
1150 {
1151 	struct wayland_output *output = data;
1152 
1153 	output->parent.configure_width = width;
1154 	output->parent.configure_height = height;
1155 
1156 	output->parent.wait_for_configure = false;
1157 	/* FIXME: implement resizing */
1158 }
1159 
1160 static void
handle_xdg_toplevel_close(void * data,struct xdg_toplevel * xdg_toplevel)1161 handle_xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel)
1162 {
1163 	struct wayland_output *output = data;
1164 	struct weston_compositor *compositor = output->base.compositor;
1165 
1166 	wayland_output_destroy(&output->base);
1167 
1168 	if (wl_list_empty(&compositor->output_list))
1169 		weston_compositor_exit(compositor);
1170 }
1171 
1172 static const struct xdg_toplevel_listener xdg_toplevel_listener = {
1173 	handle_xdg_toplevel_configure,
1174 	handle_xdg_toplevel_close,
1175 };
1176 
1177 static int
wayland_backend_create_output_surface(struct wayland_output * output)1178 wayland_backend_create_output_surface(struct wayland_output *output)
1179 {
1180 	struct wayland_backend *b = to_wayland_backend(output->base.compositor);
1181 
1182 	assert(!output->parent.surface);
1183 
1184 	output->parent.surface =
1185 		wl_compositor_create_surface(b->parent.compositor);
1186 	if (!output->parent.surface)
1187 		return -1;
1188 
1189 	wl_surface_set_user_data(output->parent.surface, output);
1190 
1191 	output->parent.draw_initial_frame = true;
1192 
1193 	if (b->parent.xdg_wm_base) {
1194 		output->parent.xdg_surface =
1195 		xdg_wm_base_get_xdg_surface(b->parent.xdg_wm_base,
1196 					    output->parent.surface);
1197 		xdg_surface_add_listener(output->parent.xdg_surface,
1198 					 &xdg_surface_listener, output);
1199 
1200 		output->parent.xdg_toplevel =
1201 			xdg_surface_get_toplevel(output->parent.xdg_surface);
1202 		xdg_toplevel_add_listener(output->parent.xdg_toplevel,
1203 					  &xdg_toplevel_listener, output);
1204 
1205 		xdg_toplevel_set_title(output->parent.xdg_toplevel, output->title);
1206 
1207 		wl_surface_commit(output->parent.surface);
1208 
1209 		output->parent.wait_for_configure = true;
1210 
1211 		while (output->parent.wait_for_configure)
1212 			wl_display_dispatch(b->parent.wl_display);
1213 
1214 		weston_log("wayland-backend: Using xdg_wm_base\n");
1215 	}
1216 	else if (b->parent.shell) {
1217 		output->parent.shell_surface =
1218 			wl_shell_get_shell_surface(b->parent.shell,
1219 						   output->parent.surface);
1220 		if (!output->parent.shell_surface) {
1221 			wl_surface_destroy(output->parent.surface);
1222 			return -1;
1223 		}
1224 
1225 		wl_shell_surface_add_listener(output->parent.shell_surface,
1226 					      &shell_surface_listener, output);
1227 
1228 		weston_log("wayland-backend: Using wl_shell\n");
1229 	}
1230 
1231 	return 0;
1232 }
1233 
1234 static int
wayland_output_enable(struct weston_output * base)1235 wayland_output_enable(struct weston_output *base)
1236 {
1237 	struct wayland_output *output = to_wayland_output(base);
1238 	struct wayland_backend *b = to_wayland_backend(base->compositor);
1239 	enum mode_status mode_status;
1240 	int ret = 0;
1241 
1242 	weston_log("Creating %dx%d wayland output at (%d, %d)\n",
1243 		   output->base.current_mode->width,
1244 		   output->base.current_mode->height,
1245 		   output->base.x, output->base.y);
1246 
1247 	if (!output->parent.surface)
1248 		ret = wayland_backend_create_output_surface(output);
1249 
1250 	if (ret < 0)
1251 		return -1;
1252 
1253 	wl_list_init(&output->shm.buffers);
1254 	wl_list_init(&output->shm.free_buffers);
1255 
1256 	if (b->use_pixman) {
1257 		if (wayland_output_init_pixman_renderer(output) < 0)
1258 			goto err_output;
1259 
1260 		output->base.repaint = wayland_output_repaint_pixman;
1261 #ifdef ENABLE_EGL
1262 	} else {
1263 		if (wayland_output_init_gl_renderer(output) < 0)
1264 			goto err_output;
1265 
1266 		output->base.repaint = wayland_output_repaint_gl;
1267 #endif
1268 	}
1269 
1270 	output->base.start_repaint_loop = wayland_output_start_repaint_loop;
1271 	output->base.assign_planes = NULL;
1272 	output->base.set_backlight = NULL;
1273 	output->base.set_dpms = NULL;
1274 	output->base.switch_mode = wayland_output_switch_mode;
1275 
1276 	if (b->sprawl_across_outputs) {
1277 		if (b->parent.fshell) {
1278 			wayland_output_resize_surface(output);
1279 
1280 			mode_status = wayland_output_fullscreen_shell_mode_feedback(output, &output->mode);
1281 
1282 			if (mode_status == MODE_STATUS_FAIL) {
1283 				zwp_fullscreen_shell_v1_present_surface(b->parent.fshell,
1284 									output->parent.surface,
1285 									ZWP_FULLSCREEN_SHELL_V1_PRESENT_METHOD_CENTER,
1286 									output->parent.output);
1287 
1288 				output->parent.draw_initial_frame = true;
1289 			}
1290 		} else {
1291 			wayland_output_set_fullscreen(output,
1292 						      WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER,
1293 						      output->mode.refresh, output->parent.output);
1294 		}
1295 	} else if (b->fullscreen) {
1296 		wayland_output_set_fullscreen(output, 0, 0, NULL);
1297 	} else {
1298 		wayland_output_set_windowed(output);
1299 	}
1300 
1301 	return 0;
1302 
1303 err_output:
1304 	wayland_backend_destroy_output_surface(output);
1305 
1306 	return -1;
1307 }
1308 
1309 static int
1310 wayland_output_setup_for_parent_output(struct wayland_output *output,
1311 				       struct wayland_parent_output *poutput);
1312 
1313 static int
1314 wayland_output_setup_fullscreen(struct wayland_output *output,
1315 				struct wayland_head *head);
1316 
1317 static int
wayland_output_attach_head(struct weston_output * output_base,struct weston_head * head_base)1318 wayland_output_attach_head(struct weston_output *output_base,
1319 			   struct weston_head *head_base)
1320 {
1321 	struct wayland_backend *b = to_wayland_backend(output_base->compositor);
1322 	struct wayland_output *output = to_wayland_output(output_base);
1323 	struct wayland_head *head = to_wayland_head(head_base);
1324 
1325 	if (!wl_list_empty(&output->base.head_list))
1326 		return -1;
1327 
1328 	if (head->parent_output) {
1329 		if (wayland_output_setup_for_parent_output(output,
1330 							   head->parent_output) < 0)
1331 			return -1;
1332 	} else if (b->fullscreen) {
1333 		if (wayland_output_setup_fullscreen(output, head) < 0)
1334 			return -1;
1335 	} else {
1336 		/* A floating window, nothing to do. */
1337 	}
1338 
1339 	return 0;
1340 }
1341 
1342 static void
wayland_output_detach_head(struct weston_output * output_base,struct weston_head * head)1343 wayland_output_detach_head(struct weston_output *output_base,
1344 			   struct weston_head *head)
1345 {
1346 	struct wayland_output *output = to_wayland_output(output_base);
1347 
1348 	/* Rely on the disable hook if the output was enabled. We do not
1349 	 * support cloned heads, so detaching is guaranteed to disable the
1350 	 * output.
1351 	 */
1352 	if (output->base.enabled)
1353 		return;
1354 
1355 	/* undo setup fullscreen */
1356 	if (output->parent.surface)
1357 		wayland_backend_destroy_output_surface(output);
1358 }
1359 
1360 static struct weston_output *
wayland_output_create(struct weston_compositor * compositor,const char * name)1361 wayland_output_create(struct weston_compositor *compositor, const char *name)
1362 {
1363 	struct wayland_output *output;
1364 	char *title;
1365 
1366 	/* name can't be NULL. */
1367 	assert(name);
1368 
1369 	output = zalloc(sizeof *output);
1370 	if (output == NULL) {
1371 		perror("zalloc");
1372 		return NULL;
1373 	}
1374 
1375 	if (asprintf(&title, "%s - %s", WINDOW_TITLE, name) < 0) {
1376 		free(output);
1377 		return NULL;
1378 	}
1379 	output->title = title;
1380 
1381 	weston_output_init(&output->base, compositor, name);
1382 
1383 	output->base.destroy = wayland_output_destroy;
1384 	output->base.disable = wayland_output_disable;
1385 	output->base.enable = wayland_output_enable;
1386 	output->base.attach_head = wayland_output_attach_head;
1387 	output->base.detach_head = wayland_output_detach_head;
1388 
1389 	weston_compositor_add_pending_output(&output->base, compositor);
1390 
1391 	return &output->base;
1392 }
1393 
1394 static struct wayland_head *
wayland_head_create(struct weston_compositor * compositor,const char * name)1395 wayland_head_create(struct weston_compositor *compositor, const char *name)
1396 {
1397 	struct wayland_head *head;
1398 
1399 	assert(name);
1400 
1401 	head = zalloc(sizeof *head);
1402 	if (!head)
1403 		return NULL;
1404 
1405 	weston_head_init(&head->base, name);
1406 	weston_head_set_connection_status(&head->base, true);
1407 	weston_compositor_add_head(compositor, &head->base);
1408 
1409 	return head;
1410 }
1411 
1412 static int
wayland_head_create_windowed(struct weston_compositor * compositor,const char * name)1413 wayland_head_create_windowed(struct weston_compositor *compositor,
1414 			     const char *name)
1415 {
1416 	 if (!wayland_head_create(compositor, name))
1417 		return -1;
1418 
1419 	return 0;
1420 }
1421 
1422 static int
wayland_head_create_for_parent_output(struct weston_compositor * compositor,struct wayland_parent_output * poutput)1423 wayland_head_create_for_parent_output(struct weston_compositor *compositor,
1424 				      struct wayland_parent_output *poutput)
1425 {
1426 	struct wayland_head *head;
1427 	char name[100];
1428 	int ret;
1429 
1430 	ret = snprintf(name, sizeof(name), "wlparent-%d", poutput->id);
1431 	if (ret < 1 || (unsigned)ret >= sizeof(name))
1432 		return -1;
1433 
1434 	head = wayland_head_create(compositor, name);
1435 	if (!head)
1436 		return -1;
1437 
1438 	assert(!poutput->head);
1439 	head->parent_output = poutput;
1440 	poutput->head = head;
1441 
1442 	weston_head_set_monitor_strings(&head->base,
1443 					poutput->physical.make,
1444 					poutput->physical.model, NULL);
1445 	weston_head_set_physical_size(&head->base,
1446 				      poutput->physical.width,
1447 				      poutput->physical.height);
1448 
1449 	return 0;
1450 }
1451 
1452 static void
wayland_head_destroy(struct wayland_head * head)1453 wayland_head_destroy(struct wayland_head *head)
1454 {
1455 	if (head->parent_output)
1456 		head->parent_output->head = NULL;
1457 
1458 	weston_head_release(&head->base);
1459 	free(head);
1460 }
1461 
1462 static int
wayland_output_set_size(struct weston_output * base,int width,int height)1463 wayland_output_set_size(struct weston_output *base, int width, int height)
1464 {
1465 	struct wayland_output *output = to_wayland_output(base);
1466 	struct weston_head *head;
1467 	int output_width, output_height;
1468 
1469 	/* We can only be called once. */
1470 	assert(!output->base.current_mode);
1471 
1472 	/* Make sure we have scale set. */
1473 	assert(output->base.scale);
1474 
1475 	if (width < 1) {
1476 		weston_log("Invalid width \"%d\" for output %s\n",
1477 			   width, output->base.name);
1478 		return -1;
1479 	}
1480 
1481 	if (height < 1) {
1482 		weston_log("Invalid height \"%d\" for output %s\n",
1483 			   height, output->base.name);
1484 		return -1;
1485 	}
1486 
1487 	wl_list_for_each(head, &output->base.head_list, output_link) {
1488 		weston_head_set_monitor_strings(head, "wayland", "none", NULL);
1489 
1490 		/* XXX: Calculate proper size. */
1491 		weston_head_set_physical_size(head, width, height);
1492 	}
1493 
1494 	output_width = width * output->base.scale;
1495 	output_height = height * output->base.scale;
1496 
1497 	output->mode.flags =
1498 		WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
1499 
1500 	output->mode.width = output_width;
1501 	output->mode.height = output_height;
1502 	output->mode.refresh = 60000;
1503 	wl_list_insert(&output->base.mode_list, &output->mode.link);
1504 
1505 	output->base.current_mode = &output->mode;
1506 
1507 	return 0;
1508 }
1509 
1510 static int
wayland_output_setup_for_parent_output(struct wayland_output * output,struct wayland_parent_output * poutput)1511 wayland_output_setup_for_parent_output(struct wayland_output *output,
1512 				       struct wayland_parent_output *poutput)
1513 {
1514 	struct weston_mode *mode;
1515 
1516 	if (poutput->current_mode) {
1517 		mode = poutput->current_mode;
1518 	} else if (poutput->preferred_mode) {
1519 		mode = poutput->preferred_mode;
1520 	} else if (!wl_list_empty(&poutput->mode_list)) {
1521 		mode = container_of(poutput->mode_list.next,
1522 				    struct weston_mode, link);
1523 	} else {
1524 		weston_log("No valid modes found. Skipping output.\n");
1525 		return -1;
1526 	}
1527 
1528 	output->base.scale = 1;
1529 	output->base.transform = WL_OUTPUT_TRANSFORM_NORMAL;
1530 
1531 	output->parent.output = poutput->global;
1532 
1533 	wl_list_insert_list(&output->base.mode_list, &poutput->mode_list);
1534 	wl_list_init(&poutput->mode_list);
1535 
1536 	/* No other mode should have CURRENT already. */
1537 	mode->flags |= WL_OUTPUT_MODE_CURRENT;
1538 	output->base.current_mode = mode;
1539 
1540 	/* output->mode is unused in this path. */
1541 
1542 	return 0;
1543 }
1544 
1545 static int
wayland_output_setup_fullscreen(struct wayland_output * output,struct wayland_head * head)1546 wayland_output_setup_fullscreen(struct wayland_output *output,
1547 				struct wayland_head *head)
1548 {
1549 	struct wayland_backend *b = to_wayland_backend(output->base.compositor);
1550 	int width = 0, height = 0;
1551 
1552 	output->base.scale = 1;
1553 	output->base.transform = WL_OUTPUT_TRANSFORM_NORMAL;
1554 
1555 	if (wayland_backend_create_output_surface(output) < 0)
1556 		return -1;
1557 
1558 	/* What should size be set if conditional is false? */
1559 	if (b->parent.xdg_wm_base || b->parent.shell) {
1560 		if (output->parent.xdg_toplevel)
1561 			xdg_toplevel_set_fullscreen(output->parent.xdg_toplevel,
1562 						    output->parent.output);
1563 		else if (output->parent.shell_surface)
1564 			wl_shell_surface_set_fullscreen(output->parent.shell_surface,
1565 							0, 0, NULL);
1566 
1567 		wl_display_roundtrip(b->parent.wl_display);
1568 
1569 		width = output->parent.configure_width;
1570 		height = output->parent.configure_height;
1571 	}
1572 
1573 	if (wayland_output_set_size(&output->base, width, height) < 0)
1574 		goto err_set_size;
1575 
1576 	/* The head is not attached yet, so set_size did not set these. */
1577 	weston_head_set_monitor_strings(&head->base, "wayland", "none", NULL);
1578 	/* XXX: Calculate proper size. */
1579 	weston_head_set_physical_size(&head->base, width, height);
1580 
1581 	return 0;
1582 
1583 err_set_size:
1584 	wayland_backend_destroy_output_surface(output);
1585 
1586 	return -1;
1587 }
1588 
1589 static void
shell_surface_ping(void * data,struct wl_shell_surface * shell_surface,uint32_t serial)1590 shell_surface_ping(void *data, struct wl_shell_surface *shell_surface,
1591 		   uint32_t serial)
1592 {
1593 	wl_shell_surface_pong(shell_surface, serial);
1594 }
1595 
1596 static void
shell_surface_configure(void * data,struct wl_shell_surface * shell_surface,uint32_t edges,int32_t width,int32_t height)1597 shell_surface_configure(void *data, struct wl_shell_surface *shell_surface,
1598 			uint32_t edges, int32_t width, int32_t height)
1599 {
1600 	struct wayland_output *output = data;
1601 
1602 	output->parent.configure_width = width;
1603 	output->parent.configure_height = height;
1604 
1605 	/* FIXME: implement resizing */
1606 }
1607 
1608 static void
shell_surface_popup_done(void * data,struct wl_shell_surface * shell_surface)1609 shell_surface_popup_done(void *data, struct wl_shell_surface *shell_surface)
1610 {
1611 }
1612 
1613 static const struct wl_shell_surface_listener shell_surface_listener = {
1614 	shell_surface_ping,
1615 	shell_surface_configure,
1616 	shell_surface_popup_done
1617 };
1618 
1619 /* Events received from the wayland-server this compositor is client of: */
1620 
1621 /* parent input interface */
1622 static void
input_set_cursor(struct wayland_input * input)1623 input_set_cursor(struct wayland_input *input)
1624 {
1625 
1626 	struct wl_buffer *buffer;
1627 	struct wl_cursor_image *image;
1628 
1629 	if (!input->backend->cursor)
1630 		return; /* Couldn't load the cursor. Can't set it */
1631 
1632 	image = input->backend->cursor->images[0];
1633 	buffer = wl_cursor_image_get_buffer(image);
1634 	if (!buffer)
1635 		return;
1636 
1637 	wl_pointer_set_cursor(input->parent.pointer, input->enter_serial,
1638 			      input->parent.cursor.surface,
1639 			      image->hotspot_x, image->hotspot_y);
1640 
1641 	wl_surface_attach(input->parent.cursor.surface, buffer, 0, 0);
1642 	wl_surface_damage(input->parent.cursor.surface, 0, 0,
1643 			  image->width, image->height);
1644 	wl_surface_commit(input->parent.cursor.surface);
1645 }
1646 
1647 static void
input_handle_pointer_enter(void * data,struct wl_pointer * pointer,uint32_t serial,struct wl_surface * surface,wl_fixed_t fixed_x,wl_fixed_t fixed_y)1648 input_handle_pointer_enter(void *data, struct wl_pointer *pointer,
1649 			   uint32_t serial, struct wl_surface *surface,
1650 			   wl_fixed_t fixed_x, wl_fixed_t fixed_y)
1651 {
1652 	struct wayland_input *input = data;
1653 	int32_t fx, fy;
1654 	enum theme_location location;
1655 	double x, y;
1656 
1657 	if (!surface) {
1658 		input->output = NULL;
1659 		input->has_focus = false;
1660 		notify_pointer_focus(&input->base, NULL, 0, 0);
1661 		return;
1662 	}
1663 
1664 	x = wl_fixed_to_double(fixed_x);
1665 	y = wl_fixed_to_double(fixed_y);
1666 
1667 	/* XXX: If we get a modifier event immediately before the focus,
1668 	 *      we should try to keep the same serial. */
1669 	input->enter_serial = serial;
1670 	input->output = wl_surface_get_user_data(surface);
1671 
1672 	if (input->output->frame) {
1673 		location = frame_pointer_enter(input->output->frame, input,
1674 					       x, y);
1675 		frame_interior(input->output->frame, &fx, &fy, NULL, NULL);
1676 		x -= fx;
1677 		y -= fy;
1678 
1679 		if (frame_status(input->output->frame) & FRAME_STATUS_REPAINT)
1680 			weston_output_schedule_repaint(&input->output->base);
1681 	} else {
1682 		location = THEME_LOCATION_CLIENT_AREA;
1683 	}
1684 
1685 	weston_output_transform_coordinate(&input->output->base, x, y, &x, &y);
1686 
1687 	if (location == THEME_LOCATION_CLIENT_AREA) {
1688 		input->has_focus = true;
1689 		notify_pointer_focus(&input->base, &input->output->base, x, y);
1690 		wl_pointer_set_cursor(input->parent.pointer,
1691 				      input->enter_serial, NULL, 0, 0);
1692 	} else {
1693 		input->has_focus = false;
1694 		notify_pointer_focus(&input->base, NULL, 0, 0);
1695 		input_set_cursor(input);
1696 	}
1697 }
1698 
1699 static void
input_handle_pointer_leave(void * data,struct wl_pointer * pointer,uint32_t serial,struct wl_surface * surface)1700 input_handle_pointer_leave(void *data, struct wl_pointer *pointer,
1701 			   uint32_t serial, struct wl_surface *surface)
1702 {
1703 	struct wayland_input *input = data;
1704 
1705 	if (!input->output)
1706 		return;
1707 
1708 	if (input->output->frame) {
1709 		frame_pointer_leave(input->output->frame, input);
1710 
1711 		if (frame_status(input->output->frame) & FRAME_STATUS_REPAINT)
1712 			weston_output_schedule_repaint(&input->output->base);
1713 	}
1714 
1715 	notify_pointer_focus(&input->base, NULL, 0, 0);
1716 	input->output = NULL;
1717 	input->has_focus = false;
1718 }
1719 
1720 static void
input_handle_motion(void * data,struct wl_pointer * pointer,uint32_t time,wl_fixed_t fixed_x,wl_fixed_t fixed_y)1721 input_handle_motion(void *data, struct wl_pointer *pointer,
1722 		    uint32_t time, wl_fixed_t fixed_x, wl_fixed_t fixed_y)
1723 {
1724 	struct wayland_input *input = data;
1725 	int32_t fx, fy;
1726 	enum theme_location location;
1727 	bool want_frame = false;
1728 	double x, y;
1729 	struct timespec ts;
1730 
1731 	if (!input->output)
1732 		return;
1733 
1734 	x = wl_fixed_to_double(fixed_x);
1735 	y = wl_fixed_to_double(fixed_y);
1736 
1737 	if (input->output->frame) {
1738 		location = frame_pointer_motion(input->output->frame, input,
1739 						x, y);
1740 		frame_interior(input->output->frame, &fx, &fy, NULL, NULL);
1741 		x -= fx;
1742 		y -= fy;
1743 
1744 		if (frame_status(input->output->frame) & FRAME_STATUS_REPAINT)
1745 			weston_output_schedule_repaint(&input->output->base);
1746 	} else {
1747 		location = THEME_LOCATION_CLIENT_AREA;
1748 	}
1749 
1750 	weston_output_transform_coordinate(&input->output->base, x, y, &x, &y);
1751 
1752 	if (input->has_focus && location != THEME_LOCATION_CLIENT_AREA) {
1753 		input_set_cursor(input);
1754 		notify_pointer_focus(&input->base, NULL, 0, 0);
1755 		input->has_focus = false;
1756 		want_frame = true;
1757 	} else if (!input->has_focus &&
1758 		   location == THEME_LOCATION_CLIENT_AREA) {
1759 		wl_pointer_set_cursor(input->parent.pointer,
1760 				      input->enter_serial, NULL, 0, 0);
1761 		notify_pointer_focus(&input->base, &input->output->base, x, y);
1762 		input->has_focus = true;
1763 		want_frame = true;
1764 	}
1765 
1766 	if (location == THEME_LOCATION_CLIENT_AREA) {
1767 		timespec_from_msec(&ts, time);
1768 		notify_motion_absolute(&input->base, &ts, x, y);
1769 		want_frame = true;
1770 	}
1771 
1772 	if (want_frame && input->seat_version < WL_POINTER_FRAME_SINCE_VERSION)
1773 		notify_pointer_frame(&input->base);
1774 }
1775 
1776 static void
input_handle_button(void * data,struct wl_pointer * pointer,uint32_t serial,uint32_t time,uint32_t button,enum wl_pointer_button_state state)1777 input_handle_button(void *data, struct wl_pointer *pointer,
1778 		    uint32_t serial, uint32_t time, uint32_t button,
1779 		    enum wl_pointer_button_state state)
1780 {
1781 	struct wayland_input *input = data;
1782 	enum theme_location location;
1783 	struct timespec ts;
1784 
1785 	if (!input->output)
1786 		return;
1787 
1788 	if (input->output->frame) {
1789 		location = frame_pointer_button(input->output->frame, input,
1790 						button, state);
1791 
1792 		if (frame_status(input->output->frame) & FRAME_STATUS_MOVE) {
1793 			if (input->output->parent.xdg_toplevel)
1794 				xdg_toplevel_move(input->output->parent.xdg_toplevel,
1795 						  input->parent.seat, serial);
1796 			else if (input->output->parent.shell_surface)
1797 				wl_shell_surface_move(input->output->parent.shell_surface,
1798 						      input->parent.seat, serial);
1799 			frame_status_clear(input->output->frame,
1800 					   FRAME_STATUS_MOVE);
1801 			return;
1802 		}
1803 
1804 		if (frame_status(input->output->frame) & FRAME_STATUS_CLOSE) {
1805 			wayland_output_destroy(&input->output->base);
1806 			input->output = NULL;
1807 			input->keyboard_focus = NULL;
1808 
1809 			if (wl_list_empty(&input->backend->compositor->output_list))
1810 				weston_compositor_exit(input->backend->compositor);
1811 
1812 			return;
1813 		}
1814 
1815 		if (frame_status(input->output->frame) & FRAME_STATUS_REPAINT)
1816 			weston_output_schedule_repaint(&input->output->base);
1817 	} else {
1818 		location = THEME_LOCATION_CLIENT_AREA;
1819 	}
1820 
1821 	if (location == THEME_LOCATION_CLIENT_AREA) {
1822 		timespec_from_msec(&ts, time);
1823 		notify_button(&input->base, &ts, button, state);
1824 		if (input->seat_version < WL_POINTER_FRAME_SINCE_VERSION)
1825 			notify_pointer_frame(&input->base);
1826 	}
1827 }
1828 
1829 static void
input_handle_axis(void * data,struct wl_pointer * pointer,uint32_t time,uint32_t axis,wl_fixed_t value)1830 input_handle_axis(void *data, struct wl_pointer *pointer,
1831 		  uint32_t time, uint32_t axis, wl_fixed_t value)
1832 {
1833 	struct wayland_input *input = data;
1834 	struct weston_pointer_axis_event weston_event;
1835 	struct timespec ts;
1836 
1837 	weston_event.axis = axis;
1838 	weston_event.value = wl_fixed_to_double(value);
1839 	weston_event.has_discrete = false;
1840 
1841 	if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL &&
1842 	    input->vert.has_discrete) {
1843 		weston_event.has_discrete = true;
1844 		weston_event.discrete = input->vert.discrete;
1845 		input->vert.has_discrete = false;
1846 	} else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL &&
1847 		   input->horiz.has_discrete) {
1848 		weston_event.has_discrete = true;
1849 		weston_event.discrete = input->horiz.discrete;
1850 		input->horiz.has_discrete = false;
1851 	}
1852 
1853 	timespec_from_msec(&ts, time);
1854 
1855 	notify_axis(&input->base, &ts, &weston_event);
1856 
1857 	if (input->seat_version < WL_POINTER_FRAME_SINCE_VERSION)
1858 		notify_pointer_frame(&input->base);
1859 }
1860 
1861 static void
input_handle_frame(void * data,struct wl_pointer * pointer)1862 input_handle_frame(void *data, struct wl_pointer *pointer)
1863 {
1864 	struct wayland_input *input = data;
1865 
1866 	notify_pointer_frame(&input->base);
1867 }
1868 
1869 static void
input_handle_axis_source(void * data,struct wl_pointer * pointer,uint32_t source)1870 input_handle_axis_source(void *data, struct wl_pointer *pointer,
1871 			 uint32_t source)
1872 {
1873 	struct wayland_input *input = data;
1874 
1875 	notify_axis_source(&input->base, source);
1876 }
1877 
1878 static void
input_handle_axis_stop(void * data,struct wl_pointer * pointer,uint32_t time,uint32_t axis)1879 input_handle_axis_stop(void *data, struct wl_pointer *pointer,
1880 		       uint32_t time, uint32_t axis)
1881 {
1882 	struct wayland_input *input = data;
1883 	struct weston_pointer_axis_event weston_event;
1884 	struct timespec ts;
1885 
1886 	weston_event.axis = axis;
1887 	weston_event.value = 0;
1888 
1889 	timespec_from_msec(&ts, time);
1890 
1891 	notify_axis(&input->base, &ts, &weston_event);
1892 }
1893 
1894 static void
input_handle_axis_discrete(void * data,struct wl_pointer * pointer,uint32_t axis,int32_t discrete)1895 input_handle_axis_discrete(void *data, struct wl_pointer *pointer,
1896 			   uint32_t axis, int32_t discrete)
1897 {
1898 	struct wayland_input *input = data;
1899 
1900 	if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL) {
1901 		input->vert.has_discrete = true;
1902 		input->vert.discrete = discrete;
1903 	} else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
1904 		input->horiz.has_discrete = true;
1905 		input->horiz.discrete = discrete;
1906 	}
1907 }
1908 
1909 static const struct wl_pointer_listener pointer_listener = {
1910 	input_handle_pointer_enter,
1911 	input_handle_pointer_leave,
1912 	input_handle_motion,
1913 	input_handle_button,
1914 	input_handle_axis,
1915 	input_handle_frame,
1916 	input_handle_axis_source,
1917 	input_handle_axis_stop,
1918 	input_handle_axis_discrete,
1919 };
1920 
1921 static void
input_handle_keymap(void * data,struct wl_keyboard * keyboard,uint32_t format,int fd,uint32_t size)1922 input_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format,
1923 		    int fd, uint32_t size)
1924 {
1925 	struct wayland_input *input = data;
1926 	struct xkb_keymap *keymap;
1927 	char *map_str;
1928 
1929 	if (!data) {
1930 		close(fd);
1931 		return;
1932 	}
1933 
1934 	if (format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
1935 		map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
1936 		if (map_str == MAP_FAILED) {
1937 			weston_log("mmap failed: %s\n", strerror(errno));
1938 			goto error;
1939 		}
1940 
1941 		keymap = xkb_keymap_new_from_string(input->backend->compositor->xkb_context,
1942 						    map_str,
1943 						    XKB_KEYMAP_FORMAT_TEXT_V1,
1944 						    0);
1945 		munmap(map_str, size);
1946 
1947 		if (!keymap) {
1948 			weston_log("failed to compile keymap\n");
1949 			goto error;
1950 		}
1951 
1952 		input->keyboard_state_update = STATE_UPDATE_NONE;
1953 	} else if (format == WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP) {
1954 		weston_log("No keymap provided; falling back to default\n");
1955 		keymap = NULL;
1956 		input->keyboard_state_update = STATE_UPDATE_AUTOMATIC;
1957 	} else {
1958 		weston_log("Invalid keymap\n");
1959 		goto error;
1960 	}
1961 
1962 	close(fd);
1963 
1964 	if (weston_seat_get_keyboard(&input->base))
1965 		weston_seat_update_keymap(&input->base, keymap);
1966 	else
1967 		weston_seat_init_keyboard(&input->base, keymap);
1968 
1969 	xkb_keymap_unref(keymap);
1970 
1971 	return;
1972 
1973 error:
1974 	wl_keyboard_release(input->parent.keyboard);
1975 	close(fd);
1976 }
1977 
1978 static void
input_handle_keyboard_enter(void * data,struct wl_keyboard * keyboard,uint32_t serial,struct wl_surface * surface,struct wl_array * keys)1979 input_handle_keyboard_enter(void *data,
1980 			    struct wl_keyboard *keyboard,
1981 			    uint32_t serial,
1982 			    struct wl_surface *surface,
1983 			    struct wl_array *keys)
1984 {
1985 	struct wayland_input *input = data;
1986 	struct wayland_output *focus;
1987 
1988 	focus = input->keyboard_focus;
1989 	if (focus) {
1990 		/* This shouldn't happen */
1991 		focus->keyboard_count--;
1992 		if (!focus->keyboard_count && focus->frame)
1993 			frame_unset_flag(focus->frame, FRAME_FLAG_ACTIVE);
1994 		if (frame_status(focus->frame) & FRAME_STATUS_REPAINT)
1995 			weston_output_schedule_repaint(&focus->base);
1996 	}
1997 
1998 	if (!surface) {
1999 		input->keyboard_focus = NULL;
2000 		return;
2001 	}
2002 
2003 	input->keyboard_focus = wl_surface_get_user_data(surface);
2004 	input->keyboard_focus->keyboard_count++;
2005 
2006 	focus = input->keyboard_focus;
2007 	if (focus->frame) {
2008 		frame_set_flag(focus->frame, FRAME_FLAG_ACTIVE);
2009 		if (frame_status(focus->frame) & FRAME_STATUS_REPAINT)
2010 			weston_output_schedule_repaint(&focus->base);
2011 	}
2012 
2013 
2014 	/* XXX: If we get a modifier event immediately before the focus,
2015 	 *      we should try to keep the same serial. */
2016 	notify_keyboard_focus_in(&input->base, keys,
2017 				 STATE_UPDATE_AUTOMATIC);
2018 }
2019 
2020 static void
input_handle_keyboard_leave(void * data,struct wl_keyboard * keyboard,uint32_t serial,struct wl_surface * surface)2021 input_handle_keyboard_leave(void *data,
2022 			    struct wl_keyboard *keyboard,
2023 			    uint32_t serial,
2024 			    struct wl_surface *surface)
2025 {
2026 	struct wayland_input *input = data;
2027 	struct wayland_output *focus;
2028 
2029 	notify_keyboard_focus_out(&input->base);
2030 
2031 	focus = input->keyboard_focus;
2032 	if (!focus)
2033 		return;
2034 
2035 	focus->keyboard_count--;
2036 	if (!focus->keyboard_count && focus->frame) {
2037 		frame_unset_flag(focus->frame, FRAME_FLAG_ACTIVE);
2038 		if (frame_status(focus->frame) & FRAME_STATUS_REPAINT)
2039 			weston_output_schedule_repaint(&focus->base);
2040 	}
2041 
2042 	input->keyboard_focus = NULL;
2043 }
2044 
2045 static void
input_handle_key(void * data,struct wl_keyboard * keyboard,uint32_t serial,uint32_t time,uint32_t key,uint32_t state)2046 input_handle_key(void *data, struct wl_keyboard *keyboard,
2047 		 uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
2048 {
2049 	struct wayland_input *input = data;
2050 	struct timespec ts;
2051 
2052 	if (!input->keyboard_focus)
2053 		return;
2054 
2055 	timespec_from_msec(&ts, time);
2056 
2057 	input->key_serial = serial;
2058 	notify_key(&input->base, &ts, key,
2059 		   state ? WL_KEYBOARD_KEY_STATE_PRESSED :
2060 			   WL_KEYBOARD_KEY_STATE_RELEASED,
2061 		   input->keyboard_state_update);
2062 }
2063 
2064 static void
input_handle_modifiers(void * data,struct wl_keyboard * wl_keyboard,uint32_t serial_in,uint32_t mods_depressed,uint32_t mods_latched,uint32_t mods_locked,uint32_t group)2065 input_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard,
2066 		       uint32_t serial_in, uint32_t mods_depressed,
2067 		       uint32_t mods_latched, uint32_t mods_locked,
2068 		       uint32_t group)
2069 {
2070 	struct weston_keyboard *keyboard;
2071 	struct wayland_input *input = data;
2072 	struct wayland_backend *b = input->backend;
2073 	uint32_t serial_out;
2074 
2075 	/* If we get a key event followed by a modifier event with the
2076 	 * same serial number, then we try to preserve those semantics by
2077 	 * reusing the same serial number on the way out too. */
2078 	if (serial_in == input->key_serial)
2079 		serial_out = wl_display_get_serial(b->compositor->wl_display);
2080 	else
2081 		serial_out = wl_display_next_serial(b->compositor->wl_display);
2082 
2083 	keyboard = weston_seat_get_keyboard(&input->base);
2084 	xkb_state_update_mask(keyboard->xkb_state.state,
2085 			      mods_depressed, mods_latched,
2086 			      mods_locked, 0, 0, group);
2087 	notify_modifiers(&input->base, serial_out);
2088 }
2089 
2090 static void
input_handle_repeat_info(void * data,struct wl_keyboard * keyboard,int32_t rate,int32_t delay)2091 input_handle_repeat_info(void *data, struct wl_keyboard *keyboard,
2092 			 int32_t rate, int32_t delay)
2093 {
2094 	struct wayland_input *input = data;
2095 	struct wayland_backend *b = input->backend;
2096 
2097 	b->compositor->kb_repeat_rate = rate;
2098 	b->compositor->kb_repeat_delay = delay;
2099 }
2100 
2101 static const struct wl_keyboard_listener keyboard_listener = {
2102 	input_handle_keymap,
2103 	input_handle_keyboard_enter,
2104 	input_handle_keyboard_leave,
2105 	input_handle_key,
2106 	input_handle_modifiers,
2107 	input_handle_repeat_info,
2108 };
2109 
2110 static void
input_handle_touch_down(void * data,struct wl_touch * wl_touch,uint32_t serial,uint32_t time,struct wl_surface * surface,int32_t id,wl_fixed_t fixed_x,wl_fixed_t fixed_y)2111 input_handle_touch_down(void *data, struct wl_touch *wl_touch,
2112 			uint32_t serial, uint32_t time,
2113 			struct wl_surface *surface, int32_t id,
2114 			wl_fixed_t fixed_x, wl_fixed_t fixed_y)
2115 {
2116 	struct wayland_input *input = data;
2117 	struct wayland_output *output;
2118 	enum theme_location location;
2119 	bool first_touch;
2120 	int32_t fx, fy;
2121 	double x, y;
2122 	struct timespec ts;
2123 
2124 	x = wl_fixed_to_double(fixed_x);
2125 	y = wl_fixed_to_double(fixed_y);
2126 
2127 	timespec_from_msec(&ts, time);
2128 
2129 	first_touch = (input->touch_points == 0);
2130 	input->touch_points++;
2131 
2132 	input->touch_focus = wl_surface_get_user_data(surface);
2133 	output = input->touch_focus;
2134 	if (!first_touch && !input->touch_active)
2135 		return;
2136 
2137 	if (output->frame) {
2138 		location = frame_touch_down(output->frame, input, id, x, y);
2139 
2140 		frame_interior(output->frame, &fx, &fy, NULL, NULL);
2141 		x -= fx;
2142 		y -= fy;
2143 
2144 		if (frame_status(output->frame) & FRAME_STATUS_REPAINT)
2145 			weston_output_schedule_repaint(&output->base);
2146 
2147 		if (first_touch && (frame_status(output->frame) & FRAME_STATUS_MOVE)) {
2148 			input->touch_points--;
2149 			if (output->parent.xdg_toplevel)
2150 				xdg_toplevel_move(output->parent.xdg_toplevel,
2151 						  input->parent.seat, serial);
2152 			else if (output->parent.shell_surface)
2153 				wl_shell_surface_move(output->parent.shell_surface,
2154 						      input->parent.seat, serial);
2155 			frame_status_clear(output->frame,
2156 					   FRAME_STATUS_MOVE);
2157 			return;
2158 		}
2159 
2160 		if (first_touch && location != THEME_LOCATION_CLIENT_AREA)
2161 			return;
2162 	}
2163 
2164 	weston_output_transform_coordinate(&output->base, x, y, &x, &y);
2165 
2166 	notify_touch(input->touch_device, &ts, id, x, y, WL_TOUCH_DOWN);
2167 	input->touch_active = true;
2168 }
2169 
2170 static void
input_handle_touch_up(void * data,struct wl_touch * wl_touch,uint32_t serial,uint32_t time,int32_t id)2171 input_handle_touch_up(void *data, struct wl_touch *wl_touch,
2172 		      uint32_t serial, uint32_t time, int32_t id)
2173 {
2174 	struct wayland_input *input = data;
2175 	struct wayland_output *output = input->touch_focus;
2176 	bool active = input->touch_active;
2177 	struct timespec ts;
2178 
2179 	timespec_from_msec(&ts, time);
2180 
2181 	input->touch_points--;
2182 	if (input->touch_points == 0) {
2183 		input->touch_focus = NULL;
2184 		input->touch_active = false;
2185 	}
2186 
2187 	if (!output)
2188 		return;
2189 
2190 	if (output->frame) {
2191 		frame_touch_up(output->frame, input, id);
2192 
2193 		if (frame_status(output->frame) & FRAME_STATUS_CLOSE) {
2194 			wayland_output_destroy(&output->base);
2195 			input->touch_focus = NULL;
2196 			input->keyboard_focus = NULL;
2197 			if (wl_list_empty(&input->backend->compositor->output_list))
2198 				weston_compositor_exit(input->backend->compositor);
2199 
2200 			return;
2201 		}
2202 		if (frame_status(output->frame) & FRAME_STATUS_REPAINT)
2203 			weston_output_schedule_repaint(&output->base);
2204 	}
2205 
2206 	if (active)
2207 		notify_touch(input->touch_device, &ts, id, 0, 0, WL_TOUCH_UP);
2208 }
2209 
2210 static void
input_handle_touch_motion(void * data,struct wl_touch * wl_touch,uint32_t time,int32_t id,wl_fixed_t fixed_x,wl_fixed_t fixed_y)2211 input_handle_touch_motion(void *data, struct wl_touch *wl_touch,
2212                         uint32_t time, int32_t id,
2213                         wl_fixed_t fixed_x, wl_fixed_t fixed_y)
2214 {
2215 	struct wayland_input *input = data;
2216 	struct wayland_output *output = input->touch_focus;
2217 	int32_t fx, fy;
2218 	double x, y;
2219 	struct timespec ts;
2220 
2221 	x = wl_fixed_to_double(fixed_x);
2222 	y = wl_fixed_to_double(fixed_y);
2223 	timespec_from_msec(&ts, time);
2224 
2225 	if (!output || !input->touch_active)
2226 		return;
2227 
2228 	if (output->frame) {
2229 		frame_interior(output->frame, &fx, &fy, NULL, NULL);
2230 		x -= fx;
2231 		y -= fy;
2232 	}
2233 
2234 	weston_output_transform_coordinate(&output->base, x, y, &x, &y);
2235 
2236 	notify_touch(input->touch_device, &ts, id, x, y, WL_TOUCH_MOTION);
2237 }
2238 
2239 static void
input_handle_touch_frame(void * data,struct wl_touch * wl_touch)2240 input_handle_touch_frame(void *data, struct wl_touch *wl_touch)
2241 {
2242 	struct wayland_input *input = data;
2243 
2244 	if (!input->touch_focus || !input->touch_active)
2245 		return;
2246 
2247 	notify_touch_frame(input->touch_device);
2248 }
2249 
2250 static void
input_handle_touch_cancel(void * data,struct wl_touch * wl_touch)2251 input_handle_touch_cancel(void *data, struct wl_touch *wl_touch)
2252 {
2253 	struct wayland_input *input = data;
2254 
2255 	if (!input->touch_focus || !input->touch_active)
2256 		return;
2257 
2258 	notify_touch_cancel(input->touch_device);
2259 }
2260 
2261 static const struct wl_touch_listener touch_listener = {
2262 	input_handle_touch_down,
2263 	input_handle_touch_up,
2264 	input_handle_touch_motion,
2265 	input_handle_touch_frame,
2266 	input_handle_touch_cancel,
2267 };
2268 
2269 
2270 static struct weston_touch_device *
create_touch_device(struct wayland_input * input)2271 create_touch_device(struct wayland_input *input)
2272 {
2273 	struct weston_touch_device *touch_device;
2274 	char str[128];
2275 
2276 	/* manufacture a unique'ish name */
2277 	snprintf(str, sizeof str, "wayland-touch[%u]",
2278 		 wl_proxy_get_id((struct wl_proxy *)input->parent.seat));
2279 
2280 	touch_device = weston_touch_create_touch_device(input->base.touch_state,
2281 							str, NULL, NULL);
2282 
2283 	return touch_device;
2284 }
2285 
2286 static void
input_handle_capabilities(void * data,struct wl_seat * seat,enum wl_seat_capability caps)2287 input_handle_capabilities(void *data, struct wl_seat *seat,
2288 		          enum wl_seat_capability caps)
2289 {
2290 	struct wayland_input *input = data;
2291 
2292 	if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->parent.pointer) {
2293 		input->parent.pointer = wl_seat_get_pointer(seat);
2294 		wl_pointer_set_user_data(input->parent.pointer, input);
2295 		wl_pointer_add_listener(input->parent.pointer,
2296 					&pointer_listener, input);
2297 		weston_seat_init_pointer(&input->base);
2298 	} else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->parent.pointer) {
2299 		if (input->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION)
2300 			wl_pointer_release(input->parent.pointer);
2301 		else
2302 			wl_pointer_destroy(input->parent.pointer);
2303 		input->parent.pointer = NULL;
2304 		weston_seat_release_pointer(&input->base);
2305 	}
2306 
2307 	if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->parent.keyboard) {
2308 		input->parent.keyboard = wl_seat_get_keyboard(seat);
2309 		wl_keyboard_set_user_data(input->parent.keyboard, input);
2310 		wl_keyboard_add_listener(input->parent.keyboard,
2311 					 &keyboard_listener, input);
2312 	} else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->parent.keyboard) {
2313 		if (input->seat_version >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
2314 			wl_keyboard_release(input->parent.keyboard);
2315 		else
2316 			wl_keyboard_destroy(input->parent.keyboard);
2317 		input->parent.keyboard = NULL;
2318 		weston_seat_release_keyboard(&input->base);
2319 	}
2320 
2321 	if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->parent.touch) {
2322 		input->parent.touch = wl_seat_get_touch(seat);
2323 		wl_touch_set_user_data(input->parent.touch, input);
2324 		wl_touch_add_listener(input->parent.touch,
2325 				      &touch_listener, input);
2326 		weston_seat_init_touch(&input->base);
2327 		input->touch_device = create_touch_device(input);
2328 	} else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->parent.touch) {
2329 		weston_touch_device_destroy(input->touch_device);
2330 		input->touch_device = NULL;
2331 		if (input->seat_version >= WL_TOUCH_RELEASE_SINCE_VERSION)
2332 			wl_touch_release(input->parent.touch);
2333 		else
2334 			wl_touch_destroy(input->parent.touch);
2335 		input->parent.touch = NULL;
2336 		weston_seat_release_touch(&input->base);
2337 	}
2338 }
2339 
2340 static void
input_handle_name(void * data,struct wl_seat * seat,const char * name)2341 input_handle_name(void *data, struct wl_seat *seat,
2342 		  const char *name)
2343 {
2344 }
2345 
2346 static const struct wl_seat_listener seat_listener = {
2347 	input_handle_capabilities,
2348 	input_handle_name,
2349 };
2350 
2351 static void
display_add_seat(struct wayland_backend * b,uint32_t id,uint32_t available_version)2352 display_add_seat(struct wayland_backend *b, uint32_t id, uint32_t available_version)
2353 {
2354 	struct wayland_input *input;
2355 	uint32_t version = MIN(available_version, 4);
2356 
2357 	input = zalloc(sizeof *input);
2358 	if (input == NULL)
2359 		return;
2360 
2361 	weston_seat_init(&input->base, b->compositor, "default");
2362 	input->backend = b;
2363 	input->parent.seat = wl_registry_bind(b->parent.registry, id,
2364 					      &wl_seat_interface, version);
2365 	input->seat_version = version;
2366 	wl_list_insert(b->input_list.prev, &input->link);
2367 
2368 	wl_seat_add_listener(input->parent.seat, &seat_listener, input);
2369 	wl_seat_set_user_data(input->parent.seat, input);
2370 
2371 	input->parent.cursor.surface =
2372 		wl_compositor_create_surface(b->parent.compositor);
2373 
2374 	input->vert.axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
2375 	input->horiz.axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL;
2376 }
2377 
2378 static void
wayland_parent_output_geometry(void * data,struct wl_output * output_proxy,int32_t x,int32_t y,int32_t physical_width,int32_t physical_height,int32_t subpixel,const char * make,const char * model,int32_t transform)2379 wayland_parent_output_geometry(void *data, struct wl_output *output_proxy,
2380 			       int32_t x, int32_t y,
2381 			       int32_t physical_width, int32_t physical_height,
2382 			       int32_t subpixel, const char *make,
2383 			       const char *model, int32_t transform)
2384 {
2385 	struct wayland_parent_output *output = data;
2386 
2387 	output->x = x;
2388 	output->y = y;
2389 	output->physical.width = physical_width;
2390 	output->physical.height = physical_height;
2391 	output->physical.subpixel = subpixel;
2392 
2393 	free(output->physical.make);
2394 	output->physical.make = strdup(make);
2395 	free(output->physical.model);
2396 	output->physical.model = strdup(model);
2397 
2398 	output->transform = transform;
2399 }
2400 
2401 static struct weston_mode *
find_mode(struct wl_list * list,int32_t width,int32_t height,uint32_t refresh)2402 find_mode(struct wl_list *list, int32_t width, int32_t height, uint32_t refresh)
2403 {
2404 	struct weston_mode *mode;
2405 
2406 	wl_list_for_each(mode, list, link) {
2407 		if (mode->width == width && mode->height == height &&
2408 		    mode->refresh == refresh)
2409 			return mode;
2410 	}
2411 
2412 	mode = zalloc(sizeof *mode);
2413 	if (!mode)
2414 		return NULL;
2415 
2416 	mode->width = width;
2417 	mode->height = height;
2418 	mode->refresh = refresh;
2419 	wl_list_insert(list, &mode->link);
2420 
2421 	return mode;
2422 }
2423 
2424 static struct weston_output *
wayland_parent_output_get_enabled_output(struct wayland_parent_output * poutput)2425 wayland_parent_output_get_enabled_output(struct wayland_parent_output *poutput)
2426 {
2427 	struct wayland_head *head = poutput->head;
2428 
2429 	if (!head)
2430 		return NULL;
2431 
2432 	if (!weston_head_is_enabled(&head->base))
2433 		return NULL;
2434 
2435 	return weston_head_get_output(&head->base);
2436 }
2437 
2438 static void
wayland_parent_output_mode(void * data,struct wl_output * wl_output_proxy,uint32_t flags,int32_t width,int32_t height,int32_t refresh)2439 wayland_parent_output_mode(void *data, struct wl_output *wl_output_proxy,
2440 			   uint32_t flags, int32_t width, int32_t height,
2441 			   int32_t refresh)
2442 {
2443 	struct wayland_parent_output *output = data;
2444 	struct weston_output *enabled_output;
2445 	struct weston_mode *mode;
2446 
2447 	enabled_output = wayland_parent_output_get_enabled_output(output);
2448 	if (enabled_output) {
2449 		mode = find_mode(&enabled_output->mode_list,
2450 				 width, height, refresh);
2451 		if (!mode)
2452 			return;
2453 		mode->flags = flags;
2454 		/* Do a mode-switch on current mode change? */
2455 	} else {
2456 		mode = find_mode(&output->mode_list, width, height, refresh);
2457 		if (!mode)
2458 			return;
2459 		mode->flags = flags;
2460 		if (flags & WL_OUTPUT_MODE_CURRENT)
2461 			output->current_mode = mode;
2462 		if (flags & WL_OUTPUT_MODE_PREFERRED)
2463 			output->preferred_mode = mode;
2464 	}
2465 }
2466 
2467 static const struct wl_output_listener output_listener = {
2468 	wayland_parent_output_geometry,
2469 	wayland_parent_output_mode
2470 };
2471 
2472 static void
output_sync_callback(void * data,struct wl_callback * callback,uint32_t unused)2473 output_sync_callback(void *data, struct wl_callback *callback, uint32_t unused)
2474 {
2475 	struct wayland_parent_output *output = data;
2476 
2477 	assert(output->sync_cb == callback);
2478 	wl_callback_destroy(callback);
2479 	output->sync_cb = NULL;
2480 
2481 	assert(output->backend->sprawl_across_outputs);
2482 
2483 	wayland_head_create_for_parent_output(output->backend->compositor, output);
2484 }
2485 
2486 static const struct wl_callback_listener output_sync_listener = {
2487 	output_sync_callback
2488 };
2489 
2490 static void
wayland_backend_register_output(struct wayland_backend * b,uint32_t id)2491 wayland_backend_register_output(struct wayland_backend *b, uint32_t id)
2492 {
2493 	struct wayland_parent_output *output;
2494 
2495 	output = zalloc(sizeof *output);
2496 	if (!output)
2497 		return;
2498 
2499 	output->backend = b;
2500 	output->id = id;
2501 	output->global = wl_registry_bind(b->parent.registry, id,
2502 					  &wl_output_interface, 1);
2503 	if (!output->global) {
2504 		free(output);
2505 		return;
2506 	}
2507 
2508 	wl_output_add_listener(output->global, &output_listener, output);
2509 
2510 	output->scale = 0;
2511 	output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
2512 	output->physical.subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN;
2513 	wl_list_init(&output->mode_list);
2514 	wl_list_insert(&b->parent.output_list, &output->link);
2515 
2516 	if (b->sprawl_across_outputs) {
2517 		output->sync_cb = wl_display_sync(b->parent.wl_display);
2518 		wl_callback_add_listener(output->sync_cb,
2519 					 &output_sync_listener, output);
2520 	}
2521 }
2522 
2523 static void
wayland_parent_output_destroy(struct wayland_parent_output * output)2524 wayland_parent_output_destroy(struct wayland_parent_output *output)
2525 {
2526 	struct weston_mode *mode, *next;
2527 
2528 	if (output->sync_cb)
2529 		wl_callback_destroy(output->sync_cb);
2530 
2531 	if (output->head)
2532 		wayland_head_destroy(output->head);
2533 
2534 	wl_output_destroy(output->global);
2535 	free(output->physical.make);
2536 	free(output->physical.model);
2537 
2538 	wl_list_for_each_safe(mode, next, &output->mode_list, link) {
2539 		wl_list_remove(&mode->link);
2540 		free(mode);
2541 	}
2542 
2543 	wl_list_remove(&output->link);
2544 	free(output);
2545 }
2546 
2547 static void
xdg_wm_base_ping(void * data,struct xdg_wm_base * shell,uint32_t serial)2548 xdg_wm_base_ping(void *data, struct xdg_wm_base *shell, uint32_t serial)
2549 {
2550 	xdg_wm_base_pong(shell, serial);
2551 }
2552 
2553 static const struct xdg_wm_base_listener wm_base_listener = {
2554 	xdg_wm_base_ping,
2555 };
2556 
2557 static void
registry_handle_global(void * data,struct wl_registry * registry,uint32_t name,const char * interface,uint32_t version)2558 registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
2559 		       const char *interface, uint32_t version)
2560 {
2561 	struct wayland_backend *b = data;
2562 
2563 	if (strcmp(interface, "wl_compositor") == 0) {
2564 		b->parent.compositor =
2565 			wl_registry_bind(registry, name,
2566 					 &wl_compositor_interface,
2567 					 MIN(version, 4));
2568 	} else if (strcmp(interface, "xdg_wm_base") == 0) {
2569 		b->parent.xdg_wm_base =
2570 			wl_registry_bind(registry, name,
2571 					 &xdg_wm_base_interface, 1);
2572 		xdg_wm_base_add_listener(b->parent.xdg_wm_base,
2573 					 &wm_base_listener, b);
2574 	} else if (strcmp(interface, "wl_shell") == 0) {
2575 		b->parent.shell =
2576 			wl_registry_bind(registry, name,
2577 					 &wl_shell_interface, 1);
2578 	} else if (strcmp(interface, "zwp_fullscreen_shell_v1") == 0) {
2579 		b->parent.fshell =
2580 			wl_registry_bind(registry, name,
2581 					 &zwp_fullscreen_shell_v1_interface, 1);
2582 	} else if (strcmp(interface, "wl_seat") == 0) {
2583 		display_add_seat(b, name, version);
2584 	} else if (strcmp(interface, "wl_output") == 0) {
2585 		wayland_backend_register_output(b, name);
2586 	} else if (strcmp(interface, "wl_shm") == 0) {
2587 		b->parent.shm =
2588 			wl_registry_bind(registry, name, &wl_shm_interface, 1);
2589 	}
2590 }
2591 
2592 static void
registry_handle_global_remove(void * data,struct wl_registry * registry,uint32_t name)2593 registry_handle_global_remove(void *data, struct wl_registry *registry,
2594 			      uint32_t name)
2595 {
2596 	struct wayland_backend *b = data;
2597 	struct wayland_parent_output *output, *next;
2598 
2599 	wl_list_for_each_safe(output, next, &b->parent.output_list, link)
2600 		if (output->id == name)
2601 			wayland_parent_output_destroy(output);
2602 }
2603 
2604 static const struct wl_registry_listener registry_listener = {
2605 	registry_handle_global,
2606 	registry_handle_global_remove
2607 };
2608 
2609 static int
wayland_backend_handle_event(int fd,uint32_t mask,void * data)2610 wayland_backend_handle_event(int fd, uint32_t mask, void *data)
2611 {
2612 	struct wayland_backend *b = data;
2613 	int count = 0;
2614 
2615 	if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) {
2616 		weston_compositor_exit(b->compositor);
2617 		return 0;
2618 	}
2619 
2620 	if (mask & WL_EVENT_READABLE)
2621 		count = wl_display_dispatch(b->parent.wl_display);
2622 	if (mask & WL_EVENT_WRITABLE)
2623 		wl_display_flush(b->parent.wl_display);
2624 
2625 	if (mask == 0) {
2626 		count = wl_display_dispatch_pending(b->parent.wl_display);
2627 		wl_display_flush(b->parent.wl_display);
2628 	}
2629 
2630 	return count;
2631 }
2632 
2633 static void
wayland_destroy(struct weston_compositor * ec)2634 wayland_destroy(struct weston_compositor *ec)
2635 {
2636 	struct wayland_backend *b = to_wayland_backend(ec);
2637 	struct weston_head *base, *next;
2638 
2639 	wl_event_source_remove(b->parent.wl_source);
2640 
2641 	weston_compositor_shutdown(ec);
2642 
2643 	wl_list_for_each_safe(base, next, &ec->head_list, compositor_link)
2644 		wayland_head_destroy(to_wayland_head(base));
2645 
2646 	if (b->parent.shm)
2647 		wl_shm_destroy(b->parent.shm);
2648 
2649 	if (b->parent.xdg_wm_base)
2650 		xdg_wm_base_destroy(b->parent.xdg_wm_base);
2651 
2652 	if (b->parent.shell)
2653 		wl_shell_destroy(b->parent.shell);
2654 
2655 	if (b->parent.fshell)
2656 		zwp_fullscreen_shell_v1_release(b->parent.fshell);
2657 
2658 	if (b->parent.compositor)
2659 		wl_compositor_destroy(b->parent.compositor);
2660 
2661 	if (b->theme)
2662 		theme_destroy(b->theme);
2663 
2664 	if (b->frame_device)
2665 		cairo_device_destroy(b->frame_device);
2666 
2667 	wl_cursor_theme_destroy(b->cursor_theme);
2668 
2669 	wl_registry_destroy(b->parent.registry);
2670 	wl_display_flush(b->parent.wl_display);
2671 	wl_display_disconnect(b->parent.wl_display);
2672 
2673 	free(b);
2674 }
2675 
2676 static const char *left_ptrs[] = {
2677 	"left_ptr",
2678 	"default",
2679 	"top_left_arrow",
2680 	"left-arrow"
2681 };
2682 
2683 static void
create_cursor(struct wayland_backend * b,struct weston_wayland_backend_config * config)2684 create_cursor(struct wayland_backend *b,
2685 	      struct weston_wayland_backend_config *config)
2686 {
2687 	unsigned int i;
2688 
2689 	b->cursor_theme = wl_cursor_theme_load(config->cursor_theme,
2690 					       config->cursor_size,
2691 					       b->parent.shm);
2692 	if (!b->cursor_theme) {
2693 		fprintf(stderr, "could not load cursor theme\n");
2694 		return;
2695 	}
2696 
2697 	b->cursor = NULL;
2698 	for (i = 0; !b->cursor && i < ARRAY_LENGTH(left_ptrs); ++i)
2699 		b->cursor = wl_cursor_theme_get_cursor(b->cursor_theme,
2700 						       left_ptrs[i]);
2701 	if (!b->cursor) {
2702 		fprintf(stderr, "could not load left cursor\n");
2703 		return;
2704 	}
2705 }
2706 
2707 static void
fullscreen_binding(struct weston_keyboard * keyboard,const struct timespec * time,uint32_t key,void * data)2708 fullscreen_binding(struct weston_keyboard *keyboard,
2709 		   const struct timespec *time, uint32_t key, void *data)
2710 {
2711 	struct wayland_backend *b = data;
2712 	struct wayland_input *input = NULL;
2713 
2714 	wl_list_for_each(input, &b->input_list, link)
2715 		if (&input->base == keyboard->seat)
2716 			break;
2717 
2718 	if (!input || !input->output)
2719 		return;
2720 
2721 	if (input->output->frame)
2722 		wayland_output_set_fullscreen(input->output, 0, 0, NULL);
2723 	else
2724 		wayland_output_set_windowed(input->output);
2725 
2726 	weston_output_schedule_repaint(&input->output->base);
2727 }
2728 
2729 static struct wayland_backend *
wayland_backend_create(struct weston_compositor * compositor,struct weston_wayland_backend_config * new_config)2730 wayland_backend_create(struct weston_compositor *compositor,
2731 		       struct weston_wayland_backend_config *new_config)
2732 {
2733 	struct wayland_backend *b;
2734 	struct wl_event_loop *loop;
2735 	int fd;
2736 
2737 	b = zalloc(sizeof *b);
2738 	if (b == NULL)
2739 		return NULL;
2740 
2741 	b->compositor = compositor;
2742 	compositor->backend = &b->base;
2743 
2744 	if (weston_compositor_set_presentation_clock_software(compositor) < 0)
2745 		goto err_compositor;
2746 
2747 	b->parent.wl_display = wl_display_connect(new_config->display_name);
2748 	if (b->parent.wl_display == NULL) {
2749 		weston_log("Error: Failed to connect to parent Wayland compositor: %s\n",
2750 			   strerror(errno));
2751 		weston_log_continue(STAMP_SPACE "display option: %s, WAYLAND_DISPLAY=%s\n",
2752 				    new_config->display_name ?: "(none)",
2753 				    getenv("WAYLAND_DISPLAY") ?: "(not set)");
2754 		goto err_compositor;
2755 	}
2756 
2757 	wl_list_init(&b->parent.output_list);
2758 	wl_list_init(&b->input_list);
2759 	b->parent.registry = wl_display_get_registry(b->parent.wl_display);
2760 	wl_registry_add_listener(b->parent.registry, &registry_listener, b);
2761 	wl_display_roundtrip(b->parent.wl_display);
2762 
2763 	create_cursor(b, new_config);
2764 
2765 #ifdef ENABLE_EGL
2766 	b->use_pixman = new_config->use_pixman;
2767 #else
2768 	b->use_pixman = true;
2769 #endif
2770 	b->fullscreen = new_config->fullscreen;
2771 
2772 	if (!b->use_pixman) {
2773 		gl_renderer = weston_load_module("gl-renderer.so",
2774 						 "gl_renderer_interface");
2775 		if (!gl_renderer)
2776 			b->use_pixman = true;
2777 	}
2778 
2779 	if (!b->use_pixman) {
2780 		const struct gl_renderer_display_options options = {
2781 			.egl_platform = EGL_PLATFORM_WAYLAND_KHR,
2782 			.egl_native_display = b->parent.wl_display,
2783 			.egl_surface_type = EGL_WINDOW_BIT,
2784 			.drm_formats = wayland_formats,
2785 			.drm_formats_count = ARRAY_LENGTH(wayland_formats),
2786 		};
2787 		if (gl_renderer->display_create(compositor, &options) < 0) {
2788 			weston_log("Failed to initialize the GL renderer; "
2789 				   "falling back to pixman.\n");
2790 			b->use_pixman = true;
2791 		}
2792 	}
2793 
2794 	if (b->use_pixman) {
2795 		if (pixman_renderer_init(compositor) < 0) {
2796 			weston_log("Failed to initialize pixman renderer\n");
2797 			goto err_display;
2798 		}
2799 	}
2800 
2801 	b->base.destroy = wayland_destroy;
2802 	b->base.create_output = wayland_output_create;
2803 
2804 	loop = wl_display_get_event_loop(compositor->wl_display);
2805 
2806 	fd = wl_display_get_fd(b->parent.wl_display);
2807 	b->parent.wl_source =
2808 		wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
2809 				     wayland_backend_handle_event, b);
2810 	if (b->parent.wl_source == NULL)
2811 		goto err_display;
2812 
2813 	wl_event_source_check(b->parent.wl_source);
2814 
2815 	if (compositor->renderer->import_dmabuf) {
2816 		if (linux_dmabuf_setup(compositor) < 0)
2817 			weston_log("Error: initializing dmabuf "
2818 			           "support failed.\n");
2819 	}
2820 
2821 	return b;
2822 err_display:
2823 	wl_display_disconnect(b->parent.wl_display);
2824 err_compositor:
2825 	weston_compositor_shutdown(compositor);
2826 	free(b);
2827 	return NULL;
2828 }
2829 
2830 static void
wayland_backend_destroy(struct wayland_backend * b)2831 wayland_backend_destroy(struct wayland_backend *b)
2832 {
2833 	wl_display_disconnect(b->parent.wl_display);
2834 
2835 	if (b->theme)
2836 		theme_destroy(b->theme);
2837 	if (b->frame_device)
2838 		cairo_device_destroy(b->frame_device);
2839 	wl_cursor_theme_destroy(b->cursor_theme);
2840 
2841 	weston_compositor_shutdown(b->compositor);
2842 	free(b);
2843 }
2844 
2845 static const struct weston_windowed_output_api windowed_api = {
2846 	wayland_output_set_size,
2847 	wayland_head_create_windowed,
2848 };
2849 
2850 static void
config_init_to_defaults(struct weston_wayland_backend_config * config)2851 config_init_to_defaults(struct weston_wayland_backend_config *config)
2852 {
2853 }
2854 
2855 WL_EXPORT int
weston_backend_init(struct weston_compositor * compositor,struct weston_backend_config * config_base)2856 weston_backend_init(struct weston_compositor *compositor,
2857 		    struct weston_backend_config *config_base)
2858 {
2859 	struct wayland_backend *b;
2860 	struct wayland_parent_output *poutput;
2861 	struct weston_wayland_backend_config new_config;
2862 	int ret;
2863 
2864 	if (config_base == NULL ||
2865 	    config_base->struct_version != WESTON_WAYLAND_BACKEND_CONFIG_VERSION ||
2866 	    config_base->struct_size > sizeof(struct weston_wayland_backend_config)) {
2867 		weston_log("wayland backend config structure is invalid\n");
2868 		return -1;
2869 	}
2870 
2871 	config_init_to_defaults(&new_config);
2872 	memcpy(&new_config, config_base, config_base->struct_size);
2873 
2874 	b = wayland_backend_create(compositor, &new_config);
2875 
2876 	if (!b)
2877 		return -1;
2878 
2879 	if (new_config.sprawl || b->parent.fshell) {
2880 		b->sprawl_across_outputs = true;
2881 		wl_display_roundtrip(b->parent.wl_display);
2882 
2883 		wl_list_for_each(poutput, &b->parent.output_list, link)
2884 			wayland_head_create_for_parent_output(compositor, poutput);
2885 
2886 		return 0;
2887 	}
2888 
2889 	if (new_config.fullscreen) {
2890 		if (!wayland_head_create(compositor, "wayland-fullscreen")) {
2891 			weston_log("Unable to create a fullscreen head.\n");
2892 			goto err_outputs;
2893 		}
2894 
2895 		return 0;
2896 	}
2897 
2898 	ret = weston_plugin_api_register(compositor, WESTON_WINDOWED_OUTPUT_API_NAME,
2899 					 &windowed_api, sizeof(windowed_api));
2900 
2901 	if (ret < 0) {
2902 		weston_log("Failed to register output API.\n");
2903 		wayland_backend_destroy(b);
2904 		return -1;
2905 	}
2906 
2907 	weston_compositor_add_key_binding(compositor, KEY_F,
2908 				          MODIFIER_CTRL | MODIFIER_ALT,
2909 				          fullscreen_binding, b);
2910 	return 0;
2911 
2912 err_outputs:
2913 	wayland_backend_destroy(b);
2914 	return -1;
2915 }
2916