diff --git a/src/drm.zig b/src/drm.zig index ba44a98..cefdac5 100644 --- a/src/drm.zig +++ b/src/drm.zig @@ -5,6 +5,7 @@ const log = std.log.scoped(.drm); pub const sys = @import("sys.zig"); pub const Format = fmt.Format; pub const FormatModifiers = fmt.FormatModifiers; +pub const ModeInfo = sys.mode.ModeInfo; pub const Card = struct { handle: std.Io.File, @@ -64,11 +65,40 @@ pub const Card = struct { } } + pub fn setClientCapability(self: Card, capability: sys.ClientCapability, value: u64) sys.IoctlError!void { + var set_cap = sys.SetClientCap{ + .capability = capability, + .value = value, + }; + try sys.ioctl(self.handle.handle, .set_client_cap, &set_cap); + } + + pub fn getCapability(self: Card, capability: sys.Capability) sys.IoctlError!u64 { + var get_cap = sys.GetCap{ + .capability = capability, + .value = 0, + }; + try sys.ioctl(self.handle.handle, .get_cap, &get_cap); + return get_cap.value; + } + + pub fn createModesettingPropertyBlob(self: Card, data: []const u8) sys.IoctlError!u32 { + var create = std.mem.zeroInit(sys.mode.CreateBlob, .{ + .length = @as(u32, @intCast(data.len)), + .data = @intFromPtr(data.ptr), + }); + try sys.ioctl(self.handle.handle, .mode_createpropblob, &create); + return create.blob_id; + } + // BEGIN MODESETTING API pub const GetResourcesError = sys.IoctlError || error{OutOfMemory}; - pub fn getModesettingResourcesAlloc(self: Card, gpa: std.mem.Allocator) GetResourcesError!ModesettingResources { + pub fn getModesettingResourcesAlloc( + self: Card, + gpa: std.mem.Allocator, + ) GetResourcesError!ModesettingResources { while (true) { var res = std.mem.zeroes(sys.mode.CardRes); try sys.ioctl(self.handle.handle, .mode_getresources, &res); diff --git a/src/sys.zig b/src/sys.zig index 3edb016..7fbc3a0 100644 --- a/src/sys.zig +++ b/src/sys.zig @@ -32,8 +32,8 @@ pub const Request = enum(u32) { // gem_close = drm_iow(0x09, drm_gem_close), // gem_flink = drm_iowr(0x0a, drm_gem_flink), // gem_open = drm_iowr(0x0b, drm_gem_open), - // get_cap = drm_iowr(0x0c, drm_get_cap), - // set_client_cap = drm_iow(0x0d, drm_set_client_cap), + get_cap = drm_iowr(0x0c, GetCap), + set_client_cap = drm_iow(0x0d, SetClientCap), set_unique = drm_iow(0x10, Unique), auth_magic = drm_iow(0x11, Auth), // block = drm_iowr(0x12, drm_block), @@ -254,6 +254,43 @@ pub const SetVersion = extern struct { dd_minor: c_int, }; +pub const GetCap = extern struct { + capability: Capability, + value: u64, +}; + +pub const Capability = enum(u64) { + dumb_buffer = 0x1, + vblank_high_crtc = 0x2, + dumb_preferred_depth = 0x3, + dumb_buffer_shadow = 0x4, + prime = 0x5, + timestamp_monotonic = 0x6, + async_page_flip = 0x7, + cursor_width = 0x8, + cursor_height = 0x9, + addfbd_modifiers = 0x10, + page_flip_target = 0x11, + crtc_in_vblank_event = 0x12, + syncobj = 0x13, + syncobj_timeline = 0x14, + atomic_async_page_flip = 0x15, +}; + +pub const SetClientCap = extern struct { + capability: ClientCapability, + value: u64, +}; + +pub const ClientCapability = enum(u64) { + stereo_3d = 1, + universal_planes = 2, + atomic = 3, + aspect_ratio = 4, + writeback_connectors = 5, + cursor_plane_hotspot = 6, +}; + pub const Ctx = extern struct { handle: Context, flags: CtxFlags,