151 lines
5.0 KiB
Rust
151 lines
5.0 KiB
Rust
use crate::{model::{misc::Game, profile::{Display, DisplayMode}}, util::bool_to_01};
|
|
use anyhow::Result;
|
|
use displayz::{query_displays, DisplaySet};
|
|
use ini::Ini;
|
|
use tauri::{AppHandle, Listener};
|
|
|
|
#[derive(Clone)]
|
|
pub struct DisplayInfo {
|
|
pub primary: Option<String>,
|
|
pub set: Option<DisplaySet>,
|
|
}
|
|
|
|
impl Default for DisplayInfo {
|
|
fn default() -> Self {
|
|
DisplayInfo {
|
|
primary: None,
|
|
set: query_displays().ok(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Display {
|
|
pub fn wait_for_exit(app: AppHandle, info: DisplayInfo) {
|
|
log::debug!("display: waiting");
|
|
tauri::async_runtime::spawn(async move {
|
|
app.listen("launch-end", move |_| {
|
|
if let Err(e) = Self::clean_up(&info) {
|
|
log::error!("error cleaning up display: {:?}", e);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
pub fn prepare(&self) -> Result<Option<DisplayInfo>> {
|
|
use anyhow::anyhow;
|
|
use displayz::{query_displays, Orientation, Resolution, Frequency};
|
|
|
|
if self.target == "default" {
|
|
log::debug!("prepare display: skip");
|
|
return Ok(None);
|
|
}
|
|
|
|
let display_set = query_displays()?;
|
|
|
|
let primary = display_set
|
|
.displays()
|
|
.find(|display| display.is_primary())
|
|
.ok_or_else(|| anyhow!("Primary display not found"))?;
|
|
|
|
let target = display_set
|
|
.displays()
|
|
.find(|display| display.name() == self.target)
|
|
.ok_or_else(|| anyhow!("Display {} not found", self.target))?;
|
|
|
|
if !self.dont_switch_primary {
|
|
target.set_primary()?;
|
|
}
|
|
let settings = target.settings()
|
|
.as_ref()
|
|
.ok_or_else(|| anyhow!("Unable to query display settings"))?;
|
|
|
|
let res = DisplayInfo {
|
|
primary: if self.dont_switch_primary { None } else { Some(primary.name().to_owned()) },
|
|
set: Some(display_set.clone()),
|
|
};
|
|
|
|
if let Some(rotation) = self.rotation {
|
|
let rez = settings.borrow_mut().resolution;
|
|
settings.borrow_mut().orientation = match rotation {
|
|
0 => Orientation::Landscape,
|
|
90 => Orientation::PortraitFlipped,
|
|
180 => Orientation::LandscapeFlipped,
|
|
270 => Orientation::Portrait,
|
|
_ => panic!("Invalid display rotation")
|
|
};
|
|
if rez.height < rez.width {
|
|
if rotation == 90 || rotation == 270 {
|
|
settings.borrow_mut().resolution = Resolution::new(rez.height, rez.width);
|
|
}
|
|
} else {
|
|
if rotation == 0 || rotation == 180 {
|
|
settings.borrow_mut().resolution = Resolution::new(rez.height, rez.width);
|
|
}
|
|
}
|
|
}
|
|
|
|
let frequency: u32 = self.frequency
|
|
.try_into()
|
|
.map_err(|e| anyhow!("Invalid display frequency: {}", e))?;
|
|
|
|
let width: u32 = self.rez.0
|
|
.try_into()
|
|
.map_err(|e| anyhow!("Invalid display width: {}", e))?;
|
|
|
|
let height: u32 = self.rez.1
|
|
.try_into()
|
|
.map_err(|e| anyhow!("Invalid display height: {}", e))?;
|
|
|
|
settings.borrow_mut().frequency = Frequency::new(frequency);
|
|
|
|
if self.borderless_fullscreen && self.mode == DisplayMode::Borderless {
|
|
settings.borrow_mut().resolution = Resolution::new(width, height);
|
|
}
|
|
|
|
display_set.apply().map_err(
|
|
|_| anyhow!("The selected monitor has been disconnected or doesn't support the chosen display mode")
|
|
)?;
|
|
displayz::refresh()?;
|
|
|
|
log::debug!("prepare display: done");
|
|
|
|
Ok(Some(res))
|
|
}
|
|
|
|
pub fn line_up(&self, game: Game, ini: &mut Ini) {
|
|
if game == Game::Chunithm {
|
|
let autism = self.monitor_index_override.unwrap_or(0).to_string();
|
|
ini.with_section(Some("gfx"))
|
|
.set("enable", "1")
|
|
.set("windowed", bool_to_01(self.mode != DisplayMode::Fullscreen))
|
|
.set("framed", bool_to_01(self.mode == DisplayMode::Window))
|
|
.set("monitor", if self.dont_switch_primary { &autism } else { "0" });
|
|
ini.with_section(Some("system"))
|
|
.set("dipsw2", bool_to_01(self.frequency == 60))
|
|
.set("dipsw3", bool_to_01(self.frequency == 60));
|
|
}
|
|
}
|
|
|
|
pub fn clean_up(info: &DisplayInfo) -> Result<()> {
|
|
use anyhow::anyhow;
|
|
|
|
let display_set = info.set.as_ref()
|
|
.ok_or_else(|| anyhow!("Unable to clean up displays: no display set"))?;
|
|
|
|
if let Some(info_primary) = &info.primary {
|
|
let primary = display_set
|
|
.displays()
|
|
.find(|display| display.name() == info_primary)
|
|
.ok_or_else(|| anyhow!("Display {} not found", info_primary))?;
|
|
|
|
primary.set_primary()?;
|
|
}
|
|
|
|
display_set.apply()?;
|
|
displayz::refresh()?;
|
|
|
|
log::debug!("undo display: done");
|
|
|
|
Ok(())
|
|
}
|
|
} |