aboutsummaryrefslogtreecommitdiff
path: root/src/wl/display.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/wl/display.zig')
-rw-r--r--src/wl/display.zig87
1 files changed, 60 insertions, 27 deletions
diff --git a/src/wl/display.zig b/src/wl/display.zig
index 3b5087d..c9e2e6e 100644
--- a/src/wl/display.zig
+++ b/src/wl/display.zig
@@ -86,7 +86,7 @@ pub fn request(self: *Self, object: anytype, args: @TypeOf(object.*).Request) !v
const id: u32 = @truncate(object.handle);
var size: u32 = 8;
- comptime var fds: []std.posix.fd_t = &.{};
+ comptime var count_fds = 0;
inline for (data) |value| {
switch (@TypeOf(value)) {
@@ -97,7 +97,7 @@ pub fn request(self: *Self, object: anytype, args: @TypeOf(object.*).Request) !v
const padding_size: usize = padding_len(u8, value.len + 1);
size += @as(u32, @intCast(@sizeOf(u32) + (value.len + 1) + padding_size));
},
- wayland.types.Fd => |fd| fds = fds ++ .{ fd },
+ wayland.types.Fd => count_fds += 1,
else => |t| switch (@typeInfo(t)) {
.pointer => |ptr| if (ptr.size == .slice) {
const padding_size: usize = padding_len(ptr.child, value.len);
@@ -108,14 +108,30 @@ pub fn request(self: *Self, object: anytype, args: @TypeOf(object.*).Request) !v
}
}
- _ = try self.stream.writeAll(&std.mem.toBytes(id));
+ {
+ var fds: [count_fds]std.posix.fd_t = undefined;
+ comptime var current_fd_index = 0;
+
+ inline for (data) |value| {
+ switch (@TypeOf(value)) {
+ wayland.types.Fd => {
+ fds[current_fd_index] = value.fd;
+ current_fd_index += 1;
+ },
+ else => {},
+ }
+ }
+
+ try ancillary_data.send_fds(self.stream.handle, &fds, std.mem.asBytes(&id));
+ }
+
_ = try self.stream.writeAll(&std.mem.toBytes((size << 16) | opcode));
inline for (data) |value| {
switch (@TypeOf(value)) {
u32, i32 => _ = try self.stream.writeAll(std.mem.asBytes(&value)),
wayland.Object.Ref => try self.stream.writeAll(std.mem.asBytes(&(@as(u32, @truncate(value))))),
- ?wayland.Object.Ref => try self.stream.writeAll(std.mem.asBytes(&(@as(u32, 0)))),
+ ?wayland.Object.Ref => try self.stream.writeAll(std.mem.asBytes(&(@as(u32, @truncate(if (value) |v| v else 0))))),
[]const u8, []u8 => {
const padding_size: usize = padding_len(u8, value.len + 1);
_ = try self.stream.writeAll(std.mem.asBytes(&@as(u32, @truncate(value.len + 1))));
@@ -124,10 +140,10 @@ pub fn request(self: *Self, object: anytype, args: @TypeOf(object.*).Request) !v
_ = try self.stream.writeAll(std.mem.asBytes(&@as(u8, 0)));
}
},
- wayland.types.Fd => {},
+ wayland.types.Fd => { },
else => |t| switch (@typeInfo(t)) {
.pointer => |ptr| if (ptr.size == .slice) {
- const padding_size: usize = @mod(@as(usize, @bitCast(-@as(isize, @intCast(value.len * @sizeOf(ptr.child))))), 4);
+ const padding_size: usize = padding_len(ptr.child, value.len);
_ = try self.stream.writeAll(std.mem.asBytes(&@as(u32, @truncate(value.len))));
_ = try self.stream.writeAll(std.mem.sliceAsBytes(value));
for (0..padding_size) |_| {
@@ -139,10 +155,6 @@ pub fn request(self: *Self, object: anytype, args: @TypeOf(object.*).Request) !v
}
}
- if (fds.len > 0) {
- try ancillary_data.send_fds(self.stream.handle, fds);
- }
-
return;
}
}
@@ -150,7 +162,7 @@ pub fn request(self: *Self, object: anytype, args: @TypeOf(object.*).Request) !v
return error.InvalidOpcode;
}
-fn read_event(self: *Self, ctx: *wayland.Context) !void {
+fn read_event(self: *Self, ctx: *const wayland.Context) !void {
const endian = @import("builtin").target.cpu.arch.endian();
const reader = self.stream.reader();
@@ -200,7 +212,7 @@ pub fn roundtrip(self: *Self, allocator: std.mem.Allocator) !void {
fn err(
self: *Self,
- ctx: *wayland.Context,
+ ctx: *const wayland.Context,
object: *wayland.Object,
code: u32,
message: []const u8,
@@ -212,7 +224,7 @@ fn err(
fn delete_id(
self: *Self,
- ctx: *wayland.Context,
+ ctx: *const wayland.Context,
id: u32,
) void {
_ = ctx;
@@ -226,6 +238,7 @@ test "request" {
req2: struct { wayland.Object.Ref },
req3: struct { []const u8 },
req4: struct { []const u16 },
+ req5: struct { wayland.types.Fd },
};
pub const Events = wayland.EventSet(@This(), .{});
@@ -237,66 +250,86 @@ test "request" {
}
};
- const in, const out = try std.posix.pipe();
- defer std.posix.close(in);
+ var tmpdir = std.testing.tmpDir(.{});
+ defer tmpdir.cleanup();
+
+ var pathbuf: [std.fs.max_path_bytes]u8 = undefined;
+ var dirbuf: [std.fs.max_path_bytes]u8 = undefined;
+ const path = try std.fmt.bufPrint(&pathbuf, "{s}/testing", .{try tmpdir.dir.realpath(".", &dirbuf)});
+
+ const address = try std.net.Address.initUnix(path);
+ var server = try address.listen(.{});
{
var sample: Sample = .init();
- var displ: Self = .from_fd(out);
+ var displ: Self = try .open(path);
defer displ.deinit(std.testing.allocator);
try displ.init(std.testing.allocator, &.{});
try displ.request(&sample, .{ .req1 = .{432} });
try displ.request(&sample, .{ .req2 = .{sample.handle} });
try displ.request(&sample, .{ .req3 = .{"abcd"} });
try displ.request(&sample, .{ .req4 = .{&[_]u16{ 1, 32, 4, 5, 5 }} });
+ try displ.request(&sample, .{ .req5 = .{ .{ .fd = displ.stream.handle } } });
}
- const file = std.fs.File{ .handle = in };
+ const conn = try server.accept();
+ const file = conn.stream;
var test_buffer: [64]u8 = undefined;
- _ = try file.readAll(test_buffer[0..12]);
+ var size = try file.readAll(test_buffer[0..12]);
try std.testing.expectEqualSlices(
u8,
&(std.mem.toBytes(@as(u32, 1)) ++
std.mem.toBytes(@as(u32, (12 << 16) | 1)) ++
std.mem.toBytes(@as(u32, 2))),
- test_buffer[0..12],
+ test_buffer[0..size],
);
- _ = try file.readAll(test_buffer[0..12]);
+ size = try file.readAll(test_buffer[0..12]);
try std.testing.expectEqualSlices(
u8,
&(std.mem.toBytes(@as(u32, 42)) ++
std.mem.toBytes(@as(u32, (12 << 16) | 0)) ++
std.mem.toBytes(@as(u32, 432))),
- test_buffer[0..12],
+ test_buffer[0..size],
);
- _ = try file.readAll(test_buffer[0..12]);
+ size = try file.readAll(test_buffer[0..12]);
try std.testing.expectEqualSlices(
u8,
&(std.mem.toBytes(@as(u32, 42)) ++
std.mem.toBytes(@as(u32, (12 << 16) | 1)) ++
std.mem.toBytes(@as(u32, 42))),
- test_buffer[0..12],
+ test_buffer[0..size],
);
- _ = try file.readAll(test_buffer[0..20]);
+ size = try file.readAll(test_buffer[0..20]);
try std.testing.expectEqualSlices(
u8,
&(std.mem.toBytes(@as(u32, 42)) ++
std.mem.toBytes(@as(u32, (20 << 16) | 2)) ++
std.mem.toBytes(@as(u32, 5))) ++ "abcd\x00\x00\x00\x00",
- test_buffer[0..20],
+ test_buffer[0..size],
);
- _ = try file.readAll(test_buffer[0..24]);
+ size = try file.readAll(test_buffer[0..24]);
try std.testing.expectEqualSlices(
u8,
&(std.mem.toBytes(@as(u32, 42)) ++
std.mem.toBytes(@as(u32, (24 << 16) | 3)) ++
std.mem.toBytes(@as(u32, 5))) ++ std.mem.toBytes([_]u16{ 1, 32, 4, 5, 5, 0 }),
- test_buffer[0..24],
+ test_buffer[0..size],
+ );
+
+ size = try file.readAll(test_buffer[0..8]);
+ try std.testing.expectEqualSlices(
+ u8,
+ &(std.mem.toBytes(@as(u32, 42)) ++
+ std.mem.toBytes(@as(u32, (8 << 16) | 4))),
+ test_buffer[0..size],
);
+
+ size = try file.readAll(test_buffer[0..]);
+ try std.testing.expectEqual(0, size);
}