aboutsummaryrefslogtreecommitdiff
path: root/src/wl/registry.zig
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2025-08-18 17:45:13 +0200
committerNathan Reiner <nathan@nathanreiner.xyz>2025-08-18 17:45:13 +0200
commit33e1de2710fe44512440e0e6055578d67dab330c (patch)
treedf8198ac5147f466bba600ca06dc1a319099d185 /src/wl/registry.zig
First sketch of wayland interface
**WARNING** this implementation is not working properly yet.
Diffstat (limited to 'src/wl/registry.zig')
-rw-r--r--src/wl/registry.zig96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/wl/registry.zig b/src/wl/registry.zig
new file mode 100644
index 0000000..e4eb3a8
--- /dev/null
+++ b/src/wl/registry.zig
@@ -0,0 +1,96 @@
+const std = @import("std");
+const wayland = @import("../root.zig");
+const wl = wayland.wl;
+
+const log = std.log.scoped(.registry);
+
+const Self = @This();
+
+pub const Events = wayland.EventSet(Self, .{
+ global,
+ global_remove,
+});
+
+pub const Request = union(enum) {
+ bind: struct { u32, u32 },
+};
+
+pub const GlobalHandler = struct {
+ interface: []const u8,
+ version: u32,
+ handler: *const fn (ctx: *wayland.Context) ?wayland.Object,
+};
+
+objects: std.ArrayListUnmanaged(?*wayland.Object) = .empty,
+interface: wayland.Object,
+handlers: []const GlobalHandler,
+
+pub fn init(
+ self: *Self,
+ allocator: std.mem.Allocator,
+ display: *wl.Display,
+ handlers: []const GlobalHandler,
+) !void {
+ self.* = .{
+ .interface = wayland.Object.from_self(self),
+ .handlers = handlers,
+ };
+ try self.objects.append(allocator, null);
+ try self.objects.append(allocator, &display.interface);
+ try self.objects.append(allocator, &self.interface);
+
+ display.interface.id = 1;
+ self.interface.id = 2;
+
+ try display.request(display, .{ .get_registry = .{&self.interface} });
+}
+
+pub fn add_object(
+ self: *Self,
+ allocator: std.mem.Allocator,
+ object: *wayland.Object,
+) !void {
+ for (self.objects.items[1..], 1..) |obj, index| {
+ if (obj == null) {
+ object.id = @truncate(index);
+ self.objects.items[index] = object;
+ return;
+ }
+ }
+
+ object.id = @truncate(self.objects.items.len);
+ try self.objects.append(allocator, object);
+}
+
+pub fn release_object(self: *Self, id: u32) void {
+ self.objects.items[id] = null;
+}
+
+fn global(
+ self: *Self,
+ ctx: *wayland.Context,
+ name: u32,
+ interface: []const u8,
+ version: u32,
+) !void {
+ for (self.handlers) |handler| {
+ if (version == handler.version and std.mem.eql(u8, interface, handler.interface)) {
+ if (handler.handler(ctx)) |object| {
+ try ctx.display.request(self, .{ .bind = .{
+ name,
+ object.id orelse return error.UnregisteredObject,
+ } });
+ }
+ }
+ }
+}
+
+fn global_remove(
+ self: *Self,
+ ctx: *wayland.Context,
+ name: u32,
+) void {
+ _ = self;
+ _ = ctx;
+ log.debug("remove_global: {}", .{name});
+}