diff --git a/include/wlr/types/wlr_mirror.h b/include/wlr/types/wlr_mirror.h index d338b515d..28387b104 100644 --- a/include/wlr/types/wlr_mirror.h +++ b/include/wlr/types/wlr_mirror.h @@ -11,6 +11,7 @@ #include #include +#include #include /** @@ -119,5 +120,10 @@ void wlr_mirror_request_blank(struct wlr_mirror *mirror); void wlr_mirror_request_box(struct wlr_mirror *mirror, struct wlr_output *output_src, struct wlr_box box); +/** + * Output is in use as a dst by another mirror session. + */ +bool wlr_mirror_v1_output_is_dst(struct wlr_output *output); + #endif diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index ce9033444..791023d2e 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -151,9 +151,6 @@ struct wlr_output { // Commit sequence number. Incremented on each commit, may overflow. uint32_t commit_seq; - // dst for an active wlr_mirror session - bool mirror_dst; - struct { // Request to render a frame struct wl_signal frame; diff --git a/include/wlr/util/addon.h b/include/wlr/util/addon.h index 382252ae2..c777f623a 100644 --- a/include/wlr/util/addon.h +++ b/include/wlr/util/addon.h @@ -40,4 +40,7 @@ void wlr_addon_finish(struct wlr_addon *addon); struct wlr_addon *wlr_addon_find(struct wlr_addon_set *set, const void *owner, const struct wlr_addon_interface *impl); +void wlr_addon_find_all(struct wl_array *all, struct wlr_addon_set *set, + const struct wlr_addon_interface *impl); + #endif diff --git a/types/wlr_mirror.c b/types/wlr_mirror.c index f628c138b..599b1be16 100644 --- a/types/wlr_mirror.c +++ b/types/wlr_mirror.c @@ -41,6 +41,8 @@ struct wlr_mirror_state { struct wlr_mirror_params params; + struct wlr_addon output_dst_addon; + struct wlr_output *output_src; // mutable struct wlr_output *output_dst; @@ -406,6 +408,23 @@ static void output_dst_handle_destroy(struct wl_listener *listener, void *data) * END wlr_mirror handler functions */ +/** + * BEGIN addons + */ + +static void output_dst_addon_handle_destroy(struct wlr_addon *addon) { + // wlr_mirror_v1_destroy finishes addon, following output_dst_handle_destroy +} + +static const struct wlr_addon_interface output_dst_addon_impl = { + .name = "wlr_mirror_output_dst", + .destroy = output_dst_addon_handle_destroy, +}; + +/** + * END addons + */ + /** * BEGIN public functions */ @@ -415,7 +434,7 @@ struct wlr_mirror *wlr_mirror_create(struct wlr_mirror_params *params) { wlr_log(WLR_ERROR, "Mirror dst '%s' not enabled", params->output_dst->name); return NULL; } - if (params->output_dst->mirror_dst) { + if (wlr_mirror_v1_output_is_dst(params->output_dst)) { wlr_log(WLR_ERROR, "Mirror dst '%s' in use by another mirror session", params->output_dst->name); return NULL; @@ -487,7 +506,8 @@ struct wlr_mirror *wlr_mirror_create(struct wlr_mirror_params *params) { state->needs_blank = true; schedule_frame_dst(state); - state->output_dst->mirror_dst = true; + wlr_addon_init(&state->output_dst_addon, &state->output_dst->addons, mirror, + &output_dst_addon_impl); return mirror; } @@ -532,7 +552,7 @@ void wlr_mirror_destroy(struct wlr_mirror *mirror) { } // the compositor may reclaim dst - state->output_dst->mirror_dst = false; + wlr_addon_finish(&state->output_dst_addon); // end the user's mirror "session" wlr_signal_emit_safe(&mirror->events.destroy, mirror); @@ -584,6 +604,14 @@ void wlr_mirror_request_box(struct wlr_mirror *mirror, state->stats.requested_boxes++; } +bool wlr_mirror_v1_output_is_dst(struct wlr_output *output) { + struct wl_array addons; + wlr_addon_find_all(&addons, &output->addons, &output_dst_addon_impl); + bool is_dst = addons.size > 0; + wl_array_release(&addons); + return is_dst; +} + /** * END public functions */ diff --git a/util/addon.c b/util/addon.c index d9e13978d..ea7d89e4f 100644 --- a/util/addon.c +++ b/util/addon.c @@ -45,3 +45,16 @@ struct wlr_addon *wlr_addon_find(struct wlr_addon_set *set, const void *owner, } return NULL; } + +void wlr_addon_find_all(struct wl_array *all, struct wlr_addon_set *set, + const struct wlr_addon_interface *impl) { + wl_array_init(all); + struct wlr_addon *addon; + wl_list_for_each(addon, &set->addons, link) { + if (addon->impl == impl) { + struct wlr_addon **addon_ptr = wl_array_add(all, sizeof(addon_ptr)); + *addon_ptr = addon; + } + } +} +