libdrm_amdgpu_sys/drm_mode/
property.rs

1use crate::{bindings, LibDrm};
2use core::ptr::addr_of;
3
4pub use bindings::{drmModePropertyPtr, drm_mode_property_enum};
5
6#[allow(dead_code)]
7#[derive(Clone)]
8pub struct drmModeProperty {
9    pub(crate) ptr: drmModePropertyPtr,
10    pub(crate) lib: LibDrm,
11}
12
13impl LibDrm {
14    pub fn get_drm_mode_property(&self, fd: i32, property_id: u32) -> Option<drmModeProperty> {
15        #[cfg(feature = "link_drm")]
16        let func = bindings::drmModeGetProperty;
17        #[cfg(feature = "dynamic_loading")]
18        let func = self.libdrm.drmModeGetProperty;
19
20        let prop_ptr = unsafe { func(fd, property_id) };
21
22        if prop_ptr.is_null() {
23            None
24        } else {
25            Some(drmModeProperty { ptr: prop_ptr, lib: self.clone() })
26        }
27    }
28}
29
30impl drmModeProperty {
31    #[cfg(feature = "link_drm")]
32    pub fn get(fd: i32, property_id: u32) -> Option<Self> {
33        let prop_ptr = unsafe { bindings::drmModeGetProperty(
34            fd,
35            property_id,
36        ) };
37
38        if prop_ptr.is_null() {
39            None
40        } else {
41            Some(Self { ptr: prop_ptr, lib: LibDrm::new().unwrap() })
42        }
43    }
44
45    pub fn name(&self) -> String {
46        let c_name = unsafe { addr_of!((*self.ptr).name).read() };
47
48        super::c_char_to_string(&c_name)
49    }
50
51    pub fn prop_id(&self) -> u32 {
52        unsafe { addr_of!((*self.ptr).prop_id).read() }
53    }
54
55    pub fn flags(&self) -> u32 {
56        unsafe { addr_of!((*self.ptr).flags).read() }
57    }
58
59    pub fn property_type(&self) -> drmModePropType {
60        let flags = self.flags();
61        let type_ = flags & (bindings::DRM_MODE_PROP_LEGACY_TYPE | bindings::DRM_MODE_PROP_EXTENDED_TYPE);
62
63        drmModePropType::from(type_)
64    }
65
66    pub fn is_atomic(&self) -> bool {
67        let flags = self.flags();
68        (flags & DRM_MODE_PROP_ATOMIC) != 0
69    }
70
71    pub fn is_pending(&self) -> bool {
72        let flags = self.flags();
73        (flags & DRM_MODE_PROP_PENDING) != 0
74    }
75
76    pub fn is_immutable(&self) -> bool {
77        let flags = self.flags();
78        (flags & DRM_MODE_PROP_IMMUTABLE) != 0
79    }
80
81    pub fn values(&self) -> Vec<u64> {
82        let ptr = unsafe { addr_of!((*self.ptr).values).read() };
83        let count = unsafe { addr_of!((*self.ptr).count_values).read() as usize };
84
85        if ptr.is_null() {
86            Vec::new()
87        } else {
88            unsafe { std::slice::from_raw_parts(ptr, count) }.to_vec()
89        }
90    }
91
92    pub fn blob_ids(&self) -> Vec<u32> {
93        let ptr = unsafe { addr_of!((*self.ptr).blob_ids).read() };
94        let count = unsafe { addr_of!((*self.ptr).count_blobs).read() as usize };
95
96        if ptr.is_null() {
97            Vec::new()
98        } else {
99            unsafe { std::slice::from_raw_parts(ptr, count) }.to_vec()
100        }
101    }
102
103    pub fn enums(&self) -> Vec<drm_mode_property_enum> {
104        let ptr = unsafe { addr_of!((*self.ptr).enums).read() };
105        let count = unsafe { addr_of!((*self.ptr).count_enums).read() as usize };
106
107        if ptr.is_null() {
108            Vec::new()
109        } else {
110            unsafe { std::slice::from_raw_parts(ptr, count) }.to_vec()
111        }
112    }
113}
114
115impl Drop for drmModeProperty {
116    fn drop(&mut self) {
117        #[cfg(feature = "link_drm")]
118        let func = bindings::drmModeFreeProperty;
119        #[cfg(feature = "dynamic_loading")]
120        let func = self.lib.libdrm.drmModeFreeProperty;
121
122	    unsafe { func(self.ptr); }
123    }
124}
125
126pub(crate) const DRM_MODE_PROP_OBJECT: u32 = 1 << 6;
127pub(crate) const DRM_MODE_PROP_SIGNED_RANGE: u32 = 2 << 6;
128
129use bindings::{
130    DRM_MODE_PROP_PENDING,
131    DRM_MODE_PROP_RANGE,
132    DRM_MODE_PROP_IMMUTABLE,
133    DRM_MODE_PROP_ENUM,
134    DRM_MODE_PROP_BLOB,
135    DRM_MODE_PROP_BITMASK,
136    DRM_MODE_PROP_LEGACY_TYPE,
137    DRM_MODE_PROP_EXTENDED_TYPE,
138    DRM_MODE_PROP_ATOMIC,
139};
140
141#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd)]
142#[repr(u32)]
143pub enum drmModePropType {
144    RANGE = DRM_MODE_PROP_RANGE,
145    ENUM = DRM_MODE_PROP_ENUM,
146    BLOB = DRM_MODE_PROP_BLOB,
147    BITMASK = DRM_MODE_PROP_BITMASK,
148    LEGACY_TYPE = DRM_MODE_PROP_LEGACY_TYPE,
149    EXTENDED_TYPE = DRM_MODE_PROP_EXTENDED_TYPE,
150    ATOMIC = DRM_MODE_PROP_ATOMIC,
151    OBJECT = DRM_MODE_PROP_OBJECT,
152    SIGNED_RANGE = DRM_MODE_PROP_SIGNED_RANGE,
153    UNKNOWN(u32),
154}
155
156impl From<u32> for drmModePropType {
157    fn from(value: u32) -> Self {
158        match value {
159            DRM_MODE_PROP_RANGE => Self::RANGE,
160            DRM_MODE_PROP_ENUM => Self::ENUM,
161            DRM_MODE_PROP_BLOB => Self::BLOB,
162            DRM_MODE_PROP_BITMASK => Self::BITMASK,
163            DRM_MODE_PROP_LEGACY_TYPE => Self::LEGACY_TYPE,
164            DRM_MODE_PROP_EXTENDED_TYPE => Self::EXTENDED_TYPE,
165            DRM_MODE_PROP_ATOMIC => Self::ATOMIC,
166            DRM_MODE_PROP_OBJECT => Self::OBJECT,
167            DRM_MODE_PROP_SIGNED_RANGE => Self::SIGNED_RANGE,
168            _ => Self::UNKNOWN(value),
169        }
170    }
171}
172
173use std::fmt;
174impl fmt::Display for drmModePropType {
175    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
176        write!(f, "{:?}", self)
177    }
178}
179
180impl drm_mode_property_enum {
181    pub fn name(&self) -> String {
182        super::c_char_to_string(&self.name)
183    }
184}