aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Freund <mail@isaacfreund.com>2023-12-29 16:22:15 -0600
committerIsaac Freund <mail@isaacfreund.com>2023-12-29 16:22:15 -0600
commitb440767b5426fa13499701ab3e3d73c575a0b7a6 (patch)
tree72437f210242e62f6e5e95fbf26ca24b82072cf4
parent677766956ebd77fb6905ed71cfa7757165fba343 (diff)
downloadriver-b440767b5426fa13499701ab3e3d73c575a0b7a6.tar.gz
river-b440767b5426fa13499701ab3e3d73c575a0b7a6.tar.xz
gamma-control: track wlroots 0.17 changes
m---------deps/zig-wlroots0
-rw-r--r--river/Output.zig94
-rw-r--r--river/Root.zig18
-rw-r--r--river/Server.zig1
4 files changed, 80 insertions, 33 deletions
diff --git a/deps/zig-wlroots b/deps/zig-wlroots
-Subproject 5581b9522eb2b3d2fca8e02a581932f6b9eb487
+Subproject 96dfdc14e99468f4aa6560c8397cd4d0eb0c282
diff --git a/river/Output.zig b/river/Output.zig
index a51201e..3b083c6 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -101,6 +101,10 @@ lock_render_state: enum {
lock_surface,
} = .blanked,
+/// Set to true if a gamma control client makes a set gamma request.
+/// This request is handled while rendering the next frame in handleFrame().
+gamma_dirty: bool = false,
+
/// The state of the output that is directly acted upon/modified through user input.
///
/// Pending state will be copied to the inflight state and communicated to clients
@@ -476,43 +480,69 @@ fn handleFrame(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void {
const output = @fieldParentPtr(Self, "frame", listener);
const scene_output = server.root.scene.getSceneOutput(output.wlr_output).?;
- if (scene_output.commit(null)) {
- if (server.lock_manager.state == .locked or
- (server.lock_manager.state == .waiting_for_lock_surfaces and output.locked_content.node.enabled) or
- server.lock_manager.state == .waiting_for_blank)
- {
- assert(!output.normal_content.node.enabled);
- assert(output.locked_content.node.enabled);
-
- switch (server.lock_manager.state) {
- .unlocked => unreachable,
- .locked => switch (output.lock_render_state) {
- .pending_unlock, .unlocked, .pending_blank, .pending_lock_surface => unreachable,
- .blanked, .lock_surface => {},
- },
- .waiting_for_blank => {
- if (output.lock_render_state != .blanked) {
- output.lock_render_state = .pending_blank;
- }
- },
- .waiting_for_lock_surfaces => {
- if (output.lock_render_state != .lock_surface) {
- output.lock_render_state = .pending_lock_surface;
- }
- },
- }
+ // TODO this should probably be retried on failure
+ output.renderAndCommit(scene_output) catch |err| switch (err) {
+ error.OutOfMemory => log.err("out of memory", .{}),
+ error.CommitFailed => log.err("output commit failed for {s}", .{output.wlr_output.name}),
+ };
+
+ var now: std.os.timespec = undefined;
+ std.os.clock_gettime(std.os.CLOCK.MONOTONIC, &now) catch @panic("CLOCK_MONOTONIC not supported");
+ scene_output.sendFrameDone(&now);
+}
+
+fn renderAndCommit(output: *Self, scene_output: *wlr.SceneOutput) !void {
+ if (output.gamma_dirty) {
+ var state = wlr.Output.State.init();
+ defer state.finish();
+
+ if (server.root.gamma_control_manager.getControl(output.wlr_output)) |control| {
+ log.info("applying gamma settings from client", .{});
+ if (!control.apply(&state)) return error.OutOfMemory;
} else {
- if (output.lock_render_state != .unlocked) {
- output.lock_render_state = .pending_unlock;
- }
+ log.info("clearing gamma settings from client", .{});
+ state.clearGammaLut();
}
+
+ if (!scene_output.buildState(&state, null)) return error.CommitFailed;
+
+ if (!output.wlr_output.commitState(&state)) return error.CommitFailed;
+
+ scene_output.damage_ring.rotate();
+ output.gamma_dirty = false;
} else {
- log.err("output commit failed for {s}", .{output.wlr_output.name});
+ if (!scene_output.commit(null)) return error.CommitFailed;
}
- var now: std.os.timespec = undefined;
- std.os.clock_gettime(std.os.CLOCK.MONOTONIC, &now) catch @panic("CLOCK_MONOTONIC not supported");
- scene_output.sendFrameDone(&now);
+ if (server.lock_manager.state == .locked or
+ (server.lock_manager.state == .waiting_for_lock_surfaces and output.locked_content.node.enabled) or
+ server.lock_manager.state == .waiting_for_blank)
+ {
+ assert(!output.normal_content.node.enabled);
+ assert(output.locked_content.node.enabled);
+
+ switch (server.lock_manager.state) {
+ .unlocked => unreachable,
+ .locked => switch (output.lock_render_state) {
+ .pending_unlock, .unlocked, .pending_blank, .pending_lock_surface => unreachable,
+ .blanked, .lock_surface => {},
+ },
+ .waiting_for_blank => {
+ if (output.lock_render_state != .blanked) {
+ output.lock_render_state = .pending_blank;
+ }
+ },
+ .waiting_for_lock_surfaces => {
+ if (output.lock_render_state != .lock_surface) {
+ output.lock_render_state = .pending_lock_surface;
+ }
+ },
+ }
+ } else {
+ if (output.lock_render_state != .unlocked) {
+ output.lock_render_state = .pending_unlock;
+ }
+ }
}
fn handlePresent(
diff --git a/river/Root.zig b/river/Root.zig
index aa3b4df..71cc1ef 100644
--- a/river/Root.zig
+++ b/river/Root.zig
@@ -102,6 +102,10 @@ power_manager: *wlr.OutputPowerManagerV1,
power_manager_set_mode: wl.Listener(*wlr.OutputPowerManagerV1.event.SetMode) =
wl.Listener(*wlr.OutputPowerManagerV1.event.SetMode).init(handlePowerManagerSetMode),
+gamma_control_manager: *wlr.GammaControlManagerV1,
+gamma_control_set_gamma: wl.Listener(*wlr.GammaControlManagerV1.event.SetGamma) =
+ wl.Listener(*wlr.GammaControlManagerV1.event.SetGamma).init(handleSetGamma),
+
/// A list of all outputs
all_outputs: wl.list.Head(Output, .all_link),
@@ -177,6 +181,7 @@ pub fn init(self: *Self) !void {
.active_outputs = undefined,
.output_manager = try wlr.OutputManagerV1.create(server.wl_server),
.power_manager = try wlr.OutputPowerManagerV1.create(server.wl_server),
+ .gamma_control_manager = try wlr.GammaControlManagerV1.create(server.wl_server),
.transaction_timeout = transaction_timeout,
};
self.hidden.pending.focus_stack.init();
@@ -198,6 +203,7 @@ pub fn init(self: *Self) !void {
self.output_manager.events.@"test".add(&self.manager_test);
self.output_layout.events.change.add(&self.layout_change);
self.power_manager.events.set_mode.add(&self.power_manager_set_mode);
+ self.gamma_control_manager.events.set_gamma.add(&self.gamma_control_set_gamma);
}
pub fn deinit(self: *Self) void {
@@ -846,3 +852,15 @@ fn handlePowerManagerSetMode(
std.log.scoped(.server).err("output commit failed for {s}", .{event.output.name});
};
}
+
+fn handleSetGamma(
+ _: *wl.Listener(*wlr.GammaControlManagerV1.event.SetGamma),
+ event: *wlr.GammaControlManagerV1.event.SetGamma,
+) void {
+ const output: *Output = @ptrFromInt(event.output.data);
+
+ std.log.debug("client requested to set gamma", .{});
+
+ output.gamma_dirty = true;
+ output.wlr_output.scheduleFrame();
+}
diff --git a/river/Server.zig b/river/Server.zig
index f17f2c1..44e26fd 100644
--- a/river/Server.zig
+++ b/river/Server.zig
@@ -142,7 +142,6 @@ pub fn init(self: *Self) !void {
_ = try wlr.DataDeviceManager.create(self.wl_server);
_ = try wlr.DataControlManagerV1.create(self.wl_server);
_ = try wlr.ExportDmabufManagerV1.create(self.wl_server);
- _ = try wlr.GammaControlManagerV1.create(self.wl_server);
_ = try wlr.ScreencopyManagerV1.create(self.wl_server);
_ = try wlr.SinglePixelBufferManagerV1.create(self.wl_server);
_ = try wlr.Viewporter.create(self.wl_server);