Implement sending command from riverctl
These commands are successfully received by the server, but not yet executed.
This commit is contained in:
@ -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});
|
||||
}
|
||||
}
|
||||
|
@ -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 {}
|
||||
|
Reference in New Issue
Block a user