diff --git a/river/OutputManager.zig b/river/OutputManager.zig new file mode 100644 index 0000000..c11acd9 --- /dev/null +++ b/river/OutputManager.zig @@ -0,0 +1,84 @@ +// This file is part of river, a dynamic tiling wayland compositor. +// +// Copyright 2020 The River Developers +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +const Self = @This(); + +const build_options = @import("build_options"); +const std = @import("std"); + +const c = @import("c.zig"); +const log = @import("log.zig"); +const util = @import("util.zig"); + +const Root = @import("Root.zig"); +const Server = @import("Server.zig"); + +root: *Root, + +listen_new_output: c.wl_listener = undefined, + +wlr_output_power_manager: *c.wlr_output_power_manager_v1, +listen_output_power_manager_set_mode: c.wl_listener = undefined, + +pub fn init(self: *Self, server: *Server) !void { + self.* = .{ + .wlr_output_power_manager = c.wlr_output_power_manager_v1_create(server.wl_display) orelse + return error.OutOfMemory, + .root = &server.root, + }; + + self.listen_new_output.notify = handleNewOutput; + c.wl_signal_add(&server.wlr_backend.events.new_output, &self.listen_new_output); + + // Set up output power manager + self.listen_output_power_manager_set_mode.notify = handleOutputPowerManagementSetMode; + c.wl_signal_add(&self.wlr_output_power_manager.events.set_mode, &self.listen_output_power_manager_set_mode); + + _ = c.wlr_xdg_output_manager_v1_create(server.wl_display, server.root.wlr_output_layout) orelse + return error.OutOfMemory; +} + +fn handleNewOutput(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { + const self = @fieldParentPtr(Self, "listen_new_output", listener.?); + const wlr_output = util.voidCast(c.wlr_output, data.?); + log.debug(.output_manager, "new output {}", .{wlr_output.name}); + self.root.addOutput(wlr_output); +} + +fn handleOutputPowerManagementSetMode(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { + const self = @fieldParentPtr(Self, "listen_output_power_manager_set_mode", listener.?); + const mode_event = util.voidCast(c.wlr_output_power_v1_set_mode_event, data.?); + const wlr_output: *c.wlr_output = mode_event.output; + + const enable = mode_event.mode == .ZWLR_OUTPUT_POWER_V1_MODE_ON; + + const log_text = if (enable) "Enabling" else "Disabling"; + log.debug( + .output_manager, + "{} dpms for output {}", + .{log_text, wlr_output.name}, + ); + + c.wlr_output_enable(wlr_output, enable); + if (!c.wlr_output_commit(wlr_output)) { + log.err( + .server, + "wlr_output_commit failed for {}", + .{wlr_output.name}, + ); + } +} diff --git a/river/Server.zig b/river/Server.zig index f93ffe8..b9b88b8 100644 --- a/river/Server.zig +++ b/river/Server.zig @@ -30,6 +30,7 @@ const DecorationManager = @import("DecorationManager.zig"); const InputManager = @import("InputManager.zig"); const LayerSurface = @import("LayerSurface.zig"); const Output = @import("Output.zig"); +const OutputManager = @import("OutputManager.zig"); const Root = @import("Root.zig"); const StatusManager = @import("StatusManager.zig"); const View = @import("View.zig"); @@ -43,7 +44,6 @@ sigterm_source: *c.wl_event_source, wlr_backend: *c.wlr_backend, noop_backend: *c.wlr_backend, -listen_new_output: c.wl_listener, wlr_xdg_shell: *c.wlr_xdg_shell, listen_new_xdg_surface: c.wl_listener, @@ -51,14 +51,12 @@ listen_new_xdg_surface: c.wl_listener, wlr_layer_shell: *c.wlr_layer_shell_v1, listen_new_layer_surface: c.wl_listener, -wlr_output_power_manager: *c.wlr_output_power_manager_v1, -listen_output_power_manager_set_mode: c.wl_listener, - wlr_xwayland: if (build_options.xwayland) *c.wlr_xwayland else void, listen_new_xwayland_surface: if (build_options.xwayland) c.wl_listener else void, decoration_manager: DecorationManager, input_manager: InputManager, +output_manager: OutputManager, root: Root, config: Config, control: Control, @@ -97,17 +95,9 @@ pub fn init(self: *Self) !void { const wlr_renderer = c.wlr_backend_get_renderer(self.wlr_backend).?; if (!c.wlr_renderer_init_wl_display(wlr_renderer, self.wl_display)) return error.DisplayInitFailed; - self.listen_new_output.notify = handleNewOutput; - c.wl_signal_add(&self.wlr_backend.events.new_output, &self.listen_new_output); - const wlr_compositor = c.wlr_compositor_create(self.wl_display, wlr_renderer) orelse return error.OutOfMemory; - // Set up output power manager - self.wlr_output_power_manager = c.wlr_output_power_manager_v1_create(self.wl_display); - self.listen_output_power_manager_set_mode.notify = handleOutputPowerManagementSetMode; - c.wl_signal_add(&self.wlr_output_power_manager.events.set_mode, &self.listen_output_power_manager_set_mode); - // Set up xdg shell self.wlr_xdg_shell = c.wlr_xdg_shell_create(self.wl_display) orelse return error.OutOfMemory; self.listen_new_xdg_surface.notify = handleNewXdgSurface; @@ -136,6 +126,7 @@ pub fn init(self: *Self) !void { try self.input_manager.init(self); try self.control.init(self); try self.status_manager.init(self); + try self.output_manager.init(self); // These all free themselves when the wl_display is destroyed _ = c.wlr_data_device_manager_create(self.wl_display) orelse return error.OutOfMemory; @@ -189,13 +180,6 @@ fn terminate(signal: c_int, data: ?*c_void) callconv(.C) c_int { return 0; } -fn handleNewOutput(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { - const self = @fieldParentPtr(Self, "listen_new_output", listener.?); - const wlr_output = util.voidCast(c.wlr_output, data.?); - log.debug(.server, "new output {}", .{wlr_output.name}); - self.root.addOutput(wlr_output); -} - fn handleNewXdgSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { // This event is raised when wlr_xdg_shell receives a new xdg surface from a // client, either a toplevel (application window) or popup. @@ -291,27 +275,3 @@ fn handleNewXwaylandSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv( const node = util.gpa.create(ViewStack(View).Node) catch return; node.view.init(output, output.current.tags, wlr_xwayland_surface); } - -fn handleOutputPowerManagementSetMode(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { - const self = @fieldParentPtr(Self, "listen_output_power_manager_set_mode", listener.?); - const mode_event = util.voidCast(c.wlr_output_power_v1_set_mode_event, data.?); - const wlr_output: *c.wlr_output = mode_event.output; - - const enable = mode_event.mode == .ZWLR_OUTPUT_POWER_V1_MODE_ON; - - const log_text = if (enable) "Enabling" else "Disabling"; - log.debug( - .server, - "{} dpms for output {}", - .{ log_text, wlr_output.name }, - ); - - c.wlr_output_enable(wlr_output, enable); - if (!c.wlr_output_commit(wlr_output)) { - log.err( - .server, - "wlr_output_commit failed for {}", - .{wlr_output.name}, - ); - } -}