1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
use crate::config::Xywh;
use anyhow::{bail, Result};
use std::io::Write;
use std::process::Child;
use std::process::Stdio;
use std::sync::RwLock;
pub struct UeInstance {
ueberzug: RwLock<Option<Child>>,
}
impl Default for UeInstance {
fn default() -> Self {
Self {
ueberzug: RwLock::new(None),
}
}
}
impl UeInstance {
pub fn draw_cover_ueberzug(&self, url: &str, draw_xywh: &Xywh, use_sixel: bool) -> Result<()> {
if draw_xywh.width <= 1 || draw_xywh.height <= 1 {
return Ok(());
}
// Ueberzug takes an area given in chars and fits the image to
// that area (from the top left).
// draw_offset.y += (draw_size.y - size.y) - (draw_size.y - size.y) / 2;
let cmd = format!("{{\"action\":\"add\",\"scaler\":\"forced_cover\",\"identifier\":\"cover\",\"x\":{},\"y\":{},\"width\":{},\"height\":{},\"path\":\"{}\"}}\n",
// let cmd = format!("{{\"action\":\"add\",\"scaler\":\"fit_contain\",\"identifier\":\"cover\",\"x\":{},\"y\":{},\"width\":{},\"height\":{},\"path\":\"{}\"}}\n",
// TODO: right now the y position of ueberzug is not consistent, and could be a 0.5 difference
// draw_xywh.x, draw_xywh.y-1,
draw_xywh.x, draw_xywh.y,//-1 + (draw_xywh.width-draw_xywh.height) % 2,
draw_xywh.width,draw_xywh.height/2,//+ (draw_xywh.width-draw_xywh.height)%2,
url,
);
// println!(
// "draw_xywh.x = {}, draw_xywh.y = {}, draw_wyxh.width = {}, draw_wyxh.height = {}",
// draw_xywh.x, draw_xywh.y, draw_xywh.width, draw_xywh.height,
// );
if use_sixel {
if let Err(e) = self.run_ueberzug_cmd_sixel(&cmd) {
bail!("Failed to run Ueberzug: {}", e)
// Ok(())
}
return Ok(());
}
if let Err(e) = self.run_ueberzug_cmd(&cmd) {
bail!("Failed to run Ueberzug: {}", e)
// Ok(())
}
Ok(())
}
pub fn clear_cover_ueberzug(&self) -> Result<()> {
let cmd = "{\"action\": \"remove\", \"identifier\": \"cover\"}\n";
if let Err(e) = self.run_ueberzug_cmd(cmd) {
bail!("Failed to run Ueberzug: {}", e)
// Ok(())
}
Ok(())
}
fn run_ueberzug_cmd(&self, cmd: &str) -> Result<()> {
let mut ueberzug = self.ueberzug.write().unwrap();
// eprintln!("using x11 output for ueberzugpp");
if ueberzug.is_none() {
*ueberzug = Some(
std::process::Command::new("ueberzug")
.args(["layer", "--silent"])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?,
);
}
let stdin = (*ueberzug).as_mut().unwrap().stdin.as_mut().unwrap();
stdin.write_all(cmd.as_bytes())?;
Ok(())
}
fn run_ueberzug_cmd_sixel(&self, cmd: &str) -> Result<()> {
let mut ueberzug = self.ueberzug.write().unwrap();
// eprintln!("using sixel output for ueberzugpp");
if ueberzug.is_none() {
*ueberzug = Some(
std::process::Command::new("ueberzug")
.args(["layer", "--silent"])
// .args(["layer", "--silent", "--no-cache", "--output", "sixel"])
// .args(["layer", "--sixel"])
// .args(["--sixel"])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?,
);
}
let stdin = (*ueberzug).as_mut().unwrap().stdin.as_mut().unwrap();
stdin.write_all(cmd.as_bytes())?;
Ok(())
}
}