136 lines
4.2 KiB
Zig
136 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 => {},
|
||
|
}
|
||
|
}
|