const std = @import("std"); const Card = @import("../card.zig").Card; const Drm = @import("../request.zig").Drm; const Connector = @import("../connector/root.zig").Connector; const fb = @import("../frame-buffer/root.zig"); const FrameBuffer = fb.FrameBuffer; const DoubleBuffer = fb.DoubleBuffer; const Mode = @import("../connector/mode.zig").Mode; pub const RawCrtc = extern struct { connector_ids: ?*u32, count_connectors: u32, id: u32, buffer_id: u32, x: u32, y: u32, gamma_size: u32, mode_valid: u32, mode: Mode, }; const PageFlipEvent = packed struct(u32) { event: bool, is_async: bool, absolute: bool, relative: bool, __padding: u28, }; const PageFlip = extern struct { crtc_id: u32, buffer_id: u32, flags: PageFlipEvent, __reserved: u32, user_data: u64, }; pub const Crtc = struct { const Self = @This(); connector_ids: ?*u32, count_connectors: u32, id: u32, buffer_id: u32, x: u32, y: u32, mode: Mode, mode_valid: u32, gamma_size: u32, card: *Card, pub fn init(card: *Card, id: u32) !Self { var raw = std.mem.zeroInit(RawCrtc, .{ .id = id }); try Drm.get_crtc.request(card.file.handle, RawCrtc, &raw); return .{ .connector_ids = raw.connector_ids, .count_connectors = raw.count_connectors, .id = raw.id, .buffer_id = raw.buffer_id, .x = raw.x, .y = raw.y, .mode = raw.mode, .mode_valid = raw.mode_valid, .gamma_size = raw.gamma_size, .card = card, }; } pub fn attach(self: *Self, frame_buffer: *FrameBuffer, connector: *Connector, mode: Mode) !void { self.connector_ids = &connector.id; self.count_connectors = 1; var crtc = RawCrtc { .id = self.id, .x = self.x, .y = self.y, .buffer_id = frame_buffer.id, .connector_ids = self.connector_ids, .count_connectors = self.count_connectors, .mode = mode, .mode_valid = 1, .gamma_size = self.gamma_size, }; try Drm.set_crtc.request(self.card.file.handle, RawCrtc, &crtc); } pub fn page_flip(self: *Self, double_buffer: *DoubleBuffer) !void { double_buffer.swap(); var flip = std.mem.zeroInit(PageFlip, .{ .buffer_id = double_buffer.crtc_buffer().id, .crtc_id = self.id, .flags = std.mem.zeroInit(PageFlipEvent, .{ .event = true }), }); try Drm.page_flip.request(self.card.file.handle, PageFlip, &flip); } pub fn detach(self: *Self) void { var crtc = RawCrtc { .id = self.id, .x = self.x, .y = self.y, .buffer_id = self.buffer_id, .connector_ids = self.connector_ids, .count_connectors = self.count_connectors, .mode = self.mode, .mode_valid = self.mode_valid, .gamma_size = self.gamma_size, }; Drm.set_crtc.request( self.card.file.handle, RawCrtc, &crtc ) catch |err| std.debug.panic("set crtc failed on detach: {}", .{err}); } };