diff --git a/Cargo.toml b/Cargo.toml index 0997ec6..dd4e3a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ exclude = ["target", "Cargo.lock"] readme = "README.md" [dependencies] - +lazy_static = "1.1.0" [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["winbase","winuser","consoleapi","processenv","wincon", "handleapi"] } diff --git a/examples/examples.rs b/examples/examples.rs index c633ff3..95840fc 100644 --- a/examples/examples.rs +++ b/examples/examples.rs @@ -7,6 +7,8 @@ //! - Run program with: `cargo run --example examples` extern crate crossterm; +#[macro_use] +extern crate lazy_static; // modules that could be test mod terminal; @@ -16,27 +18,59 @@ mod some_types; mod input; use crossterm::{Screen, Crossterm}; +use crossterm::terminal::{Terminal, ClearType}; +use crossterm::cursor::TerminalCursor; + use std::{time, thread}; use std::sync::mpsc; +use std::sync::{Arc,Mutex}; use crossterm::cursor::cursor; +use std::io::Read; fn main() { - let nthreads = 5; - let (tx, rx) = mpsc::channel(); + let input = CROSSTERM.input(); + let mut stdin = input.read_async().bytes(); + CROSSTERM.cursor().hide(); + let mut input_buf = Arc::new(Mutex::new(String::new())); - for i in 0..nthreads { - let tx = tx.clone(); - thread::spawn(move || { - let response = Crossterm::new(&Screen::default()); - tx.send(response).unwrap(); - }); + loop + { + let a = stdin.next(); + + swap_write("dddd", &input_buf.lock().unwrap()); + + match a { + Some(Ok(b'\r')) => + { + input_buf.lock().unwrap().clear(); + + // need to start receiving again because if pressed enter then async reading will stop + stdin = input.read_async().bytes(); + } + Some(Ok(val)) => + { + input_buf.lock().unwrap().push(val as char); + } + _ => {} + } + + thread::sleep(time::Duration::from_millis(100)); } - - for _ in 0..nthreads { - let screen: Crossterm = rx.recv().unwrap(); - screen.terminal(); - - } - +} + +pub fn swap_write(msg: &str, input_buf: &String) { + let term = CROSSTERM.terminal(); + let (_, term_height) = term.terminal_size(); + CROSSTERM.cursor().goto(0, term_height); + term.clear(ClearType::CurrentLine); + term.write(format!("{}\r\n", msg)); + term.write(format!(">{}", input_buf)); +} + +lazy_static! { + static ref CROSSTERM: Crossterm = { + let screen = Screen::new(true); + Crossterm::new(&screen) + }; } diff --git a/src/kernel/windows_kernel/handle.rs b/src/kernel/windows_kernel/handle.rs index 88988d7..3f8e8fe 100644 --- a/src/kernel/windows_kernel/handle.rs +++ b/src/kernel/windows_kernel/handle.rs @@ -22,7 +22,7 @@ pub fn get_current_handle(screen_manager: &Arc) -> Result { }; - handle = Ok(*winapi_screen_manager.get_handle()); + handle = Ok(winapi_screen_manager.get_handle()); return handle; } diff --git a/src/modules/write/stdout.rs b/src/modules/write/stdout.rs index 0d230e5..045df43 100644 --- a/src/modules/write/stdout.rs +++ b/src/modules/write/stdout.rs @@ -43,7 +43,7 @@ impl Stdout { /// Create new screen write instance whereon screen related actions can be performed. pub fn new(is_in_raw_mode: bool) -> Self { #[cfg(target_os = "windows")] - let screen_manager = functions::get_module::>( + let screen_manager: Box = functions::get_module::>( Box::from(WinApiStdout::new()), Box::from(AnsiStdout::new()), ).unwrap(); @@ -87,13 +87,13 @@ impl Default for Stdout /// Get the default handle to the current screen. fn default() -> Self { #[cfg(target_os = "windows")] - let screen_manager = functions::get_module::>( + let screen_manager = functions::get_module::>( Box::from(WinApiStdout::new()), Box::from(AnsiStdout::new()), ).unwrap(); #[cfg(not(target_os = "windows"))] - let screen_manager = Box::from(AnsiStdout::new()) as Box; + let screen_manager = Box::from(AnsiStdout::new()) as Box; Stdout { screen_manager , is_in_raw_mode: false} } diff --git a/src/modules/write/winapi_stdout.rs b/src/modules/write/winapi_stdout.rs index 37d60ba..b58117e 100644 --- a/src/modules/write/winapi_stdout.rs +++ b/src/modules/write/winapi_stdout.rs @@ -10,7 +10,7 @@ use std::sync::{Mutex,Arc, }; /// This struct is a wrapper for WINAPI `HANDLE` pub struct WinApiStdout { - pub handle: Arc>, + pub handle: Mutex, } impl IStdout for WinApiStdout { @@ -38,19 +38,21 @@ impl IStdout for WinApiStdout { impl WinApiStdout { pub fn new() -> Self { - WinApiStdout { handle: Arc::new(Mutex::new(handle::get_output_handle().unwrap())) } + WinApiStdout { handle: Mutex::new(handle::get_output_handle().unwrap()) } } pub fn set(&mut self, handle: HANDLE) { - self.handle = Arc::new(Mutex::new(handle)); + self.handle = Mutex::new(handle); } - pub fn get_handle(&self) -> &Arc> + pub fn get_handle(&self) -> HANDLE { - return &self.handle; + let gx = self.handle.lock(); + gx.unwrap().clone() } } unsafe impl Send for WinApiStdout {} + unsafe impl Sync for WinApiStdout {}