diff options
Diffstat (limited to 'src/screen/drm/connector')
| -rw-r--r-- | src/screen/drm/connector/connection.zig | 6 | ||||
| -rw-r--r-- | src/screen/drm/connector/mode.zig | 59 | ||||
| -rw-r--r-- | src/screen/drm/connector/root.zig | 95 |
3 files changed, 160 insertions, 0 deletions
diff --git a/src/screen/drm/connector/connection.zig b/src/screen/drm/connector/connection.zig new file mode 100644 index 0000000..9c4a8d8 --- /dev/null +++ b/src/screen/drm/connector/connection.zig @@ -0,0 +1,6 @@ +pub const Connection = enum(u32) { + undefined_state = 0, + connected = 1, + disconnected = 2, + unknown = 3, +}; diff --git a/src/screen/drm/connector/mode.zig b/src/screen/drm/connector/mode.zig new file mode 100644 index 0000000..9f4dfc4 --- /dev/null +++ b/src/screen/drm/connector/mode.zig @@ -0,0 +1,59 @@ +pub const Mode = extern struct { + const Self = @This(); + + const DimensionInfo = extern struct { + const Sync = extern struct { start: u16, end: u16 }; + + size: u16, + sync: Sync, + total: u16, + }; + + const Flags = packed struct(u32) { + phsync: bool, + nhsync: bool, + pvsync: bool, + nvsync: bool, + interlace: bool, + dblscan: bool, + csync: bool, + pcsync: bool, + ncsync: bool, + hskew: bool, + bcast: bool, + pixmux: bool, + dblclk: bool, + clkdiv2: bool, + _padding: u18, + }; + + clock: u32, + horizontal: DimensionInfo, + skew: u16, + vertical: DimensionInfo, + line_scans: u16, + vertical_refresh: u32, + + flags: Flags, + type: u32, + name: [32]u8, + + pub fn frame_rate(self: *const Self) f32 { + var rate = (@as(u64, @intCast(self.clock)) * 1000000 / self.horizontal.total + self.vertical.total / 2) / self.vertical.total; + + if (self.flags.interlace) { + rate *= 2; + } + + if (self.flags.dblscan) { + rate /= 2; + } + + if (self.line_scans > 1) { + rate /= self.line_scans; + } + + return @as(f32, @floatFromInt(rate)) / 1000.0; + } +}; + diff --git a/src/screen/drm/connector/root.zig b/src/screen/drm/connector/root.zig new file mode 100644 index 0000000..8883d29 --- /dev/null +++ b/src/screen/drm/connector/root.zig @@ -0,0 +1,95 @@ +const std = @import("std"); +const os = std.os.linux; +const Drm = @import("../request.zig").Drm; +const Card = @import("../card.zig").Card; + +pub const Connection = @import("connection.zig").Connection; +pub const Mode = @import("mode.zig").Mode; + +const RawConnector = extern struct { + encoder_ids: ?*u32, + modes: ?*Mode, + prop_ids: ?*u32, + prop_value_ids: ?*u64, + count_modes: u32, + count_props: u32, + count_encoders: u32, + encoder_id: u32, + connector_id: u32, + connector_type: u32, + connector_type_id: u32, + connection: Connection, + mm_width: u32, + mm_height: u32, + subpixel: u32, + pad: u32, +}; + +pub const Connector = struct { + const Self = @This(); + + card: *Card, + + encoder_ids: []u32, + modes: []Mode, + prop_ids: []u32, + prop_value_ids: []u64, + encoder_id: u32, + connector_id: u32, + connector_type: u32, + connector_type_id: u32, + connection: Connection, + mm_width: u32, + mm_height: u32, + subpixel: u32, + pad: u32, + + pub fn raw_without_ids(card: *Card, id: u32) !RawConnector { + var result = std.mem.zeroInit(RawConnector, .{ .connector_id = id }); + try Drm.get_connector.request(card.file.handle, RawConnector, &result); + return result; + } + + // NOTE: This function does not take in account + // that there might be some hot-plugging going + // on. This might have to change in the future. + pub fn init(card: *Card, id: u32) !Self { + var raw = try Self.raw_without_ids(card, id); + const resources = .{ + .encoder_ids = try card.allocator.alloc(u32, raw.count_encoders), + .modes = try card.allocator.alloc(Mode, raw.count_modes), + .prop_ids = try card.allocator.alloc(u32, raw.count_props), + .prop_value_ids = try card.allocator.alloc(u64, raw.count_props), + .encoder_id = raw.encoder_id, + .connector_id = raw.connector_id, + .connector_type = raw.connector_type, + .connector_type_id = raw.connector_type_id, + .connection = raw.connection, + .mm_width = raw.mm_width, + .mm_height = raw.mm_height, + .subpixel = raw.subpixel, + .pad = raw.pad, + .card = card, + }; + + @memset(resources.encoder_ids, 0); + @memset(resources.modes, std.mem.zeroes(Mode)); + @memset(resources.prop_ids, 0); + @memset(resources.prop_value_ids, 0); + + raw.encoder_ids = @ptrCast(resources.encoder_ids); + raw.modes = @ptrCast(resources.modes); + raw.prop_ids = @ptrCast(resources.prop_ids); + raw.prop_value_ids = @ptrCast(resources.prop_value_ids); + + try Drm.get_connector.request(card.file.handle, RawConnector, &raw); + + return resources; + } + + pub fn deinit(self: *Self) void { + self.card.allocator.free(self.encoder_ids); + self.card.allocator.free(self.modes); + self.card.allocator.free(self.prop_ids); + } +}; |