From 34fcd7896069e6531f3bb06a216f36d8942861a7 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Mon, 6 Nov 2023 15:25:06 -0800 Subject: [PATCH] Use `std::io::Error` for error results, except `get_planar_framebuffer` Based on discussion on https://github.com/Smithay/drm-rs/pull/173. Which this supersedes. All functions in `drm` and `drm_ffi` returning `SystemError`, except `get_planar_frambuffer`, only use it for representing standard Unix error kinds. So `std::io::Error` can be used instead. For `get_planar_framebuffer`, a `GetPlanarFramebufferError` error is defined. It might be nice if Rust has anonymous sum types for this sort of thing, but this seems like the typical pattern. And better than using the same error kind everywhere if `UnrecognizedFourcc` isn't possible in any other function. This should remove `nix` from the public API of the crate. This makes errors a bit simpler to handle for users of the library using `rustix` or a different version of `nix`, and allows `drm` to change which it uses without a breaking API change. --- drm-ffi/src/gem.rs | 22 ++--- drm-ffi/src/lib.rs | 39 +++++---- drm-ffi/src/mode.rs | 82 +++++++++--------- drm-ffi/src/result.rs | 75 ----------------- drm-ffi/src/syncobj.rs | 28 ++++--- examples/syncobj.rs | 9 +- src/control/mod.rs | 184 +++++++++++++++++++++++------------------ src/lib.rs | 36 ++++---- 8 files changed, 210 insertions(+), 265 deletions(-) delete mode 100644 drm-ffi/src/result.rs diff --git a/drm-ffi/src/gem.rs b/drm-ffi/src/gem.rs index 79e87cef..4d330d6d 100644 --- a/drm-ffi/src/gem.rs +++ b/drm-ffi/src/gem.rs @@ -5,12 +5,13 @@ use crate::ioctl; use drm_sys::*; -use crate::result::SystemError as Error; - -use std::os::unix::io::{AsRawFd, BorrowedFd}; +use std::{ + io, + os::unix::io::{AsRawFd, BorrowedFd}, +}; /// Open a GEM object given it's 32-bit name, returning the handle. -pub fn open(fd: BorrowedFd<'_>, name: u32) -> Result { +pub fn open(fd: BorrowedFd<'_>, name: u32) -> io::Result { let mut gem = drm_gem_open { name, ..Default::default() @@ -24,7 +25,7 @@ pub fn open(fd: BorrowedFd<'_>, name: u32) -> Result { } /// Closes a GEM object given it's handle. -pub fn close(fd: BorrowedFd<'_>, handle: u32) -> Result { +pub fn close(fd: BorrowedFd<'_>, handle: u32) -> io::Result { let gem = drm_gem_close { handle, ..Default::default() @@ -38,11 +39,7 @@ pub fn close(fd: BorrowedFd<'_>, handle: u32) -> Result { } /// Converts a GEM object's handle to a PRIME file descriptor. -pub fn handle_to_fd( - fd: BorrowedFd<'_>, - handle: u32, - flags: u32, -) -> Result { +pub fn handle_to_fd(fd: BorrowedFd<'_>, handle: u32, flags: u32) -> io::Result { let mut prime = drm_prime_handle { handle, flags, @@ -57,10 +54,7 @@ pub fn handle_to_fd( } /// Converts a PRIME file descriptor to a GEM object's handle. -pub fn fd_to_handle( - fd: BorrowedFd<'_>, - primefd: BorrowedFd<'_>, -) -> Result { +pub fn fd_to_handle(fd: BorrowedFd<'_>, primefd: BorrowedFd<'_>) -> io::Result { let mut prime = drm_prime_handle { fd: primefd.as_raw_fd(), ..Default::default() diff --git a/drm-ffi/src/lib.rs b/drm-ffi/src/lib.rs index 01f977d0..c63c9558 100644 --- a/drm-ffi/src/lib.rs +++ b/drm-ffi/src/lib.rs @@ -13,15 +13,16 @@ extern crate nix; #[macro_use] pub(crate) mod utils; -use crate::result::SystemError as Error; pub mod gem; mod ioctl; pub mod mode; -pub mod result; pub mod syncobj; use nix::libc::{c_int, c_ulong}; -use std::os::unix::io::{AsRawFd, BorrowedFd}; +use std::{ + io, + os::unix::io::{AsRawFd, BorrowedFd}, +}; /// /// Bindings to the methods of authentication the DRM provides. @@ -30,11 +31,13 @@ pub mod auth { use crate::ioctl; use drm_sys::*; - use nix::Error; - use std::os::unix::io::{AsRawFd, BorrowedFd}; + use std::{ + io, + os::unix::io::{AsRawFd, BorrowedFd}, + }; /// Get the 'Magic Authentication Token' for this file descriptor. - pub fn get_magic_token(fd: BorrowedFd<'_>) -> Result { + pub fn get_magic_token(fd: BorrowedFd<'_>) -> io::Result { let mut auth = drm_auth::default(); unsafe { @@ -45,7 +48,7 @@ pub mod auth { } /// Authorize another process' 'Magic Authentication Token'. - pub fn auth_magic_token(fd: BorrowedFd<'_>, auth: u32) -> Result { + pub fn auth_magic_token(fd: BorrowedFd<'_>, auth: u32) -> io::Result { let token = drm_auth { magic: auth }; unsafe { @@ -56,7 +59,7 @@ pub mod auth { } /// Acquire the 'Master DRM Lock' for this file descriptor. - pub fn acquire_master(fd: BorrowedFd<'_>) -> Result<(), Error> { + pub fn acquire_master(fd: BorrowedFd<'_>) -> io::Result<()> { unsafe { ioctl::acquire_master(fd.as_raw_fd())?; } @@ -65,7 +68,7 @@ pub mod auth { } /// Release the 'Master DRM Lock' for this file descriptor. - pub fn release_master(fd: BorrowedFd<'_>) -> Result<(), Error> { + pub fn release_master(fd: BorrowedFd<'_>) -> io::Result<()> { unsafe { ioctl::release_master(fd.as_raw_fd())?; } @@ -75,7 +78,7 @@ pub mod auth { } /// Load this device's Bus ID into a buffer. -pub fn get_bus_id(fd: BorrowedFd<'_>, mut buf: Option<&mut Vec>) -> Result { +pub fn get_bus_id(fd: BorrowedFd<'_>, mut buf: Option<&mut Vec>) -> io::Result { let mut sizes = drm_unique::default(); unsafe { ioctl::get_bus_id(fd.as_raw_fd(), &mut sizes)?; @@ -107,7 +110,7 @@ pub fn get_interrupt_from_bus_id( bus: c_int, dev: c_int, func: c_int, -) -> Result { +) -> io::Result { let mut irq = drm_irq_busid { busnum: bus, devnum: dev, @@ -123,7 +126,7 @@ pub fn get_interrupt_from_bus_id( } /// Get client information given a client's ID. -pub fn get_client(fd: BorrowedFd<'_>, idx: c_int) -> Result { +pub fn get_client(fd: BorrowedFd<'_>, idx: c_int) -> io::Result { let mut client = drm_client { idx, ..Default::default() @@ -137,7 +140,7 @@ pub fn get_client(fd: BorrowedFd<'_>, idx: c_int) -> Result { } /// Check if a capability is set. -pub fn get_capability(fd: BorrowedFd<'_>, cty: u64) -> Result { +pub fn get_capability(fd: BorrowedFd<'_>, cty: u64) -> io::Result { let mut cap = drm_get_cap { capability: cty, ..Default::default() @@ -151,11 +154,7 @@ pub fn get_capability(fd: BorrowedFd<'_>, cty: u64) -> Result, - cty: u64, - val: bool, -) -> Result { +pub fn set_capability(fd: BorrowedFd<'_>, cty: u64, val: bool) -> io::Result { let cap = drm_set_client_cap { capability: cty, value: val as u64, @@ -174,7 +173,7 @@ pub fn get_version( mut name_buf: Option<&mut Vec>, mut date_buf: Option<&mut Vec>, mut desc_buf: Option<&mut Vec>, -) -> Result { +) -> io::Result { let mut sizes = drm_version::default(); unsafe { ioctl::get_version(fd.as_raw_fd(), &mut sizes)?; @@ -211,7 +210,7 @@ pub fn wait_vblank( type_: u32, sequence: u32, signal: usize, -) -> Result { +) -> io::Result { // 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 diff --git a/drm-ffi/src/mode.rs b/drm-ffi/src/mode.rs index d95ba1cd..49c2d5a2 100644 --- a/drm-ffi/src/mode.rs +++ b/drm-ffi/src/mode.rs @@ -7,8 +7,10 @@ use crate::ioctl; use drm_sys::*; -use crate::result::SystemError as Error; -use std::os::unix::io::{AsRawFd, BorrowedFd}; +use std::{ + io, + os::unix::io::{AsRawFd, BorrowedFd}, +}; /// Enumerate most card resources. pub fn get_resources( @@ -17,7 +19,7 @@ pub fn get_resources( mut crtcs: Option<&mut Vec>, mut connectors: Option<&mut Vec>, mut encoders: Option<&mut Vec>, -) -> Result { +) -> io::Result { let mut sizes = drm_mode_card_res::default(); unsafe { ioctl::mode::get_resources(fd.as_raw_fd(), &mut sizes)?; @@ -56,7 +58,7 @@ pub fn get_resources( pub fn get_plane_resources( fd: BorrowedFd<'_>, mut planes: Option<&mut Vec>, -) -> Result { +) -> io::Result { let mut sizes = drm_mode_get_plane_res::default(); unsafe { ioctl::mode::get_plane_resources(fd.as_raw_fd(), &mut sizes)?; @@ -83,7 +85,7 @@ pub fn get_plane_resources( } /// Get info about a framebuffer. -pub fn get_framebuffer(fd: BorrowedFd<'_>, fb_id: u32) -> Result { +pub fn get_framebuffer(fd: BorrowedFd<'_>, fb_id: u32) -> io::Result { let mut info = drm_mode_fb_cmd { fb_id, ..Default::default() @@ -105,7 +107,7 @@ pub fn add_fb( bpp: u32, depth: u32, handle: u32, -) -> Result { +) -> io::Result { let mut fb = drm_mode_fb_cmd { width, height, @@ -124,7 +126,7 @@ pub fn add_fb( } /// Get info about a framebuffer (with modifiers). -pub fn get_framebuffer2(fd: BorrowedFd<'_>, fb_id: u32) -> Result { +pub fn get_framebuffer2(fd: BorrowedFd<'_>, fb_id: u32) -> io::Result { let mut info = drm_mode_fb_cmd2 { fb_id, ..Default::default() @@ -148,7 +150,7 @@ pub fn add_fb2( offsets: &[u32; 4], modifier: &[u64; 4], flags: u32, -) -> Result { +) -> io::Result { let mut fb = drm_mode_fb_cmd2 { width, height, @@ -169,7 +171,7 @@ pub fn add_fb2( } /// Remove a framebuffer. -pub fn rm_fb(fd: BorrowedFd<'_>, mut id: u32) -> Result<(), Error> { +pub fn rm_fb(fd: BorrowedFd<'_>, mut id: u32) -> io::Result<()> { unsafe { ioctl::mode::rm_fb(fd.as_raw_fd(), &mut id)?; } @@ -182,7 +184,7 @@ pub fn dirty_fb( fd: BorrowedFd<'_>, fb_id: u32, clips: &[drm_clip_rect], -) -> Result { +) -> io::Result { let mut dirty = drm_mode_fb_dirty_cmd { fb_id, num_clips: clips.len() as _, @@ -198,7 +200,7 @@ pub fn dirty_fb( } /// Get info about a CRTC -pub fn get_crtc(fd: BorrowedFd<'_>, crtc_id: u32) -> Result { +pub fn get_crtc(fd: BorrowedFd<'_>, crtc_id: u32) -> io::Result { let mut info = drm_mode_crtc { crtc_id, ..Default::default() @@ -220,7 +222,7 @@ pub fn set_crtc( y: u32, conns: &[u32], mode: Option, -) -> Result { +) -> io::Result { let mut crtc = drm_mode_crtc { set_connectors_ptr: conns.as_ptr() as _, count_connectors: conns.len() as _, @@ -251,7 +253,7 @@ pub fn get_gamma( red: &mut [u16], green: &mut [u16], blue: &mut [u16], -) -> Result { +) -> io::Result { let mut lut = drm_mode_crtc_lut { crtc_id, gamma_size: size as _, @@ -275,7 +277,7 @@ pub fn set_gamma( red: &[u16], green: &[u16], blue: &[u16], -) -> Result { +) -> io::Result { let mut lut = drm_mode_crtc_lut { crtc_id, gamma_size: size as _, @@ -302,7 +304,7 @@ pub fn set_cursor( buf_id: u32, width: u32, height: u32, -) -> Result { +) -> io::Result { let mut cursor = drm_mode_cursor { flags: DRM_MODE_CURSOR_BO, crtc_id, @@ -335,7 +337,7 @@ pub fn set_cursor2( height: u32, hot_x: i32, hot_y: i32, -) -> Result { +) -> io::Result { let mut cursor = drm_mode_cursor2 { flags: DRM_MODE_CURSOR_BO, crtc_id, @@ -361,7 +363,7 @@ pub fn move_cursor( crtc_id: u32, x: i32, y: i32, -) -> Result { +) -> io::Result { let mut cursor = drm_mode_cursor { flags: DRM_MODE_CURSOR_MOVE, crtc_id, @@ -386,7 +388,7 @@ pub fn get_connector( mut modes: Option<&mut Vec>, mut encoders: Option<&mut Vec>, force_probe: bool, -) -> Result { +) -> io::Result { assert_eq!(props.is_some(), prop_values.is_some()); let tmp_mode = drm_mode_modeinfo::default(); @@ -464,7 +466,7 @@ pub fn get_connector( } /// Get info about an encoder -pub fn get_encoder(fd: BorrowedFd<'_>, encoder_id: u32) -> Result { +pub fn get_encoder(fd: BorrowedFd<'_>, encoder_id: u32) -> io::Result { let mut info = drm_mode_get_encoder { encoder_id, ..Default::default() @@ -482,7 +484,7 @@ pub fn get_plane( fd: BorrowedFd<'_>, plane_id: u32, mut formats: Option<&mut Vec>, -) -> Result { +) -> io::Result { let mut sizes = drm_mode_get_plane { plane_id, ..Default::default() @@ -529,7 +531,7 @@ pub fn set_plane( src_y: u32, src_w: u32, src_h: u32, -) -> Result { +) -> io::Result { let mut plane = drm_mode_set_plane { plane_id, crtc_id, @@ -558,7 +560,7 @@ pub fn get_property( prop_id: u32, mut values: Option<&mut Vec>, mut enums: Option<&mut Vec>, -) -> Result { +) -> io::Result { let mut prop = drm_mode_get_property { prop_id, ..Default::default() @@ -595,7 +597,7 @@ pub fn set_connector_property( connector_id: u32, prop_id: u32, value: u64, -) -> Result { +) -> io::Result { let mut prop = drm_mode_connector_set_property { value, prop_id, @@ -614,7 +616,7 @@ pub fn get_property_blob( fd: BorrowedFd<'_>, blob_id: u32, mut data: Option<&mut Vec>, -) -> Result { +) -> io::Result { let mut sizes = drm_mode_get_blob { blob_id, ..Default::default() @@ -649,7 +651,7 @@ pub fn get_property_blob( pub fn create_property_blob( fd: BorrowedFd<'_>, data: &mut [u8], -) -> Result { +) -> io::Result { let mut blob = drm_mode_create_blob { data: data.as_mut_ptr() as _, length: data.len() as _, @@ -664,7 +666,7 @@ pub fn create_property_blob( } /// Destroy a property blob -pub fn destroy_property_blob(fd: BorrowedFd<'_>, id: u32) -> Result { +pub fn destroy_property_blob(fd: BorrowedFd<'_>, id: u32) -> io::Result { let mut blob = drm_mode_destroy_blob { blob_id: id }; unsafe { @@ -681,7 +683,7 @@ pub fn get_properties( obj_type: u32, mut props: Option<&mut Vec>, mut values: Option<&mut Vec>, -) -> Result { +) -> io::Result { assert_eq!(props.is_some(), values.is_some()); let mut sizes = drm_mode_obj_get_properties { @@ -722,7 +724,7 @@ pub fn set_property( obj_id: u32, obj_type: u32, value: u64, -) -> Result<(), Error> { +) -> io::Result<()> { let mut prop = drm_mode_obj_set_property { value, prop_id, @@ -744,7 +746,7 @@ pub fn page_flip( fb_id: u32, flags: u32, sequence: u32, -) -> Result<(), Error> { +) -> io::Result<()> { let mut flip = drm_mode_crtc_page_flip { crtc_id, fb_id, @@ -769,7 +771,7 @@ pub fn atomic_commit( prop_counts: &mut [u32], props: &mut [u32], values: &mut [u64], -) -> Result<(), Error> { +) -> io::Result<()> { let mut atomic = drm_mode_atomic { flags, count_objs: objs.len() as _, @@ -792,7 +794,7 @@ pub fn create_lease( fd: BorrowedFd<'_>, objects: &[u32], flags: u32, -) -> Result { +) -> io::Result { let mut data = drm_mode_create_lease { object_ids: objects.as_ptr() as _, object_count: objects.len() as u32, @@ -811,7 +813,7 @@ pub fn create_lease( pub fn list_lessees( fd: BorrowedFd<'_>, mut lessees: Option<&mut Vec>, -) -> Result { +) -> io::Result { let mut sizes = drm_mode_list_lessees::default(); unsafe { @@ -839,7 +841,7 @@ pub fn list_lessees( pub fn get_lease( fd: BorrowedFd<'_>, mut objects: Option<&mut Vec>, -) -> Result { +) -> io::Result { let mut sizes = drm_mode_get_lease::default(); unsafe { @@ -864,7 +866,7 @@ pub fn get_lease( } /// Revoke previously issued lease -pub fn revoke_lease(fd: BorrowedFd<'_>, lessee_id: u32) -> Result<(), Error> { +pub fn revoke_lease(fd: BorrowedFd<'_>, lessee_id: u32) -> io::Result<()> { let mut data = drm_mode_revoke_lease { lessee_id }; unsafe { @@ -881,8 +883,10 @@ pub mod dumbbuffer { use crate::ioctl; use drm_sys::*; - use crate::result::SystemError as Error; - use std::os::unix::io::{AsRawFd, BorrowedFd}; + use std::{ + io, + os::unix::io::{AsRawFd, BorrowedFd}, + }; /// Create a dumb buffer pub fn create( @@ -891,7 +895,7 @@ pub mod dumbbuffer { height: u32, bpp: u32, flags: u32, - ) -> Result { + ) -> io::Result { let mut db = drm_mode_create_dumb { height, width, @@ -908,7 +912,7 @@ pub mod dumbbuffer { } /// Destroy a dumb buffer - pub fn destroy(fd: BorrowedFd<'_>, handle: u32) -> Result { + pub fn destroy(fd: BorrowedFd<'_>, handle: u32) -> io::Result { let mut db = drm_mode_destroy_dumb { handle }; unsafe { @@ -924,7 +928,7 @@ pub mod dumbbuffer { handle: u32, pad: u32, offset: u64, - ) -> Result { + ) -> io::Result { let mut map = drm_mode_map_dumb { handle, pad, diff --git a/drm-ffi/src/result.rs b/drm-ffi/src/result.rs deleted file mode 100644 index 3222ba79..00000000 --- a/drm-ffi/src/result.rs +++ /dev/null @@ -1,75 +0,0 @@ -//! -//! Error types -//! - -use nix::errno::Errno; -use std::error::Error; -use std::fmt; - -/// A general system error that can be returned by any DRM command. -/// -/// Receiving this error likely indicates a bug in either the program, this -/// crate, or the underlying operating system. -#[derive(Debug)] -pub enum SystemError { - /// A command was attempted using an invalid file descriptor. - InvalidFileDescriptor, - - /// Provided memory area is inaccessible. - /// - /// Receiving this error indicates a bug in this crate. - MemoryFault, - - /// One or more arguments used are invalid. - /// - /// This can be due to the system not supporting a feature or value. - InvalidArgument, - - /// A command was attempted using a non-DRM device. - InvalidFileType, - - /// Permission denied. - PermissionDenied, - - /// An unknown fourcc code was received. - /// - /// This likely indicates that the drm-fourcc crate needs updating. - UnknownFourcc, - - /// Unknown system error. - Unknown { - /// Unknown [`nix::errno::Errno`] returned by the system call. - errno: Errno, - }, -} - -impl fmt::Display for SystemError { - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> fmt::Result { - fmt.write_str(match self { - SystemError::InvalidFileDescriptor => "invalid file descriptor", - SystemError::MemoryFault => "invalid memory access", - SystemError::InvalidArgument => "invalid argument", - SystemError::InvalidFileType => "invalid file type", - SystemError::PermissionDenied => "permission denied", - SystemError::UnknownFourcc => "unknown fourcc", - SystemError::Unknown { errno } => { - return write!(fmt, "unknown system error: {}", errno) - } - }) - } -} - -impl Error for SystemError {} - -impl From for SystemError { - fn from(errno: Errno) -> SystemError { - match errno { - Errno::EBADF => SystemError::InvalidFileDescriptor, - Errno::EFAULT => SystemError::MemoryFault, - Errno::EINVAL => SystemError::InvalidArgument, - Errno::ENOTTY => SystemError::InvalidFileDescriptor, - Errno::EACCES => SystemError::PermissionDenied, - _ => SystemError::Unknown { errno }, - } - } -} diff --git a/drm-ffi/src/syncobj.rs b/drm-ffi/src/syncobj.rs index 19f11703..8dd9b5d3 100644 --- a/drm-ffi/src/syncobj.rs +++ b/drm-ffi/src/syncobj.rs @@ -5,11 +5,13 @@ use crate::ioctl; use drm_sys::*; -use crate::result::SystemError as Error; -use std::os::unix::io::{AsRawFd, BorrowedFd}; +use std::{ + io, + os::unix::io::{AsRawFd, BorrowedFd}, +}; /// Creates a syncobj. -pub fn create(fd: BorrowedFd<'_>, signaled: bool) -> Result { +pub fn create(fd: BorrowedFd<'_>, signaled: bool) -> io::Result { let mut args = drm_syncobj_create { handle: 0, flags: if signaled { @@ -27,7 +29,7 @@ pub fn create(fd: BorrowedFd<'_>, signaled: bool) -> Result, handle: u32) -> Result { +pub fn destroy(fd: BorrowedFd<'_>, handle: u32) -> io::Result { let mut args = drm_syncobj_destroy { handle, pad: 0 }; unsafe { @@ -42,7 +44,7 @@ pub fn handle_to_fd( fd: BorrowedFd<'_>, handle: u32, export_sync_file: bool, -) -> Result { +) -> io::Result { let mut args = drm_syncobj_handle { handle, flags: if export_sync_file { @@ -66,7 +68,7 @@ pub fn fd_to_handle( fd: BorrowedFd<'_>, syncobj_fd: BorrowedFd<'_>, import_sync_file: bool, -) -> Result { +) -> io::Result { let mut args = drm_syncobj_handle { handle: 0, flags: if import_sync_file { @@ -92,7 +94,7 @@ pub fn wait( timeout_nsec: i64, wait_all: bool, wait_for_submit: bool, -) -> Result { +) -> io::Result { let mut args = drm_syncobj_wait { handles: handles.as_ptr() as _, timeout_nsec, @@ -118,7 +120,7 @@ pub fn wait( } /// Resets (un-signals) one or more syncobjs. -pub fn reset(fd: BorrowedFd<'_>, handles: &[u32]) -> Result { +pub fn reset(fd: BorrowedFd<'_>, handles: &[u32]) -> io::Result { let mut args = drm_syncobj_array { handles: handles.as_ptr() as _, count_handles: handles.len() as _, @@ -133,7 +135,7 @@ pub fn reset(fd: BorrowedFd<'_>, handles: &[u32]) -> Result, handles: &[u32]) -> Result { +pub fn signal(fd: BorrowedFd<'_>, handles: &[u32]) -> io::Result { let mut args = drm_syncobj_array { handles: handles.as_ptr() as _, count_handles: handles.len() as _, @@ -156,7 +158,7 @@ pub fn timeline_wait( wait_all: bool, wait_for_submit: bool, wait_available: bool, -) -> Result { +) -> io::Result { debug_assert_eq!(handles.len(), points.len()); let mut args = drm_syncobj_timeline_wait { @@ -194,7 +196,7 @@ pub fn query( handles: &[u32], points: &mut [u64], last_submitted: bool, -) -> Result { +) -> io::Result { debug_assert_eq!(handles.len(), points.len()); let mut args = drm_syncobj_timeline_array { @@ -222,7 +224,7 @@ pub fn transfer( dst_handle: u32, src_point: u64, dst_point: u64, -) -> Result { +) -> io::Result { let mut args = drm_syncobj_transfer { src_handle, dst_handle, @@ -244,7 +246,7 @@ pub fn timeline_signal( fd: BorrowedFd<'_>, handles: &[u32], points: &[u64], -) -> Result { +) -> io::Result { debug_assert_eq!(handles.len(), points.len()); let mut args = drm_syncobj_timeline_array { diff --git a/examples/syncobj.rs b/examples/syncobj.rs index bd7fc5b6..05282481 100644 --- a/examples/syncobj.rs +++ b/examples/syncobj.rs @@ -3,12 +3,13 @@ pub mod utils; use crate::utils::*; use nix::poll::PollFlags; -use std::os::unix::io::{AsFd, OwnedFd}; - -use drm::SystemError; +use std::{ + io, + os::unix::io::{AsFd, OwnedFd}, +}; impl Card { - fn simulate_command_submission(&self) -> Result { + fn simulate_command_submission(&self) -> io::Result { // Create a temporary syncobj to receive the command fence. let syncobj = self.create_syncobj(false)?; diff --git a/src/control/mod.rs b/src/control/mod.rs index 19d13c29..8b67b2d8 100644 --- a/src/control/mod.rs +++ b/src/control/mod.rs @@ -29,10 +29,10 @@ //! must be implemented on top of the basic [`super::Device`] trait. use drm_ffi as ffi; -use drm_ffi::result::SystemError; use drm_fourcc::{DrmFourcc, DrmModifier, UnrecognizedFourcc}; use bytemuck::allocation::TransparentWrapperAlloc; +use nix::libc::EINVAL; pub mod atomic; pub mod connector; @@ -52,6 +52,9 @@ use super::util::*; use std::collections::HashMap; use std::convert::TryFrom; +use std::error; +use std::fmt; +use std::io; use std::iter::Zip; use std::mem; use std::num::NonZeroUsize; @@ -84,6 +87,45 @@ pub fn from_u32>(raw: u32) -> Option { RawResourceHandle::new(raw).map(T::from) } +/// Error from [`Device::get_planar_framebuffer`] +#[derive(Debug)] +pub enum GetPlanarFramebufferError { + /// IO error + Io(io::Error), + /// Unrecognized fourcc format + UnrecognizedFourcc(drm_fourcc::UnrecognizedFourcc), +} + +impl fmt::Display for GetPlanarFramebufferError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::Io(err) => write!(f, "{}", err), + Self::UnrecognizedFourcc(err) => write!(f, "{}", err), + } + } +} + +impl error::Error for GetPlanarFramebufferError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + Self::Io(err) => Some(err), + Self::UnrecognizedFourcc(err) => Some(err), + } + } +} + +impl From for GetPlanarFramebufferError { + fn from(err: io::Error) -> Self { + Self::Io(err) + } +} + +impl From for GetPlanarFramebufferError { + fn from(err: UnrecognizedFourcc) -> Self { + Self::UnrecognizedFourcc(err) + } +} + /// This trait should be implemented by any object that acts as a DRM device and /// provides modesetting functionality. /// @@ -99,7 +141,7 @@ pub fn from_u32>(raw: u32) -> Option { /// ``` pub trait Device: super::Device { /// Gets the set of resource handles that this device currently controls - fn resource_handles(&self) -> Result { + fn resource_handles(&self) -> io::Result { let mut fbs = Vec::new(); let mut crtcs = Vec::new(); let mut connectors = Vec::new(); @@ -128,7 +170,7 @@ pub trait Device: super::Device { } /// Gets the set of plane handles that this device currently has - fn plane_handles(&self) -> Result, SystemError> { + fn plane_handles(&self) -> io::Result> { let mut planes = Vec::new(); let _ = ffi::mode::get_plane_resources(self.as_fd(), Some(&mut planes))?; Ok(unsafe { transmute_vec_from_u32(planes) }) @@ -149,7 +191,7 @@ pub trait Device: super::Device { &self, handle: connector::Handle, force_probe: bool, - ) -> Result { + ) -> io::Result { // Maximum number of encoders is 3 due to kernel restrictions let mut encoders = Vec::new(); let mut modes = Vec::new(); @@ -183,7 +225,7 @@ pub trait Device: super::Device { } /// Returns information about a specific encoder - fn get_encoder(&self, handle: encoder::Handle) -> Result { + fn get_encoder(&self, handle: encoder::Handle) -> io::Result { let info = ffi::mode::get_encoder(self.as_fd(), handle.into())?; let enc = encoder::Info { @@ -198,7 +240,7 @@ pub trait Device: super::Device { } /// Returns information about a specific CRTC - fn get_crtc(&self, handle: crtc::Handle) -> Result { + fn get_crtc(&self, handle: crtc::Handle) -> io::Result { let info = ffi::mode::get_crtc(self.as_fd(), handle.into())?; let crtc = crtc::Info { @@ -223,7 +265,7 @@ pub trait Device: super::Device { pos: (u32, u32), conns: &[connector::Handle], mode: Option, - ) -> Result<(), SystemError> { + ) -> io::Result<()> { let _info = ffi::mode::set_crtc( self.as_fd(), handle.into(), @@ -238,10 +280,7 @@ pub trait Device: super::Device { } /// Returns information about a specific framebuffer - fn get_framebuffer( - &self, - handle: framebuffer::Handle, - ) -> Result { + fn get_framebuffer(&self, handle: framebuffer::Handle) -> io::Result { let info = ffi::mode::get_framebuffer(self.as_fd(), handle.into())?; let fb = framebuffer::Info { @@ -260,13 +299,10 @@ pub trait Device: super::Device { fn get_planar_framebuffer( &self, handle: framebuffer::Handle, - ) -> Result { + ) -> Result { let info = ffi::mode::get_framebuffer2(self.as_fd(), handle.into())?; - let pixel_format = match DrmFourcc::try_from(info.pixel_format) { - Ok(pixel_format) => pixel_format, - Err(UnrecognizedFourcc(_)) => return Err(SystemError::UnknownFourcc), - }; + let pixel_format = DrmFourcc::try_from(info.pixel_format)?; let flags = FbCmd2Flags::from_bits_truncate(info.flags); let modifier = flags @@ -293,7 +329,7 @@ pub trait Device: super::Device { buffer: &B, depth: u32, bpp: u32, - ) -> Result + ) -> io::Result where B: buffer::Buffer + ?Sized, { @@ -316,7 +352,7 @@ pub trait Device: super::Device { &self, planar_buffer: &B, flags: FbCmd2Flags, - ) -> Result + ) -> io::Result where B: buffer::PlanarBuffer + ?Sized, { @@ -356,11 +392,7 @@ pub trait Device: super::Device { } /// Mark parts of a framebuffer dirty - fn dirty_framebuffer( - &self, - handle: framebuffer::Handle, - clips: &[ClipRect], - ) -> Result<(), SystemError> { + fn dirty_framebuffer(&self, handle: framebuffer::Handle, clips: &[ClipRect]) -> io::Result<()> { ffi::mode::dirty_fb(self.as_fd(), handle.into(), unsafe { // SAFETY: ClipRect is repr(transparent) for drm_clip_rect core::slice::from_raw_parts(clips.as_ptr() as *const ffi::drm_clip_rect, clips.len()) @@ -369,12 +401,12 @@ pub trait Device: super::Device { } /// Destroy a framebuffer - fn destroy_framebuffer(&self, handle: framebuffer::Handle) -> Result<(), SystemError> { + fn destroy_framebuffer(&self, handle: framebuffer::Handle) -> io::Result<()> { ffi::mode::rm_fb(self.as_fd(), handle.into()) } /// Returns information about a specific plane - fn get_plane(&self, handle: plane::Handle) -> Result { + fn get_plane(&self, handle: plane::Handle) -> io::Result { let mut formats = Vec::new(); let info = ffi::mode::get_plane(self.as_fd(), handle.into(), Some(&mut formats))?; @@ -401,7 +433,7 @@ pub trait Device: super::Device { flags: u32, crtc_rect: (i32, i32, u32, u32), src_rect: (u32, u32, u32, u32), - ) -> Result<(), SystemError> { + ) -> io::Result<()> { let _info = ffi::mode::set_plane( self.as_fd(), handle.into(), @@ -422,7 +454,7 @@ pub trait Device: super::Device { } /// Returns information about a specific property. - fn get_property(&self, handle: property::Handle) -> Result { + fn get_property(&self, handle: property::Handle) -> io::Result { let mut values = Vec::new(); let mut enums = Vec::new(); @@ -496,14 +528,14 @@ pub trait Device: super::Device { handle: T, prop: property::Handle, value: property::RawValue, - ) -> Result<(), SystemError> { + ) -> io::Result<()> { ffi::mode::set_property(self.as_fd(), prop.into(), handle.into(), T::FFI_TYPE, value)?; Ok(()) } /// Create a property blob value from a given data blob - fn create_property_blob(&self, data: &T) -> Result, SystemError> { + fn create_property_blob(&self, data: &T) -> io::Result> { let data = unsafe { std::slice::from_raw_parts_mut(data as *const _ as *mut u8, mem::size_of::()) }; @@ -513,21 +545,21 @@ pub trait Device: super::Device { } /// Get a property blob's data - fn get_property_blob(&self, blob: u64) -> Result, SystemError> { + fn get_property_blob(&self, blob: u64) -> io::Result> { let mut data = Vec::new(); let _ = ffi::mode::get_property_blob(self.as_fd(), blob as u32, Some(&mut data))?; Ok(data) } /// Destroy a given property blob value - fn destroy_property_blob(&self, blob: u64) -> Result<(), SystemError> { + fn destroy_property_blob(&self, blob: u64) -> io::Result<()> { ffi::mode::destroy_property_blob(self.as_fd(), blob as u32)?; Ok(()) } /// Returns the set of [`Mode`]s that a particular connector supports. - fn get_modes(&self, handle: connector::Handle) -> Result, SystemError> { + fn get_modes(&self, handle: connector::Handle) -> io::Result> { let mut modes = Vec::new(); let _ffi_info = ffi::mode::get_connector( @@ -544,10 +576,7 @@ pub trait Device: super::Device { } /// Gets a list of property handles and values for this resource. - fn get_properties( - &self, - handle: T, - ) -> Result { + fn get_properties(&self, handle: T) -> io::Result { let mut prop_ids = Vec::new(); let mut prop_vals = Vec::new(); @@ -574,13 +603,13 @@ pub trait Device: super::Device { red: &mut [u16], green: &mut [u16], blue: &mut [u16], - ) -> Result<(), SystemError> { + ) -> io::Result<()> { let crtc_info = self.get_crtc(crtc)?; if crtc_info.gamma_length as usize > red.len() || crtc_info.gamma_length as usize > green.len() || crtc_info.gamma_length as usize > blue.len() { - return Err(SystemError::InvalidArgument); + return Err(io::Error::from_raw_os_error(EINVAL)); } ffi::mode::get_gamma( @@ -602,13 +631,13 @@ pub trait Device: super::Device { red: &[u16], green: &[u16], blue: &[u16], - ) -> Result<(), SystemError> { + ) -> io::Result<()> { let crtc_info = self.get_crtc(crtc)?; if crtc_info.gamma_length as usize > red.len() || crtc_info.gamma_length as usize > green.len() || crtc_info.gamma_length as usize > blue.len() { - return Err(SystemError::InvalidArgument); + return Err(io::Error::from_raw_os_error(EINVAL)); } ffi::mode::set_gamma( @@ -624,13 +653,13 @@ pub trait Device: super::Device { } /// Open a GEM buffer handle by name - fn open_buffer(&self, name: buffer::Name) -> Result { + fn open_buffer(&self, name: buffer::Name) -> io::Result { let info = drm_ffi::gem::open(self.as_fd(), name.into())?; Ok(from_u32(info.handle).unwrap()) } /// Close a GEM buffer handle - fn close_buffer(&self, handle: buffer::Handle) -> Result<(), SystemError> { + fn close_buffer(&self, handle: buffer::Handle) -> io::Result<()> { let _info = drm_ffi::gem::close(self.as_fd(), handle.into())?; Ok(()) } @@ -641,7 +670,7 @@ pub trait Device: super::Device { size: (u32, u32), format: buffer::DrmFourcc, bpp: u32, - ) -> Result { + ) -> io::Result { let info = drm_ffi::mode::dumbbuffer::create(self.as_fd(), size.0, size.1, bpp, 0)?; let dumb = DumbBuffer { @@ -655,17 +684,15 @@ pub trait Device: super::Device { Ok(dumb) } /// Map the buffer for access - fn map_dumb_buffer<'a>( - &self, - buffer: &'a mut DumbBuffer, - ) -> Result, SystemError> { + fn map_dumb_buffer<'a>(&self, buffer: &'a mut DumbBuffer) -> io::Result> { let info = drm_ffi::mode::dumbbuffer::map(self.as_fd(), buffer.handle.into(), 0, 0)?; let map = { use nix::sys::mman; let prot = mman::ProtFlags::PROT_READ | mman::ProtFlags::PROT_WRITE; let flags = mman::MapFlags::MAP_SHARED; - let length = NonZeroUsize::new(buffer.length).ok_or(SystemError::InvalidArgument)?; + let length = NonZeroUsize::new(buffer.length) + .ok_or_else(|| io::Error::from_raw_os_error(EINVAL))?; let fd = self.as_fd(); let offset = info.offset as _; unsafe { mman::mmap(None, length, prot, flags, Some(fd), offset)? } @@ -680,7 +707,7 @@ pub trait Device: super::Device { } /// Free the memory resources of a dumb buffer - fn destroy_dumb_buffer(&self, buffer: DumbBuffer) -> Result<(), SystemError> { + fn destroy_dumb_buffer(&self, buffer: DumbBuffer) -> io::Result<()> { let _info = drm_ffi::mode::dumbbuffer::destroy(self.as_fd(), buffer.handle.into())?; Ok(()) @@ -691,7 +718,7 @@ pub trait Device: super::Device { /// A buffer argument of [`None`] will clear the cursor. #[deprecated(note = "Usage of deprecated ioctl set_cursor: use a cursor plane instead")] #[allow(deprecated)] - fn set_cursor(&self, crtc: crtc::Handle, buffer: Option<&B>) -> Result<(), SystemError> + fn set_cursor(&self, crtc: crtc::Handle, buffer: Option<&B>) -> io::Result<()> where B: buffer::Buffer + ?Sized, { @@ -717,7 +744,7 @@ pub trait Device: super::Device { crtc: crtc::Handle, buffer: Option<&B>, hotspot: (i32, i32), - ) -> Result<(), SystemError> + ) -> io::Result<()> where B: buffer::Buffer + ?Sized, { @@ -735,7 +762,7 @@ pub trait Device: super::Device { /// Moves a set cursor on a given crtc #[deprecated(note = "Usage of deprecated ioctl move_cursor: use a cursor plane instead")] #[allow(deprecated)] - fn move_cursor(&self, crtc: crtc::Handle, pos: (i32, i32)) -> Result<(), SystemError> { + fn move_cursor(&self, crtc: crtc::Handle, pos: (i32, i32)) -> io::Result<()> { drm_ffi::mode::move_cursor(self.as_fd(), crtc.into(), pos.0, pos.1)?; Ok(()) @@ -746,7 +773,7 @@ pub trait Device: super::Device { &self, flags: AtomicCommitFlags, mut req: atomic::AtomicModeReq, - ) -> Result<(), SystemError> { + ) -> io::Result<()> { drm_ffi::mode::atomic_commit( self.as_fd(), flags.bits(), @@ -758,17 +785,13 @@ pub trait Device: super::Device { } /// Convert a prime file descriptor to a GEM buffer handle - fn prime_fd_to_buffer(&self, fd: BorrowedFd<'_>) -> Result { + fn prime_fd_to_buffer(&self, fd: BorrowedFd<'_>) -> io::Result { let info = ffi::gem::fd_to_handle(self.as_fd(), fd)?; Ok(from_u32(info.handle).unwrap()) } /// Convert a GEM buffer handle to a prime file descriptor - fn buffer_to_prime_fd( - &self, - handle: buffer::Handle, - flags: u32, - ) -> Result { + fn buffer_to_prime_fd(&self, handle: buffer::Handle, flags: u32) -> io::Result { let info = ffi::gem::handle_to_fd(self.as_fd(), handle.into(), flags)?; Ok(unsafe { OwnedFd::from_raw_fd(info.fd) }) } @@ -780,7 +803,7 @@ pub trait Device: super::Device { framebuffer: framebuffer::Handle, flags: PageFlipFlags, target_sequence: Option, - ) -> Result<(), SystemError> { + ) -> io::Result<()> { let mut flags = flags.bits(); let sequence = match target_sequence { @@ -807,13 +830,13 @@ pub trait Device: super::Device { } /// Creates a syncobj. - fn create_syncobj(&self, signalled: bool) -> Result { + fn create_syncobj(&self, signalled: bool) -> io::Result { let info = ffi::syncobj::create(self.as_fd(), signalled)?; Ok(from_u32(info.handle).unwrap()) } /// Destroys a syncobj. - fn destroy_syncobj(&self, handle: syncobj::Handle) -> Result<(), SystemError> { + fn destroy_syncobj(&self, handle: syncobj::Handle) -> io::Result<()> { ffi::syncobj::destroy(self.as_fd(), handle.into())?; Ok(()) } @@ -823,7 +846,7 @@ pub trait Device: super::Device { &self, handle: syncobj::Handle, export_sync_file: bool, - ) -> Result { + ) -> io::Result { let info = ffi::syncobj::handle_to_fd(self.as_fd(), handle.into(), export_sync_file)?; Ok(unsafe { OwnedFd::from_raw_fd(info.fd) }) } @@ -833,7 +856,7 @@ pub trait Device: super::Device { &self, fd: BorrowedFd<'_>, import_sync_file: bool, - ) -> Result { + ) -> io::Result { let info = ffi::syncobj::fd_to_handle(self.as_fd(), fd, import_sync_file)?; Ok(from_u32(info.handle).unwrap()) } @@ -845,7 +868,7 @@ pub trait Device: super::Device { timeout_nsec: i64, wait_all: bool, wait_for_submit: bool, - ) -> Result { + ) -> io::Result { let info = ffi::syncobj::wait( self.as_fd(), bytemuck::cast_slice(handles), @@ -857,13 +880,13 @@ pub trait Device: super::Device { } /// Resets (un-signals) one or more syncobjs. - fn syncobj_reset(&self, handles: &[syncobj::Handle]) -> Result<(), SystemError> { + fn syncobj_reset(&self, handles: &[syncobj::Handle]) -> io::Result<()> { ffi::syncobj::reset(self.as_fd(), bytemuck::cast_slice(handles))?; Ok(()) } /// Signals one or more syncobjs. - fn syncobj_signal(&self, handles: &[syncobj::Handle]) -> Result<(), SystemError> { + fn syncobj_signal(&self, handles: &[syncobj::Handle]) -> io::Result<()> { ffi::syncobj::signal(self.as_fd(), bytemuck::cast_slice(handles))?; Ok(()) } @@ -877,7 +900,7 @@ pub trait Device: super::Device { wait_all: bool, wait_for_submit: bool, wait_available: bool, - ) -> Result { + ) -> io::Result { let info = ffi::syncobj::timeline_wait( self.as_fd(), bytemuck::cast_slice(handles), @@ -896,7 +919,7 @@ pub trait Device: super::Device { handles: &[syncobj::Handle], points: &mut [u64], last_submitted: bool, - ) -> Result<(), SystemError> { + ) -> io::Result<()> { ffi::syncobj::query( self.as_fd(), bytemuck::cast_slice(handles), @@ -913,7 +936,7 @@ pub trait Device: super::Device { dst_handle: syncobj::Handle, src_point: u64, dst_point: u64, - ) -> Result<(), SystemError> { + ) -> io::Result<()> { ffi::syncobj::transfer( self.as_fd(), src_handle.into(), @@ -929,7 +952,7 @@ pub trait Device: super::Device { &self, handles: &[syncobj::Handle], points: &[u64], - ) -> Result<(), SystemError> { + ) -> io::Result<()> { ffi::syncobj::timeline_signal(self.as_fd(), bytemuck::cast_slice(handles), points)?; Ok(()) } @@ -939,7 +962,7 @@ pub trait Device: super::Device { &self, objects: &[RawResourceHandle], flags: OFlag, - ) -> Result<(LeaseId, OwnedFd), SystemError> { + ) -> io::Result<(LeaseId, OwnedFd)> { let lease = ffi::mode::create_lease( self.as_fd(), bytemuck::cast_slice(objects), @@ -952,19 +975,19 @@ pub trait Device: super::Device { } /// List active lessees - fn list_lessees(&self) -> Result, SystemError> { + fn list_lessees(&self) -> io::Result> { let mut lessees = Vec::new(); ffi::mode::list_lessees(self.as_fd(), Some(&mut lessees))?; Ok(unsafe { transmute_vec_from_u32(lessees) }) } /// Revoke a previously issued drm lease - fn revoke_lease(&self, lessee_id: LeaseId) -> Result<(), SystemError> { + fn revoke_lease(&self, lessee_id: LeaseId) -> io::Result<()> { ffi::mode::revoke_lease(self.as_fd(), lessee_id.get()) } /// Receive pending events - fn receive_events(&self) -> Result + fn receive_events(&self) -> io::Result where Self: Sized, { @@ -986,7 +1009,7 @@ pub struct LeaseResources { } /// Query lease resources -pub fn get_lease(lease: D) -> Result { +pub fn get_lease(lease: D) -> io::Result { let mut crtcs = Vec::new(); let mut connectors = Vec::new(); let mut planes = Vec::new(); @@ -1292,8 +1315,8 @@ impl From for ffi::drm_mode_modeinfo { } } -impl std::fmt::Debug for Mode { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl fmt::Debug for Mode { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Mode") .field("name", &self.name()) .field("clock", &self.clock()) @@ -1409,10 +1432,7 @@ pub struct PropertyValueSet { impl PropertyValueSet { /// Returns a HashMap mapping property names to info - pub fn as_hashmap( - &self, - device: &impl Device, - ) -> Result, SystemError> { + pub fn as_hashmap(&self, device: &impl Device) -> io::Result> { let mut map = HashMap::new(); for id in self.prop_ids.iter() { let info = device.get_property(*id)?; diff --git a/src/lib.rs b/src/lib.rs index 74a30f53..de08b66c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,11 +34,15 @@ pub mod buffer; pub mod control; use std::ffi::{OsStr, OsString}; -use std::os::unix::{ffi::OsStringExt, io::AsFd}; use std::time::Duration; +use std::{ + io, + os::unix::{ffi::OsStringExt, io::AsFd}, +}; + +use nix::libc::EINVAL; use crate::util::*; -pub use drm_ffi::result::SystemError; /// This trait should be implemented by any object that acts as a DRM device. It /// is a prerequisite for using any DRM functionality. @@ -98,43 +102,39 @@ pub trait Device: AsFd { /// /// This function is only available to processes with CAP_SYS_ADMIN /// privileges (usually as root) - fn acquire_master_lock(&self) -> Result<(), SystemError> { + fn acquire_master_lock(&self) -> io::Result<()> { drm_ffi::auth::acquire_master(self.as_fd())?; Ok(()) } /// Releases the DRM Master lock for another process to use. - fn release_master_lock(&self) -> Result<(), SystemError> { + fn release_master_lock(&self) -> io::Result<()> { drm_ffi::auth::release_master(self.as_fd())?; Ok(()) } /// Generates an [`AuthToken`] for this process. #[deprecated(note = "Consider opening a render node instead.")] - fn generate_auth_token(&self) -> Result { + fn generate_auth_token(&self) -> io::Result { let token = drm_ffi::auth::get_magic_token(self.as_fd())?; Ok(AuthToken(token.magic)) } /// Authenticates an [`AuthToken`] from another process. - fn authenticate_auth_token(&self, token: AuthToken) -> Result<(), SystemError> { + fn authenticate_auth_token(&self, token: AuthToken) -> io::Result<()> { drm_ffi::auth::auth_magic_token(self.as_fd(), token.0)?; Ok(()) } /// Requests the driver to expose or hide certain capabilities. See /// [`ClientCapability`] for more information. - fn set_client_capability( - &self, - cap: ClientCapability, - enable: bool, - ) -> Result<(), SystemError> { + fn set_client_capability(&self, cap: ClientCapability, enable: bool) -> io::Result<()> { drm_ffi::set_capability(self.as_fd(), cap as u64, enable)?; Ok(()) } /// Gets the bus ID of this device. - fn get_bus_id(&self) -> Result { + fn get_bus_id(&self) -> io::Result { let mut buffer = Vec::new(); let _ = drm_ffi::get_bus_id(self.as_fd(), Some(&mut buffer))?; let bus_id = OsString::from_vec(buffer); @@ -144,21 +144,21 @@ pub trait Device: AsFd { /// Check to see if our [`AuthToken`] has been authenticated /// by the DRM Master - fn authenticated(&self) -> Result { + fn authenticated(&self) -> io::Result { let client = drm_ffi::get_client(self.as_fd(), 0)?; Ok(client.auth == 1) } /// Gets the value of a capability. - fn get_driver_capability(&self, cap: DriverCapability) -> Result { + fn get_driver_capability(&self, cap: DriverCapability) -> io::Result { let cap = drm_ffi::get_capability(self.as_fd(), cap as u64)?; Ok(cap.value) } /// # Possible errors: - /// - [`SystemError::MemoryFault`]: Kernel could not copy fields into userspace + /// - `EFAULT`: Kernel could not copy fields into userspace #[allow(missing_docs)] - fn get_driver(&self) -> Result { + fn get_driver(&self) -> io::Result { let mut name = Vec::new(); let mut date = Vec::new(); let mut desc = Vec::new(); @@ -186,13 +186,13 @@ pub trait Device: AsFd { flags: VblankWaitFlags, high_crtc: u32, user_data: usize, - ) -> Result { + ) -> io::Result { use drm_ffi::drm_vblank_seq_type::_DRM_VBLANK_HIGH_CRTC_MASK; use drm_ffi::_DRM_VBLANK_HIGH_CRTC_SHIFT; let high_crtc_mask = _DRM_VBLANK_HIGH_CRTC_MASK >> _DRM_VBLANK_HIGH_CRTC_SHIFT; if (high_crtc & !high_crtc_mask) != 0 { - return Err(SystemError::InvalidArgument); + return Err(io::Error::from_raw_os_error(EINVAL)); } let (sequence, wait_type) = match target_sequence {