diff --git a/backend/backend.c b/backend/backend.c index c6afe14b9..dbaac9494 100644 --- a/backend/backend.c +++ b/backend/backend.c @@ -203,7 +203,7 @@ static struct wlr_backend *attempt_headless_backend( } static bool attempt_drm_backend(struct wl_display *display, - struct wlr_backend *backend, struct wlr_session *session) { + struct wlr_multi_backend *multi, struct wlr_session *session) { #if WLR_HAS_DRM_BACKEND struct wlr_device *gpus[8]; ssize_t num_gpus = wlr_session_find_gpus(session, 8, gpus); @@ -232,7 +232,7 @@ static bool attempt_drm_backend(struct wl_display *display, primary_drm = drm; } - wlr_multi_backend_add(backend, drm); + wlr_multi_backend_add(multi, drm); } if (!primary_drm) { wlr_log(WLR_ERROR, "Could not successfully create backend on any GPU"); @@ -240,7 +240,7 @@ static bool attempt_drm_backend(struct wl_display *display, } if (getenv("WLR_DRM_DEVICES") == NULL) { - drm_backend_monitor_create(backend, primary_drm, session); + drm_backend_monitor_create(multi, primary_drm, session); } return true; @@ -261,7 +261,7 @@ static struct wlr_backend *attempt_libinput_backend(struct wl_display *display, } static bool attempt_backend_by_name(struct wl_display *display, - struct wlr_backend *multi, char *name, + struct wlr_multi_backend *multi, char *name, struct wlr_session **session_ptr) { struct wlr_backend *backend = NULL; if (strcmp(name, "wayland") == 0) { @@ -304,7 +304,7 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display, } struct wlr_session *session = NULL; - struct wlr_backend *multi = wlr_multi_backend_create(display); + struct wlr_multi_backend *multi = wlr_multi_backend_create(display); if (!multi) { wlr_log(WLR_ERROR, "could not allocate multibackend"); return NULL; @@ -387,10 +387,10 @@ success: if (session_ptr != NULL) { *session_ptr = session; } - return multi; + return wlr_multi_backend_base(multi); error: - wlr_backend_destroy(multi); + wlr_backend_destroy(wlr_multi_backend_base(multi)); #if WLR_HAS_SESSION wlr_session_destroy(session); #endif diff --git a/backend/drm/monitor.c b/backend/drm/monitor.c index 539e7925f..295a33777 100644 --- a/backend/drm/monitor.c +++ b/backend/drm/monitor.c @@ -64,7 +64,7 @@ static void handle_multi_destroy(struct wl_listener *listener, void *data) { } struct wlr_drm_backend_monitor *drm_backend_monitor_create( - struct wlr_backend *multi, + struct wlr_multi_backend *multi, struct wlr_backend *primary_drm, struct wlr_session *session) { struct wlr_drm_backend_monitor *monitor = @@ -87,8 +87,9 @@ struct wlr_drm_backend_monitor *drm_backend_monitor_create( monitor->primary_drm_destroy.notify = handle_primary_drm_destroy; wl_signal_add(&primary_drm->events.destroy, &monitor->primary_drm_destroy); + struct wlr_backend *multi_base = wlr_multi_backend_base(multi); monitor->multi_destroy.notify = handle_multi_destroy; - wl_signal_add(&multi->events.destroy, &monitor->multi_destroy); + wl_signal_add(&multi_base->events.destroy, &monitor->multi_destroy); return monitor; } diff --git a/backend/multi/backend.c b/backend/multi/backend.c index 49792ff90..eddaf686f 100644 --- a/backend/multi/backend.c +++ b/backend/multi/backend.c @@ -18,10 +18,10 @@ struct subbackend_state { struct wl_list link; }; -static struct wlr_multi_backend *multi_backend_from_backend( - struct wlr_backend *wlr_backend) { - assert(wlr_backend_is_multi(wlr_backend)); - return (struct wlr_multi_backend *)wlr_backend; +static struct wlr_multi_backend *multi_backend_from_backend(struct wlr_backend *backend) { + struct wlr_multi_backend *multi = wlr_multi_backend_try_from(backend); + assert(multi != NULL); + return multi; } static bool multi_backend_start(struct wlr_backend *wlr_backend) { @@ -125,7 +125,7 @@ static void handle_display_destroy(struct wl_listener *listener, void *data) { multi_backend_destroy((struct wlr_backend*)backend); } -struct wlr_backend *wlr_multi_backend_create(struct wl_display *display) { +struct wlr_multi_backend *wlr_multi_backend_create(struct wl_display *display) { struct wlr_multi_backend *backend = calloc(1, sizeof(struct wlr_multi_backend)); if (!backend) { @@ -142,11 +142,19 @@ struct wlr_backend *wlr_multi_backend_create(struct wl_display *display) { backend->display_destroy.notify = handle_display_destroy; wl_display_add_destroy_listener(display, &backend->display_destroy); - return &backend->backend; + return backend; } -bool wlr_backend_is_multi(struct wlr_backend *b) { - return b->impl == &backend_impl; +struct wlr_multi_backend *wlr_multi_backend_try_from(struct wlr_backend *backend) { + if (backend->impl != &backend_impl) { + return NULL; + } + struct wlr_multi_backend *multi = wl_container_of(backend, multi, backend); + return multi; +} + +struct wlr_backend *wlr_multi_backend_base(struct wlr_multi_backend *backend) { + return &backend->backend; } static void new_input_reemit(struct wl_listener *listener, void *data) { @@ -178,12 +186,9 @@ static struct subbackend_state *multi_backend_get_subbackend(struct wlr_multi_ba return NULL; } -bool wlr_multi_backend_add(struct wlr_backend *_multi, - struct wlr_backend *backend) { - assert(_multi && backend); - assert(_multi != backend); - - struct wlr_multi_backend *multi = multi_backend_from_backend(_multi); +bool wlr_multi_backend_add(struct wlr_multi_backend *multi, struct wlr_backend *backend) { + assert(multi && backend); + assert(&multi->backend != backend); if (multi_backend_get_subbackend(multi, backend)) { // already added @@ -213,29 +218,20 @@ bool wlr_multi_backend_add(struct wlr_backend *_multi, return true; } -void wlr_multi_backend_remove(struct wlr_backend *_multi, - struct wlr_backend *backend) { - struct wlr_multi_backend *multi = multi_backend_from_backend(_multi); - - struct subbackend_state *sub = - multi_backend_get_subbackend(multi, backend); - +void wlr_multi_backend_remove(struct wlr_multi_backend *multi, struct wlr_backend *backend) { + struct subbackend_state *sub = multi_backend_get_subbackend(multi, backend); if (sub) { wl_signal_emit_mutable(&multi->events.backend_remove, backend); subbackend_state_destroy(sub); } } -bool wlr_multi_is_empty(struct wlr_backend *_backend) { - assert(wlr_backend_is_multi(_backend)); - struct wlr_multi_backend *backend = (struct wlr_multi_backend *)_backend; +bool wlr_multi_backend_is_empty(struct wlr_multi_backend *backend) { return wl_list_length(&backend->backends) < 1; } -void wlr_multi_for_each_backend(struct wlr_backend *_backend, +void wlr_multi_backend_for_each(struct wlr_multi_backend *backend, void (*callback)(struct wlr_backend *backend, void *data), void *data) { - assert(wlr_backend_is_multi(_backend)); - struct wlr_multi_backend *backend = (struct wlr_multi_backend *)_backend; struct subbackend_state *sub; wl_list_for_each(sub, &backend->backends, link) { callback(sub->backend, data); diff --git a/include/backend/drm/monitor.h b/include/backend/drm/monitor.h index 518171932..ff72b1d1b 100644 --- a/include/backend/drm/monitor.h +++ b/include/backend/drm/monitor.h @@ -7,7 +7,7 @@ * Helper to create new DRM sub-backends on GPU hotplug. */ struct wlr_drm_backend_monitor { - struct wlr_backend *multi; + struct wlr_multi_backend *multi; struct wlr_backend *primary_drm; struct wlr_session *session; @@ -18,7 +18,7 @@ struct wlr_drm_backend_monitor { }; struct wlr_drm_backend_monitor *drm_backend_monitor_create( - struct wlr_backend *multi, struct wlr_backend *primary_drm, + struct wlr_multi_backend *multi, struct wlr_backend *primary_drm, struct wlr_session *session); #endif diff --git a/include/wlr/backend/multi.h b/include/wlr/backend/multi.h index 09000ac2f..8e60f0efd 100644 --- a/include/wlr/backend/multi.h +++ b/include/wlr/backend/multi.h @@ -11,25 +11,31 @@ #include +struct wlr_multi_backend; + /** * Creates a multi-backend. Multi-backends wrap an arbitrary number of backends * and aggregate their new_output/new_input signals. */ -struct wlr_backend *wlr_multi_backend_create(struct wl_display *display); +struct wlr_multi_backend *wlr_multi_backend_create(struct wl_display *display); + /** * Adds the given backend to the multi backend. This should be done before the * new backend is started. */ -bool wlr_multi_backend_add(struct wlr_backend *multi, +bool wlr_multi_backend_add(struct wlr_multi_backend *multi, struct wlr_backend *backend); -void wlr_multi_backend_remove(struct wlr_backend *multi, +void wlr_multi_backend_remove(struct wlr_multi_backend *multi, struct wlr_backend *backend); -bool wlr_backend_is_multi(struct wlr_backend *backend); -bool wlr_multi_is_empty(struct wlr_backend *backend); +bool wlr_multi_backend_is_empty(struct wlr_multi_backend *backend); -void wlr_multi_for_each_backend(struct wlr_backend *backend, +void wlr_multi_backend_for_each(struct wlr_multi_backend *backend, void (*callback)(struct wlr_backend *backend, void *data), void *data); +struct wlr_multi_backend *wlr_multi_backend_try_from(struct wlr_backend *backend); + +struct wlr_backend *wlr_multi_backend_base(struct wlr_multi_backend *backend); + #endif diff --git a/types/wlr_drm_lease_v1.c b/types/wlr_drm_lease_v1.c index 4ac59e187..c634b6751 100644 --- a/types/wlr_drm_lease_v1.c +++ b/types/wlr_drm_lease_v1.c @@ -704,9 +704,10 @@ struct wlr_drm_lease_v1_manager *wlr_drm_lease_v1_manager_create( wl_list_init(&manager->devices); manager->display = display; - if (wlr_backend_is_multi(backend)) { + struct wlr_multi_backend *multi = wlr_multi_backend_try_from(backend); + if (multi != NULL) { /* TODO: handle backends added after the manager is created */ - wlr_multi_for_each_backend(backend, multi_backend_cb, manager); + wlr_multi_backend_for_each(multi, multi_backend_cb, manager); } else if (wlr_backend_is_drm(backend)) { drm_lease_device_v1_create(manager, backend); }