libdrm_amdgpu_sys/drm_mode/
resource.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
use crate::{bindings, drmModeConnector, drmModeCrtc, LibDrm};
use core::ptr::addr_of;

pub use bindings::{drmModeResPtr, drmModeObjectPropertiesPtr, drmModePropertyPtr};

#[derive(Clone)]
pub struct drmModeRes {
    pub(crate) ptr: drmModeResPtr,
    pub(crate) lib: LibDrm,
}

impl LibDrm {
    pub fn get_drm_mode_resources(&self, fd: i32) -> Option<drmModeRes> {
        #[cfg(feature = "link_drm")]
        let func = bindings::drmModeGetResources;
        #[cfg(feature = "dynamic_loading")]
        let func = self.libdrm.drmModeGetResources;

        let drm_mode_res_ptr = unsafe { func(fd) };

        if drm_mode_res_ptr.is_null() { return None; }

        Some(drmModeRes {
            ptr: drm_mode_res_ptr,
            lib: self.clone(),
        })
    }
}

impl drmModeRes {
    pub fn get_drm_mode_all_connector_current(&self, fd: i32) -> Vec<drmModeConnector> {
        let ptr = unsafe { addr_of!((*self.ptr).connectors).read() };

        if ptr.is_null() {
            return Vec::new();
        }

        let count = unsafe { addr_of!((*self.ptr).count_connectors).read() as usize };
        let connectors = unsafe { std::slice::from_raw_parts(ptr, count) };

        connectors.iter().filter_map(|connector_id| {
            self.lib.get_drm_mode_connector_current(fd, *connector_id)
        }).collect()
    }

    pub fn get_drm_mode_all_connector(&self, fd: i32) -> Vec<drmModeConnector> {
        let ptr = unsafe { addr_of!((*self.ptr).connectors).read() };

        if ptr.is_null() {
            return Vec::new();
        }

        let count = unsafe { addr_of!((*self.ptr).count_connectors).read() as usize };
        let connectors = unsafe { std::slice::from_raw_parts(ptr, count) };

        connectors.iter().filter_map(|connector_id| {
            self.lib.get_drm_mode_connector(fd, *connector_id)
        }).collect()
    }

    pub fn get_drm_mode_all_crtcs(&self, fd: i32) -> Vec<drmModeCrtc> {
        let ptr = unsafe { addr_of!((*self.ptr).crtcs).read() };

        if ptr.is_null() {
            return Vec::new();
        }

        let count = unsafe { addr_of!((*self.ptr).count_crtcs).read() as usize };
        let crtcs = unsafe { std::slice::from_raw_parts(ptr, count) };

        crtcs.iter().filter_map(|crtc_id| {
            self.lib.get_drm_mode_crtc(fd, *crtc_id)
        }).collect()
    }
}

#[cfg(feature = "link_drm")]
impl drmModeRes {
    pub fn get(fd: i32) -> Option<Self> {
        let drm_mode_res_ptr = unsafe { bindings::drmModeGetResources(fd) };

        if drm_mode_res_ptr.is_null() { return None; }

        Some(Self { ptr: drm_mode_res_ptr, lib: LibDrm::new().unwrap() })
    }

    pub fn get_all_connector_current(&self, fd: i32) -> Vec<drmModeConnector> {
        let ptr = unsafe { addr_of!((*self.ptr).connectors).read() };

        if ptr.is_null() {
            return Vec::new();
        }

        let count = unsafe { addr_of!((*self.ptr).count_connectors).read() as usize };
        let connectors = unsafe { std::slice::from_raw_parts(ptr, count) };

        connectors.iter().filter_map(|connector_id| {
            drmModeConnector::get_current(fd, *connector_id)
        }).collect()
    }

    pub fn get_all_connector(&self, fd: i32) -> Vec<drmModeConnector> {
        let ptr = unsafe { addr_of!((*self.ptr).connectors).read() };

        if ptr.is_null() {
            return Vec::new();
        }

        let count = unsafe { addr_of!((*self.ptr).count_connectors).read() as usize };
        let connectors = unsafe { std::slice::from_raw_parts(ptr, count) };

        connectors.iter().filter_map(|connector_id| {
            drmModeConnector::get(fd, *connector_id)
        }).collect()
    }

    pub fn get_all_crtcs(&self, fd: i32) -> Vec<drmModeCrtc> {
        let ptr = unsafe { addr_of!((*self.ptr).crtcs).read() };

        if ptr.is_null() {
            return Vec::new();
        }

        let count = unsafe { addr_of!((*self.ptr).count_crtcs).read() as usize };
        let crtcs = unsafe { std::slice::from_raw_parts(ptr, count) };

        crtcs.iter().filter_map(|crtc_id| {
            drmModeCrtc::get(fd, *crtc_id)
        }).collect()
    }
}

impl Drop for drmModeRes {
    fn drop(&mut self) {
        #[cfg(feature = "link_drm")]
        let func = bindings::drmModeFreeResources;
        #[cfg(feature = "dynamic_loading")]
        let func = self.lib.libdrm.drmModeFreeResources;

	    unsafe { func(self.ptr); }
    }
}