image / surface spanning entire output

This commit is contained in:
Janis 2022-12-16 17:04:03 +01:00
parent 9d234eab11
commit cc20141b6d

118
main.zig
View file

@ -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;
}
}