Added Sync markers
This commit is contained in:
parent
b98f549a73
commit
c848beb721
@ -12,7 +12,7 @@ readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = { version = "0.3.5", features = ["winbase","winuser","consoleapi","processenv","wincon", "handleapi"] }
|
||||
winapi = { version = "0.3.5", features = ["winbase","winuser","consoleapi","processenv","wincon", "handleapi","errhandlingapi"] }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc = "0.2.37"
|
||||
|
@ -16,18 +16,22 @@ mod some_types;
|
||||
mod input;
|
||||
|
||||
use std::io::Write;
|
||||
|
||||
use std::{thread,time};
|
||||
fn main()
|
||||
{
|
||||
// use crossterm::screen::RawScreen;
|
||||
// use crossterm::Screen;
|
||||
//
|
||||
// let mut screen = Screen::new(true);
|
||||
//
|
||||
use crossterm::screen::RawScreen;
|
||||
use crossterm::Screen;
|
||||
|
||||
let mut screen = Screen::new(true);
|
||||
|
||||
cursor::goto();
|
||||
|
||||
// write!(screen, "text \n\r");
|
||||
// let a = screen.enable_alternate_modes(true).unwrap();
|
||||
let a = screen.enable_alternate_modes(true).unwrap();
|
||||
// cursor::goto();
|
||||
thread::sleep(time::Duration::from_millis(2000));
|
||||
drop(a);
|
||||
cursor::goto();
|
||||
//
|
||||
// write!(a, "text \n\r");
|
||||
|
||||
|
||||
}
|
||||
|
@ -23,13 +23,13 @@ pub trait IEnableAnsiCommand {
|
||||
}
|
||||
|
||||
// This trait provides an interface for switching to alternate screen and back.
|
||||
pub trait IAlternateScreenCommand: Send {
|
||||
pub trait IAlternateScreenCommand: Sync + Send {
|
||||
fn enable(&self, stdout: &mut TerminalOutput) -> io::Result<()>;
|
||||
fn disable(&self, stdout: &TerminalOutput) -> io::Result<()>;
|
||||
}
|
||||
|
||||
// This trait provides an interface for switching to raw mode and back.
|
||||
pub trait IRawScreenCommand: Send{
|
||||
pub trait IRawScreenCommand: Sync + Send{
|
||||
fn enable(&mut self) -> io::Result<()>;
|
||||
fn disable(&self) -> io::Result<()>;
|
||||
}
|
||||
|
@ -87,9 +87,8 @@ impl RawModeCommand
|
||||
impl RawModeCommand {
|
||||
/// Enables raw mode.
|
||||
pub fn enable(&mut self) -> Result<()> {
|
||||
|
||||
let mut dw_mode: DWORD = 0;
|
||||
let stdout = handle::get_output_handle().unwrap();
|
||||
let stdout = handle::get_current_handle_1().unwrap();
|
||||
|
||||
if !kernel::get_console_mode(&stdout, &mut dw_mode) {
|
||||
return Err(Error::new(
|
||||
@ -112,7 +111,7 @@ impl RawModeCommand {
|
||||
|
||||
/// Disables raw mode.
|
||||
pub fn disable(&self) -> Result<()> {
|
||||
let stdout = handle::get_output_handle().unwrap();
|
||||
let stdout = handle::get_current_handle_1().unwrap();
|
||||
|
||||
let mut dw_mode: DWORD = 0;
|
||||
if !kernel::get_console_mode(&stdout, &mut dw_mode) {
|
||||
|
@ -41,10 +41,10 @@ pub fn get_module<T>(winapi_impl: T, unix_impl: T) -> Option<T> {
|
||||
if !windows_supportable()
|
||||
{
|
||||
// Try to enable ansi on windows if not than use WINAPI.
|
||||
does_support = try_enable_ansi_support();
|
||||
// does_support = try_enable_ansi_support();
|
||||
|
||||
// uncomment this line when you want to use the winapi implementation.
|
||||
does_support = true;
|
||||
does_support = false;
|
||||
if !does_support {
|
||||
term = Some(winapi_impl);
|
||||
}
|
||||
|
@ -15,14 +15,14 @@ use std::convert::From;
|
||||
/// With this type you will be able to switch to alternate screen and back to main screen.
|
||||
pub struct AlternateScreen
|
||||
{
|
||||
command: Box<IAlternateScreenCommand + Send>,
|
||||
command: Box<IAlternateScreenCommand + Sync + Send>,
|
||||
pub screen: Screen,
|
||||
}
|
||||
|
||||
impl AlternateScreen {
|
||||
|
||||
/// Create new instance of alternate screen.
|
||||
pub fn new(command: Box<IAlternateScreenCommand + Send>, screen: Screen) -> Self
|
||||
pub fn new(command: Box<IAlternateScreenCommand + Sync + Send>, screen: Screen) -> Self
|
||||
{
|
||||
return AlternateScreen { command, screen }
|
||||
}
|
||||
@ -37,7 +37,7 @@ impl AlternateScreen {
|
||||
pub fn to_alternate_screen(stdout: TerminalOutput, raw_mode: bool) -> io::Result<AlternateScreen> {
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let command = functions::get_module::<Box<commands::IAlternateScreenCommand + Send>>(
|
||||
let command = functions::get_module::<Box<commands::IAlternateScreenCommand + Sync + Send>>(
|
||||
Box::from(commands::win_commands::ToAlternateScreenCommand::new()),
|
||||
Box::from(commands::shared_commands::ToAlternateScreenCommand::new()),
|
||||
).unwrap();
|
||||
|
@ -3,27 +3,76 @@
|
||||
use winapi::um::handleapi::INVALID_HANDLE_VALUE;
|
||||
use winapi::um::processenv::GetStdHandle;
|
||||
use winapi::um::winbase::{STD_INPUT_HANDLE, STD_OUTPUT_HANDLE};
|
||||
use winapi::um::winnt::{GENERIC_READ, GENERIC_WRITE, GENERIC_ALL, FILE_SHARE_WRITE};
|
||||
use winapi::um::fileapi::{OPEN_EXISTING, CreateFileW};
|
||||
use winapi::shared::minwindef::DWORD;
|
||||
use winapi::um::errhandlingapi::GetLastError;
|
||||
use super::*;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::io::{self, Result};
|
||||
use std::ptr::null_mut;
|
||||
|
||||
use winapi::ctypes::c_void;
|
||||
|
||||
/// Get the global stored handle whits provides access to the current screen.
|
||||
pub fn get_current_handle(stdout: &Arc<TerminalOutput>) -> Result<HANDLE> {
|
||||
let handle: Result<HANDLE>;
|
||||
// let handle: Result<HANDLE>;
|
||||
//
|
||||
// let winapi_stdout: &WinApiOutput = match stdout
|
||||
// .as_any()
|
||||
// .downcast_ref::<WinApiOutput>()
|
||||
// {
|
||||
// Some(win_api) => win_api,
|
||||
// None => return Err(io::Error::new(io::ErrorKind::Other,"Could not convert to winapi screen write, this could happen when the user has an ANSI screen write and is calling the platform specific operations 'get_cursor_pos' or 'get_terminal_size'"))
|
||||
// };
|
||||
|
||||
let winapi_stdout: &WinApiOutput = match stdout
|
||||
.as_any()
|
||||
.downcast_ref::<WinApiOutput>()
|
||||
let dw: DWORD = 0;
|
||||
unsafe {
|
||||
|
||||
let utf16: Vec<u16> = "CONOUT$".encode_utf16().collect();
|
||||
let utf16_ptr: *const u16 = utf16.as_ptr();
|
||||
|
||||
let handle = CreateFileW(utf16_ptr, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, null_mut(), OPEN_EXISTING, dw, null_mut());
|
||||
|
||||
if !is_valid_handle(&handle) {
|
||||
|
||||
unsafe
|
||||
{
|
||||
Some(win_api) => win_api,
|
||||
None => return Err(io::Error::new(io::ErrorKind::Other,"Could not convert to winapi screen write, this could happen when the user has an ANSI screen write and is calling the platform specific operations 'get_cursor_pos' or 'get_terminal_size'"))
|
||||
};
|
||||
let error = GetLastError();
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("Could not get output handle current handle!, error code: {}", error).as_ref(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(handle)
|
||||
}
|
||||
}
|
||||
|
||||
handle = Ok(winapi_stdout.get_handle());
|
||||
pub fn get_current_handle_1() -> Result<HANDLE>
|
||||
{
|
||||
let handle: Result<HANDLE>;
|
||||
use std::str;
|
||||
unsafe
|
||||
{
|
||||
let dw: DWORD = 0;
|
||||
|
||||
return handle;
|
||||
let utf16: Vec<u16> = "CONOUT$".encode_utf16().collect();
|
||||
let utf16_ptr: *const u16 = utf16.as_ptr();
|
||||
|
||||
let handle = CreateFileW(utf16_ptr, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, null_mut(), OPEN_EXISTING,dw, null_mut());
|
||||
|
||||
if !is_valid_handle(&handle) {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"Could not get output handle 1 !",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(handle)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the std_output_handle of the console
|
||||
|
@ -28,7 +28,7 @@ use Screen;
|
||||
/// ```
|
||||
pub struct TerminalCursor<'stdout> {
|
||||
screen: &'stdout Arc<TerminalOutput>,
|
||||
terminal_cursor: Box<ITerminalCursor>,
|
||||
terminal_cursor: Box<ITerminalCursor + Sync + Send>,
|
||||
}
|
||||
|
||||
impl<'stdout> TerminalCursor<'stdout> {
|
||||
@ -36,11 +36,11 @@ impl<'stdout> TerminalCursor<'stdout> {
|
||||
pub fn new(screen: &'stdout Arc<TerminalOutput>) -> TerminalCursor<'stdout> {
|
||||
#[cfg(target_os = "windows")]
|
||||
let cursor =
|
||||
functions::get_module::<Box<ITerminalCursor>>(WinApiCursor::new(), AnsiCursor::new())
|
||||
functions::get_module::<Box<ITerminalCursor + Sync + Send>>(WinApiCursor::new(), AnsiCursor::new())
|
||||
.unwrap();
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let cursor = AnsiCursor::new() as Box<ITerminalCursor>;
|
||||
let cursor = AnsiCursor::new() as Box<ITerminalCursor + Sync + Send>;
|
||||
|
||||
TerminalCursor {
|
||||
terminal_cursor: cursor,
|
||||
|
@ -25,7 +25,7 @@ use std::sync::Arc;
|
||||
///!
|
||||
///! This trait is implemented for `WINAPI` (Windows specific) and `ANSI` (Unix specific),
|
||||
///! so that cursor related actions can be preformed on both unix and windows systems.
|
||||
trait ITerminalCursor {
|
||||
trait ITerminalCursor : Sync + Send {
|
||||
/// Goto some location (x,y) in the context.
|
||||
fn goto(&self, x: u16, y: u16, stdout: &Arc<TerminalOutput>);
|
||||
/// Get the location (x,y) of the current cusror in the context
|
||||
|
@ -20,7 +20,7 @@ use Screen;
|
||||
///
|
||||
/// ```
|
||||
pub struct TerminalInput<'stdout> {
|
||||
terminal_input: Box<ITerminalInput>,
|
||||
terminal_input: Box<ITerminalInput + Sync + Send>,
|
||||
stdout: &'stdout Arc<TerminalOutput>,
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ use Screen;
|
||||
/// colored_terminal.reset();
|
||||
/// ```
|
||||
pub struct TerminalColor<'stdout> {
|
||||
color: Box<ITerminalColor>,
|
||||
color: Box<ITerminalColor + Sync + Send>,
|
||||
stdout: &'stdout Arc<TerminalOutput>,
|
||||
}
|
||||
|
||||
@ -35,13 +35,13 @@ impl<'stdout> TerminalColor<'stdout> {
|
||||
/// Create new instance whereon color related actions can be performed.
|
||||
pub fn new(stdout: &'stdout Arc<TerminalOutput>) -> TerminalColor<'stdout> {
|
||||
#[cfg(target_os = "windows")]
|
||||
let color = functions::get_module::<Box<ITerminalColor>>(
|
||||
let color = functions::get_module::<Box<ITerminalColor + Sync + Send>>(
|
||||
Box::from(WinApiColor::new()),
|
||||
Box::from(AnsiColor::new()),
|
||||
).unwrap();
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let color = Box::from(AnsiColor::new()) as Box<ITerminalColor>;
|
||||
let color = Box::from(AnsiColor::new()) as Box<ITerminalColor + Sync + Send>;
|
||||
|
||||
TerminalColor {
|
||||
color,
|
||||
|
@ -21,7 +21,7 @@ use std::fmt;
|
||||
///
|
||||
/// ```
|
||||
pub struct Terminal<'stdout> {
|
||||
terminal: Box<ITerminal>,
|
||||
terminal: Box<ITerminal + Sync + Send>,
|
||||
screen: &'stdout Arc<TerminalOutput>,
|
||||
}
|
||||
|
||||
@ -29,13 +29,13 @@ impl<'stdout> Terminal<'stdout> {
|
||||
/// Create new terminal instance whereon terminal related actions can be performed.
|
||||
pub fn new(screen: &'stdout Arc<TerminalOutput>) -> Terminal<'stdout> {
|
||||
#[cfg(target_os = "windows")]
|
||||
let terminal = functions::get_module::<Box<ITerminal>>(
|
||||
let terminal = functions::get_module::<Box<ITerminal + Sync + Send>>(
|
||||
Box::new(WinApiTerminal::new()),
|
||||
Box::new(AnsiTerminal::new()),
|
||||
).unwrap();
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let terminal = Box::from(AnsiTerminal::new()) as Box<ITerminal>;
|
||||
let terminal = Box::from(AnsiTerminal::new()) as Box<ITerminal + Sync + Send>;
|
||||
|
||||
Terminal {
|
||||
terminal,
|
||||
|
Loading…
Reference in New Issue
Block a user