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.setBuildMode(mode);
|
||||||
|
|
||||||
exe.linkLibC();
|
exe.linkLibC();
|
||||||
|
exe.addPackagePath("known-folders", "libs/known-folders/known-folders.zig");
|
||||||
exe.linkSystemLibrary("gtk4");
|
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();
|
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 std = @import("std");
|
||||||
|
const cfg = @import("config.zig");
|
||||||
|
|
||||||
pub const Action = enum {
|
pub const Action = enum {
|
||||||
shutdown,
|
shutdown,
|
||||||
|
@ -12,14 +13,15 @@ pub const Action = enum {
|
||||||
alloc: std.mem.Allocator,
|
alloc: std.mem.Allocator,
|
||||||
) !void {
|
) !void {
|
||||||
std.log.info("Executing action {s}", .{@tagName(self)});
|
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();
|
try child.spawn();
|
||||||
handle_out.* = child;
|
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
|
// partially yoinked from https://github.com/Swoogan/ziggtk
|
||||||
pub const c = @cImport({
|
pub const c = @cImport({
|
||||||
@cInclude("gtk/gtk.h");
|
@cInclude("gtk/gtk.h");
|
||||||
|
@cInclude("toml.h");
|
||||||
});
|
});
|
||||||
|
|
||||||
/// Could not get `g_signal_connect` to work. Zig says "use of undeclared identifier". Reimplemented here
|
/// 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 std = @import("std");
|
||||||
|
const cfg = @import("config.zig");
|
||||||
const ffi = @import("ffi.zig");
|
const ffi = @import("ffi.zig");
|
||||||
const c = ffi.c;
|
const c = ffi.c;
|
||||||
const gui = @import("gui.zig");
|
const gui = @import("gui.zig");
|
||||||
|
@ -44,6 +45,10 @@ pub fn log(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() !u8 {
|
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);
|
var arena = std.heap.ArenaAllocator.init(std.heap.c_allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue