summaryrefslogtreecommitdiff
path: root/src/screen/drm/card.zig
blob: 6147cf236f16f740830d5df69bf62911f8a902d1 (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
79
80
const std = @import("std");
const os = std.os.linux;

const cerror = @import("../cerror.zig");

const Resources = @import("resources.zig").Resources;
const Connector = @import("connector/root.zig").Connector;
const Encoder = @import("encoder/root.zig").Encoder;
const Crtc = @import("crtc/root.zig").Crtc;
const DoubleBuffer = @import("frame-buffer/root.zig").DoubleBuffer;
const Event = @import("event.zig").Event;


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 is_kms(self: *Card) !bool {
        const raw_info = Resources.raw_without_ids(self);
        return raw_info.count_crtcs > 0 and raw_info.count_connectors > 0 and raw_info.count_encoders > 0;
    }

    pub fn resources(self: *Card) !Resources {
        return Resources.init(self);
    }

    pub fn connector(self: *Card, id: u32) !Connector {
        return Connector.init(self, id);
    }

    pub fn encoder(self: *Card, id: u32) !Encoder {
        return Encoder.init(self, id);
    }

    pub fn crtc(self: *Card, id: u32) !Crtc {
        return Crtc.init(self, id);
    }

    pub fn create_double_buffer(self: *Card, width: u32, height: u32, bpp: u32) !DoubleBuffer {
        return DoubleBuffer.init(self, width, height, bpp);
    }

    pub fn poll_event(self: *Card, timeout: i32) !?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(Event);
            try cerror.from_usize(os.read(self.file.handle, @ptrCast(&event), @sizeOf(Event)));
            return event;
        }

        return null;
    }
};