summaryrefslogtreecommitdiff
path: root/src/screen/drm/card.zig
blob: ef56142087284d3ac8839491ff0a216772a1be10 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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_buffer(self: *Card, width: u32, height: u32) !drm.Buffer {
		return drm.Buffer.init(self, width, height);
	}

	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;
	}
};