mod core_foundation_sys_patches;
mod screenshot;
mod window_id;
use crate::PlatformApi;
use crate::{ImageOnHeap, Margin, Result, WindowList};
use crate::common::identify_transparency::identify_transparency;
use crate::common::image::crop;
use anyhow::Context;
use screenshot::capture_window_screenshot;
use std::env;
use window_id::window_list;
pub const DEFAULT_SHELL: &str = "/bin/sh";
pub fn setup() -> Result<Box<dyn PlatformApi>> {
Ok(Box::new(QuartzApi { margin: None }))
}
struct QuartzApi {
margin: Option<Margin>,
}
impl PlatformApi for QuartzApi {
fn calibrate(&mut self, window_id: u64) -> Result<()> {
let image = capture_window_screenshot(window_id)?;
self.margin = identify_transparency(*image)?;
Ok(())
}
fn window_list(&self) -> Result<WindowList> {
window_list()
}
fn capture_window_screenshot(&self, window_id: u64) -> Result<ImageOnHeap> {
let img = capture_window_screenshot(window_id)?;
if let Some(margin) = self.margin.as_ref() {
if !margin.is_zero() {
return crop(*img, margin);
}
}
Ok(img)
}
fn get_active_window(&self) -> Result<u64> {
env::var("WINDOWID")
.context("Env variable 'WINDOWID' was not set.")
.unwrap()
.parse::<u64>()
.context("Cannot parse env variable 'WINDOWID' as number")
}
}
#[cfg(feature = "test_against_real_display")]
#[cfg(test)]
mod test {
use super::*;
use image::flat::View;
use image::{save_buffer, Bgra, GenericImageView};
#[test]
fn calibrate() -> Result<()> {
let mut api = setup()?;
let win = api.get_active_window()?;
let image_raw = api.capture_window_screenshot(win)?;
let image: View<_, Bgra<u8>> = image_raw.as_view().unwrap();
let (width, height) = image.dimensions();
api.calibrate(win)?;
let image_calibrated_raw = api.capture_window_screenshot(win)?;
let image_calibrated: View<_, Bgra<u8>> = image_calibrated_raw.as_view().unwrap();
let (width_new, height_new) = image_calibrated.dimensions();
dbg!(width, width_new, height, height_new);
let Bgra([_, _, _, alpha]) = image.get_pixel(width / 2, 0);
dbg!(alpha);
if alpha == 0 {
assert!(height > height_new);
assert!(width > width_new);
} else {
assert!(height >= height_new);
assert!(width >= width_new);
}
let pixel = image.get_pixel(width - 1, height / 2);
dbg!(pixel);
save_buffer(
format!("frame-raw-{}.tga", win),
&image_raw.samples,
image_raw.layout.width,
image_raw.layout.height,
image_raw.color_hint.unwrap(),
)
.context("Cannot save a frame.")?;
Ok(())
}
}