feat: added config
This commit is contained in:
parent
346196903b
commit
9e9295426a
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
[submodule "libs/tomlc99"]
|
||||
path = libs/tomlc99
|
||||
url = https://github.com/cktan/tomlc99.git
|
||||
[submodule "libs/known-folders"]
|
||||
path = libs/known-folders
|
||||
url = https://github.com/ziglibs/known-folders.git
|
|
@ -16,7 +16,14 @@ pub fn build(b: *std.build.Builder) void {
|
|||
exe.setBuildMode(mode);
|
||||
|
||||
exe.linkLibC();
|
||||
exe.addPackagePath("known-folders", "libs/known-folders/known-folders.zig");
|
||||
exe.linkSystemLibrary("gtk4");
|
||||
exe.addIncludeDir("libs/tomlc99");
|
||||
exe.addCSourceFile("libs/tomlc99/toml.c", &[0][]u8{});
|
||||
|
||||
// needed to prevent crash caused by UBSAN because the tomlc99 has some UB
|
||||
exe.disable_sanitize_c = true;
|
||||
exe.strip = mode != .Debug;
|
||||
|
||||
exe.install();
|
||||
|
||||
|
|
1
libs/known-folders
Submodule
1
libs/known-folders
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 9db1b99219c767d5e24994b1525273fe4031e464
|
1
libs/tomlc99
Submodule
1
libs/tomlc99
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 034b23ed3e4e5ee5345040eabed470f204d7f668
|
|
@ -1,4 +1,5 @@
|
|||
const std = @import("std");
|
||||
const cfg = @import("config.zig");
|
||||
|
||||
pub const Action = enum {
|
||||
shutdown,
|
||||
|
@ -12,14 +13,15 @@ pub const Action = enum {
|
|||
alloc: std.mem.Allocator,
|
||||
) !void {
|
||||
std.log.info("Executing action {s}", .{@tagName(self)});
|
||||
var argv = [_][]const u8{ "systemctl", switch (self) {
|
||||
.shutdown => "poweroff",
|
||||
.reboot => "reboot",
|
||||
.@"suspend" => "suspend",
|
||||
.hibernate => "hibernate",
|
||||
} };
|
||||
|
||||
var child = try std.ChildProcess.init(&argv, alloc);
|
||||
const argv = switch (self) {
|
||||
.shutdown => cfg.global_config.?.shutdown_command,
|
||||
.reboot => cfg.global_config.?.reboot_command,
|
||||
.@"suspend" => cfg.global_config.?.suspend_command,
|
||||
.hibernate => cfg.global_config.?.hibernate_command,
|
||||
};
|
||||
|
||||
var child = try std.ChildProcess.init(argv, alloc);
|
||||
try child.spawn();
|
||||
handle_out.* = child;
|
||||
}
|
||||
|
|
98
src/config.zig
Normal file
98
src/config.zig
Normal file
|
@ -0,0 +1,98 @@
|
|||
const std = @import("std");
|
||||
const kf = @import("known-folders");
|
||||
const c = @import("ffi.zig").c;
|
||||
|
||||
pub var global_config: ?*Config = null;
|
||||
|
||||
pub const Config = struct {
|
||||
shutdown_command: []const []const u8 = &[_][]const u8{ "systemctl", "poweroff" },
|
||||
reboot_command: []const []const u8 = &[_][]const u8{ "systemctl", "reboot" },
|
||||
suspend_command: []const []const u8 = &[_][]const u8{ "systemctl", "suspend" },
|
||||
hibernate_command: []const []const u8 = &[_][]const u8{ "systemctl", "hibernate" },
|
||||
|
||||
alloc: std.mem.Allocator,
|
||||
command_arena: std.heap.ArenaAllocator,
|
||||
toml: ?*c.toml_table_t,
|
||||
|
||||
pub fn parse(alloc: std.mem.Allocator) !Config {
|
||||
var toml: ?*c.toml_table_t = null;
|
||||
toml: {
|
||||
var config_dir = kf.open(
|
||||
alloc,
|
||||
.roaming_configuration,
|
||||
.{},
|
||||
) catch break :toml orelse break :toml;
|
||||
defer config_dir.close();
|
||||
|
||||
const config = try config_dir.realpathAlloc(alloc, "gpower2/config.toml");
|
||||
defer alloc.free(config);
|
||||
const config_z = try std.cstr.addNullByte(alloc, config);
|
||||
defer alloc.free(config_z);
|
||||
|
||||
const c_file = c.fopen(config_z, "r");
|
||||
|
||||
std.log.debug("{x}", .{@ptrToInt(c_file)});
|
||||
if (c_file == null) {
|
||||
std.log.warn("Opening config failed, skipping config", .{});
|
||||
break :toml;
|
||||
}
|
||||
|
||||
defer _ = c.fclose(c_file);
|
||||
|
||||
var errbuf: [50:0]u8 = undefined;
|
||||
toml = c.toml_parse_file(c_file, &errbuf, errbuf.len);
|
||||
if (toml == null) {
|
||||
std.log.err("Failed to parse TOML config: {s}", .{errbuf});
|
||||
return error.TomlError;
|
||||
}
|
||||
}
|
||||
|
||||
var arena = std.heap.ArenaAllocator.init(alloc);
|
||||
errdefer arena.deinit();
|
||||
|
||||
var self = Config{
|
||||
.alloc = alloc,
|
||||
.command_arena = arena,
|
||||
.toml = toml,
|
||||
};
|
||||
|
||||
if (toml) |t| {
|
||||
errdefer c.toml_free(t);
|
||||
inline for (.{
|
||||
.shutdown_command,
|
||||
.reboot_command,
|
||||
.suspend_command,
|
||||
.hibernate_command,
|
||||
}) |f_tag| {
|
||||
const f = @tagName(f_tag);
|
||||
const array = c.toml_array_in(t, f);
|
||||
|
||||
if (array) |a| {
|
||||
var len = c.toml_array_nelem(a);
|
||||
var i: usize = 0;
|
||||
|
||||
var cmd = try arena.allocator().alloc([]u8, @intCast(usize, len));
|
||||
|
||||
while (i < len) : (i += 1) {
|
||||
const maybe_s = c.toml_string_at(a, @intCast(c_int, i));
|
||||
if (maybe_s.ok == 0) {
|
||||
std.log.err("{s} in config contains non-string value!", .{f});
|
||||
return error.InvalidConfig;
|
||||
}
|
||||
cmd[i] = try arena.allocator().dupe(u8, std.mem.sliceTo(maybe_s.u.s, 0));
|
||||
}
|
||||
|
||||
@field(self, f) = cmd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Config) void {
|
||||
if (self.toml) |t| {
|
||||
c.toml_free(t);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -1,6 +1,7 @@
|
|||
// partially yoinked from https://github.com/Swoogan/ziggtk
|
||||
pub const c = @cImport({
|
||||
@cInclude("gtk/gtk.h");
|
||||
@cInclude("toml.h");
|
||||
});
|
||||
|
||||
/// Could not get `g_signal_connect` to work. Zig says "use of undeclared identifier". Reimplemented here
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const std = @import("std");
|
||||
const cfg = @import("config.zig");
|
||||
const ffi = @import("ffi.zig");
|
||||
const c = ffi.c;
|
||||
const gui = @import("gui.zig");
|
||||
|
@ -44,6 +45,10 @@ pub fn log(
|
|||
}
|
||||
|
||||
pub fn main() !u8 {
|
||||
var conf = try cfg.Config.parse(std.heap.c_allocator);
|
||||
defer conf.deinit();
|
||||
cfg.global_config = &conf;
|
||||
|
||||
var arena = std.heap.ArenaAllocator.init(std.heap.c_allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
|
|
Loading…
Reference in a new issue