diff --git a/src/crossterm_cursor/cursor.rs b/src/crossterm_cursor/cursor.rs index 598b222..bf6c4c4 100644 --- a/src/crossterm_cursor/cursor.rs +++ b/src/crossterm_cursor/cursor.rs @@ -5,7 +5,10 @@ use std::fmt::Display; use std::ops::Drop; use {Construct, Context}; + +#[cfg(target_os = "windows")] use shared::functions::get_module; + use super::base_cursor::ITerminalCursor; use super::AnsiCursor; diff --git a/src/crossterm_state/commands/unix_command.rs b/src/crossterm_state/commands/unix_command.rs index 3d1cffb..af088cc 100644 --- a/src/crossterm_state/commands/unix_command.rs +++ b/src/crossterm_state/commands/unix_command.rs @@ -1,23 +1,24 @@ use crossterm_state::{Context}; use super::IContextCommand; - -use kernel::unix_kernel::terminal::Termios; use kernel::unix_kernel::terminal; +use termios::{Termios, tcsetattr, TCSAFLUSH, ICANON, ECHO, CREAD}; + +const FD_STDIN: ::std::os::unix::io::RawFd = 1; #[derive(Clone, Copy)] -pub struct NoncanonicaModeCommand +pub struct NoncanonicalModeCommand { key: i16 } impl IContextCommand for NoncanonicalModeCommand { - fn new(context: &mut Context) -> (Box) { + fn new(context: &mut Context) -> (Box, i16) { // println!("new new NoncanonicalModeCommand unix"); let key = super::generate_key(); - let command = NoncanonicaModeCommand{ key: key }; - context.register_change(command,key); - (Box::from(NoncanonicalModeCommand {}), key) + let command = NoncanonicalModeCommand { key: key }; + context.register_change(Box::from(command), key); + (Box::from(command),key) } fn execute(&mut self) -> bool @@ -63,7 +64,7 @@ pub struct EnableRawModeCommand impl IContextCommand for EnableRawModeCommand { - fn new(context: &Context) -> (Box, i16) { + fn new(context: &mut Context) -> (Box, i16) { // println!("new EnableRawModeCommand unix"); let key = super::generate_key(); let command = EnableRawModeCommand { original_mode: None, key: key }; diff --git a/src/crossterm_style/color/color.rs b/src/crossterm_style/color/color.rs index b6dc873..86eb577 100644 --- a/src/crossterm_style/color/color.rs +++ b/src/crossterm_style/color/color.rs @@ -8,6 +8,8 @@ use std::io; use {Construct, Context }; use crossterm_style::{ObjectStyle, StyledObject}; use super::base_color::ITerminalColor; + +#[cfg(target_os = "windows")] use shared::functions::get_module; use super::super::Color; diff --git a/src/crossterm_terminal/screen/mod.rs b/src/crossterm_terminal/screen/mod.rs index 3bd3304..5616766 100644 --- a/src/crossterm_terminal/screen/mod.rs +++ b/src/crossterm_terminal/screen/mod.rs @@ -2,6 +2,7 @@ use std::io::{self, Write}; use std::ops; use std::any::Any; +#[cfg(target_os = "windows")] use shared::functions::get_module; use crossterm_state::commands::*; use shared::traits::Construct; @@ -84,7 +85,6 @@ impl Drop for AlternateScreen { fn drop(&mut self) { - this write!(self, "{}", ToMainScreen).expect("switch to main screen"); } } diff --git a/src/crossterm_terminal/terminal.rs b/src/crossterm_terminal/terminal.rs index a340952..72d9b92 100644 --- a/src/crossterm_terminal/terminal.rs +++ b/src/crossterm_terminal/terminal.rs @@ -5,6 +5,7 @@ use std::ops::Drop; use {Construct, Context}; use super::base_terminal::{ClearType, ITerminal}; +#[cfg(target_os = "windows")] use shared::functions::get_module; use super::AnsiTerminal; diff --git a/src/kernel/unix_kernel/terminal.rs b/src/kernel/unix_kernel/terminal.rs index 30ee1d7..c13023e 100644 --- a/src/kernel/unix_kernel/terminal.rs +++ b/src/kernel/unix_kernel/terminal.rs @@ -1,7 +1,9 @@ use libc; -use self::libc::{STDOUT_FILENO, TIOCGWINSZ, c_ushort, ioctl}; -pub use self::libc::termios as Termios; -use crossterm_state::commands::{NoncanonicaModeCommand, IContextCommand}; +use self::libc::{STDOUT_FILENO, TIOCGWINSZ, c_ushort, ioctl, c_int}; +pub use self::libc::{termios, cvt}; +use termios::Termios; +use crossterm_state::commands::{NoncanonicalModeCommand, IContextCommand}; +use Context; use std::io; use std::mem; @@ -30,7 +32,7 @@ pub fn terminal_size() -> (u16,u16) { let r = unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ, &us) }; if r == 0 { // because crossterm works starts counting at 0 and unix terminal starts at cell 1 you have subtract one to get 0-based results. - Some((us.cols -1, us.rows -1)) + (us.cols -1, us.rows -1) } else { (0,0) } @@ -42,66 +44,68 @@ pub fn pos() -> (u16,u16) use std::io::Error; use std::io::{ Write,Read }; - let command = NoncanonicalModeCommand::new(); - command.execute(); + let mut context = Context::new(); + { + let command = NoncanonicalModeCommand::new(&mut context); + command.0.execute(); - // This code is original written by term_cursor credits to them. - let mut stdout = io::stdout(); + // This code is original written by term_cursor credits to them. + let mut stdout = io::stdout(); - // Write command - stdout.write(b"\x1B[6n")?; - stdout.flush()?; + // Write command + stdout.write(b"\x1B[6n"); + stdout.flush(); - // Read back result - let mut buf = [0u8; 2]; - // Expect `ESC[` - io::stdin().read_exact(&mut buf)?; - if buf[0] != 0x1B || buf[1] as char != '[' { - return (0,0); - } - - // Read rows and cols through a ad-hoc integer parsing function - let read_num = || -> Result<(i32, char), Error> { - let mut num = 0; - let mut c; - - loop { - let mut buf = [0u8; 1]; - io::stdin().read_exact(&mut buf)?; - c = buf[0] as char; - if let Some(d) = c.to_digit(10) { - num = if num == 0 { 0 } else { num * 10 }; - num += d as i32; - } else { - break; - } + // Read back result + let mut buf = [0u8; 2]; + // Expect `ESC[` + io::stdin().read_exact(&mut buf); + if buf[0] != 0x1B || buf[1] as char != '[' { + return (0, 0); } - Ok((num, c)) - }; + // Read rows and cols through a ad-hoc integer parsing function + let read_num = || -> Result<(i32, char), Error> { + let mut num = 0; + let mut c; - // Read rows and expect `;` - let (rows, c) = read_num()?; - if c != ';' { - return (0,0); + loop { + let mut buf = [0u8; 1]; + io::stdin().read_exact(&mut buf); + c = buf[0] as char; + if let Some(d) = c.to_digit(10) { + num = if num == 0 { 0 } else { num * 10 }; + num += d as i32; + } else { + break; + } + } + + Ok((num, c)) + }; + + // Read rows and expect `;` + let (rows, c) = read_num(); + if c != ';' { + return (0, 0); + } + + // Read cols + let (cols, c) = read_num(); + + // Expect `R` + let res = if c == 'R' { Ok((cols, rows)) } else { return Ok((0, 0)); }; + + res } - - // Read cols - let (cols, c) = read_num()?; - - // Expect `R` - let res = if c == 'R' { Ok((cols, rows)) } else { return (0,0); }; - - command.undo(); - res } -pub fn set_terminal_mode(terminal: &Termios) -> io::Result<()> +pub fn set_terminal_mode(termios: &Termios) -> io::Result<()> { extern "C" { pub fn tcsetattr(fd: c_int, opt: c_int, termptr: *const Termios) -> c_int; } - cvt(unsafe { tcsetattr(0, 0, termios) }).and(Ok(())) + unsafe { tcsetattr(0, 0, termios) } } pub fn get_terminal_mode() -> io::Result diff --git a/src/shared/functions.rs b/src/shared/functions.rs index cff5c25..ea0c922 100644 --- a/src/shared/functions.rs +++ b/src/shared/functions.rs @@ -23,6 +23,7 @@ pub fn get_cursor_position() -> (u16,u16) pos() } +#[cfg(windows)] /// Get the module specific implementation based on the current platform pub fn get_module(winapi_impl: T, unix_impl: T, context: &mut Context) -> Option { @@ -34,6 +35,7 @@ pub fn get_module(winapi_impl: T, unix_impl: T, context: &mut Context) -> Opt use kernel::windows_kernel::ansi_support::try_enable_ansi_support; // Try to enable ansi on windows if not than use WINAPI. + #[cfg(windows)] does_support = try_enable_ansi_support(context); if !does_support