Implement sending command from riverctl
These commands are successfully received by the server, but not yet executed.
This commit is contained in:
parent
7cb6c5d75a
commit
569308d91b
48
build.zig
48
build.zig
@ -19,11 +19,15 @@ pub fn build(b: *std.build.Builder) !void {
|
|||||||
|
|
||||||
const scan_protocols = ScanProtocolsStep.create(b);
|
const scan_protocols = ScanProtocolsStep.create(b);
|
||||||
|
|
||||||
|
{
|
||||||
const river = b.addExecutable("river", "src/river.zig");
|
const river = b.addExecutable("river", "src/river.zig");
|
||||||
river.setTarget(target);
|
river.setTarget(target);
|
||||||
river.setBuildMode(mode);
|
river.setBuildMode(mode);
|
||||||
river.addBuildOption(bool, "xwayland", xwayland);
|
river.addBuildOption(bool, "xwayland", xwayland);
|
||||||
addServerDeps(river, &scan_protocols.step);
|
|
||||||
|
addProtocolDeps(river, &scan_protocols.step);
|
||||||
|
addServerDeps(river);
|
||||||
|
|
||||||
river.install();
|
river.install();
|
||||||
|
|
||||||
const run_cmd = river.run();
|
const run_cmd = river.run();
|
||||||
@ -31,27 +35,37 @@ pub fn build(b: *std.build.Builder) !void {
|
|||||||
|
|
||||||
const run_step = b.step("run", "Run the compositor");
|
const run_step = b.step("run", "Run the compositor");
|
||||||
run_step.dependOn(&run_cmd.step);
|
run_step.dependOn(&run_cmd.step);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
const riverctl = b.addExecutable("riverctl", "src/riverctl.zig");
|
const riverctl = b.addExecutable("riverctl", "src/riverctl.zig");
|
||||||
riverctl.setTarget(target);
|
riverctl.setTarget(target);
|
||||||
riverctl.setBuildMode(mode);
|
riverctl.setBuildMode(mode);
|
||||||
riverctl.install();
|
|
||||||
|
|
||||||
|
addProtocolDeps(riverctl, &scan_protocols.step);
|
||||||
|
|
||||||
|
riverctl.linkLibC();
|
||||||
|
|
||||||
|
riverctl.linkSystemLibrary("wayland-client");
|
||||||
|
|
||||||
|
riverctl.install();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
const river_test = b.addTest("src/test_main.zig");
|
const river_test = b.addTest("src/test_main.zig");
|
||||||
river_test.setTarget(target);
|
river_test.setTarget(target);
|
||||||
river_test.setBuildMode(mode);
|
river_test.setBuildMode(mode);
|
||||||
river_test.addBuildOption(bool, "xwayland", xwayland);
|
river_test.addBuildOption(bool, "xwayland", xwayland);
|
||||||
addServerDeps(river_test, &scan_protocols.step);
|
|
||||||
|
addProtocolDeps(river_test, &scan_protocols.step);
|
||||||
|
addServerDeps(river_test);
|
||||||
|
|
||||||
const test_step = b.step("test", "Run the tests");
|
const test_step = b.step("test", "Run the tests");
|
||||||
test_step.dependOn(&river_test.step);
|
test_step.dependOn(&river_test.step);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn addServerDeps(exe: *std.build.LibExeObjStep, protocol_step: *std.build.Step) void {
|
fn addServerDeps(exe: *std.build.LibExeObjStep) void {
|
||||||
exe.step.dependOn(protocol_step);
|
|
||||||
exe.addIncludeDir("protocol");
|
|
||||||
exe.addCSourceFile("protocol/river-window-management-unstable-v1-protocol.c", &[_][]const u8{"-std=c99"});
|
|
||||||
|
|
||||||
exe.addCSourceFile("include/bindings.c", &[_][]const u8{"-std=c99"});
|
exe.addCSourceFile("include/bindings.c", &[_][]const u8{"-std=c99"});
|
||||||
exe.addIncludeDir(".");
|
exe.addIncludeDir(".");
|
||||||
|
|
||||||
@ -62,6 +76,12 @@ fn addServerDeps(exe: *std.build.LibExeObjStep, protocol_step: *std.build.Step)
|
|||||||
exe.linkSystemLibrary("xkbcommon");
|
exe.linkSystemLibrary("xkbcommon");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn addProtocolDeps(exe: *std.build.LibExeObjStep, protocol_step: *std.build.Step) void {
|
||||||
|
exe.step.dependOn(protocol_step);
|
||||||
|
exe.addIncludeDir("protocol");
|
||||||
|
exe.addCSourceFile("protocol/river-window-management-unstable-v1-protocol.c", &[_][]const u8{"-std=c99"});
|
||||||
|
}
|
||||||
|
|
||||||
const ScanProtocolsStep = struct {
|
const ScanProtocolsStep = struct {
|
||||||
builder: *std.build.Builder,
|
builder: *std.build.Builder,
|
||||||
step: std.build.Step,
|
step: std.build.Step,
|
||||||
@ -116,6 +136,18 @@ const ScanProtocolsStep = struct {
|
|||||||
_ = try self.builder.exec(
|
_ = try self.builder.exec(
|
||||||
&[_][]const u8{ "wayland-scanner", "private-code", xml_in_path, code_out_path },
|
&[_][]const u8{ "wayland-scanner", "private-code", xml_in_path, code_out_path },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// We need the client header as well for river-window-management
|
||||||
|
if (std.mem.eql(u8, basename_no_ext, "river-window-management-unstable-v1")) {
|
||||||
|
const client_header_out_path = try std.mem.concat(
|
||||||
|
self.builder.allocator,
|
||||||
|
u8,
|
||||||
|
&[_][]const u8{ "protocol/", basename_no_ext, "-client-protocol.h" },
|
||||||
|
);
|
||||||
|
_ = try self.builder.exec(
|
||||||
|
&[_][]const u8{ "wayland-scanner", "client-header", xml_in_path, client_header_out_path },
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -27,7 +27,8 @@
|
|||||||
A complete list of commands will be found in the man page.
|
A complete list of commands will be found in the man page.
|
||||||
TODO: write the man page.
|
TODO: write the man page.
|
||||||
</description>
|
</description>
|
||||||
<arg name="command" type="string" summary="the command to run"/>
|
<arg name="command" type="array" summary="the command to run as a series
|
||||||
|
of null-terminated strings"/>
|
||||||
</request>
|
</request>
|
||||||
|
|
||||||
<enum name="error">
|
<enum name="error">
|
||||||
|
@ -36,6 +36,7 @@ wl_global: *c.wl_global,
|
|||||||
listen_display_destroy: c.wl_listener,
|
listen_display_destroy: c.wl_listener,
|
||||||
|
|
||||||
pub fn init(self: *Self, server: *Server) !void {
|
pub fn init(self: *Self, server: *Server) !void {
|
||||||
|
self.server = server;
|
||||||
self.wl_global = c.wl_global_create(
|
self.wl_global = c.wl_global_create(
|
||||||
server.wl_display,
|
server.wl_display,
|
||||||
&c.zriver_window_manager_v1_interface,
|
&c.zriver_window_manager_v1_interface,
|
||||||
@ -72,6 +73,22 @@ fn resourceDestroy(wl_resource: ?*c.wl_resource) callconv(.C) void {
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
fn runCommand(wl_client: ?*c.wl_client, wl_resource: ?*c.wl_resource, command: ?[*:0]const u8) callconv(.C) void {
|
fn runCommand(wl_client: ?*c.wl_client, wl_resource: ?*c.wl_resource, command: ?*c.wl_array) callconv(.C) void {
|
||||||
Log.Debug.log("command: {}", .{command});
|
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 std = @import("std");
|
||||||
|
|
||||||
const c = @cImport({
|
const c = @cImport({
|
||||||
@cInclude();
|
@cInclude("wayland-client.h");
|
||||||
|
@cInclude("river-window-management-unstable-v1-client-protocol.h");
|
||||||
});
|
});
|
||||||
|
|
||||||
pub fn main() void {
|
const wl_registry_listener = c.wl_registry_listener{
|
||||||
std.debug.warn("hello world\n", .{});
|
.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 {}
|
||||||
|
Loading…
Reference in New Issue
Block a user