2 * Copyright © 2010-2011 Benjamin Franzke
3 * Copyright © 2013 Jason Ekstrand
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:
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.
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
38 #include <linux/input.h>
40 #include <wayland-client.h>
41 #include <wayland-cursor.h>
44 #include <wayland-egl.h>
47 #include "compositor.h"
48 #include "compositor-wayland.h"
49 #include "gl-renderer.h"
50 #include "weston-egl-ext.h"
51 #include "pixman-renderer.h"
52 #include "shared/helpers.h"
53 #include "shared/image-loader.h"
54 #include "shared/os-compatibility.h"
55 #include "shared/cairo-util.h"
56 #include "shared/timespec-util.h"
57 #include "fullscreen-shell-unstable-v1-client-protocol.h"
58 #include "xdg-shell-unstable-v6-client-protocol.h"
59 #include "presentation-time-server-protocol.h"
60 #include "linux-dmabuf.h"
61 #include "windowed-output-api.h"
63 #define WINDOW_TITLE "Weston Compositor"
65 struct wayland_backend {
66 struct weston_backend base;
67 struct weston_compositor *compositor;
70 struct wl_display *wl_display;
71 struct wl_registry *registry;
72 struct wl_compositor *compositor;
73 struct wl_shell *shell;
74 struct zxdg_shell_v6 *xdg_shell;
75 struct zwp_fullscreen_shell_v1 *fshell;
78 struct wl_list output_list;
80 struct wl_event_source *wl_source;
85 bool sprawl_across_outputs;
89 cairo_device_t *frame_device;
90 struct wl_cursor_theme *cursor_theme;
91 struct wl_cursor *cursor;
93 struct wl_list input_list;
96 struct wayland_output {
97 struct weston_output base;
100 bool draw_initial_frame;
101 struct wl_surface *surface;
103 struct wl_output *output;
106 struct wl_shell_surface *shell_surface;
107 struct zxdg_surface_v6 *xdg_surface;
108 struct zxdg_toplevel_v6 *xdg_toplevel;
109 int configure_width, configure_height;
110 bool wait_for_configure;
119 struct wl_egl_window *egl_window;
121 cairo_surface_t *top;
122 cairo_surface_t *left;
123 cairo_surface_t *right;
124 cairo_surface_t *bottom;
129 struct wl_list buffers;
130 struct wl_list free_buffers;
133 struct weston_mode mode;
135 struct wl_callback *frame_cb;
138 struct wayland_parent_output {
139 struct wayland_backend *backend; /**< convenience */
140 struct wayland_output *output;
143 struct wl_output *global;
149 int32_t width, height;
157 struct wl_callback *sync_cb; /**< wl_output < 2 done replacement */
159 struct wl_list mode_list;
160 struct weston_mode *preferred_mode;
161 struct weston_mode *current_mode;
164 struct wayland_shm_buffer {
165 struct wayland_output *output;
167 struct wl_list free_link;
169 struct wl_buffer *buffer;
172 pixman_region32_t damage; /**< in global coords */
175 pixman_image_t *pm_image;
176 cairo_surface_t *c_surface;
179 struct wayland_input {
180 struct weston_seat base;
181 struct wayland_backend *backend;
185 struct wl_seat *seat;
186 struct wl_pointer *pointer;
187 struct wl_keyboard *keyboard;
188 struct wl_touch *touch;
191 struct wl_surface *surface;
196 enum weston_key_state_update keyboard_state_update;
198 uint32_t enter_serial;
199 uint32_t touch_points;
204 struct wayland_output *output;
205 struct wayland_output *touch_focus;
206 struct wayland_output *keyboard_focus;
208 struct weston_pointer_axis_event vert, horiz;
211 struct gl_renderer_interface *gl_renderer;
213 static inline struct wayland_output *
214 to_wayland_output(struct weston_output *base)
216 return container_of(base, struct wayland_output, base);
219 static inline struct wayland_backend *
220 to_wayland_backend(struct weston_compositor *base)
222 return container_of(base->backend, struct wayland_backend, base);
226 wayland_shm_buffer_destroy(struct wayland_shm_buffer *buffer)
228 cairo_surface_destroy(buffer->c_surface);
229 pixman_image_unref(buffer->pm_image);
231 wl_buffer_destroy(buffer->buffer);
232 munmap(buffer->data, buffer->size);
234 pixman_region32_fini(&buffer->damage);
236 wl_list_remove(&buffer->link);
237 wl_list_remove(&buffer->free_link);
242 buffer_release(void *data, struct wl_buffer *buffer)
244 struct wayland_shm_buffer *sb = data;
247 wl_list_insert(&sb->output->shm.free_buffers, &sb->free_link);
249 wayland_shm_buffer_destroy(sb);
253 static const struct wl_buffer_listener buffer_listener = {
257 static struct wayland_shm_buffer *
258 wayland_output_get_shm_buffer(struct wayland_output *output)
260 struct wayland_backend *b =
261 to_wayland_backend(output->base.compositor);
262 struct wl_shm *shm = b->parent.shm;
263 struct wayland_shm_buffer *sb;
265 struct wl_shm_pool *pool;
266 int width, height, stride;
271 if (!wl_list_empty(&output->shm.free_buffers)) {
272 sb = container_of(output->shm.free_buffers.next,
273 struct wayland_shm_buffer, free_link);
274 wl_list_remove(&sb->free_link);
275 wl_list_init(&sb->free_link);
281 width = frame_width(output->frame);
282 height = frame_height(output->frame);
284 width = output->base.current_mode->width;
285 height = output->base.current_mode->height;
288 stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
290 fd = os_create_anonymous_file(height * stride);
292 weston_log("could not create an anonymous file buffer: %m\n");
296 data = mmap(NULL, height * stride, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
297 if (data == MAP_FAILED) {
298 weston_log("could not mmap %d memory for data: %m\n", height * stride);
303 sb = zalloc(sizeof *sb);
305 weston_log("could not zalloc %zu memory for sb: %m\n", sizeof *sb);
307 munmap(data, height * stride);
312 wl_list_init(&sb->free_link);
313 wl_list_insert(&output->shm.buffers, &sb->link);
315 pixman_region32_init(&sb->damage);
316 pixman_region32_copy(&sb->damage, &output->base.region);
317 sb->frame_damaged = 1;
320 sb->size = height * stride;
322 pool = wl_shm_create_pool(shm, fd, sb->size);
324 sb->buffer = wl_shm_pool_create_buffer(pool, 0,
327 WL_SHM_FORMAT_ARGB8888);
328 wl_buffer_add_listener(sb->buffer, &buffer_listener, sb);
329 wl_shm_pool_destroy(pool);
332 memset(data, 0, sb->size);
335 cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32,
336 width, height, stride);
341 frame_interior(output->frame, &fx, &fy, 0, 0);
343 pixman_image_create_bits(PIXMAN_a8r8g8b8, width, height,
344 (uint32_t *)(data + fy * stride) + fx,
351 frame_done(void *data, struct wl_callback *callback, uint32_t time)
353 struct wayland_output *output = data;
356 assert(callback == output->frame_cb);
357 wl_callback_destroy(callback);
358 output->frame_cb = NULL;
360 /* XXX: use the presentation extension for proper timings */
363 * This is the fallback case, where Presentation extension is not
364 * available from the parent compositor. We do not know the base for
365 * 'time', so we cannot feed it to finish_frame(). Do the only thing
366 * we can, and pretend finish_frame time is when we process this
369 weston_compositor_read_presentation_clock(output->base.compositor, &ts);
370 weston_output_finish_frame(&output->base, &ts, 0);
373 static const struct wl_callback_listener frame_listener = {
378 draw_initial_frame(struct wayland_output *output)
380 struct wayland_shm_buffer *sb;
382 sb = wayland_output_get_shm_buffer(output);
384 /* If we are rendering with GL, then orphan it so that it gets
385 * destroyed immediately */
386 if (output->gl.egl_window)
389 wl_surface_attach(output->parent.surface, sb->buffer, 0, 0);
390 wl_surface_damage(output->parent.surface, 0, 0,
391 output->base.current_mode->width,
392 output->base.current_mode->height);
397 wayland_output_update_gl_border(struct wayland_output *output)
399 int32_t ix, iy, iwidth, iheight, fwidth, fheight;
404 if (!(frame_status(output->frame) & FRAME_STATUS_REPAINT))
407 fwidth = frame_width(output->frame);
408 fheight = frame_height(output->frame);
409 frame_interior(output->frame, &ix, &iy, &iwidth, &iheight);
411 if (!output->gl.border.top)
412 output->gl.border.top =
413 cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
415 cr = cairo_create(output->gl.border.top);
416 frame_repaint(output->frame, cr);
418 gl_renderer->output_set_border(&output->base, GL_RENDERER_BORDER_TOP,
420 cairo_image_surface_get_stride(output->gl.border.top) / 4,
421 cairo_image_surface_get_data(output->gl.border.top));
424 if (!output->gl.border.left)
425 output->gl.border.left =
426 cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
428 cr = cairo_create(output->gl.border.left);
429 cairo_translate(cr, 0, -iy);
430 frame_repaint(output->frame, cr);
432 gl_renderer->output_set_border(&output->base, GL_RENDERER_BORDER_LEFT,
434 cairo_image_surface_get_stride(output->gl.border.left) / 4,
435 cairo_image_surface_get_data(output->gl.border.left));
438 if (!output->gl.border.right)
439 output->gl.border.right =
440 cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
441 fwidth - (ix + iwidth), 1);
442 cr = cairo_create(output->gl.border.right);
443 cairo_translate(cr, -(iwidth + ix), -iy);
444 frame_repaint(output->frame, cr);
446 gl_renderer->output_set_border(&output->base, GL_RENDERER_BORDER_RIGHT,
447 fwidth - (ix + iwidth), 1,
448 cairo_image_surface_get_stride(output->gl.border.right) / 4,
449 cairo_image_surface_get_data(output->gl.border.right));
452 if (!output->gl.border.bottom)
453 output->gl.border.bottom =
454 cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
455 fwidth, fheight - (iy + iheight));
456 cr = cairo_create(output->gl.border.bottom);
457 cairo_translate(cr, 0, -(iy + iheight));
458 frame_repaint(output->frame, cr);
460 gl_renderer->output_set_border(&output->base, GL_RENDERER_BORDER_BOTTOM,
461 fwidth, fheight - (iy + iheight),
462 cairo_image_surface_get_stride(output->gl.border.bottom) / 4,
463 cairo_image_surface_get_data(output->gl.border.bottom));
468 wayland_output_start_repaint_loop(struct weston_output *output_base)
470 struct wayland_output *output = to_wayland_output(output_base);
471 struct wayland_backend *wb =
472 to_wayland_backend(output->base.compositor);
474 /* If this is the initial frame, we need to attach a buffer so that
475 * the compositor can map the surface and include it in its render
476 * loop. If the surface doesn't end up in the render loop, the frame
477 * callback won't be invoked. The buffer is transparent and of the
478 * same size as the future real output buffer. */
479 if (output->parent.draw_initial_frame) {
480 output->parent.draw_initial_frame = false;
482 draw_initial_frame(output);
485 output->frame_cb = wl_surface_frame(output->parent.surface);
486 wl_callback_add_listener(output->frame_cb, &frame_listener, output);
487 wl_surface_commit(output->parent.surface);
488 wl_display_flush(wb->parent.wl_display);
493 wayland_output_repaint_gl(struct weston_output *output_base,
494 pixman_region32_t *damage,
497 struct wayland_output *output = to_wayland_output(output_base);
498 struct weston_compositor *ec = output->base.compositor;
500 output->frame_cb = wl_surface_frame(output->parent.surface);
501 wl_callback_add_listener(output->frame_cb, &frame_listener, output);
503 wayland_output_update_gl_border(output);
505 ec->renderer->repaint_output(&output->base, damage);
507 pixman_region32_subtract(&ec->primary_plane.damage,
508 &ec->primary_plane.damage, damage);
514 wayland_output_update_shm_border(struct wayland_shm_buffer *buffer)
516 int32_t ix, iy, iwidth, iheight, fwidth, fheight;
519 if (!buffer->output->frame || !buffer->frame_damaged)
522 cr = cairo_create(buffer->c_surface);
524 frame_interior(buffer->output->frame, &ix, &iy, &iwidth, &iheight);
525 fwidth = frame_width(buffer->output->frame);
526 fheight = frame_height(buffer->output->frame);
528 /* Set the clip so we don't unnecisaraly damage the surface */
529 cairo_move_to(cr, ix, iy);
530 cairo_rel_line_to(cr, iwidth, 0);
531 cairo_rel_line_to(cr, 0, iheight);
532 cairo_rel_line_to(cr, -iwidth, 0);
533 cairo_line_to(cr, ix, iy);
534 cairo_line_to(cr, 0, iy);
535 cairo_line_to(cr, 0, fheight);
536 cairo_line_to(cr, fwidth, fheight);
537 cairo_line_to(cr, fwidth, 0);
538 cairo_line_to(cr, 0, 0);
539 cairo_line_to(cr, 0, iy);
540 cairo_close_path(cr);
543 /* Draw using a pattern so that the final result gets clipped */
544 cairo_push_group(cr);
545 frame_repaint(buffer->output->frame, cr);
546 cairo_pop_group_to_source(cr);
547 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
554 wayland_shm_buffer_attach(struct wayland_shm_buffer *sb)
556 pixman_region32_t damage;
557 pixman_box32_t *rects;
558 int32_t ix, iy, iwidth, iheight, fwidth, fheight;
561 pixman_region32_init(&damage);
562 pixman_region32_copy(&damage, &sb->damage);
563 pixman_region32_translate(&damage, -sb->output->base.x,
564 -sb->output->base.y);
566 weston_transformed_region(sb->output->base.width,
567 sb->output->base.height,
568 sb->output->base.transform,
569 sb->output->base.current_scale,
572 if (sb->output->frame) {
573 frame_interior(sb->output->frame, &ix, &iy, &iwidth, &iheight);
574 fwidth = frame_width(sb->output->frame);
575 fheight = frame_height(sb->output->frame);
577 pixman_region32_translate(&damage, ix, iy);
579 if (sb->frame_damaged) {
580 pixman_region32_union_rect(&damage, &damage,
582 pixman_region32_union_rect(&damage, &damage,
584 pixman_region32_union_rect(&damage, &damage,
586 fwidth - (ix + iwidth), iheight);
587 pixman_region32_union_rect(&damage, &damage,
589 fwidth, fheight - (iy + iheight));
593 rects = pixman_region32_rectangles(&damage, &n);
594 wl_surface_attach(sb->output->parent.surface, sb->buffer, 0, 0);
595 for (i = 0; i < n; ++i)
596 wl_surface_damage(sb->output->parent.surface, rects[i].x1,
597 rects[i].y1, rects[i].x2 - rects[i].x1,
598 rects[i].y2 - rects[i].y1);
600 if (sb->output->frame)
601 pixman_region32_fini(&damage);
605 wayland_output_repaint_pixman(struct weston_output *output_base,
606 pixman_region32_t *damage,
609 struct wayland_output *output = to_wayland_output(output_base);
610 struct wayland_backend *b =
611 to_wayland_backend(output->base.compositor);
612 struct wayland_shm_buffer *sb;
615 if (frame_status(output->frame) & FRAME_STATUS_REPAINT)
616 wl_list_for_each(sb, &output->shm.buffers, link)
617 sb->frame_damaged = 1;
620 wl_list_for_each(sb, &output->shm.buffers, link)
621 pixman_region32_union(&sb->damage, &sb->damage, damage);
623 sb = wayland_output_get_shm_buffer(output);
625 wayland_output_update_shm_border(sb);
626 pixman_renderer_output_set_buffer(output_base, sb->pm_image);
627 b->compositor->renderer->repaint_output(output_base, &sb->damage);
629 wayland_shm_buffer_attach(sb);
631 output->frame_cb = wl_surface_frame(output->parent.surface);
632 wl_callback_add_listener(output->frame_cb, &frame_listener, output);
633 wl_surface_commit(output->parent.surface);
634 wl_display_flush(b->parent.wl_display);
636 pixman_region32_fini(&sb->damage);
637 pixman_region32_init(&sb->damage);
638 sb->frame_damaged = 0;
640 pixman_region32_subtract(&b->compositor->primary_plane.damage,
641 &b->compositor->primary_plane.damage, damage);
646 wayland_backend_destroy_output_surface(struct wayland_output *output)
648 if (output->parent.xdg_toplevel)
649 zxdg_toplevel_v6_destroy(output->parent.xdg_toplevel);
651 if (output->parent.xdg_surface)
652 zxdg_surface_v6_destroy(output->parent.xdg_surface);
654 if (output->parent.shell_surface)
655 wl_shell_surface_destroy(output->parent.shell_surface);
657 wl_surface_destroy(output->parent.surface);
661 wayland_output_destroy_shm_buffers(struct wayland_output *output)
663 struct wayland_shm_buffer *buffer, *next;
665 /* Throw away any remaining SHM buffers */
666 wl_list_for_each_safe(buffer, next, &output->shm.free_buffers, free_link)
667 wayland_shm_buffer_destroy(buffer);
668 /* These will get thrown away when they get released */
669 wl_list_for_each(buffer, &output->shm.buffers, link)
670 buffer->output = NULL;
674 wayland_output_disable(struct weston_output *base)
676 struct wayland_output *output = to_wayland_output(base);
677 struct wayland_backend *b = to_wayland_backend(base->compositor);
679 if (!output->base.enabled)
683 pixman_renderer_output_destroy(&output->base);
686 gl_renderer->output_destroy(&output->base);
687 wl_egl_window_destroy(output->gl.egl_window);
691 wayland_output_destroy_shm_buffers(output);
693 wayland_backend_destroy_output_surface(output);
696 frame_destroy(output->frame);
698 cairo_surface_destroy(output->gl.border.top);
699 cairo_surface_destroy(output->gl.border.left);
700 cairo_surface_destroy(output->gl.border.right);
701 cairo_surface_destroy(output->gl.border.bottom);
707 wayland_output_destroy(struct weston_output *base)
709 struct wayland_output *output = to_wayland_output(base);
711 wayland_output_disable(&output->base);
713 weston_output_release(&output->base);
715 if (output->frame_cb)
716 wl_callback_destroy(output->frame_cb);
722 static const struct wl_shell_surface_listener shell_surface_listener;
726 wayland_output_init_gl_renderer(struct wayland_output *output)
728 int32_t fwidth = 0, fheight = 0;
731 fwidth = frame_width(output->frame);
732 fheight = frame_height(output->frame);
734 fwidth = output->base.current_mode->width;
735 fheight = output->base.current_mode->height;
738 output->gl.egl_window =
739 wl_egl_window_create(output->parent.surface,
741 if (!output->gl.egl_window) {
742 weston_log("failure to create wl_egl_window\n");
746 if (gl_renderer->output_window_create(&output->base,
747 output->gl.egl_window,
748 output->gl.egl_window,
749 gl_renderer->alpha_attribs,
757 wl_egl_window_destroy(output->gl.egl_window);
763 wayland_output_init_pixman_renderer(struct wayland_output *output)
765 return pixman_renderer_output_create(&output->base);
769 wayland_output_resize_surface(struct wayland_output *output)
771 struct wayland_backend *b =
772 to_wayland_backend(output->base.compositor);
773 int32_t ix, iy, iwidth, iheight;
774 int32_t width, height;
775 struct wl_region *region;
777 width = output->base.current_mode->width;
778 height = output->base.current_mode->height;
781 frame_resize_inside(output->frame, width, height);
783 frame_input_rect(output->frame, &ix, &iy, &iwidth, &iheight);
784 region = wl_compositor_create_region(b->parent.compositor);
785 wl_region_add(region, ix, iy, iwidth, iheight);
786 wl_surface_set_input_region(output->parent.surface, region);
787 wl_region_destroy(region);
789 if (output->parent.xdg_surface) {
790 zxdg_surface_v6_set_window_geometry(output->parent.xdg_surface,
797 frame_opaque_rect(output->frame, &ix, &iy, &iwidth, &iheight);
798 region = wl_compositor_create_region(b->parent.compositor);
799 wl_region_add(region, ix, iy, iwidth, iheight);
800 wl_surface_set_opaque_region(output->parent.surface, region);
801 wl_region_destroy(region);
803 width = frame_width(output->frame);
804 height = frame_height(output->frame);
806 region = wl_compositor_create_region(b->parent.compositor);
807 wl_region_add(region, 0, 0, width, height);
808 wl_surface_set_input_region(output->parent.surface, region);
809 wl_region_destroy(region);
811 region = wl_compositor_create_region(b->parent.compositor);
812 wl_region_add(region, 0, 0, width, height);
813 wl_surface_set_opaque_region(output->parent.surface, region);
814 wl_region_destroy(region);
816 if (output->parent.xdg_surface) {
817 zxdg_surface_v6_set_window_geometry(output->parent.xdg_surface,
826 if (output->gl.egl_window) {
827 wl_egl_window_resize(output->gl.egl_window,
828 width, height, 0, 0);
830 /* These will need to be re-created due to the resize */
831 gl_renderer->output_set_border(&output->base,
832 GL_RENDERER_BORDER_TOP,
834 cairo_surface_destroy(output->gl.border.top);
835 output->gl.border.top = NULL;
836 gl_renderer->output_set_border(&output->base,
837 GL_RENDERER_BORDER_LEFT,
839 cairo_surface_destroy(output->gl.border.left);
840 output->gl.border.left = NULL;
841 gl_renderer->output_set_border(&output->base,
842 GL_RENDERER_BORDER_RIGHT,
844 cairo_surface_destroy(output->gl.border.right);
845 output->gl.border.right = NULL;
846 gl_renderer->output_set_border(&output->base,
847 GL_RENDERER_BORDER_BOTTOM,
849 cairo_surface_destroy(output->gl.border.bottom);
850 output->gl.border.bottom = NULL;
854 wayland_output_destroy_shm_buffers(output);
858 wayland_output_set_windowed(struct wayland_output *output)
860 struct wayland_backend *b =
861 to_wayland_backend(output->base.compositor);
867 b->theme = theme_create();
871 output->frame = frame_create(b->theme, 100, 100,
872 FRAME_BUTTON_CLOSE, output->title);
876 if (output->keyboard_count)
877 frame_set_flag(output->frame, FRAME_FLAG_ACTIVE);
879 wayland_output_resize_surface(output);
881 if (output->parent.xdg_toplevel) {
882 zxdg_toplevel_v6_unset_fullscreen(output->parent.xdg_toplevel);
883 } else if (output->parent.shell_surface) {
884 wl_shell_surface_set_toplevel(output->parent.shell_surface);
893 wayland_output_set_fullscreen(struct wayland_output *output,
894 enum wl_shell_surface_fullscreen_method method,
895 uint32_t framerate, struct wl_output *target)
898 frame_destroy(output->frame);
899 output->frame = NULL;
902 wayland_output_resize_surface(output);
904 if (output->parent.xdg_toplevel) {
905 zxdg_toplevel_v6_set_fullscreen(output->parent.xdg_toplevel, target);
906 } else if (output->parent.shell_surface) {
907 wl_shell_surface_set_fullscreen(output->parent.shell_surface,
908 method, framerate, target);
914 static struct weston_mode *
915 wayland_output_choose_mode(struct wayland_output *output,
916 struct weston_mode *ref_mode)
918 struct weston_mode *mode;
920 /* First look for an exact match */
921 wl_list_for_each(mode, &output->base.mode_list, link)
922 if (mode->width == ref_mode->width &&
923 mode->height == ref_mode->height &&
924 mode->refresh == ref_mode->refresh)
927 /* If we can't find an exact match, ignore refresh and try again */
928 wl_list_for_each(mode, &output->base.mode_list, link)
929 if (mode->width == ref_mode->width &&
930 mode->height == ref_mode->height)
933 /* Yeah, we failed */
945 mode_feedback_successful(void *data,
946 struct zwp_fullscreen_shell_mode_feedback_v1 *fb)
948 enum mode_status *value = data;
950 printf("Mode switch successful\n");
952 *value = MODE_STATUS_SUCCESS;
956 mode_feedback_failed(void *data, struct zwp_fullscreen_shell_mode_feedback_v1 *fb)
958 enum mode_status *value = data;
960 printf("Mode switch failed\n");
962 *value = MODE_STATUS_FAIL;
966 mode_feedback_cancelled(void *data, struct zwp_fullscreen_shell_mode_feedback_v1 *fb)
968 enum mode_status *value = data;
970 printf("Mode switch cancelled\n");
972 *value = MODE_STATUS_CANCEL;
975 struct zwp_fullscreen_shell_mode_feedback_v1_listener mode_feedback_listener = {
976 mode_feedback_successful,
977 mode_feedback_failed,
978 mode_feedback_cancelled,
981 static enum mode_status
982 wayland_output_fullscreen_shell_mode_feedback(struct wayland_output *output,
983 struct weston_mode *mode)
985 struct wayland_backend *b = to_wayland_backend(output->base.compositor);
986 struct zwp_fullscreen_shell_mode_feedback_v1 *mode_feedback;
987 enum mode_status mode_status;
991 zwp_fullscreen_shell_v1_present_surface_for_mode(b->parent.fshell,
992 output->parent.surface,
993 output->parent.output,
996 zwp_fullscreen_shell_mode_feedback_v1_add_listener(mode_feedback,
997 &mode_feedback_listener,
1000 output->parent.draw_initial_frame = false;
1001 draw_initial_frame(output);
1002 wl_surface_commit(output->parent.surface);
1004 mode_status = MODE_STATUS_UNKNOWN;
1005 while (mode_status == MODE_STATUS_UNKNOWN && ret >= 0)
1006 ret = wl_display_dispatch(b->parent.wl_display);
1008 zwp_fullscreen_shell_mode_feedback_v1_destroy(mode_feedback);
1014 wayland_output_switch_mode(struct weston_output *output_base,
1015 struct weston_mode *mode)
1017 struct wayland_output *output = to_wayland_output(output_base);
1018 struct wayland_backend *b;
1019 struct wl_surface *old_surface;
1020 struct weston_mode *old_mode;
1021 enum mode_status mode_status;
1023 if (output_base == NULL) {
1024 weston_log("output is NULL.\n");
1029 weston_log("mode is NULL.\n");
1033 b = to_wayland_backend(output_base->compositor);
1035 if (output->parent.xdg_surface || output->parent.shell_surface || !b->parent.fshell)
1038 mode = wayland_output_choose_mode(output, mode);
1042 if (output->base.current_mode == mode)
1045 old_mode = output->base.current_mode;
1046 old_surface = output->parent.surface;
1047 output->base.current_mode = mode;
1048 output->parent.surface =
1049 wl_compositor_create_surface(b->parent.compositor);
1050 wl_surface_set_user_data(output->parent.surface, output);
1052 /* Blow the old buffers because we changed size/surfaces */
1053 wayland_output_resize_surface(output);
1055 mode_status = wayland_output_fullscreen_shell_mode_feedback(output, mode);
1057 /* This should kick-start things again */
1058 wayland_output_start_repaint_loop(&output->base);
1060 if (mode_status == MODE_STATUS_FAIL) {
1061 output->base.current_mode = old_mode;
1062 wl_surface_destroy(output->parent.surface);
1063 output->parent.surface = old_surface;
1064 wayland_output_resize_surface(output);
1069 old_mode->flags &= ~WL_OUTPUT_MODE_CURRENT;
1070 output->base.current_mode->flags |= WL_OUTPUT_MODE_CURRENT;
1072 if (b->use_pixman) {
1073 pixman_renderer_output_destroy(output_base);
1074 if (wayland_output_init_pixman_renderer(output) < 0)
1078 gl_renderer->output_destroy(output_base);
1079 wl_egl_window_destroy(output->gl.egl_window);
1080 if (wayland_output_init_gl_renderer(output) < 0)
1084 wl_surface_destroy(old_surface);
1086 weston_output_schedule_repaint(&output->base);
1096 handle_xdg_surface_configure(void *data, struct zxdg_surface_v6 *surface,
1099 zxdg_surface_v6_ack_configure(surface, serial);
1102 static const struct zxdg_surface_v6_listener xdg_surface_listener = {
1103 handle_xdg_surface_configure
1107 handle_xdg_toplevel_configure(void *data, struct zxdg_toplevel_v6 *toplevel,
1108 int32_t width, int32_t height,
1109 struct wl_array *states)
1111 struct wayland_output *output = data;
1113 output->parent.configure_width = width;
1114 output->parent.configure_height = height;
1116 output->parent.wait_for_configure = false;
1117 /* FIXME: implement resizing */
1121 handle_xdg_toplevel_close(void *data, struct zxdg_toplevel_v6 *xdg_toplevel)
1123 struct wayland_output *output = data;
1124 struct weston_compositor *compositor = output->base.compositor;
1126 wayland_output_destroy(&output->base);
1128 if (wl_list_empty(&compositor->output_list))
1129 weston_compositor_exit(compositor);
1132 static const struct zxdg_toplevel_v6_listener xdg_toplevel_listener = {
1133 handle_xdg_toplevel_configure,
1134 handle_xdg_toplevel_close,
1138 wayland_backend_create_output_surface(struct wayland_output *output)
1140 struct wayland_backend *b = to_wayland_backend(output->base.compositor);
1142 output->parent.surface =
1143 wl_compositor_create_surface(b->parent.compositor);
1144 if (!output->parent.surface)
1147 wl_surface_set_user_data(output->parent.surface, output);
1149 output->parent.draw_initial_frame = true;
1151 if (b->parent.xdg_shell) {
1152 output->parent.xdg_surface =
1153 zxdg_shell_v6_get_xdg_surface(b->parent.xdg_shell,
1154 output->parent.surface);
1155 zxdg_surface_v6_add_listener(output->parent.xdg_surface,
1156 &xdg_surface_listener, output);
1158 output->parent.xdg_toplevel =
1159 zxdg_surface_v6_get_toplevel(output->parent.xdg_surface);
1160 zxdg_toplevel_v6_add_listener(output->parent.xdg_toplevel,
1161 &xdg_toplevel_listener, output);
1163 zxdg_toplevel_v6_set_title(output->parent.xdg_toplevel, output->title);
1165 wl_surface_commit(output->parent.surface);
1167 output->parent.wait_for_configure = true;
1169 while (output->parent.wait_for_configure)
1170 wl_display_dispatch(b->parent.wl_display);
1172 weston_log("wayland-backend: Using xdg_shell_v6\n");
1174 else if (b->parent.shell) {
1175 output->parent.shell_surface =
1176 wl_shell_get_shell_surface(b->parent.shell,
1177 output->parent.surface);
1178 if (!output->parent.shell_surface) {
1179 wl_surface_destroy(output->parent.surface);
1183 wl_shell_surface_add_listener(output->parent.shell_surface,
1184 &shell_surface_listener, output);
1186 weston_log("wayland-backend: Using wl_shell\n");
1193 wayland_output_enable(struct weston_output *base)
1195 struct wayland_output *output = to_wayland_output(base);
1196 struct wayland_backend *b = to_wayland_backend(base->compositor);
1197 enum mode_status mode_status;
1200 weston_log("Creating %dx%d wayland output at (%d, %d)\n",
1201 output->base.current_mode->width,
1202 output->base.current_mode->height,
1203 output->base.x, output->base.y);
1205 if (!output->parent.surface)
1206 ret = wayland_backend_create_output_surface(output);
1211 wl_list_init(&output->shm.buffers);
1212 wl_list_init(&output->shm.free_buffers);
1214 if (b->use_pixman) {
1215 if (wayland_output_init_pixman_renderer(output) < 0)
1218 output->base.repaint = wayland_output_repaint_pixman;
1221 if (wayland_output_init_gl_renderer(output) < 0)
1224 output->base.repaint = wayland_output_repaint_gl;
1228 output->base.start_repaint_loop = wayland_output_start_repaint_loop;
1229 output->base.assign_planes = NULL;
1230 output->base.set_backlight = NULL;
1231 output->base.set_dpms = NULL;
1232 output->base.switch_mode = wayland_output_switch_mode;
1234 if (b->sprawl_across_outputs) {
1235 if (b->parent.fshell) {
1236 wayland_output_resize_surface(output);
1238 mode_status = wayland_output_fullscreen_shell_mode_feedback(output, &output->mode);
1240 if (mode_status == MODE_STATUS_FAIL) {
1241 zwp_fullscreen_shell_v1_present_surface(b->parent.fshell,
1242 output->parent.surface,
1243 ZWP_FULLSCREEN_SHELL_V1_PRESENT_METHOD_CENTER,
1244 output->parent.output);
1246 output->parent.draw_initial_frame = true;
1249 wayland_output_set_fullscreen(output,
1250 WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER,
1251 output->mode.refresh, output->parent.output);
1253 } else if (b->fullscreen) {
1254 wayland_output_set_fullscreen(output, 0, 0, NULL);
1256 wayland_output_set_windowed(output);
1262 wayland_backend_destroy_output_surface(output);
1267 static struct wayland_output *
1268 wayland_output_create_common(struct weston_compositor *compositor,
1271 struct wayland_output *output;
1274 /* name can't be NULL. */
1277 output = zalloc(sizeof *output);
1278 if (output == NULL) {
1283 if (asprintf(&title, "%s - %s", WINDOW_TITLE, name) < 0) {
1287 output->title = title;
1289 weston_output_init(&output->base, compositor, name);
1291 output->base.destroy = wayland_output_destroy;
1292 output->base.disable = wayland_output_disable;
1293 output->base.enable = wayland_output_enable;
1299 wayland_output_create(struct weston_compositor *compositor, const char *name)
1301 struct wayland_output *output;
1303 output = wayland_output_create_common(compositor, name);
1307 weston_compositor_add_pending_output(&output->base, compositor);
1313 wayland_output_set_size(struct weston_output *base, int width, int height)
1315 struct wayland_output *output = to_wayland_output(base);
1316 int output_width, output_height;
1318 /* We can only be called once. */
1319 assert(!output->base.current_mode);
1321 /* Make sure we have scale set. */
1322 assert(output->base.scale);
1325 weston_log("Invalid width \"%d\" for output %s\n",
1326 width, output->base.name);
1331 weston_log("Invalid height \"%d\" for output %s\n",
1332 height, output->base.name);
1336 output_width = width * output->base.scale;
1337 output_height = height * output->base.scale;
1339 output->mode.flags =
1340 WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
1342 output->mode.width = output_width;
1343 output->mode.height = output_height;
1344 output->mode.refresh = 60000;
1345 wl_list_insert(&output->base.mode_list, &output->mode.link);
1347 output->base.current_mode = &output->mode;
1348 output->base.make = "wayland";
1349 output->base.model = "none";
1351 /* XXX: Calculate proper size. */
1352 output->base.mm_width = width;
1353 output->base.mm_height = height;
1359 wayland_output_create_for_parent_output(struct wayland_backend *b,
1360 struct wayland_parent_output *poutput)
1362 struct wayland_output *output;
1363 struct weston_mode *mode;
1365 output = wayland_output_create_common(b->compositor, "wlparent");
1369 if (poutput->current_mode) {
1370 mode = poutput->current_mode;
1371 } else if (poutput->preferred_mode) {
1372 mode = poutput->preferred_mode;
1373 } else if (!wl_list_empty(&poutput->mode_list)) {
1374 mode = container_of(poutput->mode_list.next,
1375 struct weston_mode, link);
1377 weston_log("No valid modes found. Skipping output.\n");
1381 output->base.scale = 1;
1382 output->base.transform = WL_OUTPUT_TRANSFORM_NORMAL;
1384 output->parent.output = poutput->global;
1386 output->base.make = poutput->physical.make;
1387 output->base.model = poutput->physical.model;
1388 output->base.mm_width = poutput->physical.width;
1389 output->base.mm_height = poutput->physical.height;
1391 wl_list_insert_list(&output->base.mode_list, &poutput->mode_list);
1392 wl_list_init(&poutput->mode_list);
1394 /* No other mode should have CURRENT already. */
1395 mode->flags |= WL_OUTPUT_MODE_CURRENT;
1396 output->base.current_mode = mode;
1398 /* output->mode is unused in this path. */
1400 weston_compositor_add_pending_output(&output->base, b->compositor);
1405 weston_output_release(&output->base);
1406 free(output->title);
1413 wayland_output_create_fullscreen(struct wayland_backend *b)
1415 struct wayland_output *output;
1416 int width = 0, height = 0;
1418 output = wayland_output_create_common(b->compositor, "wayland-fullscreen");
1422 output->base.scale = 1;
1423 output->base.transform = WL_OUTPUT_TRANSFORM_NORMAL;
1425 if (wayland_backend_create_output_surface(output) < 0)
1428 /* What should size be set if conditional is false? */
1429 if (b->parent.xdg_shell || b->parent.shell) {
1430 if (output->parent.xdg_toplevel)
1431 zxdg_toplevel_v6_set_fullscreen(output->parent.xdg_toplevel,
1432 output->parent.output);
1433 else if (output->parent.shell_surface)
1434 wl_shell_surface_set_fullscreen(output->parent.shell_surface,
1437 wl_display_roundtrip(b->parent.wl_display);
1439 width = output->parent.configure_width;
1440 height = output->parent.configure_height;
1443 if (wayland_output_set_size(&output->base, width, height) < 0)
1446 weston_compositor_add_pending_output(&output->base, b->compositor);
1451 wayland_backend_destroy_output_surface(output);
1453 weston_output_release(&output->base);
1454 free(output->title);
1461 shell_surface_ping(void *data, struct wl_shell_surface *shell_surface,
1464 wl_shell_surface_pong(shell_surface, serial);
1468 shell_surface_configure(void *data, struct wl_shell_surface *shell_surface,
1469 uint32_t edges, int32_t width, int32_t height)
1471 struct wayland_output *output = data;
1473 output->parent.configure_width = width;
1474 output->parent.configure_height = height;
1476 /* FIXME: implement resizing */
1480 shell_surface_popup_done(void *data, struct wl_shell_surface *shell_surface)
1484 static const struct wl_shell_surface_listener shell_surface_listener = {
1486 shell_surface_configure,
1487 shell_surface_popup_done
1490 /* Events received from the wayland-server this compositor is client of: */
1492 /* parent input interface */
1494 input_set_cursor(struct wayland_input *input)
1497 struct wl_buffer *buffer;
1498 struct wl_cursor_image *image;
1500 if (!input->backend->cursor)
1501 return; /* Couldn't load the cursor. Can't set it */
1503 image = input->backend->cursor->images[0];
1504 buffer = wl_cursor_image_get_buffer(image);
1508 wl_pointer_set_cursor(input->parent.pointer, input->enter_serial,
1509 input->parent.cursor.surface,
1510 image->hotspot_x, image->hotspot_y);
1512 wl_surface_attach(input->parent.cursor.surface, buffer, 0, 0);
1513 wl_surface_damage(input->parent.cursor.surface, 0, 0,
1514 image->width, image->height);
1515 wl_surface_commit(input->parent.cursor.surface);
1519 input_handle_pointer_enter(void *data, struct wl_pointer *pointer,
1520 uint32_t serial, struct wl_surface *surface,
1521 wl_fixed_t fixed_x, wl_fixed_t fixed_y)
1523 struct wayland_input *input = data;
1525 enum theme_location location;
1528 x = wl_fixed_to_double(fixed_x);
1529 y = wl_fixed_to_double(fixed_y);
1531 /* XXX: If we get a modifier event immediately before the focus,
1532 * we should try to keep the same serial. */
1533 input->enter_serial = serial;
1534 input->output = wl_surface_get_user_data(surface);
1536 if (input->output->frame) {
1537 location = frame_pointer_enter(input->output->frame, input,
1539 frame_interior(input->output->frame, &fx, &fy, NULL, NULL);
1543 if (frame_status(input->output->frame) & FRAME_STATUS_REPAINT)
1544 weston_output_schedule_repaint(&input->output->base);
1546 location = THEME_LOCATION_CLIENT_AREA;
1549 weston_output_transform_coordinate(&input->output->base, x, y, &x, &y);
1551 if (location == THEME_LOCATION_CLIENT_AREA) {
1552 input->has_focus = true;
1553 notify_pointer_focus(&input->base, &input->output->base, x, y);
1554 wl_pointer_set_cursor(input->parent.pointer,
1555 input->enter_serial, NULL, 0, 0);
1557 input->has_focus = false;
1558 notify_pointer_focus(&input->base, NULL, 0, 0);
1559 input_set_cursor(input);
1564 input_handle_pointer_leave(void *data, struct wl_pointer *pointer,
1565 uint32_t serial, struct wl_surface *surface)
1567 struct wayland_input *input = data;
1572 if (input->output->frame) {
1573 frame_pointer_leave(input->output->frame, input);
1575 if (frame_status(input->output->frame) & FRAME_STATUS_REPAINT)
1576 weston_output_schedule_repaint(&input->output->base);
1579 notify_pointer_focus(&input->base, NULL, 0, 0);
1580 input->output = NULL;
1581 input->has_focus = false;
1585 input_handle_motion(void *data, struct wl_pointer *pointer,
1586 uint32_t time, wl_fixed_t fixed_x, wl_fixed_t fixed_y)
1588 struct wayland_input *input = data;
1590 enum theme_location location;
1591 bool want_frame = false;
1598 x = wl_fixed_to_double(fixed_x);
1599 y = wl_fixed_to_double(fixed_y);
1601 if (input->output->frame) {
1602 location = frame_pointer_motion(input->output->frame, input,
1604 frame_interior(input->output->frame, &fx, &fy, NULL, NULL);
1608 if (frame_status(input->output->frame) & FRAME_STATUS_REPAINT)
1609 weston_output_schedule_repaint(&input->output->base);
1611 location = THEME_LOCATION_CLIENT_AREA;
1614 weston_output_transform_coordinate(&input->output->base, x, y, &x, &y);
1616 if (input->has_focus && location != THEME_LOCATION_CLIENT_AREA) {
1617 input_set_cursor(input);
1618 notify_pointer_focus(&input->base, NULL, 0, 0);
1619 input->has_focus = false;
1621 } else if (!input->has_focus &&
1622 location == THEME_LOCATION_CLIENT_AREA) {
1623 wl_pointer_set_cursor(input->parent.pointer,
1624 input->enter_serial, NULL, 0, 0);
1625 notify_pointer_focus(&input->base, &input->output->base, x, y);
1626 input->has_focus = true;
1630 if (location == THEME_LOCATION_CLIENT_AREA) {
1631 timespec_from_msec(&ts, time);
1632 notify_motion_absolute(&input->base, &ts, x, y);
1636 if (want_frame && input->seat_version < WL_POINTER_FRAME_SINCE_VERSION)
1637 notify_pointer_frame(&input->base);
1641 input_handle_button(void *data, struct wl_pointer *pointer,
1642 uint32_t serial, uint32_t time, uint32_t button,
1643 enum wl_pointer_button_state state)
1645 struct wayland_input *input = data;
1646 enum theme_location location;
1652 if (input->output->frame) {
1653 location = frame_pointer_button(input->output->frame, input,
1656 if (frame_status(input->output->frame) & FRAME_STATUS_MOVE) {
1657 if (input->output->parent.xdg_toplevel)
1658 zxdg_toplevel_v6_move(input->output->parent.xdg_toplevel,
1659 input->parent.seat, serial);
1660 else if (input->output->parent.shell_surface)
1661 wl_shell_surface_move(input->output->parent.shell_surface,
1662 input->parent.seat, serial);
1663 frame_status_clear(input->output->frame,
1668 if (frame_status(input->output->frame) & FRAME_STATUS_CLOSE) {
1669 wayland_output_destroy(&input->output->base);
1670 input->output = NULL;
1671 input->keyboard_focus = NULL;
1673 if (wl_list_empty(&input->backend->compositor->output_list))
1674 weston_compositor_exit(input->backend->compositor);
1679 if (frame_status(input->output->frame) & FRAME_STATUS_REPAINT)
1680 weston_output_schedule_repaint(&input->output->base);
1682 location = THEME_LOCATION_CLIENT_AREA;
1685 if (location == THEME_LOCATION_CLIENT_AREA) {
1686 timespec_from_msec(&ts, time);
1687 notify_button(&input->base, &ts, button, state);
1688 if (input->seat_version < WL_POINTER_FRAME_SINCE_VERSION)
1689 notify_pointer_frame(&input->base);
1694 input_handle_axis(void *data, struct wl_pointer *pointer,
1695 uint32_t time, uint32_t axis, wl_fixed_t value)
1697 struct wayland_input *input = data;
1698 struct weston_pointer_axis_event weston_event;
1701 weston_event.axis = axis;
1702 weston_event.value = wl_fixed_to_double(value);
1704 if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL &&
1705 input->vert.has_discrete) {
1706 weston_event.has_discrete = true;
1707 weston_event.discrete = input->vert.discrete;
1708 input->vert.has_discrete = false;
1709 } else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL &&
1710 input->horiz.has_discrete) {
1711 weston_event.has_discrete = true;
1712 weston_event.discrete = input->horiz.discrete;
1713 input->horiz.has_discrete = false;
1716 timespec_from_msec(&ts, time);
1718 notify_axis(&input->base, &ts, &weston_event);
1720 if (input->seat_version < WL_POINTER_FRAME_SINCE_VERSION)
1721 notify_pointer_frame(&input->base);
1725 input_handle_frame(void *data, struct wl_pointer *pointer)
1727 struct wayland_input *input = data;
1729 notify_pointer_frame(&input->base);
1733 input_handle_axis_source(void *data, struct wl_pointer *pointer,
1736 struct wayland_input *input = data;
1738 notify_axis_source(&input->base, source);
1742 input_handle_axis_stop(void *data, struct wl_pointer *pointer,
1743 uint32_t time, uint32_t axis)
1745 struct wayland_input *input = data;
1746 struct weston_pointer_axis_event weston_event;
1749 weston_event.axis = axis;
1750 weston_event.value = 0;
1752 timespec_from_msec(&ts, time);
1754 notify_axis(&input->base, &ts, &weston_event);
1758 input_handle_axis_discrete(void *data, struct wl_pointer *pointer,
1759 uint32_t axis, int32_t discrete)
1761 struct wayland_input *input = data;
1763 if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL) {
1764 input->vert.has_discrete = true;
1765 input->vert.discrete = discrete;
1766 } else if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
1767 input->horiz.has_discrete = true;
1768 input->horiz.discrete = discrete;
1772 static const struct wl_pointer_listener pointer_listener = {
1773 input_handle_pointer_enter,
1774 input_handle_pointer_leave,
1775 input_handle_motion,
1776 input_handle_button,
1779 input_handle_axis_source,
1780 input_handle_axis_stop,
1781 input_handle_axis_discrete,
1785 input_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format,
1786 int fd, uint32_t size)
1788 struct wayland_input *input = data;
1789 struct xkb_keymap *keymap;
1797 if (format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
1798 map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
1799 if (map_str == MAP_FAILED) {
1800 weston_log("mmap failed: %m\n");
1804 keymap = xkb_keymap_new_from_string(input->backend->compositor->xkb_context,
1806 XKB_KEYMAP_FORMAT_TEXT_V1,
1808 munmap(map_str, size);
1811 weston_log("failed to compile keymap\n");
1815 input->keyboard_state_update = STATE_UPDATE_NONE;
1816 } else if (format == WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP) {
1817 weston_log("No keymap provided; falling back to defalt\n");
1819 input->keyboard_state_update = STATE_UPDATE_AUTOMATIC;
1821 weston_log("Invalid keymap\n");
1827 if (weston_seat_get_keyboard(&input->base))
1828 weston_seat_update_keymap(&input->base, keymap);
1830 weston_seat_init_keyboard(&input->base, keymap);
1832 xkb_keymap_unref(keymap);
1837 wl_keyboard_release(input->parent.keyboard);
1842 input_handle_keyboard_enter(void *data,
1843 struct wl_keyboard *keyboard,
1845 struct wl_surface *surface,
1846 struct wl_array *keys)
1848 struct wayland_input *input = data;
1849 struct wayland_output *focus;
1851 focus = input->keyboard_focus;
1853 /* This shouldn't happen */
1854 focus->keyboard_count--;
1855 if (!focus->keyboard_count && focus->frame)
1856 frame_unset_flag(focus->frame, FRAME_FLAG_ACTIVE);
1857 if (frame_status(focus->frame) & FRAME_STATUS_REPAINT)
1858 weston_output_schedule_repaint(&focus->base);
1861 input->keyboard_focus = wl_surface_get_user_data(surface);
1862 input->keyboard_focus->keyboard_count++;
1864 focus = input->keyboard_focus;
1866 frame_set_flag(focus->frame, FRAME_FLAG_ACTIVE);
1867 if (frame_status(focus->frame) & FRAME_STATUS_REPAINT)
1868 weston_output_schedule_repaint(&focus->base);
1872 /* XXX: If we get a modifier event immediately before the focus,
1873 * we should try to keep the same serial. */
1874 notify_keyboard_focus_in(&input->base, keys,
1875 STATE_UPDATE_AUTOMATIC);
1879 input_handle_keyboard_leave(void *data,
1880 struct wl_keyboard *keyboard,
1882 struct wl_surface *surface)
1884 struct wayland_input *input = data;
1885 struct wayland_output *focus;
1887 notify_keyboard_focus_out(&input->base);
1889 focus = input->keyboard_focus;
1893 focus->keyboard_count--;
1894 if (!focus->keyboard_count && focus->frame) {
1895 frame_unset_flag(focus->frame, FRAME_FLAG_ACTIVE);
1896 if (frame_status(focus->frame) & FRAME_STATUS_REPAINT)
1897 weston_output_schedule_repaint(&focus->base);
1900 input->keyboard_focus = NULL;
1904 input_handle_key(void *data, struct wl_keyboard *keyboard,
1905 uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
1907 struct wayland_input *input = data;
1909 input->key_serial = serial;
1910 notify_key(&input->base, time, key,
1911 state ? WL_KEYBOARD_KEY_STATE_PRESSED :
1912 WL_KEYBOARD_KEY_STATE_RELEASED,
1913 input->keyboard_state_update);
1917 input_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard,
1918 uint32_t serial_in, uint32_t mods_depressed,
1919 uint32_t mods_latched, uint32_t mods_locked,
1922 struct weston_keyboard *keyboard;
1923 struct wayland_input *input = data;
1924 struct wayland_backend *b = input->backend;
1925 uint32_t serial_out;
1927 /* If we get a key event followed by a modifier event with the
1928 * same serial number, then we try to preserve those semantics by
1929 * reusing the same serial number on the way out too. */
1930 if (serial_in == input->key_serial)
1931 serial_out = wl_display_get_serial(b->compositor->wl_display);
1933 serial_out = wl_display_next_serial(b->compositor->wl_display);
1935 keyboard = weston_seat_get_keyboard(&input->base);
1936 xkb_state_update_mask(keyboard->xkb_state.state,
1937 mods_depressed, mods_latched,
1938 mods_locked, 0, 0, group);
1939 notify_modifiers(&input->base, serial_out);
1943 input_handle_repeat_info(void *data, struct wl_keyboard *keyboard,
1944 int32_t rate, int32_t delay)
1946 struct wayland_input *input = data;
1947 struct wayland_backend *b = input->backend;
1949 b->compositor->kb_repeat_rate = rate;
1950 b->compositor->kb_repeat_delay = delay;
1953 static const struct wl_keyboard_listener keyboard_listener = {
1954 input_handle_keymap,
1955 input_handle_keyboard_enter,
1956 input_handle_keyboard_leave,
1958 input_handle_modifiers,
1959 input_handle_repeat_info,
1963 input_handle_touch_down(void *data, struct wl_touch *wl_touch,
1964 uint32_t serial, uint32_t time,
1965 struct wl_surface *surface, int32_t id,
1966 wl_fixed_t fixed_x, wl_fixed_t fixed_y)
1968 struct wayland_input *input = data;
1969 struct wayland_output *output;
1970 enum theme_location location;
1975 x = wl_fixed_to_double(fixed_x);
1976 y = wl_fixed_to_double(fixed_y);
1978 first_touch = (input->touch_points == 0);
1979 input->touch_points++;
1981 input->touch_focus = wl_surface_get_user_data(surface);
1982 output = input->touch_focus;
1983 if (!first_touch && !input->touch_active)
1986 if (output->frame) {
1987 location = frame_touch_down(output->frame, input, id, x, y);
1989 frame_interior(output->frame, &fx, &fy, NULL, NULL);
1993 if (frame_status(output->frame) & FRAME_STATUS_REPAINT)
1994 weston_output_schedule_repaint(&output->base);
1996 if (first_touch && (frame_status(output->frame) & FRAME_STATUS_MOVE)) {
1997 input->touch_points--;
1998 if (output->parent.xdg_toplevel)
1999 zxdg_toplevel_v6_move(output->parent.xdg_toplevel,
2000 input->parent.seat, serial);
2001 else if (output->parent.shell_surface)
2002 wl_shell_surface_move(output->parent.shell_surface,
2003 input->parent.seat, serial);
2004 frame_status_clear(output->frame,
2009 if (first_touch && location != THEME_LOCATION_CLIENT_AREA)
2013 weston_output_transform_coordinate(&output->base, x, y, &x, &y);
2015 notify_touch(&input->base, time, id, x, y, WL_TOUCH_DOWN);
2016 input->touch_active = true;
2020 input_handle_touch_up(void *data, struct wl_touch *wl_touch,
2021 uint32_t serial, uint32_t time, int32_t id)
2023 struct wayland_input *input = data;
2024 struct wayland_output *output = input->touch_focus;
2025 bool active = input->touch_active;
2027 input->touch_points--;
2028 if (input->touch_points == 0) {
2029 input->touch_focus = NULL;
2030 input->touch_active = false;
2036 if (output->frame) {
2037 frame_touch_up(output->frame, input, id);
2039 if (frame_status(output->frame) & FRAME_STATUS_CLOSE) {
2040 wayland_output_destroy(&output->base);
2041 input->touch_focus = NULL;
2042 input->keyboard_focus = NULL;
2043 if (wl_list_empty(&input->backend->compositor->output_list))
2044 weston_compositor_exit(input->backend->compositor);
2048 if (frame_status(output->frame) & FRAME_STATUS_REPAINT)
2049 weston_output_schedule_repaint(&output->base);
2053 notify_touch(&input->base, time, id, 0, 0, WL_TOUCH_UP);
2057 input_handle_touch_motion(void *data, struct wl_touch *wl_touch,
2058 uint32_t time, int32_t id,
2059 wl_fixed_t fixed_x, wl_fixed_t fixed_y)
2061 struct wayland_input *input = data;
2062 struct wayland_output *output = input->touch_focus;
2066 x = wl_fixed_to_double(fixed_x);
2067 y = wl_fixed_to_double(fixed_y);
2069 if (!output || !input->touch_active)
2072 if (output->frame) {
2073 frame_interior(output->frame, &fx, &fy, NULL, NULL);
2078 weston_output_transform_coordinate(&output->base, x, y, &x, &y);
2080 notify_touch(&input->base, time, id, x, y, WL_TOUCH_MOTION);
2084 input_handle_touch_frame(void *data, struct wl_touch *wl_touch)
2086 struct wayland_input *input = data;
2088 if (!input->touch_focus || !input->touch_active)
2091 notify_touch_frame(&input->base);
2095 input_handle_touch_cancel(void *data, struct wl_touch *wl_touch)
2097 struct wayland_input *input = data;
2099 if (!input->touch_focus || !input->touch_active)
2102 notify_touch_cancel(&input->base);
2105 static const struct wl_touch_listener touch_listener = {
2106 input_handle_touch_down,
2107 input_handle_touch_up,
2108 input_handle_touch_motion,
2109 input_handle_touch_frame,
2110 input_handle_touch_cancel,
2115 input_handle_capabilities(void *data, struct wl_seat *seat,
2116 enum wl_seat_capability caps)
2118 struct wayland_input *input = data;
2120 if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->parent.pointer) {
2121 input->parent.pointer = wl_seat_get_pointer(seat);
2122 wl_pointer_set_user_data(input->parent.pointer, input);
2123 wl_pointer_add_listener(input->parent.pointer,
2124 &pointer_listener, input);
2125 weston_seat_init_pointer(&input->base);
2126 } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->parent.pointer) {
2127 if (input->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION)
2128 wl_pointer_release(input->parent.pointer);
2130 wl_pointer_destroy(input->parent.pointer);
2131 input->parent.pointer = NULL;
2132 weston_seat_release_pointer(&input->base);
2135 if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->parent.keyboard) {
2136 input->parent.keyboard = wl_seat_get_keyboard(seat);
2137 wl_keyboard_set_user_data(input->parent.keyboard, input);
2138 wl_keyboard_add_listener(input->parent.keyboard,
2139 &keyboard_listener, input);
2140 } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->parent.keyboard) {
2141 if (input->seat_version >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
2142 wl_keyboard_release(input->parent.keyboard);
2144 wl_keyboard_destroy(input->parent.keyboard);
2145 input->parent.keyboard = NULL;
2146 weston_seat_release_keyboard(&input->base);
2149 if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->parent.touch) {
2150 input->parent.touch = wl_seat_get_touch(seat);
2151 wl_touch_set_user_data(input->parent.touch, input);
2152 wl_touch_add_listener(input->parent.touch,
2153 &touch_listener, input);
2154 weston_seat_init_touch(&input->base);
2155 } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->parent.touch) {
2156 if (input->seat_version >= WL_TOUCH_RELEASE_SINCE_VERSION)
2157 wl_touch_release(input->parent.touch);
2159 wl_touch_destroy(input->parent.touch);
2160 input->parent.touch = NULL;
2161 weston_seat_release_touch(&input->base);
2166 input_handle_name(void *data, struct wl_seat *seat,
2171 static const struct wl_seat_listener seat_listener = {
2172 input_handle_capabilities,
2177 display_add_seat(struct wayland_backend *b, uint32_t id, uint32_t available_version)
2179 struct wayland_input *input;
2180 uint32_t version = MIN(available_version, 4);
2182 input = zalloc(sizeof *input);
2186 weston_seat_init(&input->base, b->compositor, "default");
2188 input->parent.seat = wl_registry_bind(b->parent.registry, id,
2189 &wl_seat_interface, version);
2190 input->seat_version = version;
2191 wl_list_insert(b->input_list.prev, &input->link);
2193 wl_seat_add_listener(input->parent.seat, &seat_listener, input);
2194 wl_seat_set_user_data(input->parent.seat, input);
2196 input->parent.cursor.surface =
2197 wl_compositor_create_surface(b->parent.compositor);
2199 input->vert.axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
2200 input->horiz.axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL;
2204 wayland_parent_output_geometry(void *data, struct wl_output *output_proxy,
2205 int32_t x, int32_t y,
2206 int32_t physical_width, int32_t physical_height,
2207 int32_t subpixel, const char *make,
2208 const char *model, int32_t transform)
2210 struct wayland_parent_output *output = data;
2214 output->physical.width = physical_width;
2215 output->physical.height = physical_height;
2216 output->physical.subpixel = subpixel;
2218 free(output->physical.make);
2219 output->physical.make = strdup(make);
2220 free(output->physical.model);
2221 output->physical.model = strdup(model);
2223 output->transform = transform;
2226 static struct weston_mode *
2227 find_mode(struct wl_list *list, int32_t width, int32_t height, uint32_t refresh)
2229 struct weston_mode *mode;
2231 wl_list_for_each(mode, list, link) {
2232 if (mode->width == width && mode->height == height &&
2233 mode->refresh == refresh)
2237 mode = zalloc(sizeof *mode);
2241 mode->width = width;
2242 mode->height = height;
2243 mode->refresh = refresh;
2244 wl_list_insert(list, &mode->link);
2250 wayland_parent_output_mode(void *data, struct wl_output *wl_output_proxy,
2251 uint32_t flags, int32_t width, int32_t height,
2254 struct wayland_parent_output *output = data;
2255 struct weston_mode *mode;
2257 if (output->output) {
2258 mode = find_mode(&output->output->base.mode_list,
2259 width, height, refresh);
2262 mode->flags = flags;
2263 /* Do a mode-switch on current mode change? */
2265 mode = find_mode(&output->mode_list, width, height, refresh);
2268 mode->flags = flags;
2269 if (flags & WL_OUTPUT_MODE_CURRENT)
2270 output->current_mode = mode;
2271 if (flags & WL_OUTPUT_MODE_PREFERRED)
2272 output->preferred_mode = mode;
2276 static const struct wl_output_listener output_listener = {
2277 wayland_parent_output_geometry,
2278 wayland_parent_output_mode
2282 output_sync_callback(void *data, struct wl_callback *callback, uint32_t unused)
2284 struct wayland_parent_output *output = data;
2286 assert(output->sync_cb == callback);
2287 wl_callback_destroy(callback);
2288 output->sync_cb = NULL;
2290 assert(output->backend->sprawl_across_outputs);
2292 wayland_output_create_for_parent_output(output->backend, output);
2295 static const struct wl_callback_listener output_sync_listener = {
2296 output_sync_callback
2300 wayland_backend_register_output(struct wayland_backend *b, uint32_t id)
2302 struct wayland_parent_output *output;
2304 output = zalloc(sizeof *output);
2308 output->backend = b;
2310 output->global = wl_registry_bind(b->parent.registry, id,
2311 &wl_output_interface, 1);
2312 if (!output->global) {
2317 wl_output_add_listener(output->global, &output_listener, output);
2320 output->transform = WL_OUTPUT_TRANSFORM_NORMAL;
2321 output->physical.subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN;
2322 wl_list_init(&output->mode_list);
2323 wl_list_insert(&b->parent.output_list, &output->link);
2325 if (b->sprawl_across_outputs) {
2326 output->sync_cb = wl_display_sync(b->parent.wl_display);
2327 wl_callback_add_listener(output->sync_cb,
2328 &output_sync_listener, output);
2333 wayland_parent_output_destroy(struct wayland_parent_output *output)
2335 struct weston_mode *mode, *next;
2337 if (output->sync_cb)
2338 wl_callback_destroy(output->sync_cb);
2341 wayland_output_destroy(&output->output->base);
2343 wl_output_destroy(output->global);
2344 free(output->physical.make);
2345 free(output->physical.model);
2347 wl_list_for_each_safe(mode, next, &output->mode_list, link) {
2348 wl_list_remove(&mode->link);
2352 wl_list_remove(&output->link);
2357 xdg_shell_ping(void *data, struct zxdg_shell_v6 *shell, uint32_t serial)
2359 zxdg_shell_v6_pong(shell, serial);
2362 static const struct zxdg_shell_v6_listener xdg_shell_listener = {
2367 registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
2368 const char *interface, uint32_t version)
2370 struct wayland_backend *b = data;
2372 if (strcmp(interface, "wl_compositor") == 0) {
2373 b->parent.compositor =
2374 wl_registry_bind(registry, name,
2375 &wl_compositor_interface,
2377 } else if (strcmp(interface, "zxdg_shell_v6") == 0) {
2378 b->parent.xdg_shell =
2379 wl_registry_bind(registry, name,
2380 &zxdg_shell_v6_interface, 1);
2381 zxdg_shell_v6_add_listener(b->parent.xdg_shell,
2382 &xdg_shell_listener, b);
2383 } else if (strcmp(interface, "wl_shell") == 0) {
2385 wl_registry_bind(registry, name,
2386 &wl_shell_interface, 1);
2387 } else if (strcmp(interface, "zwp_fullscreen_shell_v1") == 0) {
2389 wl_registry_bind(registry, name,
2390 &zwp_fullscreen_shell_v1_interface, 1);
2391 } else if (strcmp(interface, "wl_seat") == 0) {
2392 display_add_seat(b, name, version);
2393 } else if (strcmp(interface, "wl_output") == 0) {
2394 wayland_backend_register_output(b, name);
2395 } else if (strcmp(interface, "wl_shm") == 0) {
2397 wl_registry_bind(registry, name, &wl_shm_interface, 1);
2402 registry_handle_global_remove(void *data, struct wl_registry *registry,
2405 struct wayland_backend *b = data;
2406 struct wayland_parent_output *output, *next;
2408 wl_list_for_each_safe(output, next, &b->parent.output_list, link)
2409 if (output->id == name)
2410 wayland_parent_output_destroy(output);
2413 static const struct wl_registry_listener registry_listener = {
2414 registry_handle_global,
2415 registry_handle_global_remove
2419 wayland_backend_handle_event(int fd, uint32_t mask, void *data)
2421 struct wayland_backend *b = data;
2424 if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) {
2425 weston_compositor_exit(b->compositor);
2429 if (mask & WL_EVENT_READABLE)
2430 count = wl_display_dispatch(b->parent.wl_display);
2431 if (mask & WL_EVENT_WRITABLE)
2432 wl_display_flush(b->parent.wl_display);
2435 count = wl_display_dispatch_pending(b->parent.wl_display);
2436 wl_display_flush(b->parent.wl_display);
2443 wayland_restore(struct weston_compositor *ec)
2448 wayland_destroy(struct weston_compositor *ec)
2450 struct wayland_backend *b = to_wayland_backend(ec);
2452 wl_event_source_remove(b->parent.wl_source);
2454 weston_compositor_shutdown(ec);
2457 wl_shm_destroy(b->parent.shm);
2459 if (b->parent.xdg_shell)
2460 zxdg_shell_v6_destroy(b->parent.xdg_shell);
2462 if (b->parent.shell)
2463 wl_shell_destroy(b->parent.shell);
2465 if (b->parent.fshell)
2466 zwp_fullscreen_shell_v1_release(b->parent.fshell);
2468 if (b->parent.compositor)
2469 wl_compositor_destroy(b->parent.compositor);
2472 theme_destroy(b->theme);
2474 if (b->frame_device)
2475 cairo_device_destroy(b->frame_device);
2477 wl_cursor_theme_destroy(b->cursor_theme);
2479 wl_registry_destroy(b->parent.registry);
2480 wl_display_flush(b->parent.wl_display);
2481 wl_display_disconnect(b->parent.wl_display);
2486 static const char *left_ptrs[] = {
2494 create_cursor(struct wayland_backend *b,
2495 struct weston_wayland_backend_config *config)
2499 b->cursor_theme = wl_cursor_theme_load(config->cursor_theme,
2500 config->cursor_size,
2502 if (!b->cursor_theme) {
2503 fprintf(stderr, "could not load cursor theme\n");
2508 for (i = 0; !b->cursor && i < ARRAY_LENGTH(left_ptrs); ++i)
2509 b->cursor = wl_cursor_theme_get_cursor(b->cursor_theme,
2512 fprintf(stderr, "could not load left cursor\n");
2518 fullscreen_binding(struct weston_keyboard *keyboard, uint32_t time,
2519 uint32_t key, void *data)
2521 struct wayland_backend *b = data;
2522 struct wayland_input *input = NULL;
2524 wl_list_for_each(input, &b->input_list, link)
2525 if (&input->base == keyboard->seat)
2528 if (!input || !input->output)
2531 if (input->output->frame)
2532 wayland_output_set_fullscreen(input->output, 0, 0, NULL);
2534 wayland_output_set_windowed(input->output);
2536 weston_output_schedule_repaint(&input->output->base);
2539 static struct wayland_backend *
2540 wayland_backend_create(struct weston_compositor *compositor,
2541 struct weston_wayland_backend_config *new_config)
2543 struct wayland_backend *b;
2544 struct wl_event_loop *loop;
2547 b = zalloc(sizeof *b);
2551 b->compositor = compositor;
2552 compositor->backend = &b->base;
2554 if (weston_compositor_set_presentation_clock_software(compositor) < 0)
2555 goto err_compositor;
2557 b->parent.wl_display = wl_display_connect(new_config->display_name);
2558 if (b->parent.wl_display == NULL) {
2559 weston_log("Error: Failed to connect to parent Wayland compositor: %m\n");
2560 weston_log_continue(STAMP_SPACE "display option: %s, WAYLAND_DISPLAY=%s\n",
2561 new_config->display_name ?: "(none)",
2562 getenv("WAYLAND_DISPLAY") ?: "(not set)");
2563 goto err_compositor;
2566 wl_list_init(&b->parent.output_list);
2567 wl_list_init(&b->input_list);
2568 b->parent.registry = wl_display_get_registry(b->parent.wl_display);
2569 wl_registry_add_listener(b->parent.registry, ®istry_listener, b);
2570 wl_display_roundtrip(b->parent.wl_display);
2572 create_cursor(b, new_config);
2575 b->use_pixman = new_config->use_pixman;
2577 b->use_pixman = true;
2579 b->fullscreen = new_config->fullscreen;
2581 if (!b->use_pixman) {
2582 gl_renderer = weston_load_module("gl-renderer.so",
2583 "gl_renderer_interface");
2585 b->use_pixman = true;
2588 if (!b->use_pixman) {
2589 if (gl_renderer->display_create(compositor,
2590 EGL_PLATFORM_WAYLAND_KHR,
2591 b->parent.wl_display,
2593 gl_renderer->alpha_attribs,
2596 weston_log("Failed to initialize the GL renderer; "
2597 "falling back to pixman.\n");
2598 b->use_pixman = true;
2602 if (b->use_pixman) {
2603 if (pixman_renderer_init(compositor) < 0) {
2604 weston_log("Failed to initialize pixman renderer\n");
2609 b->base.destroy = wayland_destroy;
2610 b->base.restore = wayland_restore;
2612 loop = wl_display_get_event_loop(compositor->wl_display);
2614 fd = wl_display_get_fd(b->parent.wl_display);
2615 b->parent.wl_source =
2616 wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
2617 wayland_backend_handle_event, b);
2618 if (b->parent.wl_source == NULL)
2621 wl_event_source_check(b->parent.wl_source);
2623 if (compositor->renderer->import_dmabuf) {
2624 if (linux_dmabuf_setup(compositor) < 0)
2625 weston_log("Error: initializing dmabuf "
2626 "support failed.\n");
2631 wl_display_disconnect(b->parent.wl_display);
2633 weston_compositor_shutdown(compositor);
2639 wayland_backend_destroy(struct wayland_backend *b)
2641 wl_display_disconnect(b->parent.wl_display);
2644 theme_destroy(b->theme);
2645 if (b->frame_device)
2646 cairo_device_destroy(b->frame_device);
2647 wl_cursor_theme_destroy(b->cursor_theme);
2649 weston_compositor_shutdown(b->compositor);
2653 static const struct weston_windowed_output_api windowed_api = {
2654 wayland_output_set_size,
2655 wayland_output_create,
2659 config_init_to_defaults(struct weston_wayland_backend_config *config)
2664 weston_backend_init(struct weston_compositor *compositor,
2665 struct weston_backend_config *config_base)
2667 struct wayland_backend *b;
2668 struct wayland_parent_output *poutput;
2669 struct weston_wayland_backend_config new_config;
2672 if (config_base == NULL ||
2673 config_base->struct_version != WESTON_WAYLAND_BACKEND_CONFIG_VERSION ||
2674 config_base->struct_size > sizeof(struct weston_wayland_backend_config)) {
2675 weston_log("wayland backend config structure is invalid\n");
2679 config_init_to_defaults(&new_config);
2680 memcpy(&new_config, config_base, config_base->struct_size);
2682 b = wayland_backend_create(compositor, &new_config);
2687 if (new_config.sprawl || b->parent.fshell) {
2688 b->sprawl_across_outputs = true;
2689 wl_display_roundtrip(b->parent.wl_display);
2691 wl_list_for_each(poutput, &b->parent.output_list, link)
2692 wayland_output_create_for_parent_output(b, poutput);
2697 if (new_config.fullscreen) {
2698 if (wayland_output_create_fullscreen(b) < 0) {
2699 weston_log("Unable to create a fullscreen output.\n");
2706 ret = weston_plugin_api_register(compositor, WESTON_WINDOWED_OUTPUT_API_NAME,
2707 &windowed_api, sizeof(windowed_api));
2710 weston_log("Failed to register output API.\n");
2711 wayland_backend_destroy(b);
2715 weston_compositor_add_key_binding(compositor, KEY_F,
2716 MODIFIER_CTRL | MODIFIER_ALT,
2717 fullscreen_binding, b);
2721 wayland_backend_destroy(b);