add stdin/stdout to os_input

This commit is contained in:
Aram Drevekenin 2020-08-27 11:24:45 +02:00
parent aacc1c85dc
commit 313ec137f9
2 changed files with 35 additions and 30 deletions

View File

@ -1,6 +1,5 @@
mod os_input_output; mod os_input_output;
use std::io;
use ::std::fmt::{self, Display, Formatter}; use ::std::fmt::{self, Display, Formatter};
use std::cmp::max; use std::cmp::max;
use std::io::{Read, Write}; use std::io::{Read, Write};
@ -218,7 +217,6 @@ impl TerminalOutput {
let buffer_lines = &self.read_buffer_as_lines(); let buffer_lines = &self.read_buffer_as_lines();
let display_cols = &self.display_cols; let display_cols = &self.display_cols;
for (row, line) in buffer_lines.iter().enumerate() { for (row, line) in buffer_lines.iter().enumerate() {
// vte_output.push_str(&format!("\u{1b}[{};{}H\u{1b}[m", row + 1, 1)); // goto row/col
vte_output.push_str(&format!("\u{1b}[{};{}H\u{1b}[m", row + 1, self.x_coords + 1)); // goto row/col vte_output.push_str(&format!("\u{1b}[{};{}H\u{1b}[m", row + 1, self.x_coords + 1)); // goto row/col
for (col, t_character) in line.iter().enumerate() { for (col, t_character) in line.iter().enumerate() {
if (col as u16) < *display_cols { if (col as u16) < *display_cols {
@ -746,6 +744,7 @@ impl Screen {
active_terminal.x_coords as usize + active_terminal.cursor_position_in_last_line() active_terminal.x_coords as usize + active_terminal.cursor_position_in_last_line()
} }
pub fn render (&mut self) { pub fn render (&mut self) {
let mut stdout = self.os_api.get_stdout_writer();
for (_pid, terminal) in self.terminals.iter_mut() { for (_pid, terminal) in self.terminals.iter_mut() {
if let Some(vte_output) = terminal.buffer_as_vte_output() { if let Some(vte_output) = terminal.buffer_as_vte_output() {
if terminal.x_coords + terminal.display_cols < self.full_screen_ws.ws_col { if terminal.x_coords + terminal.display_cols < self.full_screen_ws.ws_col {
@ -755,15 +754,15 @@ impl Screen {
vte_output_boundaries.push_str(&format!("\u{1b}[{};{}H\u{1b}[m", row + 1, boundary_x_coords + 1)); // goto row/col vte_output_boundaries.push_str(&format!("\u{1b}[{};{}H\u{1b}[m", row + 1, boundary_x_coords + 1)); // goto row/col
vte_output_boundaries.push_str(&self.vertical_separator.to_string()); vte_output_boundaries.push_str(&self.vertical_separator.to_string());
} }
::std::io::stdout().write_all(&vte_output_boundaries.as_bytes()).expect("cannot write to stdout"); stdout.write_all(&vte_output_boundaries.as_bytes()).expect("cannot write to stdout");
} }
::std::io::stdout().write_all(&vte_output.as_bytes()).expect("cannot write to stdout"); stdout.write_all(&vte_output.as_bytes()).expect("cannot write to stdout");
} }
} }
let active_terminal_cursor_position = self.get_active_terminal_cursor_position(); let active_terminal_cursor_position = self.get_active_terminal_cursor_position();
let goto_cursor_position = format!("\r\u{1b}[{}C", active_terminal_cursor_position); let goto_cursor_position = format!("\r\u{1b}[{}C", active_terminal_cursor_position);
::std::io::stdout().write_all(&goto_cursor_position.as_bytes()).expect("cannot write to stdout"); stdout.write_all(&goto_cursor_position.as_bytes()).expect("cannot write to stdout");
::std::io::stdout().flush().expect("could not flush"); stdout.flush().expect("could not flush");
} }
fn terminal_ids_directly_left_of(&self, id: &RawFd) -> Option<Vec<RawFd>> { fn terminal_ids_directly_left_of(&self, id: &RawFd) -> Option<Vec<RawFd>> {
let mut ids = vec![]; let mut ids = vec![];
@ -964,7 +963,6 @@ impl PtyBus {
send_pty_instructions, send_pty_instructions,
send_screen_instructions, send_screen_instructions,
receive_pty_instructions, receive_pty_instructions,
// active_ptys: Vec::new(),
os_input, os_input,
} }
} }
@ -1000,8 +998,6 @@ fn main() {
fn start(os_input: OsInputOutput) { fn start(os_input: OsInputOutput) {
let mut active_threads = vec![]; let mut active_threads = vec![];
let stdin = io::stdin();
let full_screen_ws = os_input.get_terminal_size_using_fd(0); let full_screen_ws = os_input.get_terminal_size_using_fd(0);
os_input.into_raw_mode(0); os_input.into_raw_mode(0);
let mut screen = Screen::new(&full_screen_ws, Box::new(os_input.clone())); let mut screen = Screen::new(&full_screen_ws, Box::new(os_input.clone()));
@ -1072,30 +1068,25 @@ fn start(os_input: OsInputOutput) {
}).unwrap() }).unwrap()
); );
let mut stdin = os_input.get_stdin_reader();
loop { loop {
let mut buffer = [0; 1]; let mut buffer = [0; 1];
{ stdin.read(&mut buffer).expect("failed to read stdin");
let mut handle = stdin.lock(); if buffer[0] == 10 { // ctrl-j
handle.read(&mut buffer).expect("failed to read stdin"); send_screen_instructions.send(ScreenInstruction::ResizeLeft).unwrap();
if buffer[0] == 10 { // ctrl-j } else if buffer[0] == 11 { // ctrl-k
send_screen_instructions.send(ScreenInstruction::ResizeLeft).unwrap(); send_screen_instructions.send(ScreenInstruction::ResizeRight).unwrap();
continue; } else if buffer[0] == 16 { // ctrl-p
} else if buffer[0] == 11 { // ctrl-k send_screen_instructions.send(ScreenInstruction::MoveFocus).unwrap();
send_screen_instructions.send(ScreenInstruction::ResizeRight).unwrap(); } else if buffer[0] == 14 { // ctrl-n
continue; send_pty_instructions.send(PtyInstruction::SpawnTerminal).unwrap();
} else if buffer[0] == 16 { // ctrl-p } else if buffer[0] == 17 { // ctrl-q
send_screen_instructions.send(ScreenInstruction::MoveFocus).unwrap(); send_screen_instructions.send(ScreenInstruction::Quit).unwrap();
continue; send_pty_instructions.send(PtyInstruction::Quit).unwrap();
} else if buffer[0] == 14 { // ctrl-n break;
send_pty_instructions.send(PtyInstruction::SpawnTerminal).unwrap(); } else {
continue; send_screen_instructions.send(ScreenInstruction::WriteCharacter(buffer[0])).unwrap();
} else if buffer[0] == 17 { // ctrl-q
send_screen_instructions.send(ScreenInstruction::Quit).unwrap();
send_pty_instructions.send(PtyInstruction::Quit).unwrap();
break;
}
} }
send_screen_instructions.send(ScreenInstruction::WriteCharacter(buffer[0])).unwrap();
}; };
for thread_handler in active_threads { for thread_handler in active_threads {

View File

@ -11,6 +11,7 @@ use nix::sys::signal::kill;
use nix::pty::{forkpty, Winsize}; use nix::pty::{forkpty, Winsize};
use std::os::unix::io::RawFd; use std::os::unix::io::RawFd;
use std::process::Command; use std::process::Command;
use std::io::{Read, Write};
use std::env; use std::env;
@ -93,6 +94,8 @@ pub trait OsApi: Send + Sync {
fn write(&self, pid: RawFd, buf: &mut [u8]) -> Result<usize, nix::Error>; fn write(&self, pid: RawFd, buf: &mut [u8]) -> Result<usize, nix::Error>;
fn tcdrain(&self, pid: RawFd) -> Result<(), nix::Error>; fn tcdrain(&self, pid: RawFd) -> Result<(), nix::Error>;
fn kill(&self, pid: RawFd) -> Result<(), nix::Error>; fn kill(&self, pid: RawFd) -> Result<(), nix::Error>;
fn get_stdin_reader(&self) -> Box<dyn Read>;
fn get_stdout_writer(&self) -> Box<dyn Write>;
fn box_clone(&self) -> Box<dyn OsApi>; fn box_clone(&self) -> Box<dyn OsApi>;
} }
@ -121,6 +124,17 @@ impl OsApi for OsInputOutput {
fn box_clone(&self) -> Box<dyn OsApi> { fn box_clone(&self) -> Box<dyn OsApi> {
Box::new((*self).clone()) Box::new((*self).clone())
} }
fn get_stdin_reader(&self) -> Box<dyn Read> {
// TODO: stdin lock, right now it's not done because we don't have where to put it
// if we put it on the struct, we won't be able to clone the struct
// if we leave it here, we're referencing a temporary value
let stdin = ::std::io::stdin();
Box::new(stdin)
}
fn get_stdout_writer(&self) -> Box<dyn Write> {
let stdout = ::std::io::stdout();
Box::new(stdout)
}
fn kill(&self, fd: RawFd) -> Result<(), nix::Error> { fn kill(&self, fd: RawFd) -> Result<(), nix::Error> {
kill(Pid::from_raw(fd), None) kill(Pid::from_raw(fd), None)
} }