From cc20141b6dfc0f8721ead6a161374227c5bc61f7 Mon Sep 17 00:00:00 2001 From: Janis Date: Fri, 16 Dec 2022 17:04:03 +0100 Subject: [PATCH] image / surface spanning entire output --- main.zig | 118 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 95 insertions(+), 23 deletions(-) diff --git a/main.zig b/main.zig index c0e68a7..475789c 100644 --- a/main.zig +++ b/main.zig @@ -48,6 +48,87 @@ const Selection = struct { } }; +const Buffer = struct { + const Self = @This(); + + buffer: *wl.Buffer = undefined, + cairo: struct { + surface: *cairo.cairo_surface_t = undefined, + ctx: *cairo.cairo_t = undefined, + } = .{}, + size: Size = .{}, + data: []u8 = undefined, + + fn randomName() [13]u8 { + var name = [_]u8{'/', 'z', 'l', 'u','r','p','-','0','0','0','0','0','0'}; + + var rng = std.rand.DefaultPrng.init(@intCast(u64, std.time.milliTimestamp())); + for (name[7..]) |*c| { + c.* = rng.random().intRangeAtMost(u8, 'A', 'Z'); + } + + return name; + } + + fn init(self: *Self, shm: *wl.Shm, size: Size) !void { + const name = randomName(); + const stride = size.width * 4; + const len = stride * size.height; + + const fd = try std.os.memfd_create(&name, 0); + defer std.os.close(fd); + try std.os.ftruncate(fd, len); + + const data = try std.os.mmap( + null, + len, + std.os.PROT.READ | std.os.PROT.WRITE, + std.os.MAP.SHARED, + fd, + 0, + ); + + const pool = try shm.createPool(fd, @intCast(i32, len)); + defer pool.destroy(); + + const buffer = try pool.createBuffer( + 0, + @intCast(i32, size.width), + @intCast(i32, size.height), + @intCast(i32, stride), + .argb8888, + ); + + const surface = cairo.cairo_image_surface_create_for_data( + @ptrCast([*c]u8, data), + cairo.CAIRO_FORMAT_ARGB32, + @intCast(c_int, size.width), + @intCast(c_int, size.height), + @intCast(c_int, stride), + ) orelse return error.NoCairoSurface; + + const cairo_ctx = cairo.cairo_create(surface) orelse return error.NoCairoContext; + + self.* = .{ + .buffer = buffer, + .size = size, + .data = data, + .cairo = .{ + .surface = surface, + .ctx = cairo_ctx, + }, + }; + } + + fn deinit(self: *Self) void { + std.os.munmap(@alignCast(0x1000, self.data)); + self.buffer.destroy(); + + cairo.cairo_destroy(self.cairo.ctx); + cairo.cairo_surface_destroy(self.cairo.surface); + } +}; + const Box = struct { const Self = @This(); @@ -301,6 +382,10 @@ const Output = struct { self.output.destroy(); } + fn commitFrame(self: *Self) void { + _ = self; + } + fn xdgOutputListener(output: *zxdg.OutputV1, event: zxdg.OutputV1.Event, self: *Self) void { _ = output; @@ -336,7 +421,7 @@ const Output = struct { }; layer.ackConfigure(cfg.serial); - // TODO: send frame + self.commitFrame(); }, .closed => { self.state.removeOutput(self); @@ -832,32 +917,19 @@ const State = struct { var it = self.outputs.iterator(.forward); if (it.next()) |link| { const output = link.get(); - const os = std.os; - const buffer = blk: { - const width = 128; - const height = 128; - const stride = width * 4; - const size = stride * height; + var buffer: Buffer = undefined; + const width = output.size.width * @intCast(u32, output.scale); + const height = output.size.height * @intCast(u32, output.scale); + try buffer.init(self.shm, .{.width = width, .height = height}); + std.mem.copy(u8, buffer.data, @embedFile("cat.bgra")); - const fd = try os.memfd_create("hello-zig-wayland", 0); - try os.ftruncate(fd, size); - const data = try os.mmap(null, size, os.PROT.READ | os.PROT.WRITE, os.MAP.SHARED, fd, 0); - std.mem.copy(u8, data, @embedFile("cat.bgra")); - - const pool = try self.shm.createPool(fd, size); - defer pool.destroy(); - - break :blk try pool.createBuffer(0, width, height, stride, wl.Shm.Format.argb8888); - }; - defer buffer.destroy(); - - output.surface.attach(buffer, 0, 0); + output.surface.attach(buffer.buffer, 0, 0); output.surface.commit(); + } - while (self.running) { - if (self.dpy.dispatch() != .SUCCESS) return error.DispatchFailed; - } + while (self.running) { + if (self.dpy.dispatch() != .SUCCESS) return error.DispatchFailed; } }