dotfiles/scripts/mzteriver/src/Connection.zig

97 lines
2.6 KiB
Zig

const std = @import("std");
const wayland = @import("wayland");
const wl = wayland.client.wl;
const zriver = wayland.client.zriver;
dpy: *wl.Display,
seat: ?*wl.Seat,
ctl: ?*zriver.ControlV1,
const Connection = @This();
pub fn init() !Connection {
const dpy = try wl.Display.connect(null);
errdefer dpy.disconnect();
const reg = try dpy.getRegistry();
defer reg.destroy();
var self = Connection{
.dpy = dpy,
.seat = null,
.ctl = null,
};
reg.setListener(*Connection, registryListener, &self);
if (dpy.roundtrip() != .SUCCESS) return error.RoundtripFailed;
if (self.seat == null or self.ctl == null) return error.MissingGlobals;
std.log.info("successfully initialized wayland connection", .{});
return self;
}
pub fn deinit(self: Connection) void {
self.seat.?.destroy();
self.ctl.?.destroy();
self.dpy.disconnect();
}
pub fn runCommand(self: Connection, args: []const [:0]const u8) !void {
std.log.debug("running command: {s}", .{args});
for (args) |arg| self.ctl.?.addArgument(arg.ptr);
var success: ?bool = null;
const cb = try self.ctl.?.runCommand(self.seat.?);
cb.setListener(*?bool, cmdCallbackListener, &success);
while (success == null) {
if (self.dpy.dispatch() != .SUCCESS) return error.RoundtripFailed;
}
if (!success.?) return error.CommandFailed;
}
fn cmdCallbackListener(
_: *zriver.CommandCallbackV1,
ev: zriver.CommandCallbackV1.Event,
success: *?bool,
) void {
switch (ev) {
.success => |suc| {
success.* = true;
const output = std.mem.span(suc.output);
if (output.len != 0)
std.log.info("cmd output: {s}", .{output});
},
.failure => |fail| {
success.* = false;
std.log.err("cmd fail: {s}", .{fail.failure_message});
},
}
}
fn registryListener(reg: *wl.Registry, ev: wl.Registry.Event, self: *Connection) void {
switch (ev) {
.global => |glob| {
if (std.mem.orderZ(u8, glob.interface, wl.Seat.getInterface().name) == .eq) {
self.seat = reg.bind(
glob.name,
wl.Seat,
wl.Seat.generated_version,
) catch @panic("OOM");
} else if (std.mem.orderZ(u8, glob.interface, zriver.ControlV1.getInterface().name) == .eq) {
self.ctl = reg.bind(
glob.name,
zriver.ControlV1,
zriver.ControlV1.generated_version,
) catch @panic("OOM");
}
},
.global_remove => {},
}
}