diff --git a/build.zig b/build.zig index 48b049a..0dfdca3 100644 --- a/build.zig +++ b/build.zig @@ -211,6 +211,7 @@ fn addServerDeps(exe: *zbs.LibExeObjStep, scanner: *ScanProtocolsStep) void { exe.linkSystemLibrary("wlroots"); exe.addPackagePath("flags", "common/flags.zig"); + exe.addCSourceFile("river/wlroots_log_wrapper.c", &[_][]const u8{ "-std=c99", "-O2" }); // TODO: remove when zig issue #131 is implemented scanner.addCSource(exe); diff --git a/river/main.zig b/river/main.zig index 1482b9d..f1e75f2 100644 --- a/river/main.zig +++ b/river/main.zig @@ -87,7 +87,7 @@ pub fn main() anyerror!void { } }; - wlr.log.init(switch (runtime_log_level) { + river_init_wlroots_log(switch (runtime_log_level) { .debug => .debug, .notice, .info => .info, .warn, .err, .crit, .alert, .emerg => .err, @@ -181,3 +181,14 @@ pub fn log( const stderr = std.io.getStdErr().writer(); stderr.print(@tagName(river_level) ++ scope_prefix ++ format ++ "\n", args) catch {}; } + +/// See wlroots_log_wrapper.c +extern fn river_init_wlroots_log(importance: wlr.log.Importance) void; +export fn river_wlroots_log_callback(importance: wlr.log.Importance, ptr: [*:0]const u8, len: usize) void { + switch (importance) { + .err => log(.err, .wlroots, "{s}", .{ptr[0..len]}), + .info => log(.info, .wlroots, "{s}", .{ptr[0..len]}), + .debug => log(.debug, .wlroots, "{s}", .{ptr[0..len]}), + .silent, .last => unreachable, + } +} diff --git a/river/wlroots_log_wrapper.c b/river/wlroots_log_wrapper.c new file mode 100644 index 0000000..7562ba8 --- /dev/null +++ b/river/wlroots_log_wrapper.c @@ -0,0 +1,41 @@ +#include +#include +#include + +#include + +#define BUFFER_SIZE 1024 + +void river_wlroots_log_callback(enum wlr_log_importance importance, const char *ptr, size_t len); + +static void callback(enum wlr_log_importance importance, const char *fmt, va_list args) { + char buffer[BUFFER_SIZE]; + + // Need to make a copy of the args in case our buffer isn't big + // enough and we need to use them again. + va_list args_copy; + va_copy(args_copy, args); + + const int length = vsnprintf(buffer, BUFFER_SIZE, fmt, args); + // Need to add one for the terminating 0 byte + if (length + 1 <= BUFFER_SIZE) { + // The formatted string fit within our buffer, pass it on to river + river_wlroots_log_callback(importance, buffer, length); + } else { + // The formatted string did not fit in our buffer, we need + // to allocate enough memory to hold it. + char *allocated_buffer = malloc(length + 1); + if (allocated_buffer != NULL) { + const int length2 = vsnprintf(allocated_buffer, length + 1, fmt, args_copy); + assert(length2 == length); + river_wlroots_log_callback(importance, allocated_buffer, length); + free(allocated_buffer); + } + } + + va_end(args_copy); +} + +void river_init_wlroots_log(enum wlr_log_importance importance) { + wlr_log_init(importance, callback); +}