• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //!
2 //! Foreign function interface
3 //!
4 
5 #![warn(missing_docs)]
6 #![allow(unused_doc_comments)]
7 
8 pub use drm_sys::{self, *};
9 
10 #[macro_use]
11 pub(crate) mod utils;
12 
13 pub mod gem;
14 mod ioctl;
15 pub mod mode;
16 pub mod syncobj;
17 
18 use std::{
19     ffi::{c_int, c_ulong},
20     io,
21     os::unix::io::BorrowedFd,
22 };
23 
24 ///
25 /// Bindings to the methods of authentication the DRM provides.
26 ///
27 pub mod auth {
28     use crate::ioctl;
29     use drm_sys::*;
30 
31     use std::{io, os::unix::io::BorrowedFd};
32 
33     /// Get the 'Magic Authentication Token' for this file descriptor.
get_magic_token(fd: BorrowedFd<'_>) -> io::Result<drm_auth>34     pub fn get_magic_token(fd: BorrowedFd<'_>) -> io::Result<drm_auth> {
35         unsafe { ioctl::get_token(fd) }
36     }
37 
38     /// Authorize another process' 'Magic Authentication Token'.
auth_magic_token(fd: BorrowedFd<'_>, auth: u32) -> io::Result<drm_auth>39     pub fn auth_magic_token(fd: BorrowedFd<'_>, auth: u32) -> io::Result<drm_auth> {
40         let token = drm_auth { magic: auth };
41 
42         unsafe {
43             ioctl::auth_token(fd, &token)?;
44         }
45 
46         Ok(token)
47     }
48 
49     /// Acquire the 'Master DRM Lock' for this file descriptor.
acquire_master(fd: BorrowedFd<'_>) -> io::Result<()>50     pub fn acquire_master(fd: BorrowedFd<'_>) -> io::Result<()> {
51         unsafe { ioctl::acquire_master(fd) }
52     }
53 
54     /// Release the 'Master DRM Lock' for this file descriptor.
release_master(fd: BorrowedFd<'_>) -> io::Result<()>55     pub fn release_master(fd: BorrowedFd<'_>) -> io::Result<()> {
56         unsafe { ioctl::release_master(fd) }
57     }
58 }
59 
60 /// Load this device's Bus ID into a buffer.
get_bus_id(fd: BorrowedFd<'_>, mut buf: Option<&mut Vec<u8>>) -> io::Result<drm_unique>61 pub fn get_bus_id(fd: BorrowedFd<'_>, mut buf: Option<&mut Vec<u8>>) -> io::Result<drm_unique> {
62     let mut sizes = drm_unique::default();
63     unsafe {
64         ioctl::get_bus_id(fd, &mut sizes)?;
65     }
66 
67     if buf.is_none() {
68         return Ok(sizes);
69     }
70 
71     map_reserve!(buf, sizes.unique_len as usize);
72 
73     let mut busid = drm_unique {
74         unique_len: sizes.unique_len,
75         unique: map_ptr!(&buf),
76     };
77 
78     unsafe {
79         ioctl::get_bus_id(fd, &mut busid)?;
80     }
81 
82     map_set!(buf, busid.unique_len as usize);
83 
84     Ok(busid)
85 }
86 
87 /// Get a device's IRQ.
get_interrupt_from_bus_id( fd: BorrowedFd<'_>, bus: c_int, dev: c_int, func: c_int, ) -> io::Result<drm_irq_busid>88 pub fn get_interrupt_from_bus_id(
89     fd: BorrowedFd<'_>,
90     bus: c_int,
91     dev: c_int,
92     func: c_int,
93 ) -> io::Result<drm_irq_busid> {
94     let mut irq = drm_irq_busid {
95         busnum: bus,
96         devnum: dev,
97         funcnum: func,
98         ..Default::default()
99     };
100 
101     unsafe {
102         ioctl::get_irq_from_bus_id(fd, &mut irq)?;
103     }
104 
105     Ok(irq)
106 }
107 
108 /// Get client information given a client's ID.
get_client(fd: BorrowedFd<'_>, idx: c_int) -> io::Result<drm_client>109 pub fn get_client(fd: BorrowedFd<'_>, idx: c_int) -> io::Result<drm_client> {
110     let mut client = drm_client {
111         idx,
112         ..Default::default()
113     };
114 
115     unsafe {
116         ioctl::get_client(fd, &mut client)?;
117     }
118 
119     Ok(client)
120 }
121 
122 /// Check if a capability is set.
get_capability(fd: BorrowedFd<'_>, cty: u64) -> io::Result<drm_get_cap>123 pub fn get_capability(fd: BorrowedFd<'_>, cty: u64) -> io::Result<drm_get_cap> {
124     let mut cap = drm_get_cap {
125         capability: cty,
126         ..Default::default()
127     };
128 
129     unsafe {
130         ioctl::get_cap(fd, &mut cap)?;
131     }
132 
133     Ok(cap)
134 }
135 
136 /// Attempt to enable/disable a client's capability.
set_capability(fd: BorrowedFd<'_>, cty: u64, val: bool) -> io::Result<drm_set_client_cap>137 pub fn set_capability(fd: BorrowedFd<'_>, cty: u64, val: bool) -> io::Result<drm_set_client_cap> {
138     let cap = drm_set_client_cap {
139         capability: cty,
140         value: val as u64,
141     };
142 
143     unsafe {
144         ioctl::set_cap(fd, &cap)?;
145     }
146 
147     Ok(cap)
148 }
149 
150 /// Sets the requested interface version
set_version(fd: BorrowedFd<'_>, version: &mut drm_set_version) -> io::Result<()>151 pub fn set_version(fd: BorrowedFd<'_>, version: &mut drm_set_version) -> io::Result<()> {
152     unsafe { ioctl::set_version(fd, version) }
153 }
154 
155 /// Gets the driver version for this device.
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>156 pub fn get_version(
157     fd: BorrowedFd<'_>,
158     mut name_buf: Option<&mut Vec<i8>>,
159     mut date_buf: Option<&mut Vec<i8>>,
160     mut desc_buf: Option<&mut Vec<i8>>,
161 ) -> io::Result<drm_version> {
162     let mut sizes = drm_version::default();
163     unsafe { ioctl::get_version(fd, &mut sizes) }?;
164 
165     map_reserve!(name_buf, sizes.name_len as usize);
166     map_reserve!(date_buf, sizes.date_len as usize);
167     map_reserve!(desc_buf, sizes.desc_len as usize);
168 
169     let mut version = drm_version {
170         name_len: map_len!(&name_buf),
171         name: map_ptr!(&name_buf),
172         date_len: map_len!(&date_buf),
173         date: map_ptr!(&date_buf),
174         desc_len: map_len!(&desc_buf),
175         desc: map_ptr!(&desc_buf),
176         ..Default::default()
177     };
178 
179     unsafe { ioctl::get_version(fd, &mut version) }?;
180 
181     map_set!(name_buf, version.name_len as usize);
182     map_set!(date_buf, version.date_len as usize);
183     map_set!(desc_buf, version.desc_len as usize);
184 
185     Ok(version)
186 }
187 
188 /// Waits for a vblank.
wait_vblank( fd: BorrowedFd<'_>, type_: u32, sequence: u32, signal: usize, ) -> io::Result<drm_wait_vblank_reply>189 pub fn wait_vblank(
190     fd: BorrowedFd<'_>,
191     type_: u32,
192     sequence: u32,
193     signal: usize,
194 ) -> io::Result<drm_wait_vblank_reply> {
195     // We can't assume the kernel will completely fill the reply in the union
196     // with valid data (it won't populate the timestamp if the event flag is
197     // set, for example), so use `default` to ensure the structure is completely
198     // initialized with zeros
199     let mut wait_vblank = drm_wait_vblank::default();
200     wait_vblank.request = drm_wait_vblank_request {
201         type_,
202         sequence,
203         signal: signal as c_ulong,
204     };
205 
206     unsafe {
207         ioctl::wait_vblank(fd, &mut wait_vblank)?;
208     };
209 
210     Ok(unsafe { wait_vblank.reply })
211 }
212