From e257afeb7ea72a035202be02c90490eb3cb7129b Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 12 Jun 2017 22:22:40 -0400 Subject: [PATCH] Establish multi backend support --- backend/CMakeLists.txt | 1 + backend/backend.c | 26 +++++++-- backend/multi/backend.c | 107 ++++++++++++++++++++++++++++++++++++ include/backend/multi.h | 13 +++++ include/wlr/backend/multi.h | 10 ++++ 5 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 backend/multi/backend.c create mode 100644 include/backend/multi.h create mode 100644 include/wlr/backend/multi.h diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt index 5505e417..23914240 100644 --- a/backend/CMakeLists.txt +++ b/backend/CMakeLists.txt @@ -18,6 +18,7 @@ add_library(wlr-backend libinput/events.c libinput/keyboard.c + multi/backend.c backend.c egl.c udev.c diff --git a/backend/backend.c b/backend/backend.c index 03c662c3..02fd7479 100644 --- a/backend/backend.c +++ b/backend/backend.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "backend/libinput.h" #include "backend/udev.h" #include "common/log.h" @@ -46,19 +47,32 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display, wlr_log(L_ERROR, "Failed to start udev"); goto error; } - struct wlr_backend *wlr; - wlr = wlr_libinput_backend_create(display, session, udev); - return wlr; int gpu = wlr_udev_find_gpu(udev, session); if (gpu == -1) { wlr_log(L_ERROR, "Failed to open DRM device"); goto error_udev; } - wlr = wlr_drm_backend_create(display, session, udev, gpu); - if (!wlr) { + struct wlr_backend *multi = wlr_multi_backend_create(); + if (!multi) { goto error_gpu; } - return wlr; + struct wlr_backend *libinput = + wlr_libinput_backend_create(display, session, udev); + if (!libinput) { + goto error_multi; + } + struct wlr_backend *drm = + wlr_drm_backend_create(display, session, udev, gpu); + if (!drm) { + goto error_libinput; + } + wlr_multi_backend_add(multi, libinput); + wlr_multi_backend_add(multi, drm); + return multi; +error_libinput: + wlr_backend_destroy(libinput); +error_multi: + wlr_backend_destroy(multi); error_gpu: close(gpu); error_udev: diff --git a/backend/multi/backend.c b/backend/multi/backend.c new file mode 100644 index 00000000..e3d87ccc --- /dev/null +++ b/backend/multi/backend.c @@ -0,0 +1,107 @@ +#include +#include +#include +#include +#include "backend/multi.h" +#include "common/log.h" + +struct subbackend_state { + struct wlr_backend *backend; + struct wlr_backend *container; + struct wl_listener input_add; + struct wl_listener input_remove; + struct wl_listener output_add; + struct wl_listener output_remove; +}; + +static bool multi_backend_init(struct wlr_backend_state *state) { + for (size_t i = 0; i < state->backends->length; ++i) { + struct subbackend_state *sub = state->backends->items[i]; + if (!wlr_backend_init(sub->backend)) { + wlr_log(L_ERROR, "Failed to initialize backend %zd", i); + return false; + } + } + return true; +} + +static void multi_backend_destroy(struct wlr_backend_state *state) { + for (size_t i = 0; i < state->backends->length; ++i) { + struct subbackend_state *sub = state->backends->items[i]; + wlr_backend_destroy(sub->backend); + free(sub); + } + list_free(state->backends); + free(state); +} + +struct wlr_backend_impl backend_impl = { + .init = multi_backend_init, + .destroy = multi_backend_destroy +}; + +struct wlr_backend *wlr_multi_backend_create() { + struct wlr_backend_state *state = + calloc(1, sizeof(struct wlr_backend_state)); + if (!state) { + wlr_log(L_ERROR, "Backend allocation failed"); + return NULL; + } + state->backends = list_create(); + if (!state->backends) { + free(state); + wlr_log(L_ERROR, "Backend allocation failed"); + return NULL; + } + struct wlr_backend *backend = wlr_backend_create(&backend_impl, state); + state->backend = backend; + return backend; +} + +static void input_add_reemit(struct wl_listener *listener, void *data) { + struct subbackend_state *state = wl_container_of(listener, + state, input_add); + wl_signal_emit(&state->container->events.input_add, data); +} + +static void input_remove_reemit(struct wl_listener *listener, void *data) { + struct subbackend_state *state = wl_container_of(listener, + state, input_remove); + wl_signal_emit(&state->container->events.input_remove, data); +} + +static void output_add_reemit(struct wl_listener *listener, void *data) { + struct subbackend_state *state = wl_container_of(listener, + state, output_add); + wl_signal_emit(&state->container->events.output_add, data); +} + +static void output_remove_reemit(struct wl_listener *listener, void *data) { + struct subbackend_state *state = wl_container_of(listener, + state, output_remove); + wl_signal_emit(&state->container->events.output_remove, data); +} + +void wlr_multi_backend_add(struct wlr_backend *multi, + struct wlr_backend *backend) { + struct subbackend_state *sub = calloc(1, sizeof(struct subbackend_state)); + sub->backend = backend; + sub->container = multi; + + sub->input_add.notify = input_add_reemit; + sub->input_remove.notify = input_remove_reemit; + sub->output_add.notify = output_add_reemit; + sub->output_remove.notify = output_remove_reemit; + + wl_list_init(&sub->input_add.link); + wl_list_init(&sub->input_remove.link); + wl_list_init(&sub->output_add.link); + wl_list_init(&sub->output_remove.link); + + wl_signal_add(&backend->events.input_add, &sub->input_add); + wl_signal_add(&backend->events.input_remove, &sub->input_remove); + wl_signal_add(&backend->events.output_add, &sub->output_add); + wl_signal_add(&backend->events.output_remove, &sub->output_remove); + + list_add(multi->state->backends, sub); +} diff --git a/include/backend/multi.h b/include/backend/multi.h new file mode 100644 index 00000000..5e6930bb --- /dev/null +++ b/include/backend/multi.h @@ -0,0 +1,13 @@ +#ifndef _WLR_MULTI_BACKEND_INTERNAL +#define _WLR_MULTI_BACKEND_INTERNAL + +#include +#include +#include + +struct wlr_backend_state { + struct wlr_backend *backend; + list_t *backends; +}; + +#endif diff --git a/include/wlr/backend/multi.h b/include/wlr/backend/multi.h new file mode 100644 index 00000000..a07ca770 --- /dev/null +++ b/include/wlr/backend/multi.h @@ -0,0 +1,10 @@ +#ifndef _WLR_BACKEND_MULTI_H +#define _WLR_BACKEND_MULTI_H + +#include + +struct wlr_backend *wlr_multi_backend_create(); +void wlr_multi_backend_add(struct wlr_backend *multi, + struct wlr_backend *backend); + +#endif