From 3fd5f4ce0c7913b016383817ded5abb95e219c4c Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Fri, 22 Apr 2022 09:17:57 +0900 Subject: [PATCH] backend/wayland: Implement start() interface of ds_backend The wayland backend defers creating new outputs until a user calls ds_backend_start() even though a user requests creation of output before ds_backend_start(). The wayland backend now emits a signal of new_output if a user calls ds_backend_start(), which is for the behavior of ds_backend_start() to be consistent regardless of the actual running backend. Change-Id: If1748c7f591409c31b91438ba4ec561f7897e3fc --- src/examples/tinyds.c | 35 ++++++++++++++++++++++------------- src/libds/backend/wayland/backend.c | 17 ++++++++++++++++- src/libds/backend/wayland/backend.h | 4 ++++ src/libds/backend/wayland/output.c | 21 ++++++++++++++++++++- 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/examples/tinyds.c b/src/examples/tinyds.c index 1c5ca4f..fcaabaf 100644 --- a/src/examples/tinyds.c +++ b/src/examples/tinyds.c @@ -89,6 +89,7 @@ struct tinyds_server struct wl_list views; + struct wl_listener new_output; struct wl_listener new_input; struct wl_listener new_xdg_surface; }; @@ -115,7 +116,8 @@ static void server_fini(struct tinyds_server *server); static void server_add_view(struct tinyds_server *server, struct ds_xdg_surface *xdg_surface); static bool output_init(struct tinyds_output *output, - struct tinyds_server *server, int width, int height); + struct tinyds_server *server, struct ds_output *ds_output, + int width, int height); static void output_fini(struct tinyds_output *output); static void output_damage(struct tinyds_output *output); static void output_redraw(struct tinyds_output *output); @@ -167,6 +169,18 @@ create_wl_backend(struct wl_display *display) } static void +server_handle_new_output(struct wl_listener *listener, void *data) +{ + struct tinyds_server *server; + struct ds_output *ds_output = data; + + server = wl_container_of(listener, server, new_output); + + assert(output_init(&server->output, server, ds_output, + OUTPUT_WIDTH, OUTPUT_HEIGHT) == true); +} + +static void keyboard_handle_device_destroy(struct wl_listener *listener, void *data) { struct tinyds_keyboard *kbd; @@ -500,11 +514,13 @@ server_init(struct tinyds_server *server, struct wl_display *display) if (!server->backend) return false; + ds_wl_backend_create_output(server->backend); + server->new_input.notify = server_handle_new_input; ds_backend_add_new_input_listener(server->backend, &server->new_input); - if (!output_init(&server->output, server, OUTPUT_WIDTH, OUTPUT_HEIGHT)) - goto err; + server->new_output.notify = server_handle_new_output; + ds_backend_add_new_output_listener(server->backend, &server->new_output); server->compositor = ds_compositor_create(display); if (!server->compositor) @@ -564,9 +580,10 @@ output_handle_frame(struct wl_listener *listener, void *data TINYDS_UNUSED) static bool output_init(struct tinyds_output *output, struct tinyds_server *server, - int width, int height) + struct ds_output *ds_output, int width, int height) { output->server = server; + output->ds_output = ds_output; output->width = width; output->height = height; output->drawable = true; @@ -580,11 +597,6 @@ output_init(struct tinyds_output *output, struct tinyds_server *server, if (!output->swapchain) goto err_swapchain; - output->ds_output = - ds_wl_backend_create_output(server->backend); - if (!output->ds_output) - goto err_output; - output->output_destroy.notify = output_handle_destroy; ds_output_add_destroy_listener(output->ds_output, &output->output_destroy); @@ -593,8 +605,6 @@ output_init(struct tinyds_output *output, struct tinyds_server *server, return true; -err_output: - ds_swapchain_destroy(output->swapchain); err_swapchain: ds_allocator_destroy(output->allocator); @@ -604,8 +614,7 @@ err_swapchain: static void output_fini(struct tinyds_output *output) { - if (output->ds_output) - ds_output_destroy(output->ds_output); + ds_output_destroy(output->ds_output); ds_swapchain_destroy(output->swapchain); ds_allocator_destroy(output->allocator); } diff --git a/src/libds/backend/wayland/backend.c b/src/libds/backend/wayland/backend.c index 3b5d6ab..5719e09 100644 --- a/src/libds/backend/wayland/backend.c +++ b/src/libds/backend/wayland/backend.c @@ -81,6 +81,21 @@ wl_backend_from_backend(struct ds_backend *backend) return (struct ds_wl_backend *)backend; } +static bool +wl_backend_iface_start(struct ds_backend *ds_backend) +{ + struct ds_wl_backend *backend; + + backend = wl_backend_from_backend(ds_backend); + + ds_inf("Starting wayland backend"); + + for (size_t i = 0; i < backend->requested_outputs; i++) + create_wl_output(backend); + + return true; +} + static void wl_backend_destroy(struct ds_wl_backend *backend) { @@ -125,7 +140,7 @@ wl_backend_iface_destroy(struct ds_backend *backend) static const struct ds_backend_interface wl_backend_interface = { - .start = NULL, + .start = wl_backend_iface_start, .destroy = wl_backend_iface_destroy, .get_drm_fd = NULL, }; diff --git a/src/libds/backend/wayland/backend.h b/src/libds/backend/wayland/backend.h index 804fa22..12c8a27 100644 --- a/src/libds/backend/wayland/backend.h +++ b/src/libds/backend/wayland/backend.h @@ -32,6 +32,8 @@ struct ds_wl_backend struct wl_event_source *server_event_source; struct ds_wl_backend_server server; + + size_t requested_outputs; }; struct ds_wl_buffer @@ -122,6 +124,8 @@ struct ds_wl_touch struct ds_wl_backend * wl_backend_from_backend(struct ds_backend *backend); +struct ds_wl_output *create_wl_output(struct ds_wl_backend *backend); + void destroy_wl_buffer(struct ds_wl_buffer *buffer); diff --git a/src/libds/backend/wayland/output.c b/src/libds/backend/wayland/output.c index 36ea5f7..c57820f 100644 --- a/src/libds/backend/wayland/output.c +++ b/src/libds/backend/wayland/output.c @@ -23,6 +23,25 @@ ds_wl_backend_create_output(struct ds_backend *ds_backend) backend = wl_backend_from_backend(ds_backend); + if (!ds_backend->started) { + backend->requested_outputs++; + return NULL; + } + + output = create_wl_output(backend); + if (!output) { + ds_err("Could not create ds_wl_output"); + return NULL; + } + + return &output->base; +} + +struct ds_wl_output * +create_wl_output(struct ds_wl_backend *backend) +{ + struct ds_wl_output *output; + output = calloc(1, sizeof *output); if (!output) { ds_log_errno(DS_ERR, "Could not allocate ds_wl_output"); @@ -72,7 +91,7 @@ ds_wl_backend_create_output(struct ds_backend *ds_backend) ds_dbg("Wayland output(%p) created", output); - return &output->base; + return output; err: ds_output_destroy(&output->base); -- 2.7.4