const std = @import("std"); const os = std.os.linux; const cerror = @import("../cerror.zig"); const drm = @import("./root.zig"); pub const Card = struct { const Self = @This(); file: std.fs.File, allocator: std.mem.Allocator, pub fn open(name: []const u8, allocator: std.mem.Allocator) !Self { var dri_dir = try std.fs.openDirAbsolute("/dev/dri", .{}); defer dri_dir.close(); return .{ .file = try dri_dir.openFile(name, .{ .mode = .read_write, .lock_nonblocking = true, }), .allocator = allocator, }; } pub fn close(self: *Card) void { self.file.close(); } pub fn resources(self: *Card) !drm.Resources { return drm.Resources.init(self); } pub fn connector(self: *Card, id: u32) !drm.Connector { return drm.Connector.init(self, id); } pub fn encoder(self: *Card, id: u32) !drm.Encoder { return drm.Encoder.init(self, id); } pub fn crtc(self: *Card, id: u32) !drm.Crtc { return drm.Crtc.init(self, id); } pub fn create_double_buffer(self: *Card, width: u32, height: u32, bpp: u32) !drm.Buffer { return drm.Buffer.init(self, width, height, bpp); } pub fn request( self: *Self, comptime kind: drm.request.Kind, payload: anytype ) !void { const id = kind.id(@TypeOf(payload)); try cerror.from_usize(os.ioctl(self.file.handle, id, @intFromPtr(payload))); } pub fn poll_event(self: *Card, timeout: i32) !?drm.Event { var pollfd = os.pollfd { .fd = self.file.handle, .events = os.POLL.IN, .revents = 0 }; try cerror.from_usize(os.poll(@ptrCast(&pollfd), 1, timeout)); if ((pollfd.revents & os.POLL.IN) != 0) { var event = std.mem.zeroes(drm.Event); try cerror.from_usize(os.read(self.file.handle, @ptrCast(&event), @sizeOf(drm.Event))); return event; } return null; } };