From 7d0290bae7be060e8cf51acd34d9e1f0efbbc339 Mon Sep 17 00:00:00 2001 From: Simon Zeni Date: Fri, 13 Jun 2025 17:05:13 -0400 Subject: [PATCH 1/4] sway/config: add allow_drm_leasing config --- include/sway/config.h | 1 + include/sway/output.h | 1 + sway/config/output.c | 12 ++++++++++-- sway/ipc-json.c | 2 ++ sway/sway-output.5.scd | 5 +++++ 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/sway/config.h b/include/sway/config.h index 3c380933..544fdfd5 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -291,6 +291,7 @@ struct output_config { bool set_color_transform; struct wlr_color_transform *color_transform; int allow_tearing; + int allow_drm_leasing; int hdr; char *background; diff --git a/include/sway/output.h b/include/sway/output.h index 787527ee..4d82f9ec 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -70,6 +70,7 @@ struct sway_output { struct wl_event_source *repaint_timer; bool allow_tearing; + bool allow_drm_leasing; bool hdr; }; diff --git a/sway/config/output.c b/sway/config/output.c index ed8147b8..5b91124d 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -79,6 +79,7 @@ struct output_config *new_output_config(const char *name) { oc->color_transform = NULL; oc->power = -1; oc->allow_tearing = -1; + oc->allow_drm_leasing = -1; oc->hdr = -1; return oc; } @@ -155,6 +156,9 @@ static void supersede_output_config(struct output_config *dst, struct output_con if (src->allow_tearing != -1) { dst->allow_tearing = -1; } + if (src->allow_drm_leasing != -1) { + dst->allow_drm_leasing = -1; + } if (src->hdr != -1) { dst->hdr = -1; } @@ -233,6 +237,9 @@ static void merge_output_config(struct output_config *dst, struct output_config if (src->allow_tearing != -1) { dst->allow_tearing = src->allow_tearing; } + if (src->allow_drm_leasing != -1) { + dst->allow_drm_leasing = src->allow_drm_leasing; + } if (src->hdr != -1) { dst->hdr = src->hdr; } @@ -278,11 +285,11 @@ void store_output_config(struct output_config *oc) { sway_log(SWAY_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz " "position %d,%d scale %f subpixel %s transform %d) (bg %s %s) (power %d) " - "(max render time: %d) (allow tearing: %d) (hdr: %d)", + "(max render time: %d) (allow tearing: %d) (allow drm leasing: %d) (hdr: %d)", oc->name, oc->enabled, oc->width, oc->height, oc->refresh_rate, oc->x, oc->y, oc->scale, sway_wl_output_subpixel_to_string(oc->subpixel), oc->transform, oc->background, oc->background_option, oc->power, - oc->max_render_time, oc->allow_tearing, oc->hdr); + oc->max_render_time, oc->allow_tearing, oc->allow_drm_leasing, oc->hdr); // If the configuration was not merged into an existing configuration, add // it to the list. Otherwise we're done with it and can free it. @@ -622,6 +629,7 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output output->max_render_time = oc && oc->max_render_time > 0 ? oc->max_render_time : 0; output->allow_tearing = oc && oc->allow_tearing > 0; + output->allow_drm_leasing = oc && oc->allow_drm_leasing > 0; output->hdr = applied->image_description != NULL; return true; diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 3b69ad38..ca960a59 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -409,6 +409,8 @@ static void ipc_json_describe_enabled_output(struct sway_output *output, json_object_object_add(object, "max_render_time", json_object_new_int(output->max_render_time)); json_object_object_add(object, "allow_tearing", json_object_new_boolean(output->allow_tearing)); + json_object_object_add(object, "allow_drm_leasing", + json_object_new_boolean(output->allow_drm_leasing)); json_object_object_add(object, "hdr", json_object_new_boolean(output->hdr)); } diff --git a/sway/sway-output.5.scd b/sway/sway-output.5.scd index cc48589c..000256b0 100644 --- a/sway/sway-output.5.scd +++ b/sway/sway-output.5.scd @@ -210,6 +210,11 @@ must be separated by one space. For example: This setting only has effect when a window is fullscreen on the output. +*output* allow_drm_leasing yes|no + Allows or disallows leasing a DRM output. The DRM lease interface must be + active when calling this command. Outputs offered for leasing will be + disabled when leased by a client. + *output* hdr on|off|toggle Enables or disables HDR (High Dynamic Range). HDR enables a larger color gamut and brightness range. HDR uses the BT2020 primaries and the PQ From 3f3323c47d5aae265b1c6a35da97be6e8f942bdf Mon Sep 17 00:00:00 2001 From: Simon Zeni Date: Fri, 13 Jun 2025 17:06:37 -0400 Subject: [PATCH 2/4] swaymsg: print allow_drm_leasing config --- swaymsg/main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/swaymsg/main.c b/swaymsg/main.c index d58f29e2..84ec62b5 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c @@ -189,7 +189,7 @@ static void pretty_print_output(json_object *o) { json_object_object_get_ex(o, "current_workspace", &ws); json_object_object_get_ex(o, "non_desktop", &non_desktop); json_object *make, *model, *serial, *scale, *scale_filter, *subpixel, - *transform, *max_render_time, *adaptive_sync_status, *allow_tearing, + *transform, *max_render_time, *adaptive_sync_status, *allow_tearing, *allow_drm_leasing, *hdr; json_object_object_get_ex(o, "make", &make); json_object_object_get_ex(o, "model", &model); @@ -201,6 +201,7 @@ static void pretty_print_output(json_object *o) { json_object_object_get_ex(o, "max_render_time", &max_render_time); json_object_object_get_ex(o, "adaptive_sync_status", &adaptive_sync_status); json_object_object_get_ex(o, "allow_tearing", &allow_tearing); + json_object_object_get_ex(o, "allow_drm_leasing", &allow_drm_leasing); json_object_object_get_ex(o, "hdr", &hdr); json_object *x, *y; json_object_object_get_ex(rect, "x", &x); @@ -265,6 +266,9 @@ static void pretty_print_output(json_object *o) { printf(" Allow tearing: %s\n", json_object_get_boolean(allow_tearing) ? "yes" : "no"); + printf(" Allow DRM leasing: %s\n", + json_object_get_boolean(allow_drm_leasing) ? "yes" : "no"); + const char *hdr_str = "unsupported"; if (json_object_get_boolean(features_hdr)) { hdr_str = json_object_get_boolean(hdr) ? "on" : "off"; From 47370748a0821d02e61aa6bcc5aea588c1eaa7b0 Mon Sep 17 00:00:00 2001 From: Simon Zeni Date: Fri, 13 Jun 2025 17:07:16 -0400 Subject: [PATCH 3/4] sway/desktop: offer new output with allow_drm_leasing for lease --- sway/desktop/output.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 12dc9cc7..c7631e3f 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -597,6 +597,16 @@ void handle_new_output(struct wl_listener *listener, void *data) { sway_session_lock_add_output(server->session_lock.lock, output); } + struct output_config *oc = find_output_config(output); + if (oc && oc->allow_drm_leasing > 0) { +#if WLR_HAS_DRM_BACKEND + if (server->drm_lease_manager) { + wlr_drm_lease_v1_manager_offer_output(server->drm_lease_manager, + wlr_output); + } +#endif + } + request_modeset(); } From 129a5a0d7c2692aaa456acdf16ed762d219b34ba Mon Sep 17 00:00:00 2001 From: Simon Zeni Date: Fri, 13 Jun 2025 17:07:34 -0400 Subject: [PATCH 4/4] sway/command: add allow_drm_leasing --- include/sway/commands.h | 1 + sway/commands/output.c | 1 + sway/commands/output/allow_drm_leasing.c | 60 ++++++++++++++++++++++++ sway/meson.build | 1 + 4 files changed, 63 insertions(+) create mode 100644 sway/commands/output/allow_drm_leasing.c diff --git a/include/sway/commands.h b/include/sway/commands.h index 389c382e..9c2c9142 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -284,6 +284,7 @@ sway_cmd input_cmd_xkb_switch_layout; sway_cmd input_cmd_xkb_variant; sway_cmd output_cmd_adaptive_sync; +sway_cmd output_cmd_allow_drm_leasing; sway_cmd output_cmd_allow_tearing; sway_cmd output_cmd_background; sway_cmd output_cmd_color_profile; diff --git a/sway/commands/output.c b/sway/commands/output.c index afff23f6..f02e0dd5 100644 --- a/sway/commands/output.c +++ b/sway/commands/output.c @@ -8,6 +8,7 @@ // must be in order for the bsearch static const struct cmd_handler output_handlers[] = { { "adaptive_sync", output_cmd_adaptive_sync }, + { "allow_drm_leasing", output_cmd_allow_drm_leasing }, { "allow_tearing", output_cmd_allow_tearing }, { "background", output_cmd_background }, { "bg", output_cmd_background }, diff --git a/sway/commands/output/allow_drm_leasing.c b/sway/commands/output/allow_drm_leasing.c new file mode 100644 index 00000000..01269e03 --- /dev/null +++ b/sway/commands/output/allow_drm_leasing.c @@ -0,0 +1,60 @@ +#include "sway/commands.h" +#include "sway/output.h" +#include "sway/server.h" +#include "log.h" +#include "util.h" + +#if WLR_HAS_DRM_BACKEND +#include +#include +#endif + +struct cmd_results *output_cmd_allow_drm_leasing(int argc, char **argv) { + if (!server.drm_lease_manager) { + return cmd_results_new(CMD_FAILURE, + "DRM lease manager interface not available"); + } + + if (!config->handler_context.output_config) { + return cmd_results_new(CMD_FAILURE, "Missing output config"); + } + + if (argc == 0) { + return cmd_results_new(CMD_INVALID, "Missing allow_leasing argument"); + } + + const char *oc_name = config->handler_context.output_config->name; + if (strcmp(oc_name, "*") == 0) { + return cmd_results_new(CMD_INVALID, + "Cannot apply leasing to all outputs"); + } + + struct sway_output *sway_output = all_output_by_name_or_id(oc_name); + + if (parse_boolean(argv[0], + (config->handler_context.output_config->allow_drm_leasing == 1))) { + config->handler_context.output_config->allow_drm_leasing = 1; + +#if WLR_HAS_DRM_BACKEND + if (sway_output) { + sway_log(SWAY_DEBUG, "Offering output %s for leasing", oc_name); + wlr_drm_lease_v1_manager_offer_output(server.drm_lease_manager, + sway_output->wlr_output); + } +#endif + } else { + config->handler_context.output_config->allow_drm_leasing = 0; + +#if WLR_HAS_DRM_BACKEND + if (sway_output) { + sway_log(SWAY_DEBUG, "Withdrawing output %s from leasing", oc_name); + wlr_drm_lease_v1_manager_withdraw_output(server.drm_lease_manager, + sway_output->wlr_output); + } +#endif + } + + config->handler_context.leftovers.argc = argc - 1; + config->handler_context.leftovers.argv = argv + 1; + return NULL; +} diff --git a/sway/meson.build b/sway/meson.build index cb03a4d2..1dc44d32 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -190,6 +190,7 @@ sway_sources = files( 'commands/input/xkb_variant.c', 'commands/output/adaptive_sync.c', + 'commands/output/allow_drm_leasing.c', 'commands/output/allow_tearing.c', 'commands/output/background.c', 'commands/output/disable.c',