aboutsummaryrefslogtreecommitdiff
path: root/src/wl/output/root.zig
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 /src/wl/output/root.zig
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.
Diffstat (limited to 'src/wl/output/root.zig')
-rw-r--r--src/wl/output/root.zig156
1 files changed, 156 insertions, 0 deletions
diff --git a/src/wl/output/root.zig b/src/wl/output/root.zig
new file mode 100644
index 0000000..fca2ecc
--- /dev/null
+++ b/src/wl/output/root.zig
@@ -0,0 +1,156 @@
+const std = @import("std");
+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) {
+ release: struct {},
+};
+
+pub const Events = wayland.EventSet(Self, .{
+ geometry,
+ mode,
+ done,
+ scale,
+ name,
+ description,
+});
+
+pub const Info = struct {
+ geometry: Geometry,
+ mode: Mode,
+ scale: u32,
+ name: []const u8,
+ description: []const u8,
+};
+
+var outputs: std.ArrayListUnmanaged(*Self) = .empty;
+
+staging: Info = undefined,
+info: ?Info = null,
+handle: wayland.Object.Ref,
+
+pub fn init(
+ self: *Self,
+ allocator: std.mem.Allocator,
+ display: *wl.Display,
+) !void {
+ self.* = .{
+ .handle = try display.registry.add_object(
+ allocator,
+ wayland.Object.from_self(self),
+ ),
+ };
+}
+
+pub fn deinit(self: *Self, display: *wl.Display) !void {
+ display.request(self, .{ .release = void{} });
+}
+
+pub const handler: wl.Registry.GlobalHandler = .{
+ .interface = "wl_output",
+ .version = 4,
+ .handler = register,
+};
+
+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.handle;
+}
+
+fn geometry(
+ self: *Self,
+ ctx: *wayland.Context,
+ x: u32,
+ y: u32,
+ physical_width: u32,
+ physical_height: u32,
+ subpixel: Subpixel,
+ make: []const u8,
+ model: []const u8,
+ transform: Transform,
+) void {
+ _ = ctx;
+ self.staging.geometry = .{
+ .x = x,
+ .y = y,
+ .physical_width = physical_width,
+ .physical_height = physical_height,
+ .subpixel = subpixel,
+ .make = make,
+ .model = model,
+ .transform = transform,
+ };
+}
+
+fn mode(
+ self: *Self,
+ ctx: *wayland.Context,
+ flags: Mode.Kind,
+ width: u32,
+ height: u32,
+ refresh: u32,
+) void {
+ _ = ctx;
+ self.staging.mode = .{
+ .kind = flags,
+ .width = width,
+ .height = height,
+ .refresh = refresh,
+ };
+}
+
+fn done(self: *Self, ctx: *wayland.Context) void {
+ if (self.info) |info| {
+ ctx.allocator.free(info.name);
+ ctx.allocator.free(info.description);
+ }
+
+ self.info = self.staging;
+}
+
+fn scale(self: *Self, ctx: *wayland.Context, factor: u32) void {
+ _ = ctx;
+ self.staging.scale = factor;
+}
+
+fn name(self: *Self, ctx: *wayland.Context, n: []const u8) !void {
+ self.staging.name = try ctx.allocator.alloc(u8, n.len);
+ @memcpy(@constCast(self.staging.name), n);
+}
+
+fn description(self: *Self, ctx: *wayland.Context, d: []const u8) !void {
+ self.staging.description = try ctx.allocator.alloc(u8, d.len);
+ @memcpy(@constCast(self.staging.description), d);
+}
+
+pub fn get(index: usize) *Self {
+ 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(?)", .{});
+ }
+}