stevee

My wayland statusbar
git clone git://gtms.dev/stevee
Log | Files | Refs | Submodules | README | LICENSE

commit 8af3d680448af01192b3050bbf1516dc0790340a
parent 06fedf5965f432f21f107955e5d68a7f28abafef
Author: Andrea Feletto <andrea@andreafeletto.com>
Date:   Tue, 25 Jan 2022 01:08:52 +0100

add backlight module

Diffstat:
Msrc/config.zig | 6++++--
Msrc/main.zig | 3+++
Msrc/modules.zig | 89++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
3 files changed, 91 insertions(+), 7 deletions(-)

diff --git a/src/config.zig b/src/config.zig @@ -8,7 +8,8 @@ pub const Config = struct { border: u15, font: *fcft.Font, clockFormat: [*:0]const u8, - batteryDir: []const u8, + batteryDev: []const u8, + backlightDev: []const u8, pub fn init() !Config { var font_names = [_][*:0]const u8{"monospace:size=14"}; @@ -30,7 +31,8 @@ pub const Config = struct { .border = 2, .font = try fcft.Font.fromName(&font_names, null), .clockFormat = "%d %b %Y - %R", - .batteryDir = "BAT1", + .batteryDev = "BAT1", + .backlightDev = "intel_backlight", }; } }; diff --git a/src/main.zig b/src/main.zig @@ -12,6 +12,7 @@ pub const State = struct { loop: Loop, battery: modules.Battery, + backlight: modules.Backlight, modules: std.ArrayList(modules.Module), }; @@ -28,6 +29,8 @@ pub fn main() anyerror!void { std.log.info("modules initialization", .{}); state.modules = std.ArrayList(modules.Module).init(state.allocator); + state.backlight = try modules.Backlight.init(&state); + try state.modules.append(state.backlight.module()); state.battery = try modules.Battery.init(&state); try state.modules.append(state.battery.module()); diff --git a/src/modules.zig b/src/modules.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const fmt = std.fmt; const fs = std.fs; const io = std.io; const mem = std.mem; @@ -32,14 +33,14 @@ pub const Battery = struct { watch: i32, pub const Data = struct { - capacity: u8, + value: u8, icon: []const u8, }; pub fn init(state: *State) !Battery { const path = try fs.path.join( state.allocator, - &.{ "/sys/class/power_supply", state.config.batteryDir }, + &.{ "/sys/class/power_supply", state.config.batteryDev }, ); const uevent_path = try fs.path.joinZ( @@ -69,7 +70,7 @@ pub const Battery = struct { const self = Module.cast(Battery)(self_opaque); const data = try self.readData(); - try std.fmt.format(writer, "{s} {d}%", .{ data.icon, data.capacity }); + try fmt.format(writer, "{s} {d}%", .{ data.icon, data.value }); } fn readData(self: *const Battery) !Data { @@ -95,7 +96,7 @@ pub const Battery = struct { } return Data{ - .capacity = @floatToInt(u8, @round(capacity)), + .value = @floatToInt(u8, @round(capacity)), .icon = icon, }; } @@ -104,7 +105,7 @@ pub const Battery = struct { const value = try self.readValue(filename); defer self.state.allocator.free(value); - return std.fmt.parseInt(u32, value, 10); + return fmt.parseInt(u32, value, 10); } fn readValue(self: *const Battery, filename: []const u8) ![]u8 { @@ -123,3 +124,81 @@ pub const Battery = struct { return state.allocator.resize(str, str.len - 1).?; } }; + +pub const Backlight = struct { + state: *State, + path: []const u8, + watch: i32, + + pub const Data = struct { + value: u8, + }; + + pub fn init(state: *State) !Backlight { + const path = try fs.path.join( + state.allocator, + &.{ "/sys/class/backlight", state.config.backlightDev }, + ); + + const uevent_path = try fs.path.joinZ( + state.allocator, + &.{ path, "brightness" }, + ); + defer state.allocator.free(uevent_path); + + const watch = os.linux.inotify_add_watch( + state.loop.fds[2].fd, + uevent_path, + os.linux.IN.ACCESS, + ); + + return Backlight{ + .state = state, + .path = path, + .watch = @intCast(i32, watch), + }; + } + + pub fn module(self: *Backlight) Module { + return .{ .impl = @ptrCast(*anyopaque, self), .printFn = print }; + } + + pub fn print(self_opaque: *anyopaque, writer: StringWriter) !void { + const self = Module.cast(Backlight)(self_opaque); + + const data = try self.readData(); + try fmt.format(writer, "💡 {d}%", .{ data.value }); + } + + fn readData(self: *const Backlight) !Data { + const value = try self.readInt("actual_brightness"); + const max = try self.readInt("max_brightness"); + + const percent = @intToFloat(f64, value) * 100.0 / @intToFloat(f64, max); + + return Data{ .value = @floatToInt(u8, @round(percent)) }; + } + + fn readInt(self: *const Backlight, filename: []const u8) !u32 { + const value = try self.readValue(filename); + defer self.state.allocator.free(value); + + return fmt.parseInt(u32, value, 10); + } + + fn readValue(self: *const Backlight, filename: []const u8) ![]u8 { + const state = self.state; + + const path = try fs.path.join( + state.allocator, + &.{ self.path, filename }, + ); + defer state.allocator.free(path); + + const file = try fs.openFileAbsolute(path, .{}); + defer file.close(); + + var str = try file.readToEndAlloc(state.allocator, 128); + return state.allocator.resize(str, str.len - 1).?; + } +};