maked crossterm sendable for threads
This commit is contained in:
parent
14ecd33f11
commit
406f2046f9
@ -22,13 +22,13 @@ pub trait IEnableAnsiCommand {
|
|||||||
fn disable(&mut self) -> bool;
|
fn disable(&mut self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This trait provides an interface for switching to alternate screen and back.
|
// This trait provides an interface for switching to alternate screen and back.
|
||||||
/*pub trait IAlternateScreenCommand: Send{
|
pub trait IAlternateScreenCommand: Send {
|
||||||
fn enable(&self, screen_manager: &mut ScreenManager) -> Result<()>;
|
fn enable(&self, screen_manager: &mut ScreenManager) -> Result<()>;
|
||||||
fn disable(&self, screen_manager: &mut ScreenManager) -> Result<()>;
|
fn disable(&self, screen_manager: &mut ScreenManager) -> Result<()>;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
/// This trait provides an interface for switching to raw mode and back.
|
// This trait provides an interface for switching to raw mode and back.
|
||||||
/*pub trait IRawScreenCommand: Send{
|
/*pub trait IRawScreenCommand: Send{
|
||||||
fn enable(&mut self) -> Result<()>;
|
fn enable(&mut self) -> Result<()>;
|
||||||
fn disable(&mut self) -> Result<()>;
|
fn disable(&mut self) -> Result<()>;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! This module contains the commands that can be used for unix systems.
|
//! This module contains the commands that can be used for unix systems.
|
||||||
|
|
||||||
use super::{IRawScreenCommand, IStateCommand};
|
use super::{ IStateCommand};
|
||||||
use kernel::unix_kernel::terminal;
|
use kernel::unix_kernel::terminal;
|
||||||
use termios::{tcsetattr, Termios, CREAD, ECHO, ICANON, TCSAFLUSH};
|
use termios::{tcsetattr, Termios, CREAD, ECHO, ICANON, TCSAFLUSH};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! This module contains the commands that can be used for windows systems.
|
//! This module contains the commands that can be used for windows systems.
|
||||||
|
|
||||||
use super::{IAlternateScreenCommand, IEnableAnsiCommand, IRawScreenCommand, ScreenManager};
|
use super::{IAlternateScreenCommand, IEnableAnsiCommand, ScreenManager};
|
||||||
|
|
||||||
use kernel::windows_kernel::{ansi_support, csbi, handle, kernel};
|
use kernel::windows_kernel::{ansi_support, csbi, handle, kernel};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use super::commands::{IAlternateScreenCommand, IRawScreenCommand};
|
use super::commands::{IAlternateScreenCommand};
|
||||||
|
|
||||||
use super::screen::AlternateScreen;
|
use super::screen::AlternateScreen;
|
||||||
use super::screen::RawScreen;
|
|
||||||
|
|
||||||
use super::super::cursor;
|
use super::super::cursor;
|
||||||
use super::super::input;
|
use super::super::input;
|
||||||
@ -14,12 +13,23 @@ use std::io::Write;
|
|||||||
|
|
||||||
use std::io::Result;
|
use std::io::Result;
|
||||||
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
use common::commands::unix_command;
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
use common::commands::win_commands;
|
||||||
|
|
||||||
pub struct Crossterm {
|
pub struct Crossterm {
|
||||||
pub active_screen: manager::ScreenManager,
|
pub active_screen: manager::ScreenManager,
|
||||||
raw_terminal: Option<RawScreenCommand>,
|
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
raw_terminal: Option<unix_command::RawModeCommand>,
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
raw_terminal: Option<win_commands::RawModeCommand>,
|
||||||
// Would be cool to figure out a way to have multiple screens instead of just only the main and alternate screen.
|
// Would be cool to figure out a way to have multiple screens instead of just only the main and alternate screen.
|
||||||
// For windows this would be easy but for unix I have no idea.
|
// For windows this would be easy but for unix I have no idea.
|
||||||
alternate_screen: Option<AlternateScreenCommand>,
|
alternate_screen: Option<Box<IAlternateScreenCommand + Send>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Crossterm {
|
impl<'a> Crossterm {
|
||||||
@ -34,7 +44,13 @@ impl<'a> Crossterm {
|
|||||||
pub fn enable_raw_mode(&mut self) -> Result<()> {
|
pub fn enable_raw_mode(&mut self) -> Result<()> {
|
||||||
match self.raw_terminal {
|
match self.raw_terminal {
|
||||||
None => {
|
None => {
|
||||||
self.raw_terminal = Some(RawScreen::new());
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
let raw_terminal = Some(unix_command::RawModeCommand::new());
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
let raw_terminal = Some(win_commands::RawModeCommand::new());
|
||||||
|
|
||||||
|
self.raw_terminal = raw_terminal;
|
||||||
|
|
||||||
return self.enable_raw_mode();
|
return self.enable_raw_mode();
|
||||||
}
|
}
|
||||||
Some(ref mut raw_terminal) => {
|
Some(ref mut raw_terminal) => {
|
||||||
@ -48,7 +64,13 @@ impl<'a> Crossterm {
|
|||||||
pub fn disable_raw_mode(&mut self) -> Result<()> {
|
pub fn disable_raw_mode(&mut self) -> Result<()> {
|
||||||
match self.raw_terminal {
|
match self.raw_terminal {
|
||||||
None => {
|
None => {
|
||||||
self.raw_terminal = Some(RawScreen::new());
|
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
let raw_terminal = Some(unix_command::RawModeCommand::new());
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
let raw_terminal = Some(win_commands::RawModeCommand::new());
|
||||||
|
|
||||||
|
self.raw_terminal = raw_terminal;
|
||||||
return self.disable_raw_mode();
|
return self.disable_raw_mode();
|
||||||
}
|
}
|
||||||
Some(ref mut raw_terminal) => {
|
Some(ref mut raw_terminal) => {
|
||||||
|
@ -32,9 +32,9 @@ pub struct AlternateScreen;
|
|||||||
|
|
||||||
impl AlternateScreen {
|
impl AlternateScreen {
|
||||||
/// Create an new alternate screen type.
|
/// Create an new alternate screen type.
|
||||||
pub fn new() -> Box<commands::IAlternateScreenCommand> {
|
pub fn new() -> Box<commands::IAlternateScreenCommand + Send> {
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
let command = functions::get_module::<Box<commands::IAlternateScreenCommand>>(
|
let command = functions::get_module::<Box<commands::IAlternateScreenCommand + Send>>(
|
||||||
Box::from(commands::win_commands::ToAlternateScreenCommand::new()),
|
Box::from(commands::win_commands::ToAlternateScreenCommand::new()),
|
||||||
Box::from(commands::shared_commands::ToAlternateScreenCommand::new()),
|
Box::from(commands::shared_commands::ToAlternateScreenCommand::new()),
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
@ -6,4 +6,4 @@ mod raw;
|
|||||||
use super::{commands, functions, ScreenManager};
|
use super::{commands, functions, ScreenManager};
|
||||||
|
|
||||||
pub use self::alternate::AlternateScreen;
|
pub use self::alternate::AlternateScreen;
|
||||||
pub use self::raw::RawScreen;
|
//pub use self::raw::RawScreen;
|
||||||
|
@ -12,28 +12,23 @@
|
|||||||
//!
|
//!
|
||||||
//! With these modes you can easier design the terminal screen.
|
//! With these modes you can easier design the terminal screen.
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
//
|
||||||
use common::commands::unix_command::EnableRawModeCommand;
|
//use super::commands;
|
||||||
|
//use super::{functions, ScreenManager};
|
||||||
#[cfg(windows)]
|
//
|
||||||
use common::commands::win_commands::EnableRawModeCommand;
|
//use std::io::{self, Write};
|
||||||
|
//
|
||||||
use super::commands;
|
///// A wrapper for the raw terminal state. Which can be used to write to.
|
||||||
use super::{functions, ScreenManager};
|
//pub struct RawScreen;
|
||||||
|
//
|
||||||
use std::io::{self, Write};
|
//impl RawScreen {
|
||||||
|
// /// Create a new RawScreen type.
|
||||||
/// A wrapper for the raw terminal state. Which can be used to write to.
|
// pub fn new() -> Box<commands::IRawScreenCommand> {
|
||||||
pub struct RawScreen;
|
// Box::from(EnableRawModeCommand::new())
|
||||||
|
|
||||||
impl RawScreen {
|
|
||||||
/// Create a new RawScreen type.
|
|
||||||
pub fn new() -> Box<commands::IRawScreenCommand> {
|
|
||||||
Box::from(EnableRawModeCommand::new())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///// Trait withs contains a method for switching into raw mode.
|
|
||||||
//pub trait IntoRawMode: Write + Sized {
|
|
||||||
// fn into_raw_mode(&self, context: Rc<Context>) -> io::Result<RawTerminal>;
|
|
||||||
// }
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
/////// Trait withs contains a method for switching into raw mode.
|
||||||
|
////pub trait IntoRawMode: Write + Sized {
|
||||||
|
//// fn into_raw_mode(&self, context: Rc<Context>) -> io::Result<RawTerminal>;
|
||||||
|
////}
|
||||||
|
@ -4,11 +4,9 @@ use winapi::um::handleapi::INVALID_HANDLE_VALUE;
|
|||||||
use winapi::um::processenv::GetStdHandle;
|
use winapi::um::processenv::GetStdHandle;
|
||||||
use winapi::um::winbase::{STD_INPUT_HANDLE, STD_OUTPUT_HANDLE};
|
use winapi::um::winbase::{STD_INPUT_HANDLE, STD_OUTPUT_HANDLE};
|
||||||
use winapi::um::winnt::HANDLE;
|
use winapi::um::winnt::HANDLE;
|
||||||
|
use std::sync::Arc;
|
||||||
use super::super::super::manager::{ScreenManager, WinApiScreenManager};
|
use super::super::super::manager::{ScreenManager, WinApiScreenManager};
|
||||||
|
|
||||||
use std::io::{self, ErrorKind, Result};
|
|
||||||
|
|
||||||
/// Get the global stored handle whits provides access to the current screen.
|
/// Get the global stored handle whits provides access to the current screen.
|
||||||
pub fn get_current_handle(screen_manager: &ScreenManager) -> Result<HANDLE> {
|
pub fn get_current_handle(screen_manager: &ScreenManager) -> Result<HANDLE> {
|
||||||
let mut mutex = screen_manager;
|
let mut mutex = screen_manager;
|
||||||
@ -23,11 +21,14 @@ pub fn get_current_handle(screen_manager: &ScreenManager) -> Result<HANDLE> {
|
|||||||
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'"))
|
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;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use std::io::{self, ErrorKind, Result};
|
||||||
|
|
||||||
/// Get the std_output_handle of the console
|
/// Get the std_output_handle of the console
|
||||||
pub fn get_output_handle() -> Result<HANDLE> {
|
pub fn get_output_handle() -> Result<HANDLE> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -6,14 +6,15 @@ use super::IScreenManager;
|
|||||||
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::io::{self, Read, Write};
|
use std::sync::{Arc,Mutex};
|
||||||
|
use std::io::{self, Read, Write,Stdout};
|
||||||
use std::str::from_utf8;
|
use std::str::from_utf8;
|
||||||
|
|
||||||
/// This struct is an ANSI escape code implementation for screen related actions.
|
/// This struct is an ANSI escape code implementation for screen related actions.
|
||||||
pub struct AnsiScreenManager {
|
pub struct AnsiScreenManager {
|
||||||
is_alternate_screen: bool,
|
is_alternate_screen: bool,
|
||||||
is_raw_screen: bool,
|
is_raw_screen: bool,
|
||||||
output: RefCell<Box<Write>>,
|
output: Box<Stdout>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IScreenManager for AnsiScreenManager {
|
impl IScreenManager for AnsiScreenManager {
|
||||||
@ -34,22 +35,27 @@ impl IScreenManager for AnsiScreenManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn write_str(&self, string: &str) -> io::Result<usize> {
|
fn write_str(&self, string: &str) -> io::Result<usize> {
|
||||||
let mut output = self.output.borrow_mut();
|
let out = &self.output;
|
||||||
write!(output, "{}", string)?;
|
let mut handle = out.lock();
|
||||||
|
write!(handle, "{}", string)?;
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||||
{
|
{
|
||||||
let mut output = self.output.borrow_mut();
|
let out = &self.output;
|
||||||
output.write(buf)?;
|
let mut handle = out.lock();
|
||||||
|
handle.write(buf)?;
|
||||||
}
|
}
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&self) -> io::Result<()> {
|
fn flush(&self) -> io::Result<()> {
|
||||||
let mut output = self.output.borrow_mut();
|
let out = &self.output;
|
||||||
output.flush()
|
let mut handle = out.lock();
|
||||||
|
handle.flush();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_any(&self) -> &Any {
|
fn as_any(&self) -> &Any {
|
||||||
@ -64,7 +70,7 @@ impl IScreenManager for AnsiScreenManager {
|
|||||||
impl AnsiScreenManager {
|
impl AnsiScreenManager {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
AnsiScreenManager {
|
AnsiScreenManager {
|
||||||
output: RefCell::new(Box::from(io::stdout()) as Box<Write>),
|
output: Box::from(io::stdout()),
|
||||||
is_alternate_screen: false,
|
is_alternate_screen: false,
|
||||||
is_raw_screen: false,
|
is_raw_screen: false,
|
||||||
}
|
}
|
||||||
|
@ -36,13 +36,13 @@ impl ScreenManager {
|
|||||||
/// Create new screen manager instance whereon screen related actions can be performed.
|
/// Create new screen manager instance whereon screen related actions can be performed.
|
||||||
pub fn new() -> ScreenManager {
|
pub fn new() -> ScreenManager {
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
let screen_manager = functions::get_module::<Box<IScreenManager>>(
|
let screen_manager = functions::get_module::<Box<IScreenManager + Send>>(
|
||||||
Box::from(WinApiScreenManager::new()),
|
Box::from(WinApiScreenManager::new()),
|
||||||
Box::from(AnsiScreenManager::new()),
|
Box::from(AnsiScreenManager::new()),
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
let screen_manager = Box::from(AnsiScreenManager::new()) as Box<IScreenManager>;
|
let screen_manager = Box::from(AnsiScreenManager::new()) as Box<IScreenManager + Send>;
|
||||||
|
|
||||||
ScreenManager { screen_manager }
|
ScreenManager { screen_manager }
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,10 @@ use kernel::windows_kernel::{handle, kernel, writing};
|
|||||||
use winapi::um::wincon::ENABLE_PROCESSED_OUTPUT;
|
use winapi::um::wincon::ENABLE_PROCESSED_OUTPUT;
|
||||||
use winapi::um::winnt::HANDLE;
|
use winapi::um::winnt::HANDLE;
|
||||||
|
|
||||||
|
use std::ptr::NonNull;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// This struct is an WINAPI implementation for screen related actions.
|
/// This struct is an WINAPI implementation for screen related actions.
|
||||||
pub struct WinApiScreenManager {
|
pub struct WinApiScreenManager {
|
||||||
@ -59,11 +61,12 @@ impl IScreenManager for WinApiScreenManager {
|
|||||||
impl WinApiScreenManager {
|
impl WinApiScreenManager {
|
||||||
/// Create a new instance.
|
/// Create a new instance.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
|
||||||
WinApiScreenManager {
|
WinApiScreenManager {
|
||||||
output: handle::get_output_handle().unwrap(),
|
output: handle::get_output_handle().unwrap(),
|
||||||
|
alternate_handle: handle::get_output_handle().unwrap(),
|
||||||
is_alternate_screen: false,
|
is_alternate_screen: false,
|
||||||
is_raw_screen: false,
|
is_raw_screen: false,
|
||||||
alternate_handle: handle::get_output_handle().unwrap(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,3 +86,5 @@ impl WinApiScreenManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for WinApiScreenManager {}
|
||||||
|
@ -66,8 +66,8 @@ impl<'terminal> Terminal<'terminal> {
|
|||||||
/// term.clear(terminal::ClearType::UntilNewLine);
|
/// term.clear(terminal::ClearType::UntilNewLine);
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
pub fn clear(&self, clear_type: ClearType) {
|
pub fn clear(&mut self, clear_type: ClearType) {
|
||||||
self.terminal.clear(clear_type, &self.screen_manager);
|
self.terminal.clear(clear_type, &mut self.screen_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the terminal size (x,y).
|
/// Get the terminal size (x,y).
|
||||||
|
Loading…
Reference in New Issue
Block a user