From 5648a518059d1849e351ec54ec0b5be7a7285624 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 21 Dec 2017 19:52:10 -0500 Subject: [PATCH] multibackend skeleton --- include/sway/server.h | 23 +++++++++ sway/server.c | 110 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) diff --git a/include/sway/server.h b/include/sway/server.h index 76a054764..b1c951e3c 100644 --- a/include/sway/server.h +++ b/include/sway/server.h @@ -11,12 +11,29 @@ // TODO WLR: make Xwayland optional #include +enum sway_subbackend_type { + SWAY_SUBBACKEND_WAYLAND, + SWAY_SUBBACKEND_X11, + SWAY_SUBBACKEND_DRM, + SWAY_SUBBACKEND_HEADLESS, +}; + +struct sway_subbackend { + char *name; + enum sway_subbackend_type type; + struct wlr_backend *backend; + struct wl_list link; // sway_server::subbackends + + struct wl_listener backend_destroy; +}; + struct sway_server { struct wl_display *wl_display; struct wl_event_loop *wl_event_loop; const char *socket; struct wlr_backend *backend; + struct wl_list subbackends; // sway_server_subbackend::link struct wlr_renderer *renderer; struct wlr_compositor *compositor; @@ -51,4 +68,10 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data); void handle_xwayland_surface(struct wl_listener *listener, void *data); void handle_wl_shell_surface(struct wl_listener *listener, void *data); +struct sway_subbackend *sway_subbackend_create(enum sway_subbackend_type type, + char *name); +void sway_server_add_subbackend(struct sway_server *server, + struct sway_subbackend *subbackend); +void sway_server_remove_subbackend(struct sway_server *server, char *name); + #endif diff --git a/sway/server.c b/sway/server.c index 32c8f03c5..137add7d5 100644 --- a/sway/server.c +++ b/sway/server.c @@ -1,9 +1,11 @@ #define _POSIX_C_SOURCE 200112L +#include #include #include #include #include #include +#include #include #include #include @@ -20,6 +22,7 @@ bool server_init(struct sway_server *server) { server->wl_display = wl_display_create(); server->wl_event_loop = wl_display_get_event_loop(server->wl_display); server->backend = wlr_backend_autocreate(server->wl_display); + wl_list_init(&server->subbackends); server->renderer = wlr_gles2_renderer_create(server->backend); wl_display_init_shm(server->wl_display); @@ -82,3 +85,110 @@ void server_run(struct sway_server *server) { setenv("WAYLAND_DISPLAY", server->socket, true); wl_display_run(server->wl_display); } + +static void sway_subbackend_destroy(struct sway_subbackend *subbackend) { + wl_list_remove(&subbackend->backend_destroy.link); + wl_list_remove(&subbackend->link); + // free(name)? + free(subbackend); +} + +struct sway_subbackend *sway_subbackend_create(enum sway_subbackend_type type, + char *name) { + struct sway_subbackend *subbackend = + calloc(1, sizeof(struct sway_subbackend)); + if (subbackend == NULL) { + sway_log(L_ERROR, "could not allocate subbackend"); + return NULL; + } + + if (name == NULL) { + // TODO: figure out what to call the backend based on what the backend + // type is and how many other backends are configured of that type + // (-). + } else { + subbackend->name = name; + } + + subbackend->type = type; + wl_list_init(&subbackend->link); + + return subbackend; +} + +static void handle_subbackend_backend_destroy(struct wl_listener *listener, + void *data) { + struct sway_subbackend *subbackend = + wl_container_of(listener, subbackend, backend_destroy); + sway_subbackend_destroy(subbackend); +} + +static struct wlr_backend *wayland_backend_create() { + sway_log(L_DEBUG, "TODO: create wayland backend"); + return NULL; +} + +static struct wlr_backend *x11_backend_create() { + sway_log(L_DEBUG, "TODO: create x11 backend"); + return NULL; +} + +static struct wlr_backend *headless_backend_create() { + sway_log(L_DEBUG, "TODO: create headless backend"); + return NULL; +} + +static struct wlr_backend *drm_backend_create() { + sway_log(L_DEBUG, "TODO: create drm backend"); + return NULL; +} + +void sway_server_add_subbackend(struct sway_server *server, + struct sway_subbackend *subbackend) { + struct wlr_backend *backend = NULL; + + switch (subbackend->type) { + case SWAY_SUBBACKEND_WAYLAND: + backend = wayland_backend_create(); + break; + case SWAY_SUBBACKEND_X11: + backend = x11_backend_create(); + break; + case SWAY_SUBBACKEND_DRM: + backend = drm_backend_create(); + break; + case SWAY_SUBBACKEND_HEADLESS: + backend = headless_backend_create(); + break; + } + + if (backend == NULL) { + sway_log(L_ERROR, "could not create subbackend '%s'", subbackend->name); + sway_subbackend_destroy(subbackend); + return; + } + + wl_list_remove(&subbackend->link); + wl_list_insert(&server->subbackends, &subbackend->link); + + wl_signal_add(&backend->events.destroy, &subbackend->backend_destroy); + subbackend->backend_destroy.notify = handle_subbackend_backend_destroy; + + wlr_multi_backend_add(server->backend, backend); +} + +void sway_server_remove_subbackend(struct sway_server *server, char *name) { + struct sway_subbackend *subbackend = NULL; + wl_list_for_each(subbackend, &server->subbackends, link) { + if (strcasecmp(subbackend->name, name) == 0) { + break; + } + } + + if (!subbackend) { + sway_log(L_DEBUG, "could not find subbackend named '%s'", name); + return; + } + + wlr_backend_destroy(subbackend->backend); +}