aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ancillary-data.zig38
-rw-r--r--src/event-set.zig4
-rw-r--r--src/main.zig26
-rw-r--r--src/object.zig22
-rw-r--r--src/wl/callback.zig6
-rw-r--r--src/wl/compositor.zig4
-rw-r--r--src/wl/display.zig87
-rw-r--r--src/wl/output/root.zig16
-rw-r--r--src/wl/registry.zig8
-rw-r--r--src/wl/shm/anonymous-file.zig53
-rw-r--r--src/wl/shm/pool.zig37
-rw-r--r--src/wl/shm/root.zig25
12 files changed, 248 insertions, 78 deletions
diff --git a/src/ancillary-data.zig b/src/ancillary-data.zig
index 0754720..667ba1f 100644
--- a/src/ancillary-data.zig
+++ b/src/ancillary-data.zig
@@ -18,47 +18,47 @@ const ControlMessage = extern struct {
};
header: Header,
- payload: union {
+ payload: extern union {
fd: [255]std.posix.fd_t,
},
pub fn alignment(length: usize) usize {
- return (length + @sizeOf(usize) - 1) & ~(@sizeOf(usize) - 1);
+ return (length + @sizeOf(usize) - 1) & ~(@as(usize, @sizeOf(usize) - 1));
}
- pub fn space(self: @This()) usize {
- return self.alignment(self.length) + self.alignment(@sizeOf(Header));
+ pub fn space(length: usize) usize {
+ return alignment(length) + alignment(@sizeOf(Header));
}
pub fn from_fds(fds: []std.posix.fd_t) @This() {
- var self: @This() = .{
- };
+ var self: @This() = undefined;
- self.level = .socket;
- self.kind = .rights;
- self.length = self.alignment(@sizeOf(Header)) + (fds.len * @sizeOf(std.posix.fd_t));
+ self.header.level = .socket;
+ self.header.kind = .rights;
+ self.header.length = alignment(@sizeOf(Header)) + (fds.len * @sizeOf(std.posix.fd_t));
- @memcpy(self.payload, fds);
+ @memcpy(self.payload.fd[0..fds.len], fds);
+
+ return self;
}
};
-pub fn send_fds(socket: std.posix.socket_t, fds: []std.posix.fd_t) !void {
- var iobuf: [1]u8 = std.mem.zeroes([1]u8);
+pub fn send_fds(socket: std.posix.socket_t, fds: []std.posix.fd_t, data: []const u8) !void {
+ var cmsg: ControlMessage = .from_fds(fds);
const io = std.posix.iovec {
- .base = &iobuf,
- .len = iobuf.len,
+ .base = @constCast(@ptrCast(data)),
+ .len = data.len,
};
- var cmsg: ControlMessage = .from_fds(fds);
-
const msghdr = std.posix.msghdr_const {
.name = null,
.namelen = 0,
- .iov = &io,
- .iolen = 1,
+ .iov = @ptrCast(&io),
+ .iovlen = 1,
.control = &cmsg,
- .controllen = cmsg.control_length(),
+ .controllen = @intCast(ControlMessage.space(fds.len)),
+ .flags = 0,
};
_ = try std.posix.sendmsg(socket, &msghdr, 0);
diff --git a/src/event-set.zig b/src/event-set.zig
index 27c28bf..da17734 100644
--- a/src/event-set.zig
+++ b/src/event-set.zig
@@ -3,7 +3,7 @@ const wayland = @import("root.zig");
pub fn EventSet(T: type, events: anytype) type {
return struct {
- pub fn on_event(ptr: *anyopaque, ctx: *wayland.Context, opcode: u16, args: []const u8) void {
+ pub fn on_event(ptr: *anyopaque, ctx: *const wayland.Context, opcode: u16, args: []const u8) void {
var offset: usize = 0;
inline for (events, 0..) |event, index| {
if (@TypeOf(event) != @TypeOf(null) and index == opcode) {
@@ -66,7 +66,7 @@ test {
a: u32 = 0,
b: u32 = 0,
- pub fn something(self: *@This(), _: *wayland.Context, a: u32, b: u32) void {
+ pub fn something(self: *@This(), _: *const wayland.Context, a: u32, b: u32) void {
self.a = a;
self.b = b;
}
diff --git a/src/main.zig b/src/main.zig
index b6806be..b822109 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -2,6 +2,14 @@ const std = @import("std");
const wayland = @import("wayland");
const wl = wayland.wl;
+const log = std.log.scoped(.main);
+
+pub const std_options = std.Options{
+ .log_scope_levels = &.{
+ .{ .scope = .registry, .level = .info },
+ }
+};
+
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
@@ -17,15 +25,27 @@ pub fn main() !void {
try display.roundtrip(allocator);
try display.roundtrip(allocator);
+ const ctx: wayland.Context = .{
+ .allocator = allocator,
+ .display = &display,
+ };
+
+ try display.roundtrip(allocator);
+
for (wl.Output.instances.items) |output| {
- std.debug.print("{}\n", .{output});
+ log.debug("{}", .{output});
}
for (wl.Compositor.instances.items) |compositor| {
- std.debug.print("{}\n", .{compositor});
+ log.debug("{}", .{compositor});
}
for (wl.Shm.instances.items) |shm| {
- std.debug.print("{}\n", .{shm});
+ log.debug("{}", .{shm});
}
+
+ const pool = try wl.Shm.instances.items[0].create_pool(&ctx, 1024);
+ defer pool.deinit(&ctx);
+
+ try display.roundtrip(allocator);
}
diff --git a/src/object.zig b/src/object.zig
index 14089c1..5502d3d 100644
--- a/src/object.zig
+++ b/src/object.zig
@@ -6,13 +6,24 @@ const Self = @This();
pub const Ref = usize;
const VTable = struct {
- on_event: *const fn (ptr: *anyopaque, ctx: *wayland.Context, opcode: u16, args: []const u8) void,
+ on_event: *const fn (
+ ptr: *anyopaque,
+ ctx: *const wayland.Context,
+ opcode: u16,
+ args: []const u8,
+ ) void,
};
ptr: ?*anyopaque,
vtable: VTable,
+name: []const u8,
-pub inline fn on_event(self: *Self, ctx: *wayland.Context, opcode: u16, args: []const u8) !void {
+pub inline fn on_event(
+ self: *Self,
+ ctx: *const wayland.Context,
+ opcode: u16,
+ args: []const u8,
+) !void {
if (self.ptr) |ptr| {
self.vtable.on_event(ptr, ctx, opcode, args);
} else {
@@ -21,11 +32,14 @@ pub inline fn on_event(self: *Self, ctx: *wayland.Context, opcode: u16, args: []
}
pub inline fn from_self(ptr: anytype) Self {
+ const T = @TypeOf(ptr.*);
+
return .{
.ptr = ptr,
.vtable = VTable{
- .on_event = @TypeOf(ptr.*).Events.on_event,
+ .on_event = T.Events.on_event,
},
+ .name = @typeName(T),
};
}
@@ -42,5 +56,5 @@ pub fn format(
_ = fmt;
_ = options;
- try writer.print("Object {{ {?} }}", .{self.ptr});
+ try writer.print("Object<{s}> {{ {?} }}", .{self.name, self.ptr});
}
diff --git a/src/wl/callback.zig b/src/wl/callback.zig
index c17e190..24927b4 100644
--- a/src/wl/callback.zig
+++ b/src/wl/callback.zig
@@ -13,7 +13,7 @@ handle: wayland.Object.Ref,
pub fn init(
self: *Self,
- ctx: *wayland.Context,
+ ctx: *const wayland.Context,
is_done: *bool,
) !void {
self.is_done = is_done;
@@ -25,11 +25,11 @@ pub fn init(
}
-pub fn deinit(self: *Self, ctx: *wayland.Context) void {
+pub fn deinit(self: *Self, ctx: *const wayland.Context) void {
ctx.display.registry.disable_object(self.handle);
}
-fn done(self: *Self, ctx: *wayland.Context, value: u32) void {
+fn done(self: *Self, ctx: *const wayland.Context, value: u32) void {
_ = value;
_ = ctx;
self.is_done.* = true;
diff --git a/src/wl/compositor.zig b/src/wl/compositor.zig
index 6951446..18db0f0 100644
--- a/src/wl/compositor.zig
+++ b/src/wl/compositor.zig
@@ -22,7 +22,7 @@ pub const handler: wl.Registry.GlobalHandler = .{
pub fn init(
self: *Self,
- ctx: *wayland.Context
+ ctx: *const wayland.Context
) !void {
self.* = .{
.handle = try ctx.display.registry.add_object(
@@ -32,7 +32,7 @@ pub fn init(
};
}
-fn register(ctx: *wayland.Context) ?wayland.Object.Ref {
+fn register(ctx: *const wayland.Context) ?wayland.Object.Ref {
const compositor = ctx.allocator.create(Self) catch return null;
compositor.init(ctx) catch return null;
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);
}
diff --git a/src/wl/output/root.zig b/src/wl/output/root.zig
index ce2169f..f4ca36d 100644
--- a/src/wl/output/root.zig
+++ b/src/wl/output/root.zig
@@ -38,7 +38,7 @@ handle: wayland.Object.Ref,
pub fn init(
self: *Self,
- ctx: *wayland.Context,
+ ctx: *const wayland.Context,
) !void {
self.* = .{
.handle = try ctx.display.registry.add_object(
@@ -58,7 +58,7 @@ pub const handler: wl.Registry.GlobalHandler = .{
.handler = register,
};
-fn register(ctx: *wayland.Context) ?wayland.Object.Ref {
+fn register(ctx: *const wayland.Context) ?wayland.Object.Ref {
const output = ctx.allocator.create(Self) catch return null;
output.init(ctx) catch return null;
@@ -68,7 +68,7 @@ fn register(ctx: *wayland.Context) ?wayland.Object.Ref {
fn geometry(
self: *Self,
- ctx: *wayland.Context,
+ ctx: *const wayland.Context,
x: u32,
y: u32,
physical_width: u32,
@@ -93,7 +93,7 @@ fn geometry(
fn mode(
self: *Self,
- ctx: *wayland.Context,
+ ctx: *const wayland.Context,
flags: Mode.Kind,
width: u32,
height: u32,
@@ -108,7 +108,7 @@ fn mode(
};
}
-fn done(self: *Self, ctx: *wayland.Context) void {
+fn done(self: *Self, ctx: *const wayland.Context) void {
if (self.info) |info| {
ctx.allocator.free(info.name);
ctx.allocator.free(info.description);
@@ -117,17 +117,17 @@ fn done(self: *Self, ctx: *wayland.Context) void {
self.info = self.staging;
}
-fn scale(self: *Self, ctx: *wayland.Context, factor: u32) void {
+fn scale(self: *Self, ctx: *const wayland.Context, factor: u32) void {
_ = ctx;
self.staging.scale = factor;
}
-fn name(self: *Self, ctx: *wayland.Context, n: []const u8) !void {
+fn name(self: *Self, ctx: *const wayland.Context, n: []const u8) !void {
self.staging.name = try ctx.allocator.alloc(u8, n.len);
@memcpy(@constCast(self.staging.name), n);
}
-fn description(self: *Self, ctx: *wayland.Context, d: []const u8) !void {
+fn description(self: *Self, ctx: *const wayland.Context, d: []const u8) !void {
self.staging.description = try ctx.allocator.alloc(u8, d.len);
@memcpy(@constCast(self.staging.description), d);
}
diff --git a/src/wl/registry.zig b/src/wl/registry.zig
index 6c8ebdc..0939d17 100644
--- a/src/wl/registry.zig
+++ b/src/wl/registry.zig
@@ -18,7 +18,7 @@ pub const Request = union(enum) {
pub const GlobalHandler = struct {
interface: []const u8,
version: u32,
- handler: *const fn (ctx: *wayland.Context) ?wayland.Object.Ref,
+ handler: *const fn (ctx: *const wayland.Context) ?wayland.Object.Ref,
};
objects: std.ArrayListUnmanaged(?wayland.Object) = .empty,
@@ -52,7 +52,7 @@ pub fn add_object(
self: *Self,
allocator: std.mem.Allocator,
object: wayland.Object,
-) !usize {
+) !wayland.Object.Ref {
for (self.objects.items[1..], 1..) |obj, index| {
if (obj == null) {
self.objects.items[index] = object;
@@ -83,7 +83,7 @@ pub fn get(self: *Self, handle: usize) ?*wayland.Object {
fn global(
self: *Self,
- ctx: *wayland.Context,
+ ctx: *const wayland.Context,
name: u32,
interface: []const u8,
version: u32,
@@ -105,7 +105,7 @@ fn global(
fn global_remove(
self: *Self,
- ctx: *wayland.Context,
+ ctx: *const wayland.Context,
name: u32,
) void {
_ = self;
diff --git a/src/wl/shm/anonymous-file.zig b/src/wl/shm/anonymous-file.zig
new file mode 100644
index 0000000..f73fbc9
--- /dev/null
+++ b/src/wl/shm/anonymous-file.zig
@@ -0,0 +1,53 @@
+const std = @import("std");
+
+const Self = @This();
+
+size: usize = 0,
+name: [24]u8 = undefined,
+fd: std.posix.fd_t = undefined,
+
+pub fn init_random() !Self {
+ var buf: [8]u8 = undefined;
+ try std.posix.getrandom(&buf);
+
+ var self: Self = .{};
+
+ const name = std.fmt.bufPrint(&self.name, "/wl.shm.{x}{x}{x}{x}{x}{x}{x}{x}", .{
+ buf[0],
+ buf[1],
+ buf[2],
+ buf[3],
+ buf[4],
+ buf[5],
+ buf[6],
+ buf[7],
+ }) catch unreachable;
+
+ self.fd = try std.posix.memfd_create(name, 0);
+
+ return self;
+}
+
+pub fn truncate(self: *Self, size: usize) !void {
+ try std.posix.ftruncate(self.fd, size);
+ self.size = size;
+}
+
+pub fn mmap(self: *Self) ![]u8 {
+ return std.posix.mmap(
+ null,
+ self.size,
+ std.os.linux.PROT.READ | std.os.linux.PROT.WRITE,
+ .{
+ .TYPE = .SHARED,
+ .ANONYMOUS = true,
+ },
+ self.fd,
+ 0,
+ );
+}
+
+pub fn close(self: *Self) void {
+ std.posix.close(self.fd);
+ self.* = undefined;
+}
diff --git a/src/wl/shm/pool.zig b/src/wl/shm/pool.zig
index dc30d1b..1f42a17 100644
--- a/src/wl/shm/pool.zig
+++ b/src/wl/shm/pool.zig
@@ -1,5 +1,10 @@
+const std = @import("std");
const wayland = @import("../../root.zig");
-const Format = @import("root.zig").Format;
+const wl = wayland.wl;
+const Format = wl.Shm.Format;
+const AnonymousFile = wl.Shm.AnonymousFile;
+
+const Self = @This();
pub const Events = wayland.EventSet(@This(), .{});
pub const Requests = union(enum) {
@@ -7,3 +12,33 @@ pub const Requests = union(enum) {
destroy: struct {},
resize: struct { u32 },
};
+
+handle: wayland.Object.Ref,
+file: AnonymousFile,
+buffer: []u8,
+
+pub fn init(
+ self: *Self,
+ ctx: *const wayland.Context,
+ size: usize,
+) !void {
+ var file = try AnonymousFile.init_random();
+ errdefer file.close();
+ try file.truncate(size);
+
+ self.* = .{
+ .handle = try ctx.display.registry.add_object(
+ ctx.allocator,
+ wayland.Object.from_self(self),
+ ),
+ .file = file,
+ .buffer = try file.mmap(),
+ };
+}
+
+pub fn deinit(self: *Self, ctx: *const wayland.Context) void {
+ self.file.close();
+ std.posix.munmap(@alignCast(self.buffer));
+ ctx.display.registry.disable_object(self.handle);
+ self.* = undefined;
+}
diff --git a/src/wl/shm/root.zig b/src/wl/shm/root.zig
index 2d24aca..fd96727 100644
--- a/src/wl/shm/root.zig
+++ b/src/wl/shm/root.zig
@@ -4,12 +4,13 @@ const wl = wayland.wl;
pub const Pool = @import("pool.zig");
pub const Format = @import("format.zig").Format;
+pub const AnonymousFile = @import("anonymous-file.zig");
const Self = @This();
pub const Events = wayland.EventSet(Self, .{ announce_format });
-pub const Requests = union(enum) {
- create_pool: struct { u32, wayland.types.Fd, u32 },
+pub const Request = union(enum) {
+ create_pool: struct { wayland.Object.Ref, wayland.types.Fd, u32 },
};
pub var instances: std.ArrayListUnmanaged(*Self) = .empty;
@@ -19,7 +20,7 @@ formats: std.EnumSet(Format) = .initEmpty(),
pub fn init(
self: *Self,
- ctx: *wayland.Context,
+ ctx: *const wayland.Context,
) !void {
self.* = .{
.handle = try ctx.display.registry.add_object(
@@ -29,7 +30,7 @@ pub fn init(
};
}
-fn announce_format(self: * Self, ctx: *wayland.Context, fmt: Format) void {
+fn announce_format(self: * Self, ctx: *const wayland.Context, fmt: Format) void {
_ = ctx;
self.formats.insert(fmt);
}
@@ -40,7 +41,7 @@ pub const handler: wl.Registry.GlobalHandler = .{
.handler = register,
};
-fn register(ctx: *wayland.Context) ?wayland.Object.Ref {
+fn register(ctx: *const wayland.Context) ?wayland.Object.Ref {
const shm = ctx.allocator.create(Self) catch return null;
shm.init(ctx) catch return null;
@@ -48,6 +49,20 @@ fn register(ctx: *wayland.Context) ?wayland.Object.Ref {
return shm.handle;
}
+pub fn create_pool(self: *Self, ctx: *const wayland.Context, size: usize) !*Pool {
+ const pool = try ctx.allocator.create(Pool);
+ errdefer ctx.allocator.destroy(pool);
+ try pool.init(ctx, size);
+
+ try ctx.display.request(self, .{ .create_pool = .{
+ pool.handle,
+ .{ .fd = pool.file.fd },
+ @truncate(size)
+ } });
+
+ return pool;
+}
+
pub fn format(
self: *const Self,
comptime fmt: []const u8,