From 8f160713bbde55574f77a7f5dc6ab7f63c1caea0 Mon Sep 17 00:00:00 2001 From: Timon Date: Sat, 28 Jul 2018 08:37:21 +0000 Subject: [PATCH] Fixed unix code after refactoring windows cursor, input, rawscreen, alternate screen --- src/input/unix_input.rs | 1 - src/kernel/unix_kernel/terminal.rs | 8 +-- src/kernel/windows_kernel/cursor.rs | 15 +---- src/shared/crossterm.rs | 96 ++++++++++++++--------------- src/shared/functions.rs | 6 +- src/shared/screen.rs | 1 + src/state/commands/unix_command.rs | 26 ++++---- src/terminal/ansi_terminal.rs | 2 +- 8 files changed, 69 insertions(+), 86 deletions(-) diff --git a/src/input/unix_input.rs b/src/input/unix_input.rs index 9a75bb3..f0bd314 100644 --- a/src/input/unix_input.rs +++ b/src/input/unix_input.rs @@ -6,7 +6,6 @@ use std::sync::mpsc; 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; diff --git a/src/kernel/unix_kernel/terminal.rs b/src/kernel/unix_kernel/terminal.rs index 08454e1..39e10f1 100644 --- a/src/kernel/unix_kernel/terminal.rs +++ b/src/kernel/unix_kernel/terminal.rs @@ -45,11 +45,11 @@ pub fn terminal_size() -> (u16, u16) { use std::time::{SystemTime, Duration}; use std::io::ErrorKind; -use Crossterm; +use Terminal; use std::io::Read; /// Get the current cursor position. -pub fn pos(context: Rc) -> (u16, u16) { - let crossterm = Crossterm::from(context.clone()); +pub fn pos() -> (u16, u16) { + let crossterm = Terminal::new(); let input = crossterm.input(); let delimiter = b'R'; @@ -58,7 +58,7 @@ pub fn pos(context: Rc) -> (u16, u16) { // Where is the cursor? // Use `ESC [ 6 n`. - crossterm.write("\x1B[6n"); +// crossterm.write("\x1B[6n"); let mut buf: [u8; 1] = [0]; let mut read_chars = Vec::new(); diff --git a/src/kernel/windows_kernel/cursor.rs b/src/kernel/windows_kernel/cursor.rs index e71f3ef..b4746e7 100644 --- a/src/kernel/windows_kernel/cursor.rs +++ b/src/kernel/windows_kernel/cursor.rs @@ -38,7 +38,7 @@ pub fn save_cursor_pos(screen_manager: &ScreenManager) { /// get the current cursor position. pub fn pos(screen_manager: &ScreenManager) -> (u16, u16) { - let handle = handle::get_output_handle().unwrap(); + let handle = handle::get_current_handle(screen_manager).unwrap(); if let Ok(csbi) = csbi::get_csbi_by_handle(&handle) { ( csbi.dwCursorPosition.X as u16, csbi.dwCursorPosition.Y as u16 ) @@ -47,19 +47,6 @@ pub fn pos(screen_manager: &ScreenManager) -> (u16, u16) { } } -pub fn absolute_cursor_pos(screen_manager: &ScreenManager) -> (u16, u16) { - - let handle = handle::get_output_handle().unwrap(); - - if let Ok(csbi) = csbi::get_csbi_by_handle(&handle) { - ( - (csbi.dwMaximumWindowSize.X) as u16, - (csbi.dwMaximumWindowSize.Y) as u16, - ) - } else { - return (0, 0); - } -} /// 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: &ScreenManager) { diff --git a/src/shared/crossterm.rs b/src/shared/crossterm.rs index fa640c4..bd429c6 100644 --- a/src/shared/crossterm.rs +++ b/src/shared/crossterm.rs @@ -1,52 +1,52 @@ -////! 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, +//// context: Rc, } // ///// Create `Crossterm` instance from `Context` diff --git a/src/shared/functions.rs b/src/shared/functions.rs index c8bff18..0dc7312 100644 --- a/src/shared/functions.rs +++ b/src/shared/functions.rs @@ -15,18 +15,18 @@ 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: &ScreenManager) -> (u16, u16) { +pub fn get_terminal_size() -> (u16, u16) { #[cfg(unix)] return terminal_size(); #[cfg(windows)] - return terminal_size(screen_manager); + return terminal_size(); } /// Get the cursor position based on the current platform. pub fn get_cursor_position(screen_manager: &ScreenManager) -> (u16, u16) { #[cfg(unix)] - return pos(screen_manager); + return pos(); #[cfg(windows)] return pos(screen_manager); diff --git a/src/shared/screen.rs b/src/shared/screen.rs index 3b5cfff..027080d 100644 --- a/src/shared/screen.rs +++ b/src/shared/screen.rs @@ -98,6 +98,7 @@ impl AlternateScreen { /// By calling this method the current screen will be changed to the alternate screen. /// And you get back an handle for that screen. pub fn new() -> Box { + #[cfg(target_os = "windows")] let command = functions::get_module::>( win_commands::ToAlternateScreenBufferCommand::new(), shared_commands::ToAlternateScreenBufferCommand::new(), diff --git a/src/state/commands/unix_command.rs b/src/state/commands/unix_command.rs index 570e11b..4e17bd1 100644 --- a/src/state/commands/unix_command.rs +++ b/src/state/commands/unix_command.rs @@ -1,13 +1,13 @@ //! This module contains the commands that can be used for unix systems. -use super::IStateCommand; +use super::{IStateCommand, IRawScreenCommand}; use kernel::unix_kernel::terminal; use termios::{tcsetattr, Termios, CREAD, ECHO, ICANON, TCSAFLUSH}; use {CommandManager, Context, StateManager}; const FD_STDIN: ::std::os::unix::io::RawFd = 1; -use std::io::Result; +use std::io::{Result,Error, ErrorKind}; use std::rc::Rc; use std::sync::Mutex; @@ -76,28 +76,24 @@ impl EnableRawModeCommand { } } -impl EnableRawModeCommand { - fn execute(&mut self) -> bool { +impl IRawScreenCommand for EnableRawModeCommand { + fn enable(&mut self) -> Result<()> { if let Ok(original_mode) = self.original_mode { let mut new_mode = original_mode; terminal::make_raw(&mut new_mode); terminal::set_terminal_mode(&new_mode); - true } else { - return false; + return Err(Error::new(ErrorKind::Other,"Could not set console mode when enabling raw mode")) } + Ok(()) } - fn undo(&mut self) -> bool { - if let Some(ref original_mode) = self.original_mode { - let result = terminal::set_terminal_mode(&original_mode); - - match result { - Ok(()) => true, - Err(_) => false, - } + fn disable(&mut self) -> Result<()> { + if let Ok(ref original_mode) = self.original_mode { + let result = terminal::set_terminal_mode(&original_mode)?; } else { - return false; + return Err(Error::new(ErrorKind::Other,"Could not set console mode when enabling raw mode")) } + Ok(()) } } diff --git a/src/terminal/ansi_terminal.rs b/src/terminal/ansi_terminal.rs index 136c351..452aa22 100644 --- a/src/terminal/ansi_terminal.rs +++ b/src/terminal/ansi_terminal.rs @@ -37,7 +37,7 @@ impl ITerminal for AnsiTerminal { } fn terminal_size(&self, screen_manager: &ScreenManager) -> (u16, u16) { - functions::get_terminal_size(&self.context.screen_manager) + functions::get_terminal_size() } fn scroll_up(&self, count: i16, screen_manager: &ScreenManager) {