fix(tty): improve terminal size detection (#36)

This commit is contained in:
Fathy Boundjadj 2023-02-01 10:14:29 +01:00 committed by GitHub
parent 47540ae6c5
commit 16cf566808
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 122 additions and 17 deletions

View File

@ -7,6 +7,7 @@ edition = "2021"
libc = "0.2"
unicode-width = "0.1.10"
unicode-segmentation = "1.10.0"
chrono = "0.4.23"
[lib]
name = "carbonyl"

View File

@ -166,9 +166,9 @@ This should produce the following outputs:
```console
# Build arm64 Docker image using binaries from the Default target
$ ./scripts/docker.sh arm64 Default
$ ./scripts/docker-build.sh Default arm64
# Build amd64 Docker image using binaries from the Default target
$ ./scripts/docker.sh amd64 Default
$ ./scripts/docker-build.sh Default amd64
```
### Run

View File

@ -4,11 +4,18 @@ export CARBONYL_ROOT=$(cd $(dirname -- "$0") && dirname -- $(pwd))
source "$CARBONYL_ROOT/scripts/env.sh"
target="$1"
cpu="$2"
platform="linux"
cpu=$(uname -m)
if [ -z "$cpu" ]; then
cpu="$(uname -m)"
fi
if [[ "$cpu" == "arm64" ]]; then
cpu="aarch64"
elif [[ "$cpu" == "amd64" ]]; then
cpu="x86_64"
fi
if [[ "$OSTYPE" == "linux-gnu"* ]]; then

View File

@ -4,8 +4,8 @@ export CARBONYL_ROOT=$(cd $(dirname -- "$0") && dirname -- $(pwd))
source "$CARBONYL_ROOT/scripts/env.sh"
cpu="$1"
target="$2"
target="$1"
cpu="$2"
build_dir="$CARBONYL_ROOT/build/browser/$cpu"

View File

@ -19,4 +19,4 @@ docker manifest create "$tag:$version" \
--amend "$tag:$version-arm64" \
--amend "$tag:$version-amd64"
docker manifest push "$tag:$version"
docker manifest push "$tag:$version" --purge

View File

@ -7,7 +7,7 @@ use libc::{c_char, c_int, c_uchar, c_uint, size_t};
use crate::gfx::{Cast, Color, Point, Rect, Size};
use crate::output::Renderer;
use crate::{input, output};
use crate::{input, output, utils::log};
/// This file bridges the C++ code with Rust.
/// "C-unwind" combined with .unwrap() is used to allow catching Rust panics
@ -126,6 +126,8 @@ pub extern "C-unwind" fn carbonyl_renderer_create() -> *mut Renderer {
let mut renderer = Box::new(Renderer::new());
let src = output::size().unwrap();
log::debug!("Terminal size: {:?}", src);
renderer.set_size(Size::new(7, 14), src);
Box::into_raw(renderer)
@ -197,6 +199,8 @@ pub extern "C-unwind" fn carbonyl_output_get_size(size: *mut CSize) {
let dst = unsafe { &mut *size };
let src = output::size().unwrap().cast::<c_uint>();
log::debug!("Terminal size: {:?}", src);
dst.width = src.width * 7;
dst.height = src.height * 14;
}
@ -243,7 +247,7 @@ pub extern "C-unwind" fn carbonyl_input_listen(
mouse_move(col as c_uint * char_width, row as c_uint * char_height)
}
Terminal(terminal) => match terminal {
TerminalEvent::Name(name) => eprintln!("Terminal name: {name}"),
TerminalEvent::Name(name) => log::debug!("Terminal name: {name}"),
TerminalEvent::TrueColorSupported => renderer.enable_true_color(),
},
}

View File

@ -1,6 +1,6 @@
use std::ops::BitAnd;
use crate::control_flow;
use crate::{control_flow, utils::log};
use super::{Event, ParseControlFlow};
@ -38,7 +38,7 @@ impl Mouse {
(_, None, _) => self.col = num,
(_, _, None) => self.row = num,
_ => {
eprintln!("Misformed mouse sequence");
log::warning!("Misformed mouse sequence");
return None;
}

View File

@ -5,6 +5,8 @@ use std::mem::MaybeUninit;
use std::os::fd::RawFd;
use std::os::unix::prelude::AsRawFd;
use crate::utils::log;
pub struct Terminal {
settings: Option<TerminalSettings>,
alt_screen: bool,
@ -24,13 +26,13 @@ impl Terminal {
settings: match TerminalSettings::open_raw() {
Ok(settings) => Some(settings),
Err(error) => {
eprintln!("Failed to setup terminal: {error}");
log::error!("Failed to setup terminal: {error}");
None
}
},
alt_screen: if let Err(error) = TTY::enter_alt_screen() {
eprintln!("Failed to enter alternative screen: {error}");
log::error!("Failed to enter alternative screen: {error}");
false
} else {
@ -42,7 +44,7 @@ impl Terminal {
pub fn teardown(&mut self) {
if let Some(ref settings) = self.settings {
if let Err(error) = settings.apply() {
eprintln!("Failed to revert terminal settings: {error}");
log::error!("Failed to revert terminal settings: {error}");
}
self.settings = None;
@ -50,7 +52,7 @@ impl Terminal {
if self.alt_screen {
if let Err(error) = TTY::quit_alt_screen() {
eprintln!("Failed to quit alternative screen: {error}");
log::error!("Failed to quit alternative screen: {error}");
}
self.alt_screen = false;

View File

@ -3,3 +3,5 @@ pub mod browser;
pub mod gfx;
pub mod input;
pub mod output;
mod utils;

View File

@ -1,14 +1,30 @@
use core::mem::MaybeUninit;
use std::io;
use std::{io, str::FromStr};
use crate::gfx::Size;
use crate::{gfx::Size, utils::log};
pub fn size() -> io::Result<Size> {
let mut ptr = MaybeUninit::<libc::winsize>::uninit();
unsafe {
if libc::ioctl(libc::STDOUT_FILENO, libc::TIOCGWINSZ, ptr.as_mut_ptr()) == 0 {
let size = ptr.assume_init();
let mut size = ptr.assume_init();
if size.ws_col == 0 || size.ws_row == 0 {
let cols = parse_var("COLUMNS").unwrap_or(80);
let rows = parse_var("LINES").unwrap_or(24);
log::warning!(
"TIOCGWINSZ returned an empty size ({}x{}), defaulting to {}x{}",
size.ws_col,
size.ws_row,
cols,
rows
);
size.ws_col = cols;
size.ws_row = rows;
}
Ok(Size::new(size.ws_col as u32, size.ws_row as u32))
} else {
@ -16,3 +32,7 @@ pub fn size() -> io::Result<Size> {
}
}
}
fn parse_var<T: FromStr>(var: &str) -> Option<T> {
std::env::var(var).ok()?.parse().ok()
}

4
src/utils.rs Normal file
View File

@ -0,0 +1,4 @@
pub mod log;
mod try_block;
use try_block::*;

58
src/utils/log.rs Normal file
View File

@ -0,0 +1,58 @@
use std::path::Path;
use chrono::prelude::*;
use crate::utils::try_block;
macro_rules! debug {
($($args:expr),+) => {
crate::utils::log::write(
"DEBUG",
file!(),
line!(),
&format!($($args),*)
)
};
}
macro_rules! warning {
($($args:expr),+) => {
crate::utils::log::write(
"WARNING",
file!(),
line!(),
&format!($($args),*)
)
};
}
macro_rules! error {
($($args:expr),+) => {
crate::utils::log::write(
"ERROR",
file!(),
line!(),
&format!($($args),*)
)
};
}
pub(crate) use debug;
pub(crate) use error;
pub(crate) use warning;
pub fn write(level: &str, file: &str, line: u32, message: &str) {
let date = Utc::now();
eprintln!(
"[{:02}{:02}/{:02}{:02}{:02}.{:06}:{}:{}({})] {}",
date.month(),
date.day(),
date.hour(),
date.minute(),
date.second(),
date.nanosecond() / 1000,
level,
try_block!(Path::new(file).file_name()?.to_str()).unwrap_or("default"),
line,
message
);
}

7
src/utils/try_block.rs Normal file
View File

@ -0,0 +1,7 @@
macro_rules! try_block {
($block:expr) => {
(|| $block)()
};
}
pub(crate) use try_block;