Loop.zig (2964B)
1 const std = @import("std"); 2 3 const utils = @import("utils.zig"); 4 const Loop = @This(); 5 6 const state = &@import("root").state; 7 8 sfd: std.posix.fd_t, 9 10 pub fn init() !Loop { 11 var mask = std.posix.empty_sigset; 12 std.os.linux.sigaddset(&mask, std.os.linux.SIG.INT); 13 std.os.linux.sigaddset(&mask, std.os.linux.SIG.TERM); 14 std.os.linux.sigaddset(&mask, std.os.linux.SIG.QUIT); 15 16 _ = std.os.linux.sigprocmask(std.os.linux.SIG.BLOCK, &mask, null); 17 const sfd = std.os.linux.signalfd(-1, &mask, std.os.linux.SFD.NONBLOCK); 18 19 return Loop{ .sfd = @intCast(sfd) }; 20 } 21 22 pub fn run(self: *Loop) !void { 23 const wayland = &state.wayland; 24 const modules = &state.modules; 25 26 var fds = [_]std.posix.pollfd{ 27 .{ 28 .fd = self.sfd, 29 .events = std.posix.POLL.IN, 30 .revents = undefined, 31 }, 32 .{ 33 .fd = wayland.fd, 34 .events = std.posix.POLL.IN, 35 .revents = undefined, 36 }, 37 .{ 38 .fd = if (modules.backlight) |mod| mod.fd else -1, 39 .events = std.posix.POLL.IN, 40 .revents = undefined, 41 }, 42 .{ 43 .fd = if (modules.battery) |mod| mod.fd else -1, 44 .events = std.posix.POLL.IN, 45 .revents = undefined, 46 }, 47 .{ 48 .fd = if (modules.pulse) |mod| mod.fd else -1, 49 .events = std.posix.POLL.IN, 50 .revents = undefined, 51 }, 52 }; 53 54 while (true) { 55 while (true) { 56 const ret = wayland.display.dispatchPending(); 57 _ = wayland.display.flush(); 58 if (ret == .SUCCESS) break; 59 } 60 61 _ = std.posix.poll(&fds, -1) catch |err| { 62 std.log.err("poll failed: {s}", .{@errorName(err)}); 63 return; 64 }; 65 66 for (fds) |fd| { 67 if (fd.revents & std.posix.POLL.HUP != 0 or fd.revents & std.posix.POLL.ERR != 0) { 68 return; 69 } 70 } 71 72 // signals 73 if (fds[0].revents & std.posix.POLL.IN != 0) { 74 return; 75 } 76 77 // wayland 78 if (fds[1].revents & std.posix.POLL.IN != 0) { 79 const errno = wayland.display.dispatch(); 80 if (errno != .SUCCESS) return; 81 } 82 if (fds[1].revents & std.posix.POLL.OUT != 0) { 83 const errno = wayland.display.flush(); 84 if (errno != .SUCCESS) return; 85 } 86 87 // modules 88 if (modules.backlight) |*mod| if (fds[2].revents & std.posix.POLL.IN != 0) { 89 std.log.info("backlight", .{}); 90 mod.refresh() catch return; 91 }; 92 if (modules.battery) |*mod| if (fds[3].revents & std.posix.POLL.IN != 0) { 93 std.log.info("battery", .{}); 94 mod.refresh() catch return; 95 }; 96 if (modules.pulse) |*mod| if (fds[4].revents & std.posix.POLL.IN != 0) { 97 std.log.info("pulse", .{}); 98 mod.refresh() catch return; 99 }; 100 } 101 }