handle tty raw mode ourselves

This commit is contained in:
stjet
2025-04-21 05:51:07 +00:00
parent d32b82a2bb
commit c5a41244b4
5 changed files with 78 additions and 11 deletions

View File

@@ -9,7 +9,7 @@ default-run = "ming"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[workspace] [workspace]
members = ["linux"] members = [ "linux" ]
[build-dependencies] [build-dependencies]
bmp-rust = "0.5.0" bmp-rust = "0.5.0"

1
linux/src/keys.rs Normal file
View File

@@ -0,0 +1 @@
//

View File

@@ -1,2 +1,2 @@
pub mod fb; pub mod fb;
pub mod raw;

65
linux/src/raw.rs Normal file
View File

@@ -0,0 +1,65 @@
use std::io::Stdout;
use std::mem::zeroed;
use std::os::fd::AsRawFd;
use libc::{ cfmakeraw, c_int, tcgetattr, tcsetattr, termios, TCSAFLUSH };
//https://viewsourcecode.org/snaptoken/kilo/02.enteringRawMode.html
//on TCSAFLUSH: "The TCSAFLUSH argument specifies when to apply the change: in this case, it waits for all pending output to be written to the terminal, and also discards any input that hasn't been read."
//https://www.man7.org/linux/man-pages/man3/termios.3.html
//(use cfmakeraw instead doing all those bitwise stuff manually)
//enter and exit tty raw mode
pub struct RawStdout {
pub stdout: Stdout,
old_termios: termios,
}
impl RawStdout {
pub fn new(stdout: Stdout) -> Self {
RawStdout {
stdout,
old_termios: unsafe { zeroed() },
}
}
pub fn get_termios(raw_fd: c_int) -> Result<termios, ()> {
let mut termios_struct: termios = unsafe { zeroed() };
let result = unsafe {
tcgetattr(raw_fd, &mut termios_struct)
};
if result != -1 {
Ok(termios_struct)
} else {
Err(())
}
}
pub fn enter_raw_mode(&mut self) -> Result<(), ()> {
let raw_fd = self.stdout.as_raw_fd();
let mut termios_struct = Self::get_termios(raw_fd)?;
self.old_termios = termios_struct;
let result = unsafe {
cfmakeraw(&mut termios_struct);
tcsetattr(raw_fd, TCSAFLUSH, &mut termios_struct)
};
if result != -1 {
Ok(())
} else {
Err(())
}
}
pub fn exit_raw_mode(&mut self) -> Result<(), ()> {
let result = unsafe {
tcsetattr(self.stdout.as_raw_fd(), TCSAFLUSH, &mut self.old_termios)
};
if result != -1 {
Ok(())
} else {
Err(())
}
}
}

View File

@@ -7,8 +7,8 @@ use std::process::exit;
use std::env; use std::env;
use linux::fb::Framebuffer; use linux::fb::Framebuffer;
use linux::raw::RawStdout;
use termion::input::TermRead; use termion::input::TermRead;
use termion::raw::IntoRawMode;
use termion::event::Key; use termion::event::Key;
use ming_wm_lib::window_manager_types::KeyChar; use ming_wm_lib::window_manager_types::KeyChar;
@@ -73,13 +73,14 @@ fn init(framebuffer: Framebuffer, framebuffer_info: FramebufferInfo) {
let mut wm: WindowManager = WindowManager::new(writer, framebuffer, dimensions, rotate, grayscale); let mut wm: WindowManager = WindowManager::new(writer, framebuffer, dimensions, rotate, grayscale);
let mut stdout = stdout().into_raw_mode().unwrap(); let mut stdout = RawStdout::new(stdout());
stdout.enter_raw_mode().unwrap();
write!(stdout, "{}", CLEAR_ALL).unwrap(); write!(stdout.stdout, "{}", CLEAR_ALL).unwrap();
write!(stdout, "{}", HIDE_CURSOR).unwrap(); write!(stdout.stdout, "{}", HIDE_CURSOR).unwrap();
stdout.flush().unwrap(); stdout.stdout.flush().unwrap();
wm.draw(None, false); wm.draw(None, false);
@@ -154,13 +155,13 @@ fn init(framebuffer: Framebuffer, framebuffer_info: FramebufferInfo) {
ThreadMessage::KeyChar(kc) => wm.handle_message(WindowManagerMessage::KeyChar(kc.clone())), ThreadMessage::KeyChar(kc) => wm.handle_message(WindowManagerMessage::KeyChar(kc.clone())),
ThreadMessage::Touch(x, y) => wm.handle_message(WindowManagerMessage::Touch(x, y)), ThreadMessage::Touch(x, y) => wm.handle_message(WindowManagerMessage::Touch(x, y)),
ThreadMessage::Clear => { ThreadMessage::Clear => {
write!(stdout, "{}", CLEAR_ALL).unwrap(); write!(stdout.stdout, "{}", CLEAR_ALL).unwrap();
stdout.flush().unwrap(); stdout.stdout.flush().unwrap();
}, },
ThreadMessage::Exit => { ThreadMessage::Exit => {
if !wm.locked { if !wm.locked {
write!(stdout, "{}", SHOW_CURSOR).unwrap(); write!(stdout.stdout, "{}", SHOW_CURSOR).unwrap();
stdout.suspend_raw_mode().unwrap(); stdout.exit_raw_mode().unwrap();
exit(0); exit(0);
} }
}, },