From c050f2484c946bcf259a778d07d5ec49a4f663e3 Mon Sep 17 00:00:00 2001 From: Troye Stonich Date: Mon, 9 Feb 2026 19:06:54 -0500 Subject: [PATCH] Implement power management --- cage.c | 11 +++++++++++ meson.build | 4 ++++ output.c | 28 ++++++++++++++++++++++++++++ output.h | 1 + server.h | 3 +++ 5 files changed, 47 insertions(+) diff --git a/cage.c b/cage.c index 7c3d89d..f139693 100644 --- a/cage.c +++ b/cage.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -511,6 +512,15 @@ main(int argc, char *argv[]) server.output_manager_test.notify = handle_output_manager_test; wl_signal_add(&server.output_manager_v1->events.test, &server.output_manager_test); + server.output_power_manager_v1 = wlr_output_power_manager_v1_create(server.wl_display); + if (!server.output_power_manager_v1) { + wlr_log(WLR_ERROR, "Unable to create output power manager"); + ret = 1; + goto end; + } + server.output_power_manager_set_mode.notify = handle_output_power_manager_set_mode; + wl_signal_add(&server.output_power_manager_v1->events.set_mode, &server.output_power_manager_set_mode); + #if WLR_HAS_DRM_BACKEND server.drm_lease_v1 = wlr_drm_lease_v1_manager_create(server.wl_display, server.backend); if (server.drm_lease_v1) { @@ -643,6 +653,7 @@ main(int argc, char *argv[]) #endif wl_list_remove(&server.new_virtual_pointer.link); wl_list_remove(&server.new_virtual_keyboard.link); + wl_list_remove(&server.output_power_manager_set_mode.link); wl_list_remove(&server.output_manager_apply.link); wl_list_remove(&server.output_manager_test.link); wl_list_remove(&server.xdg_toplevel_decoration.link); diff --git a/meson.build b/meson.build index f8ccd76..f0d8b59 100644 --- a/meson.build +++ b/meson.build @@ -41,6 +41,10 @@ wayland_server = dependency('wayland-server') xkbcommon = dependency('xkbcommon') math = cc.find_library('m') +# Add wlroots protocol directory to include path +wlroots_incdir = wlroots.get_variable('includedir', default_value: '/usr/local/include') +add_project_arguments('-I' + wlroots_incdir + '/wlroots-0.19/protocol', language: 'c') + wl_protocol_dir = wayland_protos.get_variable('pkgdatadir') wayland_scanner = find_program('wayland-scanner') wayland_scanner_server = generator( diff --git a/output.c b/output.c index 9f2a708..55a2b61 100644 --- a/output.c +++ b/output.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -430,3 +431,30 @@ handle_output_manager_test(struct wl_listener *listener, void *data) wlr_output_configuration_v1_destroy(config); } + +void +handle_output_power_manager_set_mode(struct wl_listener *listener, void *data) +{ + struct cg_server *server = wl_container_of(listener, server, output_power_manager_set_mode); + struct wlr_output_power_v1_set_mode_event *event = data; + struct cg_output *output = event->output->data; + + if (!output) { + return; + } + + struct wlr_output_state state = {0}; + + switch (event->mode) { + case ZWLR_OUTPUT_POWER_V1_MODE_OFF: + wlr_output_state_set_enabled(&state, false); + break; + case ZWLR_OUTPUT_POWER_V1_MODE_ON: + wlr_output_state_set_enabled(&state, true); + break; + } + + if (wlr_output_test_state(event->output, &state)) { + wlr_output_commit_state(event->output, &state); + } +} diff --git a/output.h b/output.h index fa72545..363f701 100644 --- a/output.h +++ b/output.h @@ -22,6 +22,7 @@ struct cg_output { void handle_output_manager_apply(struct wl_listener *listener, void *data); void handle_output_manager_test(struct wl_listener *listener, void *data); +void handle_output_power_manager_set_mode(struct wl_listener *listener, void *data); void handle_output_layout_change(struct wl_listener *listener, void *data); void handle_new_output(struct wl_listener *listener, void *data); void output_set_window_title(struct cg_output *output, const char *title); diff --git a/server.h b/server.h index 27f212a..b2cd198 100644 --- a/server.h +++ b/server.h @@ -61,6 +61,9 @@ struct cg_server { struct wl_listener output_manager_apply; struct wl_listener output_manager_test; + struct wlr_output_power_manager_v1 *output_power_manager_v1; + struct wl_listener output_power_manager_set_mode; + #if WLR_HAS_DRM_BACKEND struct wlr_drm_lease_v1_manager *drm_lease_v1; struct wl_listener drm_lease_request;