struct wl_list views;
+ struct wl_listener new_output;
struct wl_listener new_input;
struct wl_listener new_xdg_surface;
};
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);
}
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;
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)
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;
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);
return true;
-err_output:
- ds_swapchain_destroy(output->swapchain);
err_swapchain:
ds_allocator_destroy(output->allocator);
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);
}
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)
{
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,
};
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");
ds_dbg("Wayland output(%p) created", output);
- return &output->base;
+ return output;
err:
ds_output_destroy(&output->base);