use std::fmt::{self};
use bitflags::bitflags;
#[derive(Debug, Clone)]
pub struct Monitor {
pub connector: String,
pub vendor: String,
pub product: String,
pub serial: String,
}
impl Monitor {
pub fn from(result: (String, String, String, String)) -> Monitor {
Monitor {
connector: result.0,
vendor: result.1,
product: result.2,
serial: result.3,
}
}
}
impl std::fmt::Display for Monitor {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{} {} {} {}",
self.connector, self.vendor, self.product, self.serial
)
}
}
bitflags! {
pub struct Transform: u32 {
const NORMAL = 0b000;
const R90 = 0b001;
const R180 = 0b010;
const R270 = Self::R90.bits | Self::R180.bits;
const FLIPPED = 0b100;
const F90 = Self::R90.bits | Self::FLIPPED.bits;
const F180 = Self::R180.bits | Self::FLIPPED.bits;
const F270 = Self::R270.bits | Self::FLIPPED.bits;
}
}
impl fmt::Display for Transform {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let display = if self.contains(Transform::R270) {
"left"
} else if self.contains(Transform::R180) {
"inverted"
} else if self.contains(Transform::R90) {
"right"
} else {
"normal"
};
write!(
f,
"{}{}",
if self.contains(Transform::FLIPPED) {
"Flipped "
} else {
""
},
display
)
}
}
#[derive(Debug)]
pub struct LogicalMonitor {
pub x: i32,
pub y: i32,
pub scale: f64,
pub transform: Transform,
pub primary: bool,
pub monitors: Vec<Monitor>,
pub properties: dbus::arg::PropMap,
}
impl Clone for LogicalMonitor {
fn clone(&self) -> Self {
Self {
x: self.x,
y: self.y,
scale: self.scale,
transform: self.transform,
primary: self.primary,
monitors: self.monitors.clone(),
properties: dbus::arg::PropMap::new(),
}
}
}
impl LogicalMonitor {
pub fn from(
result: (
i32,
i32,
f64,
u32,
bool,
Vec<(String, String, String, String)>,
dbus::arg::PropMap,
),
) -> LogicalMonitor {
LogicalMonitor {
x: result.0,
y: result.1,
scale: result.2,
transform: Transform::from_bits_truncate(result.3),
primary: result.4,
monitors: result
.5
.into_iter()
.map(Monitor::from)
.collect(),
properties: result.6,
}
}
pub fn to_result<'a>(
&self,
mode_id: &'a str,
) -> (
i32,
i32,
f64,
u32,
bool,
Vec<(&str, &'a str, dbus::arg::PropMap)>,
) {
(
self.x,
self.y,
self.scale,
self.transform.bits(),
self.primary,
self.monitors
.iter()
.map(|monitor| {
(
monitor.connector.as_str(),
mode_id,
dbus::arg::PropMap::new(),
)
})
.collect(),
)
}
}
impl std::fmt::Display for LogicalMonitor {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(
f,
"x: {}, y: {}, scale: {}, rotation: {}, primary: {}",
self.x,
self.y,
self.scale,
self.transform,
if self.primary { "yes" } else { "no" }
)?;
writeln!(f, "associated physical monitors:")?;
for monitor in self.monitors.iter() {
writeln!(f, "\t{}", monitor)?
}
Ok(())
}
}