zayneko/src/main.zig
2025-05-18 00:27:28 +02:00

135 lines
4.2 KiB
Zig

const std = @import("std");
const mem = std.mem;
const posix = std.posix;
const wayland = @import("wayland");
const wl = wayland.client.wl;
const zwlr = wayland.client.zwlr;
const layer_shell = zwlr.common.zwlr.layer_shell_v1;
const Context = struct {
shm: ?*wl.Shm = null,
shell: *zwlr.LayerShellV1 = undefined,
surface: *wl.Surface = undefined,
layer_surface: *zwlr.LayerSurfaceV1 = undefined,
buffer: ?*wl.Buffer = null,
compositor: *wl.Compositor = undefined,
blk: []u32 = undefined,
width: i32 = 0,
height: i32 = 0,
};
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const display = try wl.Display.connect(null);
defer display.disconnect();
const registry = try display.getRegistry();
defer registry.destroy();
var context = Context{};
registry.setListener(*Context, registryListener, &context);
if (display.roundtrip() != .SUCCESS) return error.RoundtripFailed;
context.surface = try context.compositor.createSurface();
defer context.surface.destroy();
context.layer_surface = try context.shell.getLayerSurface(context.surface, null, .top, "zayneko");
defer context.layer_surface.destroy();
context.layer_surface.setExclusiveZone(20);
context.layer_surface.setAnchor(.{
.top = true,
.bottom = false,
.left = true,
.right = true,
});
context.layer_surface.setSize(0, 20);
context.layer_surface.setListener(*Context, layerSurfaceListener, &context);
context.surface.commit();
if (display.roundtrip() != .SUCCESS) return error.RoundtripFailed;
std.debug.print("{}\n", .{context.blk.len});
for (context.blk) |*a|
// a.* = if (i < 2000) 0 else 0xFFFFFFFF;
a.* = 0xFFFFFFFF;
context.surface.attach(context.buffer, 0, 0);
context.surface.damageBuffer(0, 0, context.width, context.height);
context.surface.commit();
_ = display.flush();
if (display.dispatchPending() != .SUCCESS) return error.DispatchFailed;
std.time.sleep(4000000000);
}
fn registryListener(
registry: *wl.Registry,
event: wl.Registry.Event,
context: *Context,
) void {
switch (event) {
.global => |global| {
if (mem.orderZ(u8, global.interface, wl.Shm.interface.name) == .eq) {
context.shm = registry.bind(global.name, wl.Shm, 1) catch return;
} else if (mem.orderZ(u8, global.interface, zwlr.LayerShellV1.interface.name) == .eq) {
context.shell = registry.bind(global.name, zwlr.LayerShellV1, 4) catch return;
} else if (mem.orderZ(u8, global.interface, wl.Compositor.interface.name) == .eq) {
context.compositor = registry.bind(global.name, wl.Compositor, 5) catch return;
}
},
.global_remove => {},
}
}
fn layerSurfaceListener(
surface: *zwlr.LayerSurfaceV1,
event: zwlr.LayerSurfaceV1.Event,
context: *Context,
) void {
switch (event) {
.configure => |configure| {
surface.ackConfigure(configure.serial);
context.buffer = blk: {
const width: i32 = @intCast((configure.width));
const height: i32 = @intCast((configure.height));
context.width = width;
context.height = height;
const stride: i32 = width * 4;
const size: i32 = stride * height;
const sizeu = configure.width * configure.height * 4;
const fd = posix.memfd_create("zayneko", 0) catch return;
posix.ftruncate(fd, sizeu) catch return;
const tmp align(@alignOf(u32)) = posix.mmap(null, sizeu, posix.PROT.READ | posix.PROT.WRITE, .{ .TYPE = .SHARED }, fd, 0) catch return;
context.blk = mem.bytesAsSlice(u32, tmp);
const pool = context.shm.?.createPool(fd, size) catch return;
defer pool.destroy();
break :blk pool.createBuffer(0, width, height, stride, .argb8888) catch null;
};
context.surface.attach(context.buffer, 0, 0);
context.surface.commit();
},
.closed => {},
}
}