const std = @import("std"); const wayland = @import("../../root.zig"); const wl = wayland.wl; const Format = wl.Shm.Format; const AnonymousFile = wl.Shm.AnonymousFile; const Self = @This(); const log = std.log.scoped(.@"wl.shm.pool"); pub const Events = wayland.EventSet(@This(), .{}); pub const Request = union(enum) { create_buffer: struct { wayland.Object.Ref, u32, u32, u32, u32, Format }, destroy: void, resize: struct { u32 }, }; handle: wayland.Object.Ref, file: AnonymousFile, buffer: []u8, pub fn init( self: *Self, ctx: 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: wayland.Context) void { self.file.close(); std.posix.munmap(@alignCast(self.buffer)); ctx.display.registry.disable_object(self.handle); ctx.display.request(self, .{ .destroy = {} }) catch |e| { log.err("error on deinit: {}", .{e}); }; self.* = undefined; } pub fn create_buffer( self: *Self, ctx: wayland.Context, offset: usize, width: usize, height: usize, comptime format: Format, ) !*wl.Buffer(format) { const stride = width * format.bytes_per_pixel(); const data = self.buffer[offset..offset + stride * height]; const buffer = try ctx.allocator.create(wl.Buffer(format)); errdefer ctx.allocator.destroy(buffer); try buffer.init( ctx, width, height, data, ); try ctx.display.request( self, .{ .create_buffer = .{ buffer.handle, @truncate(offset), @truncate(width), @truncate(height), @truncate(stride), format, } } ); return buffer; }