fixed input and cursor with new implementation

This commit is contained in:
TimonPost 2018-07-27 22:28:30 +02:00
parent d7387ed227
commit 26472359bc
24 changed files with 424 additions and 517 deletions

View File

@ -25,4 +25,12 @@ use crossterm::Terminal;
use std::{thread, time};
fn main() {
let term = Terminal::new();
let mut cursor = term.cursor();
cursor.goto(10,10);
cursor.print("test");
let stdin = term.input();
let line = stdin.read_line();
println!("{:?}", line)
}

View File

@ -4,95 +4,63 @@
use super::*;
use shared::functions;
use Context;
use {Context,ScreenManager};
/// This struct is an ansi implementation for cursor related actions.
pub struct AnsiCursor {
context: Rc<Context>,
}
pub struct AnsiCursor;
impl AnsiCursor {
pub fn new(context: Rc<Context>) -> Box<AnsiCursor> {
Box::from(AnsiCursor { context })
pub fn new() -> Box<AnsiCursor> {
Box::from(AnsiCursor { })
}
}
impl ITerminalCursor for AnsiCursor {
fn goto(&self, x: u16, y: u16) {
let mut screen = self.context.screen_manager.lock().unwrap();
{
screen.write_string(format!(csi!("{};{}H"), y + 1, x + 1));
}
fn goto(&self, x: u16, y: u16, screen_manager: &ScreenManager) {
screen_manager.write_string(format!(csi!("{};{}H"), y + 1, x + 1));
}
fn pos(&self) -> (u16, u16) {
functions::get_cursor_position(self.context.clone())
fn pos(&self, screen_manager: &ScreenManager) -> (u16, u16) {
functions::get_cursor_position(screen_manager)
}
fn move_up(&self, count: u16) {
let mut screen = self.context.screen_manager.lock().unwrap();
{
screen.write_string(format!(csi!("{}A"), count));
}
fn move_up(&self, count: u16, screen_manager: &ScreenManager) {
screen_manager.write_string(format!(csi!("{}A"), count));
}
fn move_right(&self, count: u16) {
let mut screen = self.context.screen_manager.lock().unwrap();
{
screen.write_string(format!(csi!("{}C"), count));
}
fn move_right(&self, count: u16, screen_manager: &ScreenManager) {
screen_manager.write_string(format!(csi!("{}C"), count));
}
fn move_down(&self, count: u16) {
let mut screen = self.context.screen_manager.lock().unwrap();
{
screen.write_string(format!(csi!("{}B"), count));
}
fn move_down(&self, count: u16, screen_manager: &ScreenManager) {
screen_manager.write_string(format!(csi!("{}B"), count));
}
fn move_left(&self, count: u16) {
let mut screen = self.context.screen_manager.lock().unwrap();
{
screen.write_string(format!(csi!("{}D"), count));
}
fn move_left(&self, count: u16, screen_manager: &ScreenManager) {
screen_manager.write_string(format!(csi!("{}D"), count));
}
fn save_position(&self) {
let mut screen = self.context.screen_manager.lock().unwrap();
{
screen.write_str(csi!("s"));
}
fn save_position(&self, screen_manager: &ScreenManager) {
screen_manager.write_str(csi!("s"));
}
fn reset_position(&self) {
let mut screen = self.context.screen_manager.lock().unwrap();
{
screen.write_str(csi!("u"));
}
fn reset_position(&self, screen_manager: &ScreenManager) {
screen_manager.write_str(csi!("u"));
}
fn hide(&self) {
let mut screen = self.context.screen_manager.lock().unwrap();
{
screen.write_str(csi!("?25l"));
}
fn hide(&self, screen_manager: &ScreenManager) {
screen_manager.write_str(csi!("?25l"));
}
fn show(&self) {
let mut screen = self.context.screen_manager.lock().unwrap();
{
screen.write_str(csi!("?25h"));
}
fn show(&self, screen_manager: &ScreenManager) {
screen_manager.write_str(csi!("?25h"));
}
fn blink(&self, blink: bool) {
let mut screen = self.context.screen_manager.lock().unwrap();
{
fn blink(&self, blink: bool, screen_manager: &ScreenManager) {
if blink {
screen.write_str(csi!("?12h"));
screen_manager.write_str(csi!("?12h"));
} else {
screen.write_str(csi!("?12l"));
}
screen_manager.write_str(csi!("?12l"));
}
}
}

View File

@ -13,25 +13,25 @@ use std::rc::Rc;
/// Struct that stores an specific platform implementation for cursor related actions.
pub struct TerminalCursor<'cursor> {
context: &'cursor ScreenManager,
screen_manager: &'cursor ScreenManager,
terminal_cursor: Box<ITerminalCursor>,
}
impl<'cursor> TerminalCursor<'cursor> {
/// Create new cursor instance whereon cursor related actions can be performed.
pub fn new(context: &'cursor ScreenManager) -> TerminalCursor<'cursor> {
pub fn new(screen_manager: &'cursor ScreenManager) -> TerminalCursor<'cursor> {
#[cfg(target_os = "windows")]
let cursor = functions::get_module::<Box<ITerminalCursor>>(
WinApiCursor::new(context.screen_manager.clone()),
AnsiCursor::new(context.clone()),
WinApiCursor::new(),
AnsiCursor::new(),
).unwrap();
#[cfg(not(target_os = "windows"))]
let cursor = AnsiCursor::new(context.clone()) as Box<ITerminalCursor>;
let cursor = AnsiCursor::new() as Box<ITerminalCursor>;
TerminalCursor {
terminal_cursor: cursor,
context,
screen_manager: screen_manager,
}
}
@ -56,8 +56,8 @@ impl<'cursor> TerminalCursor<'cursor> {
/// }
///
/// ```
pub fn goto(&mut self, x: u16, y: u16) -> &mut TerminalCursor {
self.terminal_cursor.goto(x, y);
pub fn goto(&mut self, x: u16, y: u16) -> &mut TerminalCursor<'cursor> {
self.terminal_cursor.goto(x, y, &self.screen_manager);
self
}
@ -83,7 +83,7 @@ impl<'cursor> TerminalCursor<'cursor> {
///
/// ```
pub fn pos(&self) -> (u16, u16) {
self.terminal_cursor.pos()
self.terminal_cursor.pos(&self.screen_manager)
}
/// Move the current cursor position `n` times up.
@ -107,8 +107,8 @@ impl<'cursor> TerminalCursor<'cursor> {
/// }
///
/// ```
pub fn move_up(&mut self, count: u16) -> &mut TerminalCursor {
self.terminal_cursor.move_up(count);
pub fn move_up(&mut self, count: u16) -> &mut TerminalCursor<'cursor> {
self.terminal_cursor.move_up(count, &self.screen_manager);
self
}
@ -131,8 +131,8 @@ impl<'cursor> TerminalCursor<'cursor> {
/// cursor.move_right(3);
/// }
/// ```
pub fn move_right(&mut self, count: u16) -> &mut TerminalCursor {
self.terminal_cursor.move_right(count);
pub fn move_right(&mut self, count: u16) -> &mut TerminalCursor<'cursor> {
self.terminal_cursor.move_right(count, &self.screen_manager);
self
}
@ -157,8 +157,8 @@ impl<'cursor> TerminalCursor<'cursor> {
/// }
///
/// ```
pub fn move_down(&mut self, count: u16) -> &mut TerminalCursor {
self.terminal_cursor.move_down(count);
pub fn move_down(&mut self, count: u16) -> &mut TerminalCursor<'cursor> {
self.terminal_cursor.move_down(count, &self.screen_manager);
self
}
@ -183,8 +183,8 @@ impl<'cursor> TerminalCursor<'cursor> {
/// }
///
/// ```
pub fn move_left(&mut self, count: u16) -> &mut TerminalCursor {
self.terminal_cursor.move_left(count);
pub fn move_left(&mut self, count: u16) -> &mut TerminalCursor<'cursor> {
self.terminal_cursor.move_left(count, &self.screen_manager);
self
}
@ -224,19 +224,13 @@ impl<'cursor> TerminalCursor<'cursor> {
/// .print("@");
///
/// ```
pub fn print<D: Display>(&mut self, value: D) -> &mut TerminalCursor {
{
pub fn print<D: Display>(&mut self, value: D) -> &mut TerminalCursor<'cursor> {
use std::fmt::Write;
let mut string = String::new();
write!(string, "{}", value).unwrap();
let mut mutex = &self.context.screen_manager;
{
let mut screen_manager = mutex.lock().unwrap();
screen_manager.write_string(string);
screen_manager.flush();
}
}
&self.screen_manager.write_string(string);
&self.screen_manager.flush();
self
}
@ -257,7 +251,7 @@ impl<'cursor> TerminalCursor<'cursor> {
///
/// ```
pub fn save_position(&self) {
self.terminal_cursor.save_position();
self.terminal_cursor.save_position(&self.screen_manager);
}
/// Return to saved cursor position
@ -277,7 +271,7 @@ impl<'cursor> TerminalCursor<'cursor> {
///
/// ```
pub fn reset_position(&self) {
self.terminal_cursor.reset_position();
self.terminal_cursor.reset_position(&self.screen_manager);
}
/// Hide de cursor in the console.
@ -295,7 +289,7 @@ impl<'cursor> TerminalCursor<'cursor> {
///
/// ```
pub fn hide(&self) {
self.terminal_cursor.hide();
self.terminal_cursor.hide(&self.screen_manager);
}
/// Show the cursor in the console.
@ -313,7 +307,7 @@ impl<'cursor> TerminalCursor<'cursor> {
///
/// ```
pub fn show(&self) {
self.terminal_cursor.show();
self.terminal_cursor.show(&self.screen_manager);
}
/// Enable or disable blinking of the terminal.
@ -335,37 +329,37 @@ impl<'cursor> TerminalCursor<'cursor> {
///
/// ```
pub fn blink(&self, blink: bool) {
self.terminal_cursor.blink(blink);
self.terminal_cursor.blink(blink, &self.screen_manager);
}
}
/// Get an TerminalCursor implementation whereon cursor related actions can be performed.
///
/// Check `/examples/version/cursor` in the libary for more spesific examples.
///
/// #Example
///
/// ```rust
///
/// extern crate crossterm;
/// use self::crossterm::Context;
/// use self::crossterm::cursor;
///
/// let context = Context::new();
///
/// // Get cursor and goto pos X: 5, Y: 10
/// let mut cursor = cursor::cursor(&context);
/// cursor.goto(5,10);
///
/// cursor.show();
/// cursor.hide();
/// cursor.blink();
/// cursor.move_left(2);
///
/// //Or you can do it in one line.
/// cursor::cursor(&context).goto(5,10);
///
/// ```
pub fn cursor(context: &Rc<Context>) -> Box<TerminalCursor> {
Box::from(TerminalCursor::new(context.clone()))
}
// Get an TerminalCursor implementation whereon cursor related actions can be performed.
//
// Check `/examples/version/cursor` in the libary for more spesific examples.
//
// #Example
//
// ```rust
//
// extern crate crossterm;
// use self::crossterm::Context;
// use self::crossterm::cursor;
//
// let context = Context::new();
//
// // Get cursor and goto pos X: 5, Y: 10
// let mut cursor = cursor::cursor(&context);
// cursor.goto(5,10);
//
// cursor.show();
// cursor.hide();
// cursor.blink();
// cursor.move_left(2);
//
// //Or you can do it in one line.
// cursor::cursor(&context).goto(5,10);
//
// ```
//pub fn cursor(context: &ScreenManager) -> Box<TerminalCursor> {
// Box::from(TerminalCursor::new(context.clone()))
//}

View File

@ -17,8 +17,8 @@ use self::ansi_cursor::AnsiCursor;
#[cfg(target_os = "windows")]
use self::winapi_cursor::WinApiCursor;
pub use self::cursor::{cursor, TerminalCursor};
pub use self::cursor::{TerminalCursor};
use ScreenManager;
use std::rc::Rc;
///! This trait defines the actions that can be preformed with the terminal cursor.

View File

@ -20,47 +20,47 @@ impl WinApiCursor {
impl ITerminalCursor for WinApiCursor {
fn goto(&self, x: u16, y: u16, screen_manager: &ScreenManager) {
cursor::set_console_cursor_position(x as i16, y as i16, &self.screen_manager);
cursor::set_console_cursor_position(x as i16, y as i16, screen_manager);
}
fn pos(&self, screen_manager: &ScreenManager) -> (u16, u16) {
cursor::pos(&self.screen_manager)
cursor::pos(screen_manager)
}
fn move_up(&self, count: u16, screen_manager: &ScreenManager) {
let (xpos, ypos) = self.pos();
self.goto(xpos, ypos - count);
let (xpos, ypos) = self.pos(screen_manager);
self.goto(xpos, ypos - count, screen_manager);
}
fn move_right(&self, count: u16, screen_manager: &ScreenManager) {
let (xpos, ypos) = self.pos();
self.goto(xpos + count, ypos);
let (xpos, ypos) = self.pos(screen_manager);
self.goto(xpos + count, ypos, screen_manager);
}
fn move_down(&self, count: u16, screen_manager: &ScreenManager) {
let (xpos, ypos) = self.pos();
self.goto(xpos, ypos + count);
let (xpos, ypos) = self.pos(screen_manager);
self.goto(xpos, ypos + count, screen_manager);
}
fn move_left(&self, count: u16, screen_manager: &ScreenManager) {
let (xpos, ypos) = self.pos();
self.goto(xpos - count, ypos);
let (xpos, ypos) = self.pos(screen_manager);
self.goto(xpos - count, ypos, screen_manager);
}
fn save_position(&self, screen_manager: &ScreenManager) {
cursor::save_cursor_pos(&self.screen_manager);
cursor::save_cursor_pos(screen_manager);
}
fn reset_position(&self, screen_manager: &ScreenManager) {
cursor::reset_to_saved_position(&self.screen_manager);
cursor::reset_to_saved_position(screen_manager);
}
fn hide(&self, screen_manager: &ScreenManager) {
cursor::cursor_visibility(false, &self.screen_manager);
cursor::cursor_visibility(false, screen_manager);
}
fn show(&self, screen_manager: &ScreenManager) {
cursor::cursor_visibility(true, &self.screen_manager);
cursor::cursor_visibility(true, screen_manager);
}
fn blink(&self, blink: bool, screen_manager: &ScreenManager) {}

View File

@ -2,48 +2,44 @@ use std::io;
use super::*;
use std::rc::Rc;
use Context;
use {Context, ScreenManager };
pub struct TerminalInput {
context: Rc<Context>,
pub struct TerminalInput<'terminal> {
terminal_input: Box<ITerminalInput>,
screen_manager: &'terminal ScreenManager
}
impl TerminalInput {
pub fn new(context: Rc<Context>) -> TerminalInput {
impl<'terminal> TerminalInput<'terminal> {
pub fn new(screen_manager: &'terminal ScreenManager) -> TerminalInput<'terminal> {
#[cfg(target_os = "windows")]
let input = Box::from(WindowsInput::new(context.clone()));
let input = Box::from(WindowsInput::new());
#[cfg(not(target_os = "windows"))]
let input = Box::from(UnixInput::new());
TerminalInput {
terminal_input: input,
context,
screen_manager: screen_manager
}
}
pub fn read_line(&self) -> io::Result<String> {
self.terminal_input.read_line()
self.terminal_input.read_line(&self.screen_manager)
}
pub fn read_char(&self) -> io::Result<char> {
return self.terminal_input.read_char();
}
pub fn read_key(&self) -> io::Result<Key> {
self.terminal_input.read_pressed_key()
return self.terminal_input.read_char(&self.screen_manager);
}
pub fn read_async(&self) -> AsyncReader {
self.terminal_input.read_async()
self.terminal_input.read_async(&self.screen_manager)
}
pub fn read_until_async(&self, delimiter: u8) -> AsyncReader {
self.terminal_input.read_until_async(delimiter)
self.terminal_input.read_until_async(delimiter,&self.screen_manager)
}
}
pub fn input(context: &Rc<Context>) -> Box<TerminalInput> {
return Box::from(TerminalInput::new(context.clone()));
pub fn input(screen_manager: &ScreenManager) -> TerminalInput {
return TerminalInput::new(screen_manager)
}

View File

@ -13,18 +13,18 @@ use self::unix_input::UnixInput;
mod unix_input;
pub use self::input::{input, TerminalInput};
use ScreenManager;
use std::io::Read;
use std::sync::mpsc;
trait ITerminalInput {
fn read_line(&self) -> io::Result<String>;
fn read_line(&self, screen_manger: &ScreenManager) -> io::Result<String>;
fn read_char(&self) -> io::Result<char>;
fn read_pressed_key(&self) -> io::Result<Key>;
fn read_char(&self, screen_manger: &ScreenManager) -> io::Result<char>;
fn read_async(&self) -> AsyncReader;
fn read_until_async(&self, delimiter: u8) -> AsyncReader;
fn read_async(&self, screen_manger: &ScreenManager) -> AsyncReader;
fn read_until_async(&self, delimiter: u8, screen_manger: &ScreenManager) -> AsyncReader;
}
pub struct AsyncReader {

View File

@ -8,7 +8,7 @@ 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;
impl UnixInput {
@ -18,7 +18,7 @@ impl UnixInput {
}
impl ITerminalInput for UnixInput {
fn read_line(&self) -> io::Result<String> {
fn read_line(&self, screen_manger: &ScreenManager) -> io::Result<String> {
let mut rv = String::new();
io::stdin().read_line(&mut rv)?;
let len = rv.trim_right_matches(&['\r', '\n'][..]).len();
@ -26,15 +26,11 @@ impl ITerminalInput for UnixInput {
Ok(rv)
}
fn read_char(&self) -> io::Result<char> {
fn read_char(&self, screen_manger: &ScreenManager) -> io::Result<char> {
read_char()
}
fn read_pressed_key(&self) -> io::Result<Key> {
Ok(Key::Unknown)
}
fn read_async(&self) -> AsyncReader {
fn read_async(&self, screen_manger: &ScreenManager) -> AsyncReader {
let (send, recv) = mpsc::channel();
thread::spawn(move || for i in get_tty().unwrap().bytes() {
@ -46,7 +42,7 @@ impl ITerminalInput for UnixInput {
AsyncReader { recv: recv }
}
fn read_until_async(&self, delimiter: u8) -> AsyncReader {
fn read_until_async(&self, delimiter: u8, screen_manger: &ScreenManager) -> AsyncReader {
let (send, recv) = mpsc::channel();
thread::spawn(move || for i in get_tty().unwrap().bytes() {

View File

@ -9,36 +9,23 @@ use super::{AsyncReader, ITerminalInput, Key};
use winapi::um::winnt::INT;
use winapi::um::winuser;
use super::super::terminal::terminal;
use std::rc::Rc;
use Context;
use ScreenManager;
pub struct WindowsInput {
context: Rc<Context>,
pub display_input: bool,
}
pub struct WindowsInput;
impl WindowsInput {
pub fn new(context: Rc<Context>) -> WindowsInput {
WindowsInput {
context,
display_input: false,
}
pub fn new() -> WindowsInput {
WindowsInput {}
}
}
impl ITerminalInput for WindowsInput {
fn read_line(&self) -> io::Result<String> {
let term = terminal(&self.context);
fn read_line(&self,screen_manger: &ScreenManager) -> io::Result<String> {
let mut chars: Vec<char> = Vec::new();
loop {
let mut is_raw_screen = false;
{
let mutex = &self.context.screen_manager;
let screen = mutex.lock().unwrap();
is_raw_screen = screen.is_raw_screen();
}
let is_raw_screen = screen_manger.is_raw_screen();
// _getwch is without echo and _getwche is with echo
let pressed_char = unsafe { if is_raw_screen { _getwch() } else { _getwche() } };
@ -63,15 +50,8 @@ impl ITerminalInput for WindowsInput {
return Ok(chars.into_iter().collect());
}
fn read_char(&self) -> io::Result<char> {
let term = terminal(&self.context);
let mut is_raw_screen = false;
{
let mutex = &self.context.screen_manager;
let screen = mutex.lock().unwrap();
is_raw_screen = screen.is_raw_screen();
}
fn read_char(&self, screen_manger: &ScreenManager) -> io::Result<char> {
let is_raw_screen = screen_manger.is_raw_screen();
// _getwch is without echo and _getwche is with echo
let pressed_char = unsafe { if is_raw_screen { _getwch() } else { _getwche() } };
@ -86,9 +66,6 @@ impl ITerminalInput for WindowsInput {
match char::from_u32(pressed_char as u32) {
Some(c) => {
if self.display_input {
term.write(c);
}
return Ok(c);
}
None => Err(io::Error::new(
@ -98,41 +75,11 @@ impl ITerminalInput for WindowsInput {
}
}
fn read_pressed_key(&self) -> io::Result<Key> {
use Context;
let context = Context::new();
let buf: [u8; 1024] = unsafe { ::std::mem::zeroed() };
// reading::read(&mut buf, &context.screen_manager);
Ok(Key::Unknown)
// let pressed_char = unsafe { _getwch() };
//
// // if 0 or 0xe0 we need to listen again because the next key will be an special key
// if pressed_char == 0 || pressed_char == 0xe0 {
// let special_key: i32 = unsafe { _getwch() };
// println!("spkey {}",special_key);
// return Ok(key_from_key_code(0x26));
// } else {
// match char::from_u32(pressed_char as u32)
// {
// Some(c) => return Ok(Key::Char(c)),
// None => { panic!("Some error needs to be returned") }
// }
// }
}
fn read_async(&self) -> AsyncReader {
fn read_async(&self,screen_manger: &ScreenManager) -> AsyncReader {
let (tx, rx) = mpsc::channel();
let mut is_raw_screen = false;
let is_raw_screen = screen_manger.is_raw_screen();
{
let mutex = &self.context.screen_manager;
let screen = mutex.lock().unwrap();
is_raw_screen = screen.is_raw_screen();
}
// panic!("is raw screen: {} ", is_raw_screen);
thread::spawn(move || {
loop {
@ -155,15 +102,10 @@ impl ITerminalInput for WindowsInput {
AsyncReader { recv: rx }
}
fn read_until_async(&self, delimiter: u8) -> AsyncReader {
fn read_until_async(&self, delimiter: u8,screen_manger: &ScreenManager) -> AsyncReader {
let (tx, rx) = mpsc::channel();
let mut is_raw_screen = false;
{
let mutex =&self.context.screen_manager;
let screen = mutex.lock().unwrap();
is_raw_screen = screen.is_raw_screen();
}
let is_raw_screen = screen_manger.is_raw_screen();
thread::spawn(move || {
loop {

View File

@ -16,7 +16,7 @@ use std::sync::Mutex;
use ScreenManager;
/// Create a new console screen buffer info struct.
pub fn get_csbi(screen_manager: &Rc<Mutex<ScreenManager>>) -> Result<CONSOLE_SCREEN_BUFFER_INFO> {
pub fn get_csbi(screen_manager: &ScreenManager) -> Result<CONSOLE_SCREEN_BUFFER_INFO> {
let mut csbi = CONSOLE_SCREEN_BUFFER_INFO::empty();
let success;
@ -36,7 +36,7 @@ pub fn get_csbi(screen_manager: &Rc<Mutex<ScreenManager>>) -> Result<CONSOLE_SCR
/// Get buffer info and handle of the current screen.
pub fn get_csbi_and_handle(
screen_manager: &Rc<Mutex<ScreenManager>>,
screen_manager: &ScreenManager,
) -> Result<(CONSOLE_SCREEN_BUFFER_INFO, HANDLE)> {
let handle = handle::get_current_handle(screen_manager)?;
let csbi = get_csbi_by_handle(&handle)?;
@ -63,7 +63,7 @@ pub fn get_csbi_by_handle(handle: &HANDLE) -> Result<CONSOLE_SCREEN_BUFFER_INFO>
/// Set the console screen buffer size
pub fn set_console_screen_buffer_size(
size: COORD,
screen_manager: &Rc<Mutex<ScreenManager>>,
screen_manager: &ScreenManager,
) -> bool {
let handle = handle::get_current_handle(screen_manager).unwrap();

View File

@ -16,7 +16,7 @@ use std::sync::Mutex;
static mut SAVED_CURSOR_POS: (u16, u16) = (0, 0);
/// Reset to saved cursor position
pub fn reset_to_saved_position(screen_manager: &Rc<Mutex<ScreenManager>>) {
pub fn reset_to_saved_position(screen_manager: &ScreenManager) {
unsafe {
set_console_cursor_position(
SAVED_CURSOR_POS.0 as i16,
@ -27,7 +27,7 @@ pub fn reset_to_saved_position(screen_manager: &Rc<Mutex<ScreenManager>>) {
}
/// Save current cursor position to recall later.
pub fn save_cursor_pos(screen_manager: &Rc<Mutex<ScreenManager>>) {
pub fn save_cursor_pos(screen_manager: &ScreenManager) {
let position = pos(screen_manager);
unsafe {
@ -36,7 +36,7 @@ pub fn save_cursor_pos(screen_manager: &Rc<Mutex<ScreenManager>>) {
}
/// get the current cursor position.
pub fn pos(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
pub fn pos(screen_manager: &ScreenManager) -> (u16, u16) {
let handle = handle::get_output_handle().unwrap();
@ -47,7 +47,7 @@ pub fn pos(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
}
}
pub fn absolute_cursor_pos(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
pub fn absolute_cursor_pos(screen_manager: &ScreenManager) -> (u16, u16) {
let handle = handle::get_output_handle().unwrap();
@ -62,7 +62,7 @@ pub fn absolute_cursor_pos(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u
}
/// 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: &Rc<Mutex<ScreenManager>>) {
pub fn set_console_cursor_position(x: i16, y: i16, screen_manager: &ScreenManager) {
if x < 0 || x >= <i16>::max_value() {
panic!(
"Argument Out of Range Exception when setting cursor position to X: {}",
@ -91,7 +91,7 @@ pub fn set_console_cursor_position(x: i16, y: i16, screen_manager: &Rc<Mutex<Scr
}
/// change the cursor visibility.
pub fn cursor_visibility(visable: bool, screen_manager: &Rc<Mutex<ScreenManager>>) -> Result<()> {
pub fn cursor_visibility(visable: bool, screen_manager: &ScreenManager) -> Result<()> {
let handle = handle::get_current_handle(screen_manager).unwrap();
let cursor_info = CONSOLE_CURSOR_INFO {

View File

@ -6,27 +6,23 @@ use winapi::um::winnt::HANDLE;
use std::io::{self, ErrorKind, Result};
use std::rc::Rc;
use std::sync::Mutex;
use super::super::super::manager::{ScreenManager, WinApiScreenManager};
/// Get the global stored handle whits provides access to the current screen.
pub fn get_current_handle(screen_manager: &Rc<Mutex<ScreenManager>>) -> Result<HANDLE> {
pub fn get_current_handle(screen_manager: &ScreenManager) -> Result<HANDLE> {
let mut mutex = screen_manager;
let handle: Result<HANDLE>;
let mut screen_manager = mutex.lock().unwrap();
{
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
let winapi_screen_manager: &WinApiScreenManager = match screen_manager
.as_any()
.downcast_mut::<WinApiScreenManager>()
.downcast_ref::<WinApiScreenManager>()
{
Some(win_api) => win_api,
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());
}
return handle;
}

View File

@ -37,7 +37,7 @@ pub fn get_console_mode(handle: &HANDLE, current_mode: &mut u32) -> bool {
}
/// Change the console text attribute.
pub fn set_console_text_attribute(value: u16, screen_manager: &Rc<Mutex<ScreenManager>>) -> bool {
pub fn set_console_text_attribute(value: u16, screen_manager: &ScreenManager) -> bool {
let handle = handle::get_current_handle(screen_manager).unwrap();
unsafe {
@ -49,7 +49,7 @@ pub fn set_console_text_attribute(value: u16, screen_manager: &Rc<Mutex<ScreenMa
pub fn set_console_info(
absolute: bool,
rect: &SMALL_RECT,
screen_manager: &Rc<Mutex<ScreenManager>>,
screen_manager: &ScreenManager,
) -> bool {
let handle = handle::get_current_handle(screen_manager).unwrap();
@ -72,7 +72,7 @@ pub fn is_true(value: i32) -> bool {
}
///// Get the original color of the terminal.
//pub fn get_original_console_color(screen_manager: &Rc<Mutex<ScreenManager>>) -> u16 {
//pub fn get_original_console_color(screen_manager: &ScreenManager) -> u16 {
// let console_buffer_info = csbi::get_console_screen_buffer_info(screen_manager);
// console_buffer_info.wAttributes as u16
//}

View File

@ -5,7 +5,7 @@ use ScreenManager;
use super::{csbi, handle};
/// Get the terminal size
pub fn terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
pub fn terminal_size(screen_manager: &ScreenManager) -> (u16, u16) {
let handle = handle::get_output_handle().unwrap();
@ -19,7 +19,7 @@ pub fn terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
}
}
pub fn buffer_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
pub fn buffer_size(screen_manager: &ScreenManager) -> (u16, u16) {
let handle = handle::get_output_handle().unwrap();

View File

@ -20,7 +20,7 @@ pub fn fill_console_output_character(
cells_written: &mut u32,
start_location: COORD,
cells_to_write: u32,
screen_manager: &Rc<Mutex<ScreenManager>>,
screen_manager: &ScreenManager,
) -> bool {
let handle = handle::get_current_handle(screen_manager).unwrap();
@ -42,7 +42,7 @@ pub fn fill_console_output_attribute(
cells_written: &mut u32,
start_location: COORD,
cells_to_write: u32,
screen_manager: &Rc<Mutex<ScreenManager>>,
screen_manager: &ScreenManager,
) -> bool {
// Get the position of the current console window

View File

@ -11,11 +11,11 @@ mod state;
pub mod cursor;
pub mod input;
pub mod manager;
pub mod style;
//pub mod style;
pub mod terminal;
pub use shared::Terminal::Terminal;
pub use shared::crossterm::Crossterm;
//pub use shared::crossterm::Crossterm;
pub use shared::raw;
pub use shared::screen;
pub use state::context::Context;

View File

@ -4,14 +4,14 @@
use std::any::Any;
use std::io::{self, Read, Write};
use std::sync::Mutex;
use super::IScreenManager;
use std::str::from_utf8;
pub struct AnsiScreenManager {
is_alternate_screen: bool,
is_raw_screen: bool,
output: Box<Write>,
input: Box<Read>,
output: Mutex<Box<Write>>
}
impl IScreenManager for AnsiScreenManager {
@ -31,41 +31,37 @@ impl IScreenManager for AnsiScreenManager {
self.is_alternate_screen
}
fn write_string(&mut self, string: String) -> io::Result<usize> {
write!(self.output, "{}", string)?;
fn write_str(&self, string: &str) -> io::Result<usize> {
{
let mx = &self.output;
let mut output = mx.lock().unwrap();
write!(output, "{}", string)?;
}
self.flush();
Ok(0)
}
fn write_str(&mut self, string: &str) -> io::Result<usize> {
write!(self.output, "{}", string)?;
self.flush();
fn write(&self, buf: &[u8]) -> io::Result<usize> {
{
let mx = &self.output;
let mut output = mx.lock().unwrap();
output.write(buf)?;
}
Ok(0)
}
// fn read_line(&mut self) -> io::Result<String>
// {
// let mut rv = String::new();
// self.input.read_line(&mut rv)?;
// let len = rv.trim_right_matches(&['\r', '\n'][..]).len();
// rv.truncate(len);
// Ok(rv)
// }
//
// fn read_char(&mut self) -> io::Result<String>
// {
//
// }
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.output.write(buf)
fn flush(&self) -> io::Result<()> {
let mx = &self.output;
let mut output = mx.lock().unwrap();
output.flush()
}
fn flush(&mut self) -> io::Result<()> {
self.output.flush()
fn as_any(&self) -> &Any {
self
}
fn as_any(&mut self) -> &mut Any {
fn as_any_mut(&mut self) -> &mut Any {
self
}
}
@ -73,8 +69,7 @@ impl IScreenManager for AnsiScreenManager {
impl AnsiScreenManager {
pub fn new() -> Self {
AnsiScreenManager {
input: (Box::from(io::stdin()) as Box<Read>),
output: (Box::from(io::stdout()) as Box<Write>),
output: Mutex::new(Box::from(io::stdout()) as Box<Write>),
is_alternate_screen: false,
is_raw_screen: false,
}

View File

@ -52,27 +52,26 @@ impl ScreenManager {
}
/// Write an ANSI code as String.
pub fn write_string(&mut self, string: String) -> io::Result<usize> {
self.screen_manager.write_string(string)
pub fn write_string(&self, string: String) -> io::Result<usize> {
self.screen_manager.write_str(string.as_str())
}
pub fn flush(&self) -> io::Result<()>
{
self.screen_manager.flush()
}
/// Write an ANSI code as &str
pub fn write_str(&mut self, string: &str) -> io::Result<usize> {
pub fn write_str(&self, string: &str) -> io::Result<usize> {
self.screen_manager.write_str(string)
}
/// Can be used to get an specific implementation used for the current platform.
pub fn as_any(&mut self) -> &mut Any {
pub fn as_any(&self) -> &Any {
self.screen_manager.as_any()
}
}
impl Write for ScreenManager {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.screen_manager.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.screen_manager.flush()
/// Can be used to get an specific implementation used for the current platform.
pub fn as_any_mut(&mut self) -> &mut Any {
self.screen_manager.as_any_mut()
}
}

View File

@ -39,14 +39,14 @@ pub trait IScreenManager {
fn is_raw_screen(&self) -> bool;
fn is_alternate_screen(&self) -> bool;
/// Write ansi code as String to the current stdout.
fn write_string(&mut self, string: String) -> io::Result<usize>;
/// Write a &str to the current stdout.
fn write_str(&mut self, string: &str) -> io::Result<usize>;
fn write_str(&self, string: &str) -> io::Result<usize>;
/// Write [u8] buffer to console.
fn write(&mut self, buf: &[u8]) -> io::Result<usize>;
fn write(&self, buf: &[u8]) -> io::Result<usize>;
/// Flush the current output.
fn flush(&mut self) -> io::Result<()>;
fn flush(&self) -> io::Result<()>;
/// Can be used to convert to an specific IScreenManager implementation.
fn as_any(&mut self) -> &mut Any;
fn as_any(&self) -> &Any;
/// Can be used to convert to an specific mutable IScreenManager implementation.
fn as_any_mut(&mut self) -> &mut Any;
}

View File

@ -15,7 +15,6 @@ pub struct WinApiScreenManager {
}
impl IScreenManager for WinApiScreenManager {
fn set_is_raw_screen(&mut self, value: bool) {
self.is_raw_screen = value;
}
@ -31,16 +30,11 @@ impl IScreenManager for WinApiScreenManager {
self.is_alternate_screen
}
fn write_string(&mut self, string: String) -> io::Result<usize> {
fn write_str(&self, string: &str) -> io::Result<usize> {
self.write(string.as_bytes())
}
fn write_str(&mut self, string: &str) -> io::Result<usize> {
self.write(string.as_bytes())
}
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
fn write(&self, buf: &[u8]) -> io::Result<usize> {
if self.is_alternate_screen {
writing::write_char_buffer(&self.alternate_handle, buf)
} else {
@ -48,11 +42,15 @@ impl IScreenManager for WinApiScreenManager {
}
}
fn flush(&mut self) -> io::Result<()> {
fn flush(&self) -> io::Result<()> {
Ok(())
}
fn as_any(&mut self) -> &mut Any {
fn as_any(&self) -> &Any {
self
}
fn as_any_mut(&mut self) -> &mut Any {
self
}
}
@ -76,7 +74,7 @@ impl WinApiScreenManager {
}
/// get the current screen handle.
pub fn get_handle(&mut self) -> &HANDLE {
pub fn get_handle(&self) -> &HANDLE {
if self.is_alternate_screen {
return &self.alternate_handle;
} else {

View File

@ -2,6 +2,12 @@ use {StateManager, ScreenManager};
use super::super::state::commands::*;
use super::raw::RawTerminal;
use super::screen::AlternateScreen;
use super::super::cursor;
use super::super::input;
use super::super::terminal;
use std::collections::HashMap;
use std::io::Result;
@ -93,6 +99,18 @@ impl Terminal{
return Ok(())
}
pub fn cursor(&self) -> cursor::TerminalCursor {
cursor::TerminalCursor::new(&self.active_screen)
}
pub fn input(&self) -> input::TerminalInput {
return input::TerminalInput::new(&self.active_screen)
}
pub fn terminal(&self) -> input::TerminalInput {
return input::TerminalInput::new(&self.active_screen)
}
}
impl Drop for Terminal

View File

@ -1,183 +1,183 @@
//! 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>,
}
/// Create `Crossterm` instance from `Context`
impl From<Rc<Context>> for Crossterm {
fn from(context: Rc<Context>) -> Self {
return Crossterm { context: context };
}
}
impl Crossterm {
pub fn new() -> Crossterm {
return Crossterm {
context: Context::new(),
};
}
/// Get an Terminal implementation whereon terminal related actions can be performed.
///
/// #Example
///
/// ```rust
///
/// extern crate crossterm;
/// use crossterm::Crossterm;
/// use crossterm::terminal;
///
/// let crossterm = Crossterm::new();
/// let mut terminal = crossterm.terminal();
///
/// ```
pub fn terminal(&self) -> terminal::Terminal {
return terminal::Terminal::new(self.context.clone());
}
/// Get an TerminalCursor implementation whereon cursor related actions can be performed.
///
/// #Example
///
/// ```rust
///
/// extern crate crossterm;
/// use crossterm::Crossterm;
/// use crossterm::terminal;
///
/// let crossterm = Crossterm::new();
/// let mut cursor = crossterm.cursor();
///
/// // move cursor to x: 5 and y:10
/// cursor.goto(5,10);
///
/// ```
pub fn cursor(&self) -> cursor::TerminalCursor {
return cursor::TerminalCursor::new(self.context.clone());
}
/// Get an Color implementation whereon color related actions can be performed.
///
/// Check `/examples/version/color` in the library for more specific examples.
///
/// #Example
///
/// ```rust
///
/// extern crate crossterm;
/// use crossterm::Crossterm;
/// use crossterm::terminal;
///
/// let crossterm = Crossterm::new();
/// let mut terminal_color = crossterm.color();
///
/// ```
pub fn color(&self) -> style::TerminalColor {
return style::TerminalColor::new(self.context.clone());
}
pub fn input(&self) -> input::TerminalInput {
return input::TerminalInput::new(self.context.clone());
}
/// Wraps an displayable object so it can be formatted with colors and attributes.
///
/// Check `/examples/color` in the library for more specific examples.
///
/// #Example
///
/// ```rust
/// extern crate crossterm;
///
/// use self::crossterm::style::{paint,Color};
/// use self::crossterm::Crossterm;
///
/// fn main()
/// {
/// let crossterm = Crossterm::new();
/// // Create an styledobject object from the text 'Unstyled font'
/// // Currently it has the default foreground color and background color.
/// println!("{}",crossterm.paint("Unstyled font"));
///
/// // Create an displayable object from the text 'Colored font',
/// // Paint this with the `Red` foreground color and `Blue` background color.
/// // Print the result.
/// let styledobject = crossterm.paint("Colored font").with(Color::Red).on(Color::Blue);
/// println!("{}", styledobject);
///
/// // Or all in one line
/// println!("{}", crossterm.paint("Colored font").with(Color::Red).on(Color::Blue));
/// }
/// ```
pub fn paint<'a, D: Display>(&'a self, value: D) -> style::StyledObject<D> {
self.terminal().paint(value)
}
/// Write any displayable value to the current screen weather it will be the main screen or alternate screen.
///
/// #Example
///
/// ```rust
///
/// extern crate crossterm;
/// use crossterm::Crossterm;
///
/// let mut crossterm = Crossterm::new();
/// crossterm.write("Some text \n Some text on new line.");
///
/// ```
pub fn write<D: Display>(&self, value: D) {
self.terminal().write(value)
}
/// Get an copy of the context that `Crossterm` uses internally.
pub fn context(&self) -> Rc<Context> {
self.context.clone()
}
// context: Rc<Context>,
}
//
///// Create `Crossterm` instance from `Context`
//impl From<Rc<Context>> for Crossterm {
// fn from(context: Rc<Context>) -> Self {
// return Crossterm { context: context };
// }
//}
//
//impl Crossterm {
// pub fn new() -> Crossterm {
// return Crossterm {
// context: Context::new(),
// };
// }
//
// /// Get an Terminal implementation whereon terminal related actions can be performed.
// ///
// /// #Example
// ///
// /// ```rust
// ///
// /// extern crate crossterm;
// /// use crossterm::Crossterm;
// /// use crossterm::terminal;
// ///
// /// let crossterm = Crossterm::new();
// /// let mut terminal = crossterm.terminal();
// ///
// /// ```
// pub fn terminal(&self) -> terminal::Terminal {
// return terminal::Terminal::new(self.context.clone());
// }
//
// /// Get an TerminalCursor implementation whereon cursor related actions can be performed.
// ///
// /// #Example
// ///
// /// ```rust
// ///
// /// extern crate crossterm;
// /// use crossterm::Crossterm;
// /// use crossterm::terminal;
// ///
// /// let crossterm = Crossterm::new();
// /// let mut cursor = crossterm.cursor();
// ///
// /// // move cursor to x: 5 and y:10
// /// cursor.goto(5,10);
// ///
// /// ```
// pub fn cursor(&self) -> cursor::TerminalCursor {
// return cursor::TerminalCursor::new(self.context.clone());
// }
//
// /// Get an Color implementation whereon color related actions can be performed.
// ///
// /// Check `/examples/version/color` in the library for more specific examples.
// ///
// /// #Example
// ///
// /// ```rust
// ///
// /// extern crate crossterm;
// /// use crossterm::Crossterm;
// /// use crossterm::terminal;
// ///
// /// let crossterm = Crossterm::new();
// /// let mut terminal_color = crossterm.color();
// ///
// /// ```
// pub fn color(&self) -> style::TerminalColor {
// return style::TerminalColor::new(self.context.clone());
// }
//
// pub fn input(&self) -> input::TerminalInput {
// return input::TerminalInput::new(self.context.clone());
// }
//
// /// Wraps an displayable object so it can be formatted with colors and attributes.
// ///
// /// Check `/examples/color` in the library for more specific examples.
// ///
// /// #Example
// ///
// /// ```rust
// /// extern crate crossterm;
// ///
// /// use self::crossterm::style::{paint,Color};
// /// use self::crossterm::Crossterm;
// ///
// /// fn main()
// /// {
// /// let crossterm = Crossterm::new();
// /// // Create an styledobject object from the text 'Unstyled font'
// /// // Currently it has the default foreground color and background color.
// /// println!("{}",crossterm.paint("Unstyled font"));
// ///
// /// // Create an displayable object from the text 'Colored font',
// /// // Paint this with the `Red` foreground color and `Blue` background color.
// /// // Print the result.
// /// let styledobject = crossterm.paint("Colored font").with(Color::Red).on(Color::Blue);
// /// println!("{}", styledobject);
// ///
// /// // Or all in one line
// /// println!("{}", crossterm.paint("Colored font").with(Color::Red).on(Color::Blue));
// /// }
// /// ```
// pub fn paint<'a, D: Display>(&'a self, value: D) -> style::StyledObject<D> {
// self.terminal().paint(value)
// }
//
// /// Write any displayable value to the current screen weather it will be the main screen or alternate screen.
// ///
// /// #Example
// ///
// /// ```rust
// ///
// /// extern crate crossterm;
// /// use crossterm::Crossterm;
// ///
// /// let mut crossterm = Crossterm::new();
// /// crossterm.write("Some text \n Some text on new line.");
// ///
// /// ```
// pub fn write<D: Display>(&self, value: D) {
// self.terminal().write(value)
// }
//
// /// Get an copy of the context that `Crossterm` uses internally.
// pub fn context(&self) -> Rc<Context> {
// self.context.clone()
// }
//}

View File

@ -15,7 +15,7 @@ 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: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
pub fn get_terminal_size(screen_manager: &ScreenManager) -> (u16, u16) {
#[cfg(unix)]
return terminal_size();
@ -24,12 +24,12 @@ pub fn get_terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16
}
/// Get the cursor position based on the current platform.
pub fn get_cursor_position(context: Rc<Context>) -> (u16, u16) {
pub fn get_cursor_position(screen_manager: &ScreenManager) -> (u16, u16) {
#[cfg(unix)]
return pos(context.clone());
return pos(screen_manager);
#[cfg(windows)]
return pos(&context.screen_manager);
return pos(screen_manager);
}
/// exit the current terminal.

View File

@ -147,16 +147,13 @@ impl IAlternateScreenCommand for ToAlternateScreenBufferCommand {
// Make the new screen buffer the active screen buffer.
csbi::set_active_screen_buffer(new_handle)?;
let b: &mut WinApiScreenManager = match screen_manager
.as_any()
match screen_manager
.as_any_mut()
.downcast_mut::<WinApiScreenManager>()
{
Some(b) => b,
Some(b) => b.set_alternate_handle(new_handle),
None => return Err(Error::new(ErrorKind::Other,"Invalid cast exception")),
};
b.set_alternate_handle(new_handle);
Ok(())
}