diff options
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..4be9614 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,215 @@ +//! +//! Foreign function interface +//! + +#![warn(missing_docs)] +#![allow(unused_doc_comments)] + +pub use drm_sys::{self, *}; + +#[macro_use] +pub(crate) mod utils; + +pub mod gem; +mod ioctl; +pub mod mode; +pub mod syncobj; + +use std::{ + ffi::{c_int, c_ulong}, + io, + os::unix::io::BorrowedFd, +}; + +/// +/// Bindings to the methods of authentication the DRM provides. +/// +pub mod auth { + use crate::ioctl; + use drm_sys::*; + + use std::{io, os::unix::io::BorrowedFd}; + + /// Get the 'Magic Authentication Token' for this file descriptor. + pub fn get_magic_token(fd: BorrowedFd<'_>) -> io::Result<drm_auth> { + unsafe { ioctl::get_token(fd) } + } + + /// Authorize another process' 'Magic Authentication Token'. + pub fn auth_magic_token(fd: BorrowedFd<'_>, auth: u32) -> io::Result<drm_auth> { + let token = drm_auth { magic: auth }; + + unsafe { + ioctl::auth_token(fd, &token)?; + } + + Ok(token) + } + + /// Acquire the 'Master DRM Lock' for this file descriptor. + pub fn acquire_master(fd: BorrowedFd<'_>) -> io::Result<()> { + unsafe { ioctl::acquire_master(fd) } + } + + /// Release the 'Master DRM Lock' for this file descriptor. + pub fn release_master(fd: BorrowedFd<'_>) -> io::Result<()> { + unsafe { ioctl::release_master(fd) } + } +} + +/// Load this device's Bus ID into a buffer. +pub fn get_bus_id(fd: BorrowedFd<'_>, mut buf: Option<&mut Vec<u8>>) -> io::Result<drm_unique> { + let mut sizes = drm_unique::default(); + unsafe { + ioctl::get_bus_id(fd, &mut sizes)?; + } + + if buf.is_none() { + return Ok(sizes); + } + + map_reserve!(buf, sizes.unique_len as usize); + + let mut busid = drm_unique { + unique_len: sizes.unique_len, + unique: map_ptr!(&buf), + }; + + unsafe { + ioctl::get_bus_id(fd, &mut busid)?; + } + + map_set!(buf, busid.unique_len as usize); + + Ok(busid) +} + +/// Get a device's IRQ. +pub fn get_interrupt_from_bus_id( + fd: BorrowedFd<'_>, + bus: c_int, + dev: c_int, + func: c_int, +) -> io::Result<drm_irq_busid> { + let mut irq = drm_irq_busid { + busnum: bus, + devnum: dev, + funcnum: func, + ..Default::default() + }; + + unsafe { + ioctl::get_irq_from_bus_id(fd, &mut irq)?; + } + + Ok(irq) +} + +/// Get client information given a client's ID. +pub fn get_client(fd: BorrowedFd<'_>, idx: c_int) -> io::Result<drm_client> { + let mut client = drm_client { + idx, + ..Default::default() + }; + + unsafe { + ioctl::get_client(fd, &mut client)?; + } + + Ok(client) +} + +/// Check if a capability is set. +pub fn get_capability(fd: BorrowedFd<'_>, cty: u64) -> io::Result<drm_get_cap> { + let mut cap = drm_get_cap { + capability: cty, + ..Default::default() + }; + + unsafe { + ioctl::get_cap(fd, &mut cap)?; + } + + Ok(cap) +} + +/// Attempt to enable/disable a client's capability. +pub fn set_capability(fd: BorrowedFd<'_>, cty: u64, val: bool) -> io::Result<drm_set_client_cap> { + let cap = drm_set_client_cap { + capability: cty, + value: val as u64, + }; + + unsafe { + ioctl::set_cap(fd, &cap)?; + } + + Ok(cap) +} + +/// Sets the requested interface version +pub fn set_version(fd: BorrowedFd<'_>, version: &mut drm_set_version) -> io::Result<()> { + unsafe { ioctl::set_version(fd, version) } +} + +/// Gets the driver version for this device. +pub fn get_version( + fd: BorrowedFd<'_>, + mut name_buf: Option<&mut Vec<i8>>, + mut date_buf: Option<&mut Vec<i8>>, + mut desc_buf: Option<&mut Vec<i8>>, +) -> io::Result<drm_version> { + let mut sizes = drm_version::default(); + unsafe { + ioctl::get_version(fd, &mut sizes)?; + } + + map_reserve!(name_buf, sizes.name_len as usize); + map_reserve!(date_buf, sizes.date_len as usize); + map_reserve!(desc_buf, sizes.desc_len as usize); + + let mut version = drm_version { + name_len: map_len!(&name_buf), + name: map_ptr!(&name_buf), + date_len: map_len!(&date_buf), + date: map_ptr!(&date_buf), + desc_len: map_len!(&desc_buf), + desc: map_ptr!(&desc_buf), + ..Default::default() + }; + + unsafe { + ioctl::get_version(fd, &mut version)?; + } + + map_set!(name_buf, version.name_len as usize); + map_set!(date_buf, version.date_len as usize); + map_set!(desc_buf, version.desc_len as usize); + + Ok(version) +} + +/// Waits for a vblank. +pub fn wait_vblank( + fd: BorrowedFd<'_>, + type_: u32, + sequence: u32, + signal: usize, +) -> io::Result<drm_wait_vblank_reply> { + // We can't assume the kernel will completely fill the reply in the union + // with valid data (it won't populate the timestamp if the event flag is + // set, for example), so use `default` to ensure the structure is completely + // initialized with zeros + let mut wait_vblank = drm_wait_vblank::default(); + wait_vblank.request = drm_wait_vblank_request { + type_, + sequence, + signal: signal as c_ulong, + }; + + unsafe { + ioctl::wait_vblank(fd, &mut wait_vblank)?; + }; + + Ok(unsafe { wait_vblank.reply }) +} |