diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/WindowManagement.zig | 21 | ||||
| -rw-r--r-- | src/riverctl.zig | 59 |
2 files changed, 75 insertions, 5 deletions
diff --git a/src/WindowManagement.zig b/src/WindowManagement.zig index be8d425..7c14838 100644 --- a/src/WindowManagement.zig +++ b/src/WindowManagement.zig @@ -36,6 +36,7 @@ wl_global: *c.wl_global, listen_display_destroy: c.wl_listener, pub fn init(self: *Self, server: *Server) !void { + self.server = server; self.wl_global = c.wl_global_create( server.wl_display, &c.zriver_window_manager_v1_interface, @@ -72,6 +73,22 @@ fn resourceDestroy(wl_resource: ?*c.wl_resource) callconv(.C) void { // TODO } -fn runCommand(wl_client: ?*c.wl_client, wl_resource: ?*c.wl_resource, command: ?[*:0]const u8) callconv(.C) void { - Log.Debug.log("command: {}", .{command}); +fn runCommand(wl_client: ?*c.wl_client, wl_resource: ?*c.wl_resource, command: ?*c.wl_array) callconv(.C) void { + const self = @ptrCast(*Self, @alignCast(@alignOf(*Self), c.wl_resource_get_user_data(wl_resource))); + const allocator = self.server.allocator; + + var args = std.ArrayList([]const u8).init(allocator); + + var i: usize = 0; + const data = @ptrCast([*]const u8, command.?.data); + while (i < command.?.size) { + const slice = std.mem.spanZ(@ptrCast([*:0]const u8, &data[i])); + args.append(std.mem.dupe(allocator, u8, slice) catch unreachable) catch unreachable; + + i += slice.len + 1; + } + + for (args.items) |x| { + std.debug.warn("{}\n", .{x}); + } } diff --git a/src/riverctl.zig b/src/riverctl.zig index b26bcb7..5f6dd54 100644 --- a/src/riverctl.zig +++ b/src/riverctl.zig @@ -18,9 +18,62 @@ const std = @import("std"); const c = @cImport({ - @cInclude(); + @cInclude("wayland-client.h"); + @cInclude("river-window-management-unstable-v1-client-protocol.h"); }); -pub fn main() void { - std.debug.warn("hello world\n", .{}); +const wl_registry_listener = c.wl_registry_listener{ + .global = handleGlobal, + .global_remove = handleGlobalRemove, +}; + +var river_window_manager: ?*c.zriver_window_manager_v1 = null; + +pub fn main() !void { + const wl_display = c.wl_display_connect(null) orelse return error.CantConnectToDisplay; + const wl_registry = c.wl_display_get_registry(wl_display); + + _ = c.wl_registry_add_listener(wl_registry, &wl_registry_listener, null); + if (c.wl_display_roundtrip(wl_display) == -1) return error.RoundtripFailed; + + const wm = river_window_manager orelse return error.RiverWMNotAdvertised; + + var command: c.wl_array = undefined; + c.wl_array_init(&command); + var it = std.process.args(); + // Skip our name + _ = it.nextPosix(); + while (it.nextPosix()) |arg| { + // Add one as we need to copy the null terminators as well + var ptr = @ptrCast([*]u8, c.wl_array_add(&command, arg.len + 1) orelse + return error.OutOfMemory); + for (arg) |ch, i| ptr[i] = ch; + ptr[arg.len] = 0; + } + + c.zriver_window_manager_v1_run_command(wm, &command); + if (c.wl_display_roundtrip(wl_display) == -1) return error.RoundtripFailed; +} + +fn handleGlobal( + data: ?*c_void, + wl_registry: ?*c.wl_registry, + name: u32, + interface: ?[*:0]const u8, + version: u32, +) callconv(.C) void { + // We only care about the river_window_manager global + if (std.mem.eql( + u8, + std.mem.spanZ(interface.?), + std.mem.spanZ(@ptrCast([*:0]const u8, c.zriver_window_manager_v1_interface.name.?)), + )) { + river_window_manager = @ptrCast( + *c.zriver_window_manager_v1, + c.wl_registry_bind(wl_registry, name, &c.zriver_window_manager_v1_interface, 1), + ); + } } + +/// Ignore the event +fn handleGlobalRemove(data: ?*c_void, wl_registry: ?*c.wl_registry, name: u32) callconv(.C) void {} |
