aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2025-08-22 20:12:56 +0200
committerNathan Reiner <nathan@nathanreiner.xyz>2025-08-22 20:12:56 +0200
commit956ecb061b1862a4b632c8d5d6b6fa4318e1f640 (patch)
treef00adc9bfced275f280239b25a2b2ae15f57765b
parent33e1de2710fe44512440e0e6055578d67dab330c (diff)
object refactor and add wl output
Now the Object is held by the registry instead of the struct its referencing and the struct only has a `handle` which is a usize.
-rw-r--r--src/event-set.zig8
-rw-r--r--src/main.zig6
-rw-r--r--src/object.zig9
-rw-r--r--src/wl/callback.zig19
-rw-r--r--src/wl/display.zig128
-rw-r--r--src/wl/output/geometry.zig12
-rw-r--r--src/wl/output/mode.zig26
-rw-r--r--src/wl/output/root.zig (renamed from src/wl/output.zig)85
-rw-r--r--src/wl/output/subpixel.zig8
-rw-r--r--src/wl/output/transform.zig10
-rw-r--r--src/wl/registry.zig52
-rw-r--r--src/wl/root.zig2
12 files changed, 231 insertions, 134 deletions
diff --git a/src/event-set.zig b/src/event-set.zig
index 5721a4e..27c28bf 100644
--- a/src/event-set.zig
+++ b/src/event-set.zig
@@ -4,7 +4,6 @@ const wayland = @import("root.zig");
pub fn EventSet(T: type, events: anytype) type {
return struct {
pub fn on_event(ptr: *anyopaque, ctx: *wayland.Context, opcode: u16, args: []const u8) void {
- std.debug.print("event {} {}\n", .{T, opcode});
var offset: usize = 0;
inline for (events, 0..) |event, index| {
if (@TypeOf(event) != @TypeOf(null) and index == opcode) {
@@ -31,7 +30,7 @@ pub fn EventSet(T: type, events: anytype) type {
},
*wayland.Object => {
const result = std.mem.readPackedIntNative(u32, args, offset * 8);
- fn_args[arg_index] = ctx.display.registry.objects.items[result] orelse unreachable;
+ fn_args[arg_index] = ctx.display.registry.get(result) orelse unreachable;
offset += @sizeOf(u32);
},
else => |t| switch (@typeInfo(t)) {
@@ -67,7 +66,7 @@ test {
a: u32 = 0,
b: u32 = 0,
- pub fn something(self: *@This(), a: u32, b: u32) void {
+ pub fn something(self: *@This(), _: *wayland.Context, a: u32, b: u32) void {
self.a = a;
self.b = b;
}
@@ -75,8 +74,9 @@ test {
var dummy = Dummy{};
const Events = EventSet(Dummy, .{null, Dummy.something });
+ var ctx: wayland.Context = undefined;
- Events.on_event(&dummy, 1, &(std.mem.toBytes(@as(u32, 1)) ++ std.mem.toBytes(@as(u32, 2))));
+ Events.on_event(&dummy, &ctx, 1, &(std.mem.toBytes(@as(u32, 1)) ++ std.mem.toBytes(@as(u32, 2))));
try std.testing.expectEqual(dummy.a, 1);
try std.testing.expectEqual(dummy.b, 2);
diff --git a/src/main.zig b/src/main.zig
index 7e27f94..a9a5ef6 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -7,9 +7,13 @@ pub fn main() !void {
const allocator = gpa.allocator();
var display: wl.Display = try .open_default(allocator);
- defer display.close();
+ defer display.deinit(allocator);
try display.init(allocator, &.{wl.Output.handler});
try display.roundtrip(allocator);
try display.roundtrip(allocator);
+
+ for (wl.Output.all()) |output| {
+ std.debug.print("{}\n", .{output});
+ }
}
diff --git a/src/object.zig b/src/object.zig
index 0751859..14089c1 100644
--- a/src/object.zig
+++ b/src/object.zig
@@ -3,11 +3,12 @@ const wayland = @import("root.zig");
const Self = @This();
+pub const Ref = usize;
+
const VTable = struct {
on_event: *const fn (ptr: *anyopaque, ctx: *wayland.Context, opcode: u16, args: []const u8) void,
};
-id: ?u32 = null,
ptr: ?*anyopaque,
vtable: VTable,
@@ -28,6 +29,10 @@ pub inline fn from_self(ptr: anytype) Self {
};
}
+pub fn disable(self: *Self) void {
+ self.ptr = null;
+}
+
pub fn format(
self: *const Self,
comptime fmt: []const u8,
@@ -37,5 +42,5 @@ pub fn format(
_ = fmt;
_ = options;
- try writer.print("Object {{ {?} }}", .{self.id});
+ try writer.print("Object {{ {?} }}", .{self.ptr});
}
diff --git a/src/wl/callback.zig b/src/wl/callback.zig
index 0e7ea5b..c17e190 100644
--- a/src/wl/callback.zig
+++ b/src/wl/callback.zig
@@ -9,23 +9,26 @@ const Self = @This();
pub const Events = wayland.EventSet(Self, .{done});
is_done: *bool,
-interface: wayland.Object,
+handle: wayland.Object.Ref,
pub fn init(
self: *Self,
- allocator: std.mem.Allocator,
- display: *wl.Display,
+ ctx: *wayland.Context,
is_done: *bool,
) !void {
self.is_done = is_done;
- self.interface = wayland.Object.from_self(self);
- try display.registry.add_object(allocator, &self.interface);
- std.debug.print("ids {any}\n", .{display.registry.objects.items});
- std.debug.print("callback #{?}\n", .{self.interface.id});
- try display.request(display, .{ .sync = .{&self.interface} });
+ self.handle = try ctx.display.registry.add_object(
+ ctx.allocator,
+ wayland.Object.from_self(self),
+ );
+ try ctx.display.request(ctx.display, .{ .sync = .{self.handle} });
}
+pub fn deinit(self: *Self, ctx: *wayland.Context) void {
+ ctx.display.registry.disable_object(self.handle);
+}
+
fn done(self: *Self, ctx: *wayland.Context, value: u32) void {
_ = value;
_ = ctx;
diff --git a/src/wl/display.zig b/src/wl/display.zig
index 4f04746..db5ed3c 100644
--- a/src/wl/display.zig
+++ b/src/wl/display.zig
@@ -14,8 +14,8 @@ pub const Error = enum(u32) {
};
pub const Request = union(enum) {
- sync: struct { *wayland.Object },
- get_registry: struct { *wayland.Object },
+ sync: struct { wayland.Object.Ref },
+ get_registry: struct { wayland.Object.Ref },
};
pub const Events = wayland.EventSet(Self, .{
@@ -24,19 +24,23 @@ pub const Events = wayland.EventSet(Self, .{
});
stream: std.net.Stream,
-interface: wayland.Object,
registry: wl.Registry,
+handle: wayland.Object.Ref,
pub fn init(
self: *Self,
allocator: std.mem.Allocator,
handlers: []const wl.Registry.GlobalHandler,
) !void {
- self.interface = wayland.Object.from_self(self);
try self.registry.init(allocator, self, handlers);
}
-pub fn from_fd(fd: std.posix.fd_t) void {
+pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
+ self.close();
+ self.registry.deinit(allocator);
+}
+
+pub fn from_fd(fd: std.posix.fd_t) Self {
var self: Self = undefined;
self.stream = std.net.Stream{ .handle = fd };
return self;
@@ -65,8 +69,12 @@ pub fn default_path(allocator: std.mem.Allocator) ![]const u8 {
return std.fmt.allocPrint(allocator, "{s}/{s}", .{ xdg_runtime_dir, wayland_display });
}
+fn padding_len(T: type, length: usize) usize {
+ return @mod(@as(usize, @bitCast(-@as(isize, @intCast(length * @sizeOf(T))))), 4);
+}
+
pub fn request(self: *Self, object: anytype, args: @TypeOf(object.*).Request) !void {
- comptime std.debug.assert(@FieldType(@TypeOf(object.*), "interface") == wayland.Object);
+ comptime std.debug.assert(@FieldType(@TypeOf(object.*), "handle") == wayland.Object.Ref);
comptime std.debug.assert(@typeInfo(@TypeOf(object.*).Request) == .@"union");
const tag_type = @typeInfo(@TypeOf(args)).@"union".tag_type.?;
const opcode: u32 = @intFromEnum(args);
@@ -74,21 +82,21 @@ pub fn request(self: *Self, object: anytype, args: @TypeOf(object.*).Request) !v
inline for (@typeInfo(tag_type).@"enum".fields) |f| {
if (f.value == opcode) {
const data = @field(args, f.name);
- const id = object.interface.id orelse return error.UnregisteredObject;
+ const id: u32 = @truncate(object.handle);
var size: u32 = 8;
inline for (data) |value| {
switch (@TypeOf(value)) {
u32, i32 => |t| size += @sizeOf(t),
- *wayland.Object => size += @sizeOf(u32),
+ wayland.Object.Ref => size += @sizeOf(u32),
[]const u8, []u8 => {
- const padding_size: usize = @mod(@as(usize, @bitCast(-@as(isize, @intCast(value.len + 1)))), 4);
+ const padding_size: usize = padding_len(u8, value.len + 1);
size += @as(u32, @intCast(@sizeOf(u32) + (value.len + 1) + padding_size));
},
else => |t| switch (@typeInfo(t)) {
.pointer => |ptr| if (ptr.size == .slice) {
- const padding_size: usize = @mod(@as(usize, @bitCast(-@as(isize, @intCast(value.len * @sizeOf(ptr.child))))), 4);
+ const padding_size: usize = padding_len(ptr.child, value.len);
size += @intCast(@sizeOf(u32) + (value.len * @sizeOf(ptr.child)) + padding_size);
} else @compileError(std.fmt.comptimePrint("size: unsupported type {}", .{t})),
else => @compileError(std.fmt.comptimePrint("size: unsupported type {}", .{t})),
@@ -102,9 +110,9 @@ pub fn request(self: *Self, object: anytype, args: @TypeOf(object.*).Request) !v
inline for (data) |value| {
switch (@TypeOf(value)) {
u32, i32 => _ = try self.stream.writeAll(std.mem.asBytes(&value)),
- *wayland.Object => try self.stream.writeAll(std.mem.asBytes(&(value.id orelse return error.UnregisteredObject))),
+ wayland.Object.Ref => try self.stream.writeAll(std.mem.asBytes(&(@as(u32, @truncate(value))))),
[]const u8, []u8 => {
- const padding_size: usize = @mod(@as(usize, @bitCast(-@as(isize, @intCast(value.len + 1)))), 4);
+ const padding_size: usize = padding_len(u8, value.len + 1);
_ = try self.stream.writeAll(std.mem.asBytes(&@as(u32, @truncate(value.len + 1))));
_ = try self.stream.writeAll(value);
for (0..padding_size + 1) |_| {
@@ -131,41 +139,51 @@ pub fn request(self: *Self, object: anytype, args: @TypeOf(object.*).Request) !v
return error.InvalidOpcode;
}
-pub fn roundtrip(self: *Self, allocator: std.mem.Allocator) !void {
- var done = false;
- var callback: wl.Callback = undefined;
- try callback.init(allocator, self, &done);
+fn read_event(self: *Self, ctx: *wayland.Context) !void {
+ const endian = @import("builtin").target.cpu.arch.endian();
+ const reader = self.stream.reader();
+
+ const object_id = try reader.readInt(u32, endian);
+ const message_info = try reader.readInt(u32, endian);
+
+ const opcode: u16 = @truncate(message_info & 0xffff);
+ const size: u16 = @truncate(((message_info >> 16) & 0xffff));
+ const body_size = size - 2 * @sizeOf(u32);
+
+ const body = try ctx.allocator.alloc(u8, body_size);
+ defer ctx.allocator.free(body);
+ _ = try reader.readAll(body);
+
+ if (object_id >= self.registry.objects.items.len) {
+ return error.UnregisteredObject;
+ }
+
+ if (self.registry.get(object_id)) |object| {
+ try object.on_event(ctx, opcode, body);
+ } else {
+ return error.UnregisteredObject;
+ }
+}
+
+pub fn roundtrip(self: *Self, allocator: std.mem.Allocator) !void {
var context: wayland.Context = .{
.display = self,
.allocator = allocator,
};
- while (!done) {
- const endian = @import("builtin").target.cpu.arch.endian();
- const reader = self.stream.reader();
-
- const object_id = try reader.readInt(u32, endian);
-
- const message_info = try reader.readInt(u32, endian);
-
- const opcode: u16 = @truncate(message_info & 0xffff);
- const size: u16 = @truncate(((message_info >> 16) & 0xffff));
- const body_size = size - 2 * @sizeOf(u32);
+ var done = false;
- const body = try allocator.alloc(u8, body_size);
- defer allocator.free(body);
- _ = try reader.readAll(body);
+ var callback: wl.Callback = undefined;
+ try callback.init(&context, &done);
+ defer callback.deinit(&context);
- if (object_id >= self.registry.objects.items.len) {
- return error.UnregisteredObject;
- }
+ errdefer self.read_event(&context) catch |e| {
+ log.err("cleanup error: {}", .{e});
+ };
- if (self.registry.objects.items[object_id]) |object| {
- try object.on_event(&context, opcode, body);
- } else {
- return error.UnregisteredObject;
- }
+ while (!done) {
+ try self.read_event(&context);
}
}
@@ -194,17 +212,17 @@ test "request" {
const Sample = struct {
pub const Request = union(enum) {
req1: struct { u32 },
- req2: struct { *wayland.Object },
+ req2: struct { wayland.Object.Ref },
req3: struct { []const u8 },
req4: struct { []const u16 },
};
pub const Events = wayland.EventSet(@This(), .{});
- interface: wayland.Object,
+ handle: wayland.Object.Ref,
- pub fn init(self: *@This()) void {
- self.interface = wayland.Object.from_self(self);
+ pub fn init() @This() {
+ return .{ .handle = 42 };
}
};
@@ -212,24 +230,32 @@ test "request" {
defer std.posix.close(in);
{
- var sample: Sample = undefined;
- sample.init();
- sample.interface.id = 42;
+ var sample: Sample = .init();
var displ: Self = .from_fd(out);
- defer displ.close();
- try displ.init();
- try displ.request(sample, .{ .req1 = .{432} });
- try displ.request(sample, .{ .req2 = .{&sample.interface} });
- try displ.request(sample, .{ .req3 = .{"abcd"} });
- try displ.request(sample, .{ .req4 = .{&[_]u16{ 1, 32, 4, 5, 5 }} });
+ defer displ.deinit(std.testing.allocator);
+ try displ.init(std.testing.allocator, &.{});
+ try displ.request(&sample, .{ .req1 = .{432} });
+ try displ.request(&sample, .{ .req2 = .{sample.handle} });
+ try displ.request(&sample, .{ .req3 = .{"abcd"} });
+ try displ.request(&sample, .{ .req4 = .{&[_]u16{ 1, 32, 4, 5, 5 }} });
}
const file = std.fs.File{ .handle = in };
+
var test_buffer: [64]u8 = undefined;
_ = try file.readAll(test_buffer[0..12]);
try std.testing.expectEqualSlices(
u8,
+ &(std.mem.toBytes(@as(u32, 1)) ++
+ std.mem.toBytes(@as(u32, (12 << 16) | 1)) ++
+ std.mem.toBytes(@as(u32, 2))),
+ test_buffer[0..12],
+ );
+
+ _ = try file.readAll(test_buffer[0..12]);
+ try std.testing.expectEqualSlices(
+ u8,
&(std.mem.toBytes(@as(u32, 42)) ++
std.mem.toBytes(@as(u32, (12 << 16) | 0)) ++
std.mem.toBytes(@as(u32, 432))),
diff --git a/src/wl/output/geometry.zig b/src/wl/output/geometry.zig
new file mode 100644
index 0000000..2dfcf2f
--- /dev/null
+++ b/src/wl/output/geometry.zig
@@ -0,0 +1,12 @@
+const Subpixel = @import("root.zig").Subpixel;
+const Transform = @import("root.zig").Transform;
+
+x: u32,
+y: u32,
+physical_width: u32,
+physical_height: u32,
+subpixel: Subpixel,
+make: []const u8,
+model: []const u8,
+transform: Transform,
+
diff --git a/src/wl/output/mode.zig b/src/wl/output/mode.zig
new file mode 100644
index 0000000..a21e8e0
--- /dev/null
+++ b/src/wl/output/mode.zig
@@ -0,0 +1,26 @@
+const std = @import("std");
+
+const Self = @This();
+
+pub const Kind = enum(u32) {
+ current = 1,
+ preferred = 2,
+};
+
+kind: Kind,
+width: u32,
+height: u32,
+refresh: u32,
+
+
+pub fn format(
+ self: *const Self,
+ comptime fmt: []const u8,
+ options: std.fmt.FormatOptions,
+ writer: anytype,
+) !void {
+ _ = fmt;
+ _ = options;
+ const ghz: f32 = @as(f32, @floatFromInt(self.refresh)) / 1000.0;
+ try writer.print("{}x{}@{d:.2}", .{ self.width, self.height, ghz});
+}
diff --git a/src/wl/output.zig b/src/wl/output/root.zig
index 99e8ca1..fca2ecc 100644
--- a/src/wl/output.zig
+++ b/src/wl/output/root.zig
@@ -1,7 +1,12 @@
const std = @import("std");
-const wayland = @import("../root.zig");
+const wayland = @import("../../root.zig");
const wl = wayland.wl;
+pub const Subpixel = @import("subpixel.zig").Subpixel;
+pub const Transform = @import("transform.zig").Transform;
+pub const Geometry = @import("geometry.zig");
+pub const Mode = @import("mode.zig");
+
const Self = @This();
pub const Requests = union(enum) {
@@ -17,49 +22,6 @@ pub const Events = wayland.EventSet(Self, .{
description,
});
-pub const Subpixel = enum(u32) {
- unkown = 0,
- none = 1,
- orizontal_rgb = 2,
- orizontal_bgr = 3,
- vertical_rgb = 4,
- vertical_bgr = 5,
-};
-
-pub const Transform = enum(u32) {
- normal = 0,
- normal_90 = 1,
- normal_180 = 2,
- normal_270 = 3,
- flipped = 4,
- flipped_90 = 5,
- flipped_180 = 6,
- flipped_270 = 7,
-};
-
-pub const Geometry = struct {
- x: u32,
- y: u32,
- physical_width: u32,
- physical_height: u32,
- subpixel: Subpixel,
- make: []const u8,
- model: []const u8,
- transform: Transform,
-};
-
-pub const Mode = struct {
- pub const Kind = enum(u32) {
- current = 1,
- preferred = 2,
- };
-
- kind: Kind,
- width: u32,
- height: u32,
- refresh: u32,
-};
-
pub const Info = struct {
geometry: Geometry,
mode: Mode,
@@ -72,15 +34,19 @@ var outputs: std.ArrayListUnmanaged(*Self) = .empty;
staging: Info = undefined,
info: ?Info = null,
-interface: wayland.Object,
+handle: wayland.Object.Ref,
pub fn init(
self: *Self,
allocator: std.mem.Allocator,
display: *wl.Display,
) !void {
- self.* = .{ .interface = wayland.Object.from_self(self) };
- try display.registry.add_object(allocator, &self.interface);
+ self.* = .{
+ .handle = try display.registry.add_object(
+ allocator,
+ wayland.Object.from_self(self),
+ ),
+ };
}
pub fn deinit(self: *Self, display: *wl.Display) !void {
@@ -93,11 +59,11 @@ pub const handler: wl.Registry.GlobalHandler = .{
.handler = register,
};
-pub fn register(ctx: *wayland.Context) ?wayland.Object {
+pub fn register(ctx: *wayland.Context) ?wayland.Object.Ref {
const output = ctx.allocator.create(Self) catch return null;
output.init(ctx.allocator, ctx.display) catch return null;
outputs.append(ctx.allocator, output) catch return null;
- return output.interface;
+ return output.handle;
}
fn geometry(
@@ -167,5 +133,24 @@ fn description(self: *Self, ctx: *wayland.Context, d: []const u8) !void {
}
pub fn get(index: usize) *Self {
- return &outputs.items[index];
+ return outputs.items[index];
+}
+
+pub fn all() []*Self {
+ return outputs.items;
+}
+
+pub fn format(
+ self: *const Self,
+ comptime fmt: []const u8,
+ options: std.fmt.FormatOptions,
+ writer: anytype,
+) !void {
+ _ = fmt;
+ _ = options;
+ if (self.info) |info| {
+ try writer.print("output({s}) [ {} ]", .{ info.name, info.mode});
+ } else {
+ try writer.print("output(?)", .{});
+ }
}
diff --git a/src/wl/output/subpixel.zig b/src/wl/output/subpixel.zig
new file mode 100644
index 0000000..f6d3bba
--- /dev/null
+++ b/src/wl/output/subpixel.zig
@@ -0,0 +1,8 @@
+pub const Subpixel = enum(u32) {
+ unkown = 0,
+ none = 1,
+ orizontal_rgb = 2,
+ orizontal_bgr = 3,
+ vertical_rgb = 4,
+ vertical_bgr = 5,
+};
diff --git a/src/wl/output/transform.zig b/src/wl/output/transform.zig
new file mode 100644
index 0000000..f41ea9a
--- /dev/null
+++ b/src/wl/output/transform.zig
@@ -0,0 +1,10 @@
+pub const Transform = enum(u32) {
+ normal = 0,
+ normal_90 = 1,
+ normal_180 = 2,
+ normal_270 = 3,
+ flipped = 4,
+ flipped_90 = 5,
+ flipped_180 = 6,
+ flipped_270 = 7,
+};
diff --git a/src/wl/registry.zig b/src/wl/registry.zig
index e4eb3a8..9d91952 100644
--- a/src/wl/registry.zig
+++ b/src/wl/registry.zig
@@ -12,18 +12,18 @@ pub const Events = wayland.EventSet(Self, .{
});
pub const Request = union(enum) {
- bind: struct { u32, u32 },
+ bind: struct { u32, []const u8, u32, u32 },
};
pub const GlobalHandler = struct {
interface: []const u8,
version: u32,
- handler: *const fn (ctx: *wayland.Context) ?wayland.Object,
+ handler: *const fn (ctx: *wayland.Context) ?wayland.Object.Ref,
};
-objects: std.ArrayListUnmanaged(?*wayland.Object) = .empty,
-interface: wayland.Object,
+objects: std.ArrayListUnmanaged(?wayland.Object) = .empty,
handlers: []const GlobalHandler,
+handle: wayland.Object.Ref,
pub fn init(
self: *Self,
@@ -32,40 +32,55 @@ pub fn init(
handlers: []const GlobalHandler,
) !void {
self.* = .{
- .interface = wayland.Object.from_self(self),
.handlers = handlers,
+ .handle = 2,
};
try self.objects.append(allocator, null);
- try self.objects.append(allocator, &display.interface);
- try self.objects.append(allocator, &self.interface);
+ try self.objects.append(allocator, wayland.Object.from_self(display));
+ try self.objects.append(allocator, wayland.Object.from_self(self));
- display.interface.id = 1;
- self.interface.id = 2;
+ display.handle = 1;
- try display.request(display, .{ .get_registry = .{&self.interface} });
+ try display.request(display, .{ .get_registry = .{ self.handle } });
+}
+
+pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
+ self.objects.deinit(allocator);
}
pub fn add_object(
self: *Self,
allocator: std.mem.Allocator,
- object: *wayland.Object,
-) !void {
+ object: wayland.Object,
+) !usize {
for (self.objects.items[1..], 1..) |obj, index| {
if (obj == null) {
- object.id = @truncate(index);
self.objects.items[index] = object;
- return;
+ return index;
}
}
- object.id = @truncate(self.objects.items.len);
try self.objects.append(allocator, object);
+ return self.objects.items.len - 1;
+}
+
+pub fn disable_object(self: *Self, id: usize) void {
+ if (self.objects.items[id]) |*object| {
+ object.disable();
+ }
}
pub fn release_object(self: *Self, id: u32) void {
self.objects.items[id] = null;
}
+pub fn get(self: *Self, handle: usize) ?*wayland.Object {
+ if (self.objects.items[handle]) |*objects| {
+ return objects;
+ }
+ return null;
+}
+
fn global(
self: *Self,
ctx: *wayland.Context,
@@ -73,12 +88,15 @@ fn global(
interface: []const u8,
version: u32,
) !void {
+ log.debug("global {s}", .{interface});
for (self.handlers) |handler| {
if (version == handler.version and std.mem.eql(u8, interface, handler.interface)) {
- if (handler.handler(ctx)) |object| {
+ if (handler.handler(ctx)) |object_ref| {
try ctx.display.request(self, .{ .bind = .{
name,
- object.id orelse return error.UnregisteredObject,
+ interface,
+ version,
+ @truncate(object_ref),
} });
}
}
diff --git a/src/wl/root.zig b/src/wl/root.zig
index b9e149f..778b085 100644
--- a/src/wl/root.zig
+++ b/src/wl/root.zig
@@ -1,4 +1,4 @@
pub const Display = @import("display.zig");
pub const Registry = @import("registry.zig");
pub const Callback = @import("callback.zig");
-pub const Output = @import("output.zig");
+pub const Output = @import("output/root.zig");