From 26472359bcb0547fc4a1c72cd742095ccdead64b Mon Sep 17 00:00:00 2001 From: TimonPost Date: Fri, 27 Jul 2018 22:28:30 +0200 Subject: [PATCH] fixed input and cursor with new implementation --- examples/Crossterm 0.3.1/bin.rs | 8 + src/cursor/ansi_cursor.rs | 90 +++---- src/cursor/cursor.rs | 122 +++++---- src/cursor/mod.rs | 4 +- src/cursor/winapi_cursor.rs | 28 +- src/input/input.rs | 30 +-- src/input/mod.rs | 10 +- src/input/unix_input.rs | 14 +- src/input/windows_input.rs | 82 +----- src/kernel/windows_kernel/csbi.rs | 6 +- src/kernel/windows_kernel/cursor.rs | 12 +- src/kernel/windows_kernel/handle.rs | 12 +- src/kernel/windows_kernel/kernel.rs | 6 +- src/kernel/windows_kernel/terminal.rs | 4 +- src/kernel/windows_kernel/writing.rs | 4 +- src/lib.rs | 4 +- src/manager/ansi_manager.rs | 53 ++-- src/manager/manager.rs | 23 +- src/manager/mod.rs | 12 +- src/manager/win_manager.rs | 20 +- src/shared/Terminal.rs | 18 ++ src/shared/crossterm.rs | 362 +++++++++++++------------- src/shared/functions.rs | 8 +- src/state/commands/win_commands.rs | 9 +- 24 files changed, 424 insertions(+), 517 deletions(-) diff --git a/examples/Crossterm 0.3.1/bin.rs b/examples/Crossterm 0.3.1/bin.rs index 88221a3..d72e649 100644 --- a/examples/Crossterm 0.3.1/bin.rs +++ b/examples/Crossterm 0.3.1/bin.rs @@ -25,4 +25,12 @@ use crossterm::Terminal; use std::{thread, time}; fn main() { + let term = Terminal::new(); + let mut cursor = term.cursor(); + cursor.goto(10,10); + cursor.print("test"); + + let stdin = term.input(); + let line = stdin.read_line(); + println!("{:?}", line) } diff --git a/src/cursor/ansi_cursor.rs b/src/cursor/ansi_cursor.rs index 79c6284..e90bc22 100644 --- a/src/cursor/ansi_cursor.rs +++ b/src/cursor/ansi_cursor.rs @@ -4,95 +4,63 @@ use super::*; use shared::functions; -use Context; +use {Context,ScreenManager}; /// This struct is an ansi implementation for cursor related actions. -pub struct AnsiCursor { - context: Rc, -} +pub struct AnsiCursor; impl AnsiCursor { - pub fn new(context: Rc) -> Box { - Box::from(AnsiCursor { context }) + pub fn new() -> Box { + Box::from(AnsiCursor { }) } } impl ITerminalCursor for AnsiCursor { - fn goto(&self, x: u16, y: u16) { - let mut screen = self.context.screen_manager.lock().unwrap(); - { - screen.write_string(format!(csi!("{};{}H"), y + 1, x + 1)); - } + fn goto(&self, x: u16, y: u16, screen_manager: &ScreenManager) { + screen_manager.write_string(format!(csi!("{};{}H"), y + 1, x + 1)); } - fn pos(&self) -> (u16, u16) { - functions::get_cursor_position(self.context.clone()) + fn pos(&self, screen_manager: &ScreenManager) -> (u16, u16) { + functions::get_cursor_position(screen_manager) } - fn move_up(&self, count: u16) { - let mut screen = self.context.screen_manager.lock().unwrap(); - { - screen.write_string(format!(csi!("{}A"), count)); - } + fn move_up(&self, count: u16, screen_manager: &ScreenManager) { + screen_manager.write_string(format!(csi!("{}A"), count)); } - fn move_right(&self, count: u16) { - let mut screen = self.context.screen_manager.lock().unwrap(); - { - screen.write_string(format!(csi!("{}C"), count)); - } + fn move_right(&self, count: u16, screen_manager: &ScreenManager) { + screen_manager.write_string(format!(csi!("{}C"), count)); } - fn move_down(&self, count: u16) { - let mut screen = self.context.screen_manager.lock().unwrap(); - { - screen.write_string(format!(csi!("{}B"), count)); - } + fn move_down(&self, count: u16, screen_manager: &ScreenManager) { + screen_manager.write_string(format!(csi!("{}B"), count)); } - fn move_left(&self, count: u16) { - let mut screen = self.context.screen_manager.lock().unwrap(); - { - screen.write_string(format!(csi!("{}D"), count)); - } + fn move_left(&self, count: u16, screen_manager: &ScreenManager) { + screen_manager.write_string(format!(csi!("{}D"), count)); } - fn save_position(&self) { - let mut screen = self.context.screen_manager.lock().unwrap(); - { - screen.write_str(csi!("s")); - } + fn save_position(&self, screen_manager: &ScreenManager) { + screen_manager.write_str(csi!("s")); } - fn reset_position(&self) { - let mut screen = self.context.screen_manager.lock().unwrap(); - { - screen.write_str(csi!("u")); - } + fn reset_position(&self, screen_manager: &ScreenManager) { + screen_manager.write_str(csi!("u")); } - fn hide(&self) { - let mut screen = self.context.screen_manager.lock().unwrap(); - { - screen.write_str(csi!("?25l")); - } + fn hide(&self, screen_manager: &ScreenManager) { + screen_manager.write_str(csi!("?25l")); } - fn show(&self) { - let mut screen = self.context.screen_manager.lock().unwrap(); - { - screen.write_str(csi!("?25h")); - } + fn show(&self, screen_manager: &ScreenManager) { + screen_manager.write_str(csi!("?25h")); } - fn blink(&self, blink: bool) { - let mut screen = self.context.screen_manager.lock().unwrap(); - { - if blink { - screen.write_str(csi!("?12h")); - } else { - screen.write_str(csi!("?12l")); - } + fn blink(&self, blink: bool, screen_manager: &ScreenManager) { + if blink { + screen_manager.write_str(csi!("?12h")); + } else { + screen_manager.write_str(csi!("?12l")); } } } diff --git a/src/cursor/cursor.rs b/src/cursor/cursor.rs index e3f86d6..755cc50 100644 --- a/src/cursor/cursor.rs +++ b/src/cursor/cursor.rs @@ -13,25 +13,25 @@ use std::rc::Rc; /// Struct that stores an specific platform implementation for cursor related actions. pub struct TerminalCursor<'cursor> { - context: &'cursor ScreenManager, + screen_manager: &'cursor ScreenManager, terminal_cursor: Box, } impl<'cursor> TerminalCursor<'cursor> { /// Create new cursor instance whereon cursor related actions can be performed. - pub fn new(context: &'cursor ScreenManager) -> TerminalCursor<'cursor> { + pub fn new(screen_manager: &'cursor ScreenManager) -> TerminalCursor<'cursor> { #[cfg(target_os = "windows")] let cursor = functions::get_module::>( - WinApiCursor::new(context.screen_manager.clone()), - AnsiCursor::new(context.clone()), + WinApiCursor::new(), + AnsiCursor::new(), ).unwrap(); #[cfg(not(target_os = "windows"))] - let cursor = AnsiCursor::new(context.clone()) as Box; + let cursor = AnsiCursor::new() as Box; TerminalCursor { terminal_cursor: cursor, - context, + screen_manager: screen_manager, } } @@ -56,8 +56,8 @@ impl<'cursor> TerminalCursor<'cursor> { /// } /// /// ``` - pub fn goto(&mut self, x: u16, y: u16) -> &mut TerminalCursor { - self.terminal_cursor.goto(x, y); + pub fn goto(&mut self, x: u16, y: u16) -> &mut TerminalCursor<'cursor> { + self.terminal_cursor.goto(x, y, &self.screen_manager); self } @@ -83,7 +83,7 @@ impl<'cursor> TerminalCursor<'cursor> { /// /// ``` pub fn pos(&self) -> (u16, u16) { - self.terminal_cursor.pos() + self.terminal_cursor.pos(&self.screen_manager) } /// Move the current cursor position `n` times up. @@ -107,8 +107,8 @@ impl<'cursor> TerminalCursor<'cursor> { /// } /// /// ``` - pub fn move_up(&mut self, count: u16) -> &mut TerminalCursor { - self.terminal_cursor.move_up(count); + pub fn move_up(&mut self, count: u16) -> &mut TerminalCursor<'cursor> { + self.terminal_cursor.move_up(count, &self.screen_manager); self } @@ -131,8 +131,8 @@ impl<'cursor> TerminalCursor<'cursor> { /// cursor.move_right(3); /// } /// ``` - pub fn move_right(&mut self, count: u16) -> &mut TerminalCursor { - self.terminal_cursor.move_right(count); + pub fn move_right(&mut self, count: u16) -> &mut TerminalCursor<'cursor> { + self.terminal_cursor.move_right(count, &self.screen_manager); self } @@ -157,8 +157,8 @@ impl<'cursor> TerminalCursor<'cursor> { /// } /// /// ``` - pub fn move_down(&mut self, count: u16) -> &mut TerminalCursor { - self.terminal_cursor.move_down(count); + pub fn move_down(&mut self, count: u16) -> &mut TerminalCursor<'cursor> { + self.terminal_cursor.move_down(count, &self.screen_manager); self } @@ -183,8 +183,8 @@ impl<'cursor> TerminalCursor<'cursor> { /// } /// /// ``` - pub fn move_left(&mut self, count: u16) -> &mut TerminalCursor { - self.terminal_cursor.move_left(count); + pub fn move_left(&mut self, count: u16) -> &mut TerminalCursor<'cursor> { + self.terminal_cursor.move_left(count, &self.screen_manager); self } @@ -224,19 +224,13 @@ impl<'cursor> TerminalCursor<'cursor> { /// .print("@"); /// /// ``` - pub fn print(&mut self, value: D) -> &mut TerminalCursor { - { - use std::fmt::Write; - let mut string = String::new(); - write!(string, "{}", value).unwrap(); + pub fn print(&mut self, value: D) -> &mut TerminalCursor<'cursor> { + use std::fmt::Write; + let mut string = String::new(); + write!(string, "{}", value).unwrap(); - let mut mutex = &self.context.screen_manager; - { - let mut screen_manager = mutex.lock().unwrap(); - screen_manager.write_string(string); - screen_manager.flush(); - } - } + &self.screen_manager.write_string(string); + &self.screen_manager.flush(); self } @@ -257,7 +251,7 @@ impl<'cursor> TerminalCursor<'cursor> { /// /// ``` pub fn save_position(&self) { - self.terminal_cursor.save_position(); + self.terminal_cursor.save_position(&self.screen_manager); } /// Return to saved cursor position @@ -277,7 +271,7 @@ impl<'cursor> TerminalCursor<'cursor> { /// /// ``` pub fn reset_position(&self) { - self.terminal_cursor.reset_position(); + self.terminal_cursor.reset_position(&self.screen_manager); } /// Hide de cursor in the console. @@ -295,7 +289,7 @@ impl<'cursor> TerminalCursor<'cursor> { /// /// ``` pub fn hide(&self) { - self.terminal_cursor.hide(); + self.terminal_cursor.hide(&self.screen_manager); } /// Show the cursor in the console. @@ -313,7 +307,7 @@ impl<'cursor> TerminalCursor<'cursor> { /// /// ``` pub fn show(&self) { - self.terminal_cursor.show(); + self.terminal_cursor.show(&self.screen_manager); } /// Enable or disable blinking of the terminal. @@ -335,37 +329,37 @@ impl<'cursor> TerminalCursor<'cursor> { /// /// ``` pub fn blink(&self, blink: bool) { - self.terminal_cursor.blink(blink); + self.terminal_cursor.blink(blink, &self.screen_manager); } } -/// Get an TerminalCursor implementation whereon cursor related actions can be performed. -/// -/// Check `/examples/version/cursor` in the libary for more spesific examples. -/// -/// #Example -/// -/// ```rust -/// -/// extern crate crossterm; -/// use self::crossterm::Context; -/// use self::crossterm::cursor; -/// -/// let context = Context::new(); -/// -/// // Get cursor and goto pos X: 5, Y: 10 -/// let mut cursor = cursor::cursor(&context); -/// cursor.goto(5,10); -/// -/// cursor.show(); -/// cursor.hide(); -/// cursor.blink(); -/// cursor.move_left(2); -/// -/// //Or you can do it in one line. -/// cursor::cursor(&context).goto(5,10); -/// -/// ``` -pub fn cursor(context: &Rc) -> Box { - Box::from(TerminalCursor::new(context.clone())) -} +// Get an TerminalCursor implementation whereon cursor related actions can be performed. +// +// Check `/examples/version/cursor` in the libary for more spesific examples. +// +// #Example +// +// ```rust +// +// extern crate crossterm; +// use self::crossterm::Context; +// use self::crossterm::cursor; +// +// let context = Context::new(); +// +// // Get cursor and goto pos X: 5, Y: 10 +// let mut cursor = cursor::cursor(&context); +// cursor.goto(5,10); +// +// cursor.show(); +// cursor.hide(); +// cursor.blink(); +// cursor.move_left(2); +// +// //Or you can do it in one line. +// cursor::cursor(&context).goto(5,10); +// +// ``` +//pub fn cursor(context: &ScreenManager) -> Box { +// Box::from(TerminalCursor::new(context.clone())) +//} diff --git a/src/cursor/mod.rs b/src/cursor/mod.rs index efed75c..87f1954 100644 --- a/src/cursor/mod.rs +++ b/src/cursor/mod.rs @@ -17,8 +17,8 @@ use self::ansi_cursor::AnsiCursor; #[cfg(target_os = "windows")] use self::winapi_cursor::WinApiCursor; -pub use self::cursor::{cursor, TerminalCursor}; - +pub use self::cursor::{TerminalCursor}; +use ScreenManager; use std::rc::Rc; ///! This trait defines the actions that can be preformed with the terminal cursor. diff --git a/src/cursor/winapi_cursor.rs b/src/cursor/winapi_cursor.rs index 18d6d25..ab359ed 100644 --- a/src/cursor/winapi_cursor.rs +++ b/src/cursor/winapi_cursor.rs @@ -20,47 +20,47 @@ impl WinApiCursor { impl ITerminalCursor for WinApiCursor { fn goto(&self, x: u16, y: u16, screen_manager: &ScreenManager) { - cursor::set_console_cursor_position(x as i16, y as i16, &self.screen_manager); + cursor::set_console_cursor_position(x as i16, y as i16, screen_manager); } fn pos(&self, screen_manager: &ScreenManager) -> (u16, u16) { - cursor::pos(&self.screen_manager) + cursor::pos(screen_manager) } fn move_up(&self, count: u16, screen_manager: &ScreenManager) { - let (xpos, ypos) = self.pos(); - self.goto(xpos, ypos - count); + let (xpos, ypos) = self.pos(screen_manager); + self.goto(xpos, ypos - count, screen_manager); } fn move_right(&self, count: u16, screen_manager: &ScreenManager) { - let (xpos, ypos) = self.pos(); - self.goto(xpos + count, ypos); + let (xpos, ypos) = self.pos(screen_manager); + self.goto(xpos + count, ypos, screen_manager); } fn move_down(&self, count: u16, screen_manager: &ScreenManager) { - let (xpos, ypos) = self.pos(); - self.goto(xpos, ypos + count); + let (xpos, ypos) = self.pos(screen_manager); + self.goto(xpos, ypos + count, screen_manager); } fn move_left(&self, count: u16, screen_manager: &ScreenManager) { - let (xpos, ypos) = self.pos(); - self.goto(xpos - count, ypos); + let (xpos, ypos) = self.pos(screen_manager); + self.goto(xpos - count, ypos, screen_manager); } fn save_position(&self, screen_manager: &ScreenManager) { - cursor::save_cursor_pos(&self.screen_manager); + cursor::save_cursor_pos(screen_manager); } fn reset_position(&self, screen_manager: &ScreenManager) { - cursor::reset_to_saved_position(&self.screen_manager); + cursor::reset_to_saved_position(screen_manager); } fn hide(&self, screen_manager: &ScreenManager) { - cursor::cursor_visibility(false, &self.screen_manager); + cursor::cursor_visibility(false, screen_manager); } fn show(&self, screen_manager: &ScreenManager) { - cursor::cursor_visibility(true, &self.screen_manager); + cursor::cursor_visibility(true, screen_manager); } fn blink(&self, blink: bool, screen_manager: &ScreenManager) {} diff --git a/src/input/input.rs b/src/input/input.rs index 9e7b577..b46cc7e 100644 --- a/src/input/input.rs +++ b/src/input/input.rs @@ -2,48 +2,44 @@ use std::io; use super::*; use std::rc::Rc; -use Context; +use {Context, ScreenManager }; -pub struct TerminalInput { - context: Rc, +pub struct TerminalInput<'terminal> { terminal_input: Box, + screen_manager: &'terminal ScreenManager } -impl TerminalInput { - pub fn new(context: Rc) -> TerminalInput { +impl<'terminal> TerminalInput<'terminal> { + pub fn new(screen_manager: &'terminal ScreenManager) -> TerminalInput<'terminal> { #[cfg(target_os = "windows")] - let input = Box::from(WindowsInput::new(context.clone())); + let input = Box::from(WindowsInput::new()); #[cfg(not(target_os = "windows"))] let input = Box::from(UnixInput::new()); TerminalInput { terminal_input: input, - context, + screen_manager: screen_manager } } pub fn read_line(&self) -> io::Result { - self.terminal_input.read_line() + self.terminal_input.read_line(&self.screen_manager) } pub fn read_char(&self) -> io::Result { - return self.terminal_input.read_char(); - } - - pub fn read_key(&self) -> io::Result { - self.terminal_input.read_pressed_key() + return self.terminal_input.read_char(&self.screen_manager); } pub fn read_async(&self) -> AsyncReader { - self.terminal_input.read_async() + self.terminal_input.read_async(&self.screen_manager) } pub fn read_until_async(&self, delimiter: u8) -> AsyncReader { - self.terminal_input.read_until_async(delimiter) + self.terminal_input.read_until_async(delimiter,&self.screen_manager) } } -pub fn input(context: &Rc) -> Box { - return Box::from(TerminalInput::new(context.clone())); +pub fn input(screen_manager: &ScreenManager) -> TerminalInput { + return TerminalInput::new(screen_manager) } diff --git a/src/input/mod.rs b/src/input/mod.rs index c1d1887..daecd57 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -13,18 +13,18 @@ use self::unix_input::UnixInput; mod unix_input; pub use self::input::{input, TerminalInput}; +use ScreenManager; use std::io::Read; use std::sync::mpsc; trait ITerminalInput { - fn read_line(&self) -> io::Result; + fn read_line(&self, screen_manger: &ScreenManager) -> io::Result; - fn read_char(&self) -> io::Result; - fn read_pressed_key(&self) -> io::Result; + fn read_char(&self, screen_manger: &ScreenManager) -> io::Result; - fn read_async(&self) -> AsyncReader; - fn read_until_async(&self, delimiter: u8) -> AsyncReader; + fn read_async(&self, screen_manger: &ScreenManager) -> AsyncReader; + fn read_until_async(&self, delimiter: u8, screen_manger: &ScreenManager) -> AsyncReader; } pub struct AsyncReader { diff --git a/src/input/unix_input.rs b/src/input/unix_input.rs index 086d3ac..9a75bb3 100644 --- a/src/input/unix_input.rs +++ b/src/input/unix_input.rs @@ -8,7 +8,7 @@ use std::thread; use super::super::kernel::unix_kernel::terminal::{get_tty, read_char}; use super::super::terminal::terminal; use super::{AsyncReader, ITerminalInput, Key}; - +use ScreenManager; pub struct UnixInput; impl UnixInput { @@ -18,7 +18,7 @@ impl UnixInput { } impl ITerminalInput for UnixInput { - fn read_line(&self) -> io::Result { + fn read_line(&self, screen_manger: &ScreenManager) -> io::Result { let mut rv = String::new(); io::stdin().read_line(&mut rv)?; let len = rv.trim_right_matches(&['\r', '\n'][..]).len(); @@ -26,15 +26,11 @@ impl ITerminalInput for UnixInput { Ok(rv) } - fn read_char(&self) -> io::Result { + fn read_char(&self, screen_manger: &ScreenManager) -> io::Result { read_char() } - fn read_pressed_key(&self) -> io::Result { - Ok(Key::Unknown) - } - - fn read_async(&self) -> AsyncReader { + fn read_async(&self, screen_manger: &ScreenManager) -> AsyncReader { let (send, recv) = mpsc::channel(); thread::spawn(move || for i in get_tty().unwrap().bytes() { @@ -46,7 +42,7 @@ impl ITerminalInput for UnixInput { AsyncReader { recv: recv } } - fn read_until_async(&self, delimiter: u8) -> AsyncReader { + fn read_until_async(&self, delimiter: u8, screen_manger: &ScreenManager) -> AsyncReader { let (send, recv) = mpsc::channel(); thread::spawn(move || for i in get_tty().unwrap().bytes() { diff --git a/src/input/windows_input.rs b/src/input/windows_input.rs index ba983ba..83c5cf4 100644 --- a/src/input/windows_input.rs +++ b/src/input/windows_input.rs @@ -9,36 +9,23 @@ use super::{AsyncReader, ITerminalInput, Key}; use winapi::um::winnt::INT; use winapi::um::winuser; -use super::super::terminal::terminal; use std::rc::Rc; -use Context; +use ScreenManager; -pub struct WindowsInput { - context: Rc, - pub display_input: bool, -} +pub struct WindowsInput; impl WindowsInput { - pub fn new(context: Rc) -> WindowsInput { - WindowsInput { - context, - display_input: false, - } + pub fn new() -> WindowsInput { + WindowsInput {} } } impl ITerminalInput for WindowsInput { - fn read_line(&self) -> io::Result { - let term = terminal(&self.context); + fn read_line(&self,screen_manger: &ScreenManager) -> io::Result { let mut chars: Vec = Vec::new(); loop { - let mut is_raw_screen = false; - { - let mutex = &self.context.screen_manager; - let screen = mutex.lock().unwrap(); - is_raw_screen = screen.is_raw_screen(); - } + let is_raw_screen = screen_manger.is_raw_screen(); // _getwch is without echo and _getwche is with echo let pressed_char = unsafe { if is_raw_screen { _getwch() } else { _getwche() } }; @@ -63,15 +50,8 @@ impl ITerminalInput for WindowsInput { return Ok(chars.into_iter().collect()); } - fn read_char(&self) -> io::Result { - let term = terminal(&self.context); - - let mut is_raw_screen = false; - { - let mutex = &self.context.screen_manager; - let screen = mutex.lock().unwrap(); - is_raw_screen = screen.is_raw_screen(); - } + fn read_char(&self, screen_manger: &ScreenManager) -> io::Result { + let is_raw_screen = screen_manger.is_raw_screen(); // _getwch is without echo and _getwche is with echo let pressed_char = unsafe { if is_raw_screen { _getwch() } else { _getwche() } }; @@ -86,9 +66,6 @@ impl ITerminalInput for WindowsInput { match char::from_u32(pressed_char as u32) { Some(c) => { - if self.display_input { - term.write(c); - } return Ok(c); } None => Err(io::Error::new( @@ -98,41 +75,11 @@ impl ITerminalInput for WindowsInput { } } - fn read_pressed_key(&self) -> io::Result { - use Context; - let context = Context::new(); - - let buf: [u8; 1024] = unsafe { ::std::mem::zeroed() }; - // reading::read(&mut buf, &context.screen_manager); - - Ok(Key::Unknown) - // let pressed_char = unsafe { _getwch() }; - // - // // if 0 or 0xe0 we need to listen again because the next key will be an special key - // if pressed_char == 0 || pressed_char == 0xe0 { - // let special_key: i32 = unsafe { _getwch() }; - // println!("spkey {}",special_key); - // return Ok(key_from_key_code(0x26)); - // } else { - // match char::from_u32(pressed_char as u32) - // { - // Some(c) => return Ok(Key::Char(c)), - // None => { panic!("Some error needs to be returned") } - // } - // } - } - - fn read_async(&self) -> AsyncReader { + fn read_async(&self,screen_manger: &ScreenManager) -> AsyncReader { let (tx, rx) = mpsc::channel(); - let mut is_raw_screen = false; + let is_raw_screen = screen_manger.is_raw_screen(); - { - let mutex = &self.context.screen_manager; - let screen = mutex.lock().unwrap(); - is_raw_screen = screen.is_raw_screen(); - } -// panic!("is raw screen: {} ", is_raw_screen); thread::spawn(move || { loop { @@ -155,15 +102,10 @@ impl ITerminalInput for WindowsInput { AsyncReader { recv: rx } } - fn read_until_async(&self, delimiter: u8) -> AsyncReader { + fn read_until_async(&self, delimiter: u8,screen_manger: &ScreenManager) -> AsyncReader { let (tx, rx) = mpsc::channel(); - let mut is_raw_screen = false; - { - let mutex =&self.context.screen_manager; - let screen = mutex.lock().unwrap(); - is_raw_screen = screen.is_raw_screen(); - } + let is_raw_screen = screen_manger.is_raw_screen(); thread::spawn(move || { loop { diff --git a/src/kernel/windows_kernel/csbi.rs b/src/kernel/windows_kernel/csbi.rs index 75962dc..a91be01 100644 --- a/src/kernel/windows_kernel/csbi.rs +++ b/src/kernel/windows_kernel/csbi.rs @@ -16,7 +16,7 @@ use std::sync::Mutex; use ScreenManager; /// Create a new console screen buffer info struct. -pub fn get_csbi(screen_manager: &Rc>) -> Result { +pub fn get_csbi(screen_manager: &ScreenManager) -> Result { let mut csbi = CONSOLE_SCREEN_BUFFER_INFO::empty(); let success; @@ -36,7 +36,7 @@ pub fn get_csbi(screen_manager: &Rc>) -> Result>, + screen_manager: &ScreenManager, ) -> Result<(CONSOLE_SCREEN_BUFFER_INFO, HANDLE)> { let handle = handle::get_current_handle(screen_manager)?; let csbi = get_csbi_by_handle(&handle)?; @@ -63,7 +63,7 @@ pub fn get_csbi_by_handle(handle: &HANDLE) -> Result /// Set the console screen buffer size pub fn set_console_screen_buffer_size( size: COORD, - screen_manager: &Rc>, + screen_manager: &ScreenManager, ) -> bool { let handle = handle::get_current_handle(screen_manager).unwrap(); diff --git a/src/kernel/windows_kernel/cursor.rs b/src/kernel/windows_kernel/cursor.rs index 2cc7e92..e71f3ef 100644 --- a/src/kernel/windows_kernel/cursor.rs +++ b/src/kernel/windows_kernel/cursor.rs @@ -16,7 +16,7 @@ use std::sync::Mutex; static mut SAVED_CURSOR_POS: (u16, u16) = (0, 0); /// Reset to saved cursor position -pub fn reset_to_saved_position(screen_manager: &Rc>) { +pub fn reset_to_saved_position(screen_manager: &ScreenManager) { unsafe { set_console_cursor_position( SAVED_CURSOR_POS.0 as i16, @@ -27,7 +27,7 @@ pub fn reset_to_saved_position(screen_manager: &Rc>) { } /// Save current cursor position to recall later. -pub fn save_cursor_pos(screen_manager: &Rc>) { +pub fn save_cursor_pos(screen_manager: &ScreenManager) { let position = pos(screen_manager); unsafe { @@ -36,7 +36,7 @@ pub fn save_cursor_pos(screen_manager: &Rc>) { } /// get the current cursor position. -pub fn pos(screen_manager: &Rc>) -> (u16, u16) { +pub fn pos(screen_manager: &ScreenManager) -> (u16, u16) { let handle = handle::get_output_handle().unwrap(); @@ -47,7 +47,7 @@ pub fn pos(screen_manager: &Rc>) -> (u16, u16) { } } -pub fn absolute_cursor_pos(screen_manager: &Rc>) -> (u16, u16) { +pub fn absolute_cursor_pos(screen_manager: &ScreenManager) -> (u16, u16) { let handle = handle::get_output_handle().unwrap(); @@ -62,7 +62,7 @@ pub fn absolute_cursor_pos(screen_manager: &Rc>) -> (u16, u } /// Set the cursor position to the given x and y. Note that this is 0 based. -pub fn set_console_cursor_position(x: i16, y: i16, screen_manager: &Rc>) { +pub fn set_console_cursor_position(x: i16, y: i16, screen_manager: &ScreenManager) { if x < 0 || x >= ::max_value() { panic!( "Argument Out of Range Exception when setting cursor position to X: {}", @@ -91,7 +91,7 @@ pub fn set_console_cursor_position(x: i16, y: i16, screen_manager: &Rc>) -> Result<()> { +pub fn cursor_visibility(visable: bool, screen_manager: &ScreenManager) -> Result<()> { let handle = handle::get_current_handle(screen_manager).unwrap(); let cursor_info = CONSOLE_CURSOR_INFO { diff --git a/src/kernel/windows_kernel/handle.rs b/src/kernel/windows_kernel/handle.rs index 49e34d0..78f2206 100644 --- a/src/kernel/windows_kernel/handle.rs +++ b/src/kernel/windows_kernel/handle.rs @@ -6,27 +6,23 @@ use winapi::um::winnt::HANDLE; use std::io::{self, ErrorKind, Result}; use std::rc::Rc; use std::sync::Mutex; - use super::super::super::manager::{ScreenManager, WinApiScreenManager}; /// Get the global stored handle whits provides access to the current screen. -pub fn get_current_handle(screen_manager: &Rc>) -> Result { +pub fn get_current_handle(screen_manager: &ScreenManager) -> Result { let mut mutex = screen_manager; let handle: Result; - let mut screen_manager = mutex.lock().unwrap(); - { - let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager + let winapi_screen_manager: &WinApiScreenManager = match screen_manager .as_any() - .downcast_mut::() + .downcast_ref::() { Some(win_api) => win_api, None => return Err(io::Error::new(io::ErrorKind::Other,"Could not convert to winapi screen manager, this could happen when the user has an ANSI screen manager and is calling the platform specific operations 'get_cursor_pos' or 'get_terminal_size'")) }; - handle = Ok(*winapi_screen_manager.get_handle()); - } + handle = Ok(*winapi_screen_manager.get_handle()); return handle; } diff --git a/src/kernel/windows_kernel/kernel.rs b/src/kernel/windows_kernel/kernel.rs index fb8257f..156e19e 100644 --- a/src/kernel/windows_kernel/kernel.rs +++ b/src/kernel/windows_kernel/kernel.rs @@ -37,7 +37,7 @@ pub fn get_console_mode(handle: &HANDLE, current_mode: &mut u32) -> bool { } /// Change the console text attribute. -pub fn set_console_text_attribute(value: u16, screen_manager: &Rc>) -> bool { +pub fn set_console_text_attribute(value: u16, screen_manager: &ScreenManager) -> bool { let handle = handle::get_current_handle(screen_manager).unwrap(); unsafe { @@ -49,7 +49,7 @@ pub fn set_console_text_attribute(value: u16, screen_manager: &Rc>, + screen_manager: &ScreenManager, ) -> bool { let handle = handle::get_current_handle(screen_manager).unwrap(); @@ -72,7 +72,7 @@ pub fn is_true(value: i32) -> bool { } ///// Get the original color of the terminal. -//pub fn get_original_console_color(screen_manager: &Rc>) -> u16 { +//pub fn get_original_console_color(screen_manager: &ScreenManager) -> u16 { // let console_buffer_info = csbi::get_console_screen_buffer_info(screen_manager); // console_buffer_info.wAttributes as u16 //} diff --git a/src/kernel/windows_kernel/terminal.rs b/src/kernel/windows_kernel/terminal.rs index 8f100a2..15028d1 100644 --- a/src/kernel/windows_kernel/terminal.rs +++ b/src/kernel/windows_kernel/terminal.rs @@ -5,7 +5,7 @@ use ScreenManager; use super::{csbi, handle}; /// Get the terminal size -pub fn terminal_size(screen_manager: &Rc>) -> (u16, u16) { +pub fn terminal_size(screen_manager: &ScreenManager) -> (u16, u16) { let handle = handle::get_output_handle().unwrap(); @@ -19,7 +19,7 @@ pub fn terminal_size(screen_manager: &Rc>) -> (u16, u16) { } } -pub fn buffer_size(screen_manager: &Rc>) -> (u16, u16) { +pub fn buffer_size(screen_manager: &ScreenManager) -> (u16, u16) { let handle = handle::get_output_handle().unwrap(); diff --git a/src/kernel/windows_kernel/writing.rs b/src/kernel/windows_kernel/writing.rs index 0355a4f..f6d25b7 100644 --- a/src/kernel/windows_kernel/writing.rs +++ b/src/kernel/windows_kernel/writing.rs @@ -20,7 +20,7 @@ pub fn fill_console_output_character( cells_written: &mut u32, start_location: COORD, cells_to_write: u32, - screen_manager: &Rc>, + screen_manager: &ScreenManager, ) -> bool { let handle = handle::get_current_handle(screen_manager).unwrap(); @@ -42,7 +42,7 @@ pub fn fill_console_output_attribute( cells_written: &mut u32, start_location: COORD, cells_to_write: u32, - screen_manager: &Rc>, + screen_manager: &ScreenManager, ) -> bool { // Get the position of the current console window diff --git a/src/lib.rs b/src/lib.rs index 2040558..f1c6068 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,11 +11,11 @@ mod state; pub mod cursor; pub mod input; pub mod manager; -pub mod style; +//pub mod style; pub mod terminal; pub use shared::Terminal::Terminal; -pub use shared::crossterm::Crossterm; +//pub use shared::crossterm::Crossterm; pub use shared::raw; pub use shared::screen; pub use state::context::Context; diff --git a/src/manager/ansi_manager.rs b/src/manager/ansi_manager.rs index 4ea1265..8898a68 100644 --- a/src/manager/ansi_manager.rs +++ b/src/manager/ansi_manager.rs @@ -4,14 +4,14 @@ use std::any::Any; use std::io::{self, Read, Write}; - +use std::sync::Mutex; use super::IScreenManager; +use std::str::from_utf8; pub struct AnsiScreenManager { is_alternate_screen: bool, is_raw_screen: bool, - output: Box, - input: Box, + output: Mutex> } impl IScreenManager for AnsiScreenManager { @@ -31,41 +31,37 @@ impl IScreenManager for AnsiScreenManager { self.is_alternate_screen } - fn write_string(&mut self, string: String) -> io::Result { - write!(self.output, "{}", string)?; + fn write_str(&self, string: &str) -> io::Result { + { + let mx = &self.output; + + let mut output = mx.lock().unwrap(); + write!(output, "{}", string)?; + } self.flush(); Ok(0) } - fn write_str(&mut self, string: &str) -> io::Result { - write!(self.output, "{}", string)?; - self.flush(); + fn write(&self, buf: &[u8]) -> io::Result { + { + let mx = &self.output; + let mut output = mx.lock().unwrap(); + output.write(buf)?; + } Ok(0) } - // fn read_line(&mut self) -> io::Result - // { - // let mut rv = String::new(); - // self.input.read_line(&mut rv)?; - // let len = rv.trim_right_matches(&['\r', '\n'][..]).len(); - // rv.truncate(len); - // Ok(rv) - // } - // - // fn read_char(&mut self) -> io::Result - // { - // - // } - - fn write(&mut self, buf: &[u8]) -> io::Result { - self.output.write(buf) + fn flush(&self) -> io::Result<()> { + let mx = &self.output; + let mut output = mx.lock().unwrap(); + output.flush() } - fn flush(&mut self) -> io::Result<()> { - self.output.flush() + fn as_any(&self) -> &Any { + self } - fn as_any(&mut self) -> &mut Any { + fn as_any_mut(&mut self) -> &mut Any { self } } @@ -73,8 +69,7 @@ impl IScreenManager for AnsiScreenManager { impl AnsiScreenManager { pub fn new() -> Self { AnsiScreenManager { - input: (Box::from(io::stdin()) as Box), - output: (Box::from(io::stdout()) as Box), + output: Mutex::new(Box::from(io::stdout()) as Box), is_alternate_screen: false, is_raw_screen: false, } diff --git a/src/manager/manager.rs b/src/manager/manager.rs index 29de940..e8a3b31 100644 --- a/src/manager/manager.rs +++ b/src/manager/manager.rs @@ -52,27 +52,26 @@ impl ScreenManager { } /// Write an ANSI code as String. - pub fn write_string(&mut self, string: String) -> io::Result { - self.screen_manager.write_string(string) + pub fn write_string(&self, string: String) -> io::Result { + self.screen_manager.write_str(string.as_str()) } + pub fn flush(&self) -> io::Result<()> + { + self.screen_manager.flush() + } /// Write an ANSI code as &str - pub fn write_str(&mut self, string: &str) -> io::Result { + pub fn write_str(&self, string: &str) -> io::Result { self.screen_manager.write_str(string) } /// Can be used to get an specific implementation used for the current platform. - pub fn as_any(&mut self) -> &mut Any { + pub fn as_any(&self) -> &Any { self.screen_manager.as_any() } -} -impl Write for ScreenManager { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.screen_manager.write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - self.screen_manager.flush() + /// Can be used to get an specific implementation used for the current platform. + pub fn as_any_mut(&mut self) -> &mut Any { + self.screen_manager.as_any_mut() } } diff --git a/src/manager/mod.rs b/src/manager/mod.rs index d52aa91..d97e720 100644 --- a/src/manager/mod.rs +++ b/src/manager/mod.rs @@ -39,14 +39,14 @@ pub trait IScreenManager { fn is_raw_screen(&self) -> bool; fn is_alternate_screen(&self) -> bool; - /// Write ansi code as String to the current stdout. - fn write_string(&mut self, string: String) -> io::Result; /// Write a &str to the current stdout. - fn write_str(&mut self, string: &str) -> io::Result; + fn write_str(&self, string: &str) -> io::Result; /// Write [u8] buffer to console. - fn write(&mut self, buf: &[u8]) -> io::Result; + fn write(&self, buf: &[u8]) -> io::Result; /// Flush the current output. - fn flush(&mut self) -> io::Result<()>; + fn flush(&self) -> io::Result<()>; /// Can be used to convert to an specific IScreenManager implementation. - fn as_any(&mut self) -> &mut Any; + fn as_any(&self) -> &Any; + /// Can be used to convert to an specific mutable IScreenManager implementation. + fn as_any_mut(&mut self) -> &mut Any; } diff --git a/src/manager/win_manager.rs b/src/manager/win_manager.rs index f24d311..c5a6ac8 100644 --- a/src/manager/win_manager.rs +++ b/src/manager/win_manager.rs @@ -15,7 +15,6 @@ pub struct WinApiScreenManager { } impl IScreenManager for WinApiScreenManager { - fn set_is_raw_screen(&mut self, value: bool) { self.is_raw_screen = value; } @@ -31,16 +30,11 @@ impl IScreenManager for WinApiScreenManager { self.is_alternate_screen } - - fn write_string(&mut self, string: String) -> io::Result { + fn write_str(&self, string: &str) -> io::Result { self.write(string.as_bytes()) } - fn write_str(&mut self, string: &str) -> io::Result { - self.write(string.as_bytes()) - } - - fn write(&mut self, buf: &[u8]) -> io::Result { + fn write(&self, buf: &[u8]) -> io::Result { if self.is_alternate_screen { writing::write_char_buffer(&self.alternate_handle, buf) } else { @@ -48,11 +42,15 @@ impl IScreenManager for WinApiScreenManager { } } - fn flush(&mut self) -> io::Result<()> { + fn flush(&self) -> io::Result<()> { Ok(()) } - fn as_any(&mut self) -> &mut Any { + fn as_any(&self) -> &Any { + self + } + + fn as_any_mut(&mut self) -> &mut Any { self } } @@ -76,7 +74,7 @@ impl WinApiScreenManager { } /// get the current screen handle. - pub fn get_handle(&mut self) -> &HANDLE { + pub fn get_handle(&self) -> &HANDLE { if self.is_alternate_screen { return &self.alternate_handle; } else { diff --git a/src/shared/Terminal.rs b/src/shared/Terminal.rs index a7d35fc..86df135 100644 --- a/src/shared/Terminal.rs +++ b/src/shared/Terminal.rs @@ -2,6 +2,12 @@ use {StateManager, ScreenManager}; use super::super::state::commands::*; use super::raw::RawTerminal; use super::screen::AlternateScreen; + +use super::super::cursor; +use super::super::input; +use super::super::terminal; + + use std::collections::HashMap; use std::io::Result; @@ -93,6 +99,18 @@ impl Terminal{ return Ok(()) } + + pub fn cursor(&self) -> cursor::TerminalCursor { + cursor::TerminalCursor::new(&self.active_screen) + } + + pub fn input(&self) -> input::TerminalInput { + return input::TerminalInput::new(&self.active_screen) + } + + pub fn terminal(&self) -> input::TerminalInput { + return input::TerminalInput::new(&self.active_screen) + } } impl Drop for Terminal diff --git a/src/shared/crossterm.rs b/src/shared/crossterm.rs index 2733176..fa640c4 100644 --- a/src/shared/crossterm.rs +++ b/src/shared/crossterm.rs @@ -1,183 +1,183 @@ -//! This module provides easy access to the functionalities of crossterm. -//! since `crossterm version 0.3.0` an `Context` type is introduced (check that documentation for more info why this type is introduced). -//! -//! You have to provide this `Context` to the modules: `cursor::cursor(), color::color(), terminal::terminal()`. -//! -//! use crossterm::Context; -//! use crossterm::cursor; -//! use crossterm::color; -//! use crossterm::terminal; -//! -//! let context = Context::new(); -//! let cursor = cursor::cursor(&context) -//! let terminal = terminal::terminal(&context); -//! let color = terminal::color(&context); -//! -//! Because it can seem a little odd to constantly create an Context and provide it to these modules. -//! You can better use `Crossterm` for accessing these modules. -//! `Crossterm` handles the Context internally so jo do not have to bother about it, for example: -//! -//! let crossterm = Crossterm::new(); -//! let color = crossterm.color(); -//! let cursor = crossterm.cursor(); -//! let terminal = crossterm.terminal(); - -use super::super::cursor; -use super::super::input::input; -use super::super::style; -use super::super::terminal::terminal; - -use Context; - -use std::convert::From; -use std::fmt::Display; -use std::mem; -use std::rc::Rc; -use std::sync::Arc; - -/// Because it can seem a little odd to constantly create an `Context` and provide it to modules like: `cursor, color and terminal`. -/// You can better use `Crossterm` for accessing these modules. -/// `Crossterm` handles the Context internally so jo do not have to bother about it, for example: -/// -/// Check `/examples/Crossterm 0.3.0/program_examples/first_depth_search` in the library for more specific examples. -/// -/// let crossterm = Crossterm::new(); -/// let color = crossterm.color(); -/// let cursor = crossterm.cursor(); -/// let terminal = crossterm.terminal(); +////! This module provides easy access to the functionalities of crossterm. +////! since `crossterm version 0.3.0` an `Context` type is introduced (check that documentation for more info why this type is introduced). +////! +////! You have to provide this `Context` to the modules: `cursor::cursor(), color::color(), terminal::terminal()`. +////! +////! use crossterm::Context; +////! use crossterm::cursor; +////! use crossterm::color; +////! use crossterm::terminal; +////! +////! let context = Context::new(); +////! let cursor = cursor::cursor(&context) +////! let terminal = terminal::terminal(&context); +////! let color = terminal::color(&context); +////! +////! Because it can seem a little odd to constantly create an Context and provide it to these modules. +////! You can better use `Crossterm` for accessing these modules. +////! `Crossterm` handles the Context internally so jo do not have to bother about it, for example: +////! +////! let crossterm = Crossterm::new(); +////! let color = crossterm.color(); +////! let cursor = crossterm.cursor(); +////! let terminal = crossterm.terminal(); +// +//use super::super::cursor; +//use super::super::input::input; +//use super::super::style; +//use super::super::terminal::terminal; +// +//use Context; +// +//use std::convert::From; +//use std::fmt::Display; +//use std::mem; +//use std::rc::Rc; +//use std::sync::Arc; +// +///// Because it can seem a little odd to constantly create an `Context` and provide it to modules like: `cursor, color and terminal`. +///// You can better use `Crossterm` for accessing these modules. +///// `Crossterm` handles the Context internally so jo do not have to bother about it, for example: +///// +///// Check `/examples/Crossterm 0.3.0/program_examples/first_depth_search` in the library for more specific examples. +///// +///// let crossterm = Crossterm::new(); +///// let color = crossterm.color(); +///// let cursor = crossterm.cursor(); +///// let terminal = crossterm.terminal(); pub struct Crossterm { - context: Rc, -} - -/// Create `Crossterm` instance from `Context` -impl From> for Crossterm { - fn from(context: Rc) -> Self { - return Crossterm { context: context }; - } -} - -impl Crossterm { - pub fn new() -> Crossterm { - return Crossterm { - context: Context::new(), - }; - } - - /// Get an Terminal implementation whereon terminal related actions can be performed. - /// - /// #Example - /// - /// ```rust - /// - /// extern crate crossterm; - /// use crossterm::Crossterm; - /// use crossterm::terminal; - /// - /// let crossterm = Crossterm::new(); - /// let mut terminal = crossterm.terminal(); - /// - /// ``` - pub fn terminal(&self) -> terminal::Terminal { - return terminal::Terminal::new(self.context.clone()); - } - - /// Get an TerminalCursor implementation whereon cursor related actions can be performed. - /// - /// #Example - /// - /// ```rust - /// - /// extern crate crossterm; - /// use crossterm::Crossterm; - /// use crossterm::terminal; - /// - /// let crossterm = Crossterm::new(); - /// let mut cursor = crossterm.cursor(); - /// - /// // move cursor to x: 5 and y:10 - /// cursor.goto(5,10); - /// - /// ``` - pub fn cursor(&self) -> cursor::TerminalCursor { - return cursor::TerminalCursor::new(self.context.clone()); - } - - /// Get an Color implementation whereon color related actions can be performed. - /// - /// Check `/examples/version/color` in the library for more specific examples. - /// - /// #Example - /// - /// ```rust - /// - /// extern crate crossterm; - /// use crossterm::Crossterm; - /// use crossterm::terminal; - /// - /// let crossterm = Crossterm::new(); - /// let mut terminal_color = crossterm.color(); - /// - /// ``` - pub fn color(&self) -> style::TerminalColor { - return style::TerminalColor::new(self.context.clone()); - } - - pub fn input(&self) -> input::TerminalInput { - return input::TerminalInput::new(self.context.clone()); - } - - /// Wraps an displayable object so it can be formatted with colors and attributes. - /// - /// Check `/examples/color` in the library for more specific examples. - /// - /// #Example - /// - /// ```rust - /// extern crate crossterm; - /// - /// use self::crossterm::style::{paint,Color}; - /// use self::crossterm::Crossterm; - /// - /// fn main() - /// { - /// let crossterm = Crossterm::new(); - /// // Create an styledobject object from the text 'Unstyled font' - /// // Currently it has the default foreground color and background color. - /// println!("{}",crossterm.paint("Unstyled font")); - /// - /// // Create an displayable object from the text 'Colored font', - /// // Paint this with the `Red` foreground color and `Blue` background color. - /// // Print the result. - /// let styledobject = crossterm.paint("Colored font").with(Color::Red).on(Color::Blue); - /// println!("{}", styledobject); - /// - /// // Or all in one line - /// println!("{}", crossterm.paint("Colored font").with(Color::Red).on(Color::Blue)); - /// } - /// ``` - pub fn paint<'a, D: Display>(&'a self, value: D) -> style::StyledObject { - self.terminal().paint(value) - } - - /// Write any displayable value to the current screen weather it will be the main screen or alternate screen. - /// - /// #Example - /// - /// ```rust - /// - /// extern crate crossterm; - /// use crossterm::Crossterm; - /// - /// let mut crossterm = Crossterm::new(); - /// crossterm.write("Some text \n Some text on new line."); - /// - /// ``` - pub fn write(&self, value: D) { - self.terminal().write(value) - } - - /// Get an copy of the context that `Crossterm` uses internally. - pub fn context(&self) -> Rc { - self.context.clone() - } +// context: Rc, } +// +///// Create `Crossterm` instance from `Context` +//impl From> for Crossterm { +// fn from(context: Rc) -> Self { +// return Crossterm { context: context }; +// } +//} +// +//impl Crossterm { +// pub fn new() -> Crossterm { +// return Crossterm { +// context: Context::new(), +// }; +// } +// +// /// Get an Terminal implementation whereon terminal related actions can be performed. +// /// +// /// #Example +// /// +// /// ```rust +// /// +// /// extern crate crossterm; +// /// use crossterm::Crossterm; +// /// use crossterm::terminal; +// /// +// /// let crossterm = Crossterm::new(); +// /// let mut terminal = crossterm.terminal(); +// /// +// /// ``` +// pub fn terminal(&self) -> terminal::Terminal { +// return terminal::Terminal::new(self.context.clone()); +// } +// +// /// Get an TerminalCursor implementation whereon cursor related actions can be performed. +// /// +// /// #Example +// /// +// /// ```rust +// /// +// /// extern crate crossterm; +// /// use crossterm::Crossterm; +// /// use crossterm::terminal; +// /// +// /// let crossterm = Crossterm::new(); +// /// let mut cursor = crossterm.cursor(); +// /// +// /// // move cursor to x: 5 and y:10 +// /// cursor.goto(5,10); +// /// +// /// ``` +// pub fn cursor(&self) -> cursor::TerminalCursor { +// return cursor::TerminalCursor::new(self.context.clone()); +// } +// +// /// Get an Color implementation whereon color related actions can be performed. +// /// +// /// Check `/examples/version/color` in the library for more specific examples. +// /// +// /// #Example +// /// +// /// ```rust +// /// +// /// extern crate crossterm; +// /// use crossterm::Crossterm; +// /// use crossterm::terminal; +// /// +// /// let crossterm = Crossterm::new(); +// /// let mut terminal_color = crossterm.color(); +// /// +// /// ``` +// pub fn color(&self) -> style::TerminalColor { +// return style::TerminalColor::new(self.context.clone()); +// } +// +// pub fn input(&self) -> input::TerminalInput { +// return input::TerminalInput::new(self.context.clone()); +// } +// +// /// Wraps an displayable object so it can be formatted with colors and attributes. +// /// +// /// Check `/examples/color` in the library for more specific examples. +// /// +// /// #Example +// /// +// /// ```rust +// /// extern crate crossterm; +// /// +// /// use self::crossterm::style::{paint,Color}; +// /// use self::crossterm::Crossterm; +// /// +// /// fn main() +// /// { +// /// let crossterm = Crossterm::new(); +// /// // Create an styledobject object from the text 'Unstyled font' +// /// // Currently it has the default foreground color and background color. +// /// println!("{}",crossterm.paint("Unstyled font")); +// /// +// /// // Create an displayable object from the text 'Colored font', +// /// // Paint this with the `Red` foreground color and `Blue` background color. +// /// // Print the result. +// /// let styledobject = crossterm.paint("Colored font").with(Color::Red).on(Color::Blue); +// /// println!("{}", styledobject); +// /// +// /// // Or all in one line +// /// println!("{}", crossterm.paint("Colored font").with(Color::Red).on(Color::Blue)); +// /// } +// /// ``` +// pub fn paint<'a, D: Display>(&'a self, value: D) -> style::StyledObject { +// self.terminal().paint(value) +// } +// +// /// Write any displayable value to the current screen weather it will be the main screen or alternate screen. +// /// +// /// #Example +// /// +// /// ```rust +// /// +// /// extern crate crossterm; +// /// use crossterm::Crossterm; +// /// +// /// let mut crossterm = Crossterm::new(); +// /// crossterm.write("Some text \n Some text on new line."); +// /// +// /// ``` +// pub fn write(&self, value: D) { +// self.terminal().write(value) +// } +// +// /// Get an copy of the context that `Crossterm` uses internally. +// pub fn context(&self) -> Rc { +// self.context.clone() +// } +//} diff --git a/src/shared/functions.rs b/src/shared/functions.rs index a54e97c..c8bff18 100644 --- a/src/shared/functions.rs +++ b/src/shared/functions.rs @@ -15,7 +15,7 @@ use kernel::windows_kernel::cursor::{pos, absolute_cursor_pos}; use kernel::unix_kernel::terminal::{exit, pos, terminal_size}; /// Get the terminal size based on the current platform. -pub fn get_terminal_size(screen_manager: &Rc>) -> (u16, u16) { +pub fn get_terminal_size(screen_manager: &ScreenManager) -> (u16, u16) { #[cfg(unix)] return terminal_size(); @@ -24,12 +24,12 @@ pub fn get_terminal_size(screen_manager: &Rc>) -> (u16, u16 } /// Get the cursor position based on the current platform. -pub fn get_cursor_position(context: Rc) -> (u16, u16) { +pub fn get_cursor_position(screen_manager: &ScreenManager) -> (u16, u16) { #[cfg(unix)] - return pos(context.clone()); + return pos(screen_manager); #[cfg(windows)] - return pos(&context.screen_manager); + return pos(screen_manager); } /// exit the current terminal. diff --git a/src/state/commands/win_commands.rs b/src/state/commands/win_commands.rs index 3111a25..4cbf8d0 100644 --- a/src/state/commands/win_commands.rs +++ b/src/state/commands/win_commands.rs @@ -147,16 +147,13 @@ impl IAlternateScreenCommand for ToAlternateScreenBufferCommand { // Make the new screen buffer the active screen buffer. csbi::set_active_screen_buffer(new_handle)?; - let b: &mut WinApiScreenManager = match screen_manager - .as_any() + match screen_manager + .as_any_mut() .downcast_mut::() { - Some(b) => b, + Some(b) => b.set_alternate_handle(new_handle), None => return Err(Error::new(ErrorKind::Other,"Invalid cast exception")), }; - - b.set_alternate_handle(new_handle); - Ok(()) }