aboutsummaryrefslogtreecommitdiff
path: root/src/wl/output.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/output.zig
First sketch of wayland interface
**WARNING** this implementation is not working properly yet.
Diffstat (limited to 'src/wl/output.zig')
-rw-r--r--src/wl/output.zig171
1 files changed, 171 insertions, 0 deletions
diff --git a/src/wl/output.zig b/src/wl/output.zig
new file mode 100644
index 0000000..99e8ca1
--- /dev/null
+++ b/src/wl/output.zig
@@ -0,0 +1,171 @@
+const std = @import("std");
+const wayland = @import("../root.zig");
+const wl = wayland.wl;
+
+const Self = @This();
+
+pub const Requests = union(enum) {
+ release: struct {},
+};
+
+pub const Events = wayland.EventSet(Self, .{
+ geometry,
+ mode,
+ done,
+ scale,
+ name,
+ 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,
+ scale: u32,
+ name: []const u8,
+ description: []const u8,
+};
+
+var outputs: std.ArrayListUnmanaged(*Self) = .empty;
+
+staging: Info = undefined,
+info: ?Info = null,
+interface: wayland.Object,
+
+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);
+}
+
+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 {
+ 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;
+}
+
+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];
+}