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, }; pub var instances: std.ArrayListUnmanaged(*Self) = .empty; staging: Info = undefined, info: ?Info = null, handle: wayland.Object.Ref, pub fn init( self: *Self, ctx: *const wayland.Context, ) !void { self.* = .{ .handle = try ctx.display.registry.add_object( ctx.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, }; fn register(ctx: *const wayland.Context) ?wayland.Object.Ref { const output = ctx.allocator.create(Self) catch return null; output.init(ctx) catch return null; instances.append(ctx.allocator, output) catch return null; return output.handle; } fn geometry( self: *Self, ctx: *const 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: *const 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: *const 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: *const wayland.Context, factor: u32) void { _ = ctx; self.staging.scale = factor; } fn name(self: *Self, ctx: *const 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: *const wayland.Context, d: []const u8) !void { self.staging.description = try ctx.allocator.alloc(u8, d.len); @memcpy(@constCast(self.staging.description), d); } 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("wl.output({s}) [ {} ]", .{ info.name, info.mode}); } else { try writer.print("wl.output(?)", .{}); } }