use control;
use drm_ffi as ffi;
pub type RawValue = u64;
#[repr(transparent)]
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
pub struct Handle(control::RawResourceHandle);
impl From<Handle> for control::RawResourceHandle {
fn from(handle: Handle) -> Self {
handle.0
}
}
impl From<Handle> for u32 {
fn from(handle: Handle) -> Self {
handle.0.into()
}
}
impl From<control::RawResourceHandle> for Handle {
fn from(handle: control::RawResourceHandle) -> Self {
Handle(handle)
}
}
impl control::ResourceHandle for Handle {
const FFI_TYPE: u32 = ffi::DRM_MODE_OBJECT_PROPERTY;
}
impl std::fmt::Debug for Handle {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.debug_tuple("property::Handle").field(&self.0).finish()
}
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Info {
pub(crate) handle: Handle,
pub(crate) val_type: ValueType,
pub(crate) mutable: bool,
pub(crate) atomic: bool,
pub(crate) info: ffi::drm_mode_get_property,
}
impl Info {
pub fn name(&self) -> &std::ffi::CStr {
unsafe { std::ffi::CStr::from_ptr(&self.info.name[0] as _) }
}
pub fn value_type(&self) -> ValueType {
self.val_type
}
pub fn mutable(&self) -> bool {
self.mutable
}
pub fn atomic(&self) -> bool {
self.atomic
}
}
#[allow(clippy::upper_case_acronyms)]
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum ValueType {
Unknown,
Boolean,
UnsignedRange(u64, u64),
SignedRange(i64, i64),
Enum(EnumValues),
Bitmask,
Blob,
Object,
CRTC,
Connector,
Encoder,
Framebuffer,
Plane,
Property,
}
impl ValueType {
pub fn convert_value(&self, value: RawValue) -> Value {
use std::mem::transmute as tm;
match self {
ValueType::Unknown => Value::Unknown(value),
ValueType::Boolean => Value::Boolean(value != 0),
ValueType::UnsignedRange(_, _) => Value::UnsignedRange(value),
ValueType::SignedRange(_, _) => Value::SignedRange(value as i64),
ValueType::Enum(values) => Value::Enum(values.get_value_from_raw_value(value)),
ValueType::Bitmask => Value::Bitmask(value),
ValueType::Blob => Value::Blob(value),
ValueType::Object => Value::Object(unsafe { tm(value as u32) }),
ValueType::CRTC => Value::CRTC(unsafe { tm(value as u32) }),
ValueType::Connector => Value::Connector(unsafe { tm(value as u32) }),
ValueType::Encoder => Value::Encoder(unsafe { tm(value as u32) }),
ValueType::Framebuffer => Value::Framebuffer(unsafe { tm(value as u32) }),
ValueType::Plane => Value::Plane(unsafe { tm(value as u32) }),
ValueType::Property => Value::Property(unsafe { tm(value as u32) }),
}
}
}
#[allow(missing_docs)]
#[allow(clippy::upper_case_acronyms)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum Value<'a> {
Unknown(RawValue),
Boolean(bool),
UnsignedRange(u64),
SignedRange(i64),
Enum(Option<&'a EnumValue>),
Bitmask(u64),
Blob(u64),
Object(Option<super::RawResourceHandle>),
CRTC(Option<super::crtc::Handle>),
Connector(Option<super::connector::Handle>),
Encoder(Option<super::encoder::Handle>),
Framebuffer(Option<super::framebuffer::Handle>),
Plane(Option<super::plane::Handle>),
Property(Option<Handle>),
}
impl<'a> From<Value<'a>> for RawValue {
fn from(value: Value<'a>) -> Self {
use std::mem::transmute as tm;
match value {
Value::Unknown(x) => x,
Value::Boolean(true) => 1,
Value::Boolean(false) => 0,
Value::UnsignedRange(x) => x,
Value::SignedRange(x) => x as u64,
Value::Enum(val) => val.map_or(0, EnumValue::value),
Value::Bitmask(x) => x,
Value::Blob(x) => x,
Value::Object(x) => unsafe { tm::<_, u32>(x).into() },
Value::CRTC(x) => unsafe { tm::<_, u32>(x).into() },
Value::Connector(x) => unsafe { tm::<_, u32>(x).into() },
Value::Encoder(x) => unsafe { tm::<_, u32>(x).into() },
Value::Framebuffer(x) => unsafe { tm::<_, u32>(x).into() },
Value::Plane(x) => unsafe { tm::<_, u32>(x).into() },
Value::Property(x) => unsafe { tm::<_, u32>(x).into() },
}
}
}
#[repr(transparent)]
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
pub struct EnumValue(ffi::drm_mode_property_enum);
impl EnumValue {
pub fn value(&self) -> RawValue {
self.0.value
}
pub fn name(&self) -> &std::ffi::CStr {
unsafe { std::ffi::CStr::from_ptr(&self.0.name[0] as _) }
}
}
impl std::fmt::Debug for EnumValue {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.debug_struct("EnumValue")
.field("value", &self.value())
.field("name", &self.name())
.finish()
}
}
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
pub struct EnumValues {
pub(crate) values: [u64; 24],
pub(crate) enums: [EnumValue; 24],
pub(crate) length: usize,
}
impl EnumValues {
pub fn values(&self) -> (&[RawValue], &[EnumValue]) {
(&self.values[..self.length], &self.enums[..self.length])
}
pub fn get_value_from_raw_value(&self, value: RawValue) -> Option<&EnumValue> {
let (values, enums) = self.values();
let index = if values.get(value as usize) == Some(&value) {
value as usize
} else {
values.iter().position(|&v| v == value)?
};
Some(&enums[index])
}
}
impl std::fmt::Debug for EnumValues {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let (vals, enums) = self.values();
f.debug_struct("EnumValues")
.field("values", &vals)
.field("enums", &enums)
.finish()
}
}