crossterm-rs / crossterm

Cross platform terminal library rust
MIT License
3.28k stars 281 forks source link

Feature request: uefi support #896

Open joholl opened 6 months ago

joholl commented 6 months ago

Problem

This crate is great! It would be even greater, if it supported uefi. Rust nightly contains much of std already, see this example in the official docs.

In the end, I would love to use ratatui on Linux/Windows/UEFI with crossterm as a backend.

Solution

What we already have:

Open questions:

I do not know if this feature request makes sense because I have not a full understanding of UEFI, crossterm, ratatui and terminals in general.

Development

If you quickly want to spin up a Rust application using stdout on UEFI (qemu):

sudo apt install ovmf  # for qemu uefi image
rustup target add x86_64-unknown-uefi  # install cross-compile toolchain

cargo init
cargo add r-efi
# copy this example into main.rs: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/platform-support/unknown-uefi.md#example-hello-world-with-std
cargo build --target=x86_64-unknown-uefi
qemu-system-x86_64 -m 4G -cpu max -smp 4 -bios /usr/share/ovmf/OVMF.fd -nographic -no-reboot -nic none -drive file=fat:rw:./target/x86_64-unknown-uefi/debug,format=raw,media=disk
# type "<ESC>" to drop into shell
# type "fs0:" to change drive
# type "ls" to find your binary name: <...>.efi
# type "<...>.efi" to run application

PoC code for getting the terminal dimensions via query_mode:

let mut columns: usize = 0;
let mut rows: usize = 0;
let r = unsafe {
    let con_out: *mut simple_text_output::Protocol = (*system_table).con_out;
    let query_mode: extern "efiapi" fn(
        _: *mut simple_text_output::Protocol,
        usize,
        *mut usize,
        *mut usize,
    ) -> efi::Status = (*con_out).query_mode;

    let mode_number = 0;

    query_mode(
        con_out,
        mode_number,
        &mut columns as *mut _,
        &mut rows as *mut _,
    )
};
assert!(!r.is_error());