From 956ecb061b1862a4b632c8d5d6b6fa4318e1f640 Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Fri, 22 Aug 2025 20:12:56 +0200 Subject: 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. --- src/wl/output/geometry.zig | 12 ++++ src/wl/output/mode.zig | 26 ++++++++ src/wl/output/root.zig | 156 ++++++++++++++++++++++++++++++++++++++++++++ src/wl/output/subpixel.zig | 8 +++ src/wl/output/transform.zig | 10 +++ 5 files changed, 212 insertions(+) create mode 100644 src/wl/output/geometry.zig create mode 100644 src/wl/output/mode.zig create mode 100644 src/wl/output/root.zig create mode 100644 src/wl/output/subpixel.zig create mode 100644 src/wl/output/transform.zig (limited to 'src/wl/output') 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/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(?)", .{}); + } +} 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, +}; -- cgit v1.2.3-70-g09d2