Added Sync markers

This commit is contained in:
TimonPost 2018-08-21 21:17:53 +02:00
parent b98f549a73
commit c848beb721
12 changed files with 92 additions and 40 deletions

View File

@ -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"

View File

@ -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");
}

View File

@ -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<()>;
}

View File

@ -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) {

View File

@ -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);
}

View File

@ -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();

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -20,7 +20,7 @@ use Screen;
///
/// ```
pub struct TerminalInput<'stdout> {
terminal_input: Box<ITerminalInput>,
terminal_input: Box<ITerminalInput + Sync + Send>,
stdout: &'stdout Arc<TerminalOutput>,
}

View File

@ -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,

View File

@ -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,