diff --git a/Cargo.lock b/Cargo.lock index 5b40d9f3..751625a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3792,12 +3792,12 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed" +checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0" dependencies = [ "rustix", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] diff --git a/image/Cargo.toml b/image/Cargo.toml index b4b98d47..997541bf 100644 --- a/image/Cargo.toml +++ b/image/Cargo.toml @@ -15,5 +15,5 @@ image.workspace = true [target.'cfg(not(windows))'.dependencies] color_quant = "1.1.0" base64 = "0.22.1" -nix = { version = "0.30.1", features = ["poll", "term"] } +nix = { version = "0.30.1", features = ["poll", "term", "ioctl"] } libc = "0.2.177" diff --git a/image/src/iterm.rs b/image/src/iterm.rs index cca369d3..3d57f0e1 100644 --- a/image/src/iterm.rs +++ b/image/src/iterm.rs @@ -21,7 +21,7 @@ impl super::ImageBackend for ITermBackend { image: &DynamicImage, _colors: usize, ) -> Result { - let tty_size = unsafe { get_dimensions() }; + let tty_size = get_dimensions()?; let width_ratio = f64::from(tty_size.ws_col) / f64::from(tty_size.ws_xpixel); let height_ratio = f64::from(tty_size.ws_row) / f64::from(tty_size.ws_ypixel); diff --git a/image/src/kitty.rs b/image/src/kitty.rs index 31804b89..1689ac28 100644 --- a/image/src/kitty.rs +++ b/image/src/kitty.rs @@ -73,7 +73,7 @@ impl super::ImageBackend for KittyBackend { image: &DynamicImage, _colors: usize, ) -> Result { - let tty_size = unsafe { get_dimensions() }; + let tty_size = get_dimensions()?; let width_ratio = f64::from(tty_size.ws_col) / f64::from(tty_size.ws_xpixel); let height_ratio = f64::from(tty_size.ws_row) / f64::from(tty_size.ws_ypixel); diff --git a/image/src/lib.rs b/image/src/lib.rs index 7748b650..bab5c299 100644 --- a/image/src/lib.rs +++ b/image/src/lib.rs @@ -1,5 +1,6 @@ -use anyhow::Result; +use anyhow::{bail, Result}; use image::DynamicImage; +use nix::pty::Winsize; #[derive(clap::ValueEnum, Clone, PartialEq, Eq, Debug)] pub enum ImageProtocol { @@ -50,16 +51,23 @@ pub fn get_image_backend(image_protocol: ImageProtocol) -> Option libc::winsize { - use libc::{ioctl, winsize, STDOUT_FILENO, TIOCGWINSZ}; - use std::mem::zeroed; +fn get_dimensions() -> Result { + nix::ioctl_read_bad!(ioctl, nix::libc::TIOCGWINSZ, nix::libc::winsize); - let mut window: winsize = zeroed(); - let result = ioctl(STDOUT_FILENO, TIOCGWINSZ, &mut window); + let mut window = Winsize { + ws_col: 0, + ws_row: 0, + ws_xpixel: 0, + ws_ypixel: 0, + }; + let result = unsafe { + use std::os::fd::AsRawFd as _; + ioctl(std::io::stdout().as_raw_fd(), &mut window)? + }; if result == -1 { - zeroed() + bail!("ioctl error!") } else { - window + Ok(window) } } diff --git a/image/src/sixel.rs b/image/src/sixel.rs index 1a8343e2..8a8af6fc 100644 --- a/image/src/sixel.rs +++ b/image/src/sixel.rs @@ -66,7 +66,7 @@ impl SixelBackend { impl super::ImageBackend for SixelBackend { #[allow(clippy::map_entry)] fn add_image(&self, lines: Vec, image: &DynamicImage, colors: usize) -> Result { - let tty_size = unsafe { get_dimensions() }; + let tty_size = get_dimensions()?; let cw = tty_size.ws_xpixel / tty_size.ws_col; let lh = tty_size.ws_ypixel / tty_size.ws_row; let width_ratio = 1.0 / cw as f64;