From 9b4be5a59506a81175ab2eb9248f4035176df5f0 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 17 Jan 2019 20:13:55 +1000 Subject: Introduce noop backend The noop backend is similar to headless, but it doesn't contain a renderer. It can be used as a place to stash views for when there's no physical outputs connected. --- backend/noop/backend.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ backend/noop/output.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 backend/noop/backend.c create mode 100644 backend/noop/output.c (limited to 'backend/noop') diff --git a/backend/noop/backend.c b/backend/noop/backend.c new file mode 100644 index 00000000..340fce0d --- /dev/null +++ b/backend/noop/backend.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include "backend/noop.h" +#include "util/signal.h" + +struct wlr_noop_backend *noop_backend_from_backend( + struct wlr_backend *wlr_backend) { + assert(wlr_backend_is_noop(wlr_backend)); + return (struct wlr_noop_backend *)wlr_backend; +} + +static bool backend_start(struct wlr_backend *wlr_backend) { + struct wlr_noop_backend *backend = noop_backend_from_backend(wlr_backend); + wlr_log(WLR_INFO, "Starting noop backend"); + + struct wlr_noop_output *output; + wl_list_for_each(output, &backend->outputs, link) { + wlr_output_update_enabled(&output->wlr_output, true); + wlr_signal_emit_safe(&backend->backend.events.new_output, + &output->wlr_output); + } + + backend->started = true; + return true; +} + +static void backend_destroy(struct wlr_backend *wlr_backend) { + struct wlr_noop_backend *backend = noop_backend_from_backend(wlr_backend); + if (!wlr_backend) { + return; + } + + struct wlr_noop_output *output, *output_tmp; + wl_list_for_each_safe(output, output_tmp, &backend->outputs, link) { + wlr_output_destroy(&output->wlr_output); + } + + wlr_signal_emit_safe(&wlr_backend->events.destroy, backend); + + free(backend); +} + +static const struct wlr_backend_impl backend_impl = { + .start = backend_start, + .destroy = backend_destroy, +}; + +struct wlr_backend *wlr_noop_backend_create(struct wl_display *display) { + wlr_log(WLR_INFO, "Creating noop backend"); + + struct wlr_noop_backend *backend = + calloc(1, sizeof(struct wlr_noop_backend)); + if (!backend) { + wlr_log(WLR_ERROR, "Failed to allocate wlr_noop_backend"); + return NULL; + } + wlr_backend_init(&backend->backend, &backend_impl); + backend->display = display; + wl_list_init(&backend->outputs); + + return &backend->backend; +} + +bool wlr_backend_is_noop(struct wlr_backend *backend) { + return backend->impl == &backend_impl; +} diff --git a/backend/noop/output.c b/backend/noop/output.c new file mode 100644 index 00000000..a2595eff --- /dev/null +++ b/backend/noop/output.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include "backend/noop.h" +#include "util/signal.h" + +static struct wlr_noop_output *noop_output_from_output( + struct wlr_output *wlr_output) { + assert(wlr_output_is_noop(wlr_output)); + return (struct wlr_noop_output *)wlr_output; +} + +static void output_transform(struct wlr_output *wlr_output, + enum wl_output_transform transform) { + // empty +} + +static bool output_make_current(struct wlr_output *wlr_output, int *buffer_age) { + return true; +} + +static bool output_swap_buffers(struct wlr_output *wlr_output, + pixman_region32_t *damage) { + return true; +} + +static void output_destroy(struct wlr_output *wlr_output) { + struct wlr_noop_output *output = + noop_output_from_output(wlr_output); + + wl_list_remove(&output->link); + + free(output); +} + +static const struct wlr_output_impl output_impl = { + .transform = output_transform, + .destroy = output_destroy, + .make_current = output_make_current, + .swap_buffers = output_swap_buffers, +}; + +bool wlr_output_is_noop(struct wlr_output *wlr_output) { + return wlr_output->impl == &output_impl; +} + +struct wlr_output *wlr_noop_add_output(struct wlr_backend *wlr_backend) { + struct wlr_noop_backend *backend = noop_backend_from_backend(wlr_backend); + + struct wlr_noop_output *output = calloc(1, sizeof(struct wlr_noop_output)); + if (output == NULL) { + wlr_log(WLR_ERROR, "Failed to allocate wlr_noop_output"); + return NULL; + } + output->backend = backend; + wlr_output_init(&output->wlr_output, &backend->backend, &output_impl, + backend->display); + struct wlr_output *wlr_output = &output->wlr_output; + + strncpy(wlr_output->make, "noop", sizeof(wlr_output->make)); + strncpy(wlr_output->model, "noop", sizeof(wlr_output->model)); + snprintf(wlr_output->name, sizeof(wlr_output->name), "NOOP-%d", + wl_list_length(&backend->outputs) + 1); + + wl_list_insert(&backend->outputs, &output->link); + + if (backend->started) { + wlr_output_update_enabled(wlr_output, true); + wlr_signal_emit_safe(&backend->backend.events.new_output, wlr_output); + } + + return wlr_output; +} -- cgit v1.2.3