libdrm_amdgpu_sys/drm_mode/
resource.rs

1use crate::{bindings, drmModeConnector, drmModeCrtc, LibDrm};
2use core::ptr::addr_of;
3
4pub use bindings::{drmModeResPtr, drmModeObjectPropertiesPtr, drmModePropertyPtr};
5
6#[derive(Clone)]
7pub struct drmModeRes {
8    pub(crate) ptr: drmModeResPtr,
9    pub(crate) lib: LibDrm,
10}
11
12impl LibDrm {
13    pub fn get_drm_mode_resources(&self, fd: i32) -> Option<drmModeRes> {
14        #[cfg(feature = "link_drm")]
15        let func = bindings::drmModeGetResources;
16        #[cfg(feature = "dynamic_loading")]
17        let func = self.libdrm.drmModeGetResources;
18
19        let drm_mode_res_ptr = unsafe { func(fd) };
20
21        if drm_mode_res_ptr.is_null() { return None; }
22
23        Some(drmModeRes {
24            ptr: drm_mode_res_ptr,
25            lib: self.clone(),
26        })
27    }
28}
29
30impl drmModeRes {
31    pub fn get_drm_mode_all_connector_current(&self, fd: i32) -> Vec<drmModeConnector> {
32        let ptr = unsafe { addr_of!((*self.ptr).connectors).read() };
33
34        if ptr.is_null() {
35            return Vec::new();
36        }
37
38        let count = unsafe { addr_of!((*self.ptr).count_connectors).read() as usize };
39        let connectors = unsafe { std::slice::from_raw_parts(ptr, count) };
40
41        connectors.iter().filter_map(|connector_id| {
42            self.lib.get_drm_mode_connector_current(fd, *connector_id)
43        }).collect()
44    }
45
46    pub fn get_drm_mode_all_connector(&self, fd: i32) -> Vec<drmModeConnector> {
47        let ptr = unsafe { addr_of!((*self.ptr).connectors).read() };
48
49        if ptr.is_null() {
50            return Vec::new();
51        }
52
53        let count = unsafe { addr_of!((*self.ptr).count_connectors).read() as usize };
54        let connectors = unsafe { std::slice::from_raw_parts(ptr, count) };
55
56        connectors.iter().filter_map(|connector_id| {
57            self.lib.get_drm_mode_connector(fd, *connector_id)
58        }).collect()
59    }
60
61    pub fn get_drm_mode_all_crtcs(&self, fd: i32) -> Vec<drmModeCrtc> {
62        let ptr = unsafe { addr_of!((*self.ptr).crtcs).read() };
63
64        if ptr.is_null() {
65            return Vec::new();
66        }
67
68        let count = unsafe { addr_of!((*self.ptr).count_crtcs).read() as usize };
69        let crtcs = unsafe { std::slice::from_raw_parts(ptr, count) };
70
71        crtcs.iter().filter_map(|crtc_id| {
72            self.lib.get_drm_mode_crtc(fd, *crtc_id)
73        }).collect()
74    }
75}
76
77#[cfg(feature = "link_drm")]
78impl drmModeRes {
79    pub fn get(fd: i32) -> Option<Self> {
80        let drm_mode_res_ptr = unsafe { bindings::drmModeGetResources(fd) };
81
82        if drm_mode_res_ptr.is_null() { return None; }
83
84        Some(Self { ptr: drm_mode_res_ptr, lib: LibDrm::new().unwrap() })
85    }
86
87    pub fn get_all_connector_current(&self, fd: i32) -> Vec<drmModeConnector> {
88        let ptr = unsafe { addr_of!((*self.ptr).connectors).read() };
89
90        if ptr.is_null() {
91            return Vec::new();
92        }
93
94        let count = unsafe { addr_of!((*self.ptr).count_connectors).read() as usize };
95        let connectors = unsafe { std::slice::from_raw_parts(ptr, count) };
96
97        connectors.iter().filter_map(|connector_id| {
98            drmModeConnector::get_current(fd, *connector_id)
99        }).collect()
100    }
101
102    pub fn get_all_connector(&self, fd: i32) -> Vec<drmModeConnector> {
103        let ptr = unsafe { addr_of!((*self.ptr).connectors).read() };
104
105        if ptr.is_null() {
106            return Vec::new();
107        }
108
109        let count = unsafe { addr_of!((*self.ptr).count_connectors).read() as usize };
110        let connectors = unsafe { std::slice::from_raw_parts(ptr, count) };
111
112        connectors.iter().filter_map(|connector_id| {
113            drmModeConnector::get(fd, *connector_id)
114        }).collect()
115    }
116
117    pub fn get_all_crtcs(&self, fd: i32) -> Vec<drmModeCrtc> {
118        let ptr = unsafe { addr_of!((*self.ptr).crtcs).read() };
119
120        if ptr.is_null() {
121            return Vec::new();
122        }
123
124        let count = unsafe { addr_of!((*self.ptr).count_crtcs).read() as usize };
125        let crtcs = unsafe { std::slice::from_raw_parts(ptr, count) };
126
127        crtcs.iter().filter_map(|crtc_id| {
128            drmModeCrtc::get(fd, *crtc_id)
129        }).collect()
130    }
131}
132
133impl Drop for drmModeRes {
134    fn drop(&mut self) {
135        #[cfg(feature = "link_drm")]
136        let func = bindings::drmModeFreeResources;
137        #[cfg(feature = "dynamic_loading")]
138        let func = self.lib.libdrm.drmModeFreeResources;
139
140	    unsafe { func(self.ptr); }
141    }
142}