Refactored WinApi code
This commit is contained in:
parent
2cc40d5d28
commit
d38f406dc7
@ -45,6 +45,12 @@ fn main() {
|
||||
use crossterm::raw::RawTerminal;
|
||||
use crossterm::Crossterm;
|
||||
|
||||
|
||||
use crossterm::cursor::cursor::TerminalCursor;
|
||||
use crossterm::terminal::terminal::Terminal;
|
||||
use crossterm::terminal::ClearType;
|
||||
use std::io::Read;
|
||||
|
||||
pub fn crossterm() {
|
||||
let crossterm = Crossterm::new();
|
||||
let mut term = crossterm.terminal();
|
||||
@ -57,27 +63,30 @@ pub fn crossterm() {
|
||||
let mut raw_screen = RawTerminal::new(&crossterm.context());
|
||||
raw_screen.enable();
|
||||
|
||||
let mut stdin = input.read_async().bytes();
|
||||
let mut stdin = input.read_until_async().bytes();
|
||||
|
||||
let mut buf = String::new();
|
||||
|
||||
let mut counter: u16 = 1;
|
||||
let (term_x, term_y) = term.terminal_size();
|
||||
let mut command_bar_y = term_y;
|
||||
let (curs_x, curs_y) = cursor.pos();
|
||||
|
||||
let mut counter: u16 = 0 + curs_y;
|
||||
loop {
|
||||
cursor.goto(0, counter);
|
||||
term.write("test data");
|
||||
let (curs_x, curs_y) = cursor.pos();
|
||||
term.write(format!("cursor pos {} term pos: {} command pos: {}", curs_y, term_y, command_bar_y));
|
||||
cursor.goto(0, counter + 1);
|
||||
|
||||
let (term_width, term_height) = term.terminal_size();
|
||||
let (cursor_x, cursor_y) = cursor.pos();
|
||||
|
||||
if cursor_y >= term_height {
|
||||
if (curs_y >= term_y - 1 )
|
||||
{
|
||||
cursor.goto(0, counter + 1);
|
||||
term.clear(ClearType::CurrentLine);
|
||||
cursor.goto(0, counter + 2);
|
||||
term.write(format!("> {}", buf));
|
||||
term.scroll_up(1);
|
||||
}
|
||||
|
||||
cursor.goto(0, term_height);
|
||||
term.clear(ClearType::CurrentLine);
|
||||
term.write(format!("> {}", buf));
|
||||
|
||||
while let Some(b) = stdin.next() {
|
||||
if let Ok(b) = b {
|
||||
if b == 3 {
|
||||
@ -93,18 +102,3 @@ pub fn crossterm() {
|
||||
thread::sleep(time::Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
|
||||
use crossterm::cursor::cursor::TerminalCursor;
|
||||
use crossterm::terminal::terminal::Terminal;
|
||||
use crossterm::terminal::ClearType;
|
||||
use std::io::Read;
|
||||
|
||||
//pub fn swap_write(terminal: &mut Terminal, out: &mut RawTerminal, cursor: &mut TerminalCursor, msg: &str, input_buf: &String) {
|
||||
// let (term_width,term_height) = terminal.terminal_size();
|
||||
// let (x,y) = cursor.get_post();
|
||||
// cursor.goto(0,0);
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//}
|
||||
|
@ -29,6 +29,11 @@ impl ITerminalCursor for AnsiCursor {
|
||||
functions::get_cursor_position(self.context.clone())
|
||||
}
|
||||
|
||||
fn absolute_pos(&self) -> (u16, u16)
|
||||
{
|
||||
functions::get_absolute_cursor_pos(&self.context)
|
||||
}
|
||||
|
||||
fn move_up(&self, count: u16) {
|
||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
||||
{
|
||||
|
@ -82,10 +82,15 @@ impl TerminalCursor {
|
||||
/// }
|
||||
///
|
||||
/// ```
|
||||
pub fn pos(&mut self) -> (u16, u16) {
|
||||
pub fn pos(&self) -> (u16, u16) {
|
||||
self.terminal_cursor.pos()
|
||||
}
|
||||
|
||||
pub fn absolute_pos(&self) -> (u16, u16)
|
||||
{
|
||||
self.terminal_cursor.absolute_pos()
|
||||
}
|
||||
|
||||
/// Move the current cursor position `n` times up.
|
||||
///
|
||||
/// #Example
|
||||
|
@ -34,6 +34,9 @@ pub trait ITerminalCursor {
|
||||
fn goto(&self, x: u16, y: u16);
|
||||
/// Get the location (x,y) of the current cusror in the context
|
||||
fn pos(&self) -> (u16, u16);
|
||||
|
||||
fn absolute_pos(&self) -> (u16, u16);
|
||||
|
||||
/// Move cursor n times up
|
||||
fn move_up(&self, count: u16);
|
||||
/// Move the cursor `n` times to the right.
|
||||
|
@ -29,6 +29,11 @@ impl ITerminalCursor for WinApiCursor {
|
||||
cursor::pos(&self.screen_manager)
|
||||
}
|
||||
|
||||
fn absolute_pos(&self) -> (u16, u16)
|
||||
{
|
||||
cursor::absolute_cursor_pos(&self.screen_manager)
|
||||
}
|
||||
|
||||
fn move_up(&self, count: u16) {
|
||||
let (xpos, ypos) = self.pos();
|
||||
self.goto(xpos, ypos - count);
|
||||
|
@ -33,7 +33,15 @@ impl ITerminalInput for WindowsInput {
|
||||
let mut chars: Vec<char> = Vec::new();
|
||||
|
||||
loop {
|
||||
let pressed_char = unsafe { _getwch() };
|
||||
let mut is_raw_screen = false;
|
||||
{
|
||||
let mutex = &self.context.screen_manager;
|
||||
let screen = mutex.lock().unwrap();
|
||||
is_raw_screen = screen.is_raw_screen();
|
||||
}
|
||||
|
||||
// _getwch is without echo and _getwche is with echo
|
||||
let pressed_char = unsafe { if is_raw_screen { _getwch() } else { _getwche() } };
|
||||
|
||||
// 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 {
|
||||
@ -45,9 +53,7 @@ impl ITerminalInput for WindowsInput {
|
||||
chars.push(c);
|
||||
}
|
||||
|
||||
if self.display_input {
|
||||
term.write(c);
|
||||
}
|
||||
|
||||
}
|
||||
None => panic!("Some error needs to be returned"),
|
||||
};
|
||||
@ -60,7 +66,15 @@ impl ITerminalInput for WindowsInput {
|
||||
fn read_char(&self) -> io::Result<char> {
|
||||
let term = terminal(&self.context);
|
||||
|
||||
let pressed_char = unsafe { _getwch() };
|
||||
let mut is_raw_screen = false;
|
||||
{
|
||||
let mutex = &self.context.screen_manager;
|
||||
let screen = mutex.lock().unwrap();
|
||||
is_raw_screen = screen.is_raw_screen();
|
||||
}
|
||||
|
||||
// _getwch is without echo and _getwche is with echo
|
||||
let pressed_char = unsafe { if is_raw_screen { _getwch() } else { _getwche() } };
|
||||
|
||||
// we could return error but maybe option to keep listening until valid character is inputted.
|
||||
if pressed_char == 0 || pressed_char == 0xe0 {
|
||||
@ -111,9 +125,19 @@ impl ITerminalInput for WindowsInput {
|
||||
fn read_async(&self) -> 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();
|
||||
}
|
||||
// panic!("is raw screen: {} ", is_raw_screen);
|
||||
thread::spawn(move || {
|
||||
loop {
|
||||
let pressed_char: u8 = (unsafe { _getwch() }) as u8;
|
||||
|
||||
// _getwch is without echo and _getwche is with echo
|
||||
let pressed_char = unsafe { if is_raw_screen { _getwch() } else { _getwche() } };
|
||||
|
||||
// we could return error but maybe option to keep listening until valid character is inputted.
|
||||
if pressed_char == 0 || pressed_char == 0xe0 {
|
||||
@ -134,9 +158,17 @@ impl ITerminalInput for WindowsInput {
|
||||
fn read_until_async(&self, delimiter: u8) -> 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();
|
||||
}
|
||||
|
||||
thread::spawn(move || {
|
||||
loop {
|
||||
let pressed_char: u8 = (unsafe { _getwch() }) as u8;
|
||||
// _getwch is without echo and _getwche is with echo
|
||||
let pressed_char = unsafe { if is_raw_screen { _getwch() } else { _getwche() } } as u8;
|
||||
|
||||
let end_of_stream = (pressed_char == delimiter);
|
||||
|
||||
@ -153,6 +185,7 @@ impl ITerminalInput for WindowsInput {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn is_line_end(key: char) -> bool {
|
||||
if key as u8 == 13 {
|
||||
return true;
|
||||
@ -212,6 +245,6 @@ fn key_from_key_code(code: INT) -> Key {
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn _getwche() -> INT;
|
||||
fn _getwch() -> INT;
|
||||
fn _getwch_nolock() -> INT;
|
||||
}
|
||||
|
@ -37,16 +37,30 @@ 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) {
|
||||
if let Ok(csbi) = csbi::get_csbi(screen_manager) {
|
||||
(
|
||||
csbi.dwCursorPosition.X as u16,
|
||||
csbi.dwCursorPosition.Y as u16,
|
||||
)
|
||||
|
||||
let handle = handle::get_output_handle().unwrap();
|
||||
|
||||
if let Ok(csbi) = csbi::get_csbi_by_handle(&handle) {
|
||||
( csbi.dwCursorPosition.X as u16, csbi.dwCursorPosition.Y as u16 )
|
||||
} else {
|
||||
(0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn absolute_cursor_pos(screen_manager: &Rc<Mutex<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: &Rc<Mutex<ScreenManager>>) {
|
||||
if x < 0 || x >= <i16>::max_value() {
|
||||
|
@ -1,31 +1,19 @@
|
||||
//! This module is the core of all the `WINAPI` actions. All unsafe `WINAPI` function call are done here.
|
||||
//! I am planing to refactor this a little since a lot of code could be handled safer.
|
||||
|
||||
use std::rc::Rc;
|
||||
use Context;
|
||||
|
||||
use winapi::shared::minwindef::{FALSE, TRUE};
|
||||
use winapi::shared::ntdef::NULL;
|
||||
use winapi::um::consoleapi::WriteConsoleW;
|
||||
use winapi::um::consoleapi::{GetConsoleMode, SetConsoleMode};
|
||||
|
||||
use winapi::um::wincon;
|
||||
use winapi::um::wincon::{
|
||||
CreateConsoleScreenBuffer, FillConsoleOutputAttribute, FillConsoleOutputCharacterA,
|
||||
GetConsoleScreenBufferInfo, GetLargestConsoleWindowSize, SetConsoleActiveScreenBuffer,
|
||||
SetConsoleCursorInfo, SetConsoleCursorPosition, SetConsoleScreenBufferSize,
|
||||
SetConsoleTextAttribute, SetConsoleWindowInfo, WriteConsoleOutputAttribute,
|
||||
WriteConsoleOutputCharacterA, WriteConsoleOutputCharacterW, WriteConsoleOutputW, CHAR_INFO,
|
||||
CONSOLE_CURSOR_INFO, CONSOLE_SCREEN_BUFFER_INFO, COORD, ENABLE_PROCESSED_INPUT, PSMALL_RECT,
|
||||
SMALL_RECT,
|
||||
};
|
||||
use winapi::um::winnt::HANDLE;
|
||||
use winapi::um::wincon::{
|
||||
SetConsoleTextAttribute, SetConsoleWindowInfo, GetLargestConsoleWindowSize,
|
||||
COORD, SMALL_RECT
|
||||
};
|
||||
|
||||
use super::{handle, Empty};
|
||||
use super::super::super::manager::ScreenManager;
|
||||
|
||||
use super::super::super::manager::{ScreenManager, WinApiScreenManager};
|
||||
use std::io::{ErrorKind, Result};
|
||||
use std::sync::Mutex;
|
||||
use std::rc::Rc;
|
||||
|
||||
/// Get the largest console window size possible.
|
||||
pub fn get_largest_console_window_size() -> COORD {
|
||||
|
@ -5,7 +5,6 @@ pub mod cursor;
|
||||
pub mod kernel;
|
||||
pub mod terminal;
|
||||
pub mod writing;
|
||||
//pub mod reading;
|
||||
pub mod csbi;
|
||||
pub mod handle;
|
||||
|
||||
|
@ -2,11 +2,14 @@ use std::rc::Rc;
|
||||
use std::sync::Mutex;
|
||||
use ScreenManager;
|
||||
|
||||
use super::csbi;
|
||||
use super::{csbi, handle};
|
||||
|
||||
/// Get the terminal size
|
||||
pub fn terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
|
||||
if let Ok(csbi) = csbi::get_csbi(screen_manager) {
|
||||
|
||||
let handle = handle::get_output_handle().unwrap();
|
||||
|
||||
if let Ok(csbi) = csbi::get_csbi_by_handle(&handle) {
|
||||
(
|
||||
(csbi.srWindow.Right - csbi.srWindow.Left) as u16,
|
||||
(csbi.srWindow.Bottom - csbi.srWindow.Top) as u16,
|
||||
@ -16,6 +19,20 @@ pub fn terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn buffer_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
|
||||
|
||||
let handle = handle::get_output_handle().unwrap();
|
||||
|
||||
if let Ok(csbi) = csbi::get_csbi_by_handle(&handle) {
|
||||
(
|
||||
(csbi.dwSize.X) as u16,
|
||||
(csbi.dwSize.Y) as u16,
|
||||
)
|
||||
} else {
|
||||
return (0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Exit the current process.
|
||||
pub fn exit() {
|
||||
::std::process::exit(256);
|
||||
|
@ -8,14 +8,27 @@ use std::io::{self, Read, Write};
|
||||
use super::IScreenManager;
|
||||
|
||||
pub struct AnsiScreenManager {
|
||||
pub is_alternate_screen: bool,
|
||||
is_alternate_screen: bool,
|
||||
is_raw_screen: bool,
|
||||
output: Box<Write>,
|
||||
input: Box<Read>,
|
||||
}
|
||||
|
||||
impl IScreenManager for AnsiScreenManager {
|
||||
fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool) {
|
||||
self.is_alternate_screen = is_alternate_screen;
|
||||
fn set_is_raw_screen(&mut self, value: bool) {
|
||||
self.is_raw_screen = value;
|
||||
}
|
||||
|
||||
fn set_is_alternate_screen(&mut self, value: bool) {
|
||||
self.is_alternate_screen = value;
|
||||
}
|
||||
|
||||
fn is_raw_screen(&self) -> bool {
|
||||
self.is_raw_screen
|
||||
}
|
||||
|
||||
fn is_alternate_screen(&self) -> bool {
|
||||
self.is_alternate_screen
|
||||
}
|
||||
|
||||
fn write_string(&mut self, string: String) -> io::Result<usize> {
|
||||
@ -63,6 +76,7 @@ impl AnsiScreenManager {
|
||||
input: (Box::from(io::stdin()) as Box<Read>),
|
||||
output: (Box::from(io::stdout()) as Box<Write>),
|
||||
is_alternate_screen: false,
|
||||
is_raw_screen: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,10 +33,22 @@ impl ScreenManager {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_is_raw_screen(&mut self, value: bool) {
|
||||
self.screen_manager.set_is_raw_screen(value);
|
||||
}
|
||||
|
||||
/// Toggle a boolean to whether alternate screen is on or of.
|
||||
pub fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool) {
|
||||
self.screen_manager
|
||||
.toggle_is_alternate_screen(is_alternate_screen);
|
||||
pub fn set_is_alternate_screen(&mut self, value: bool) {
|
||||
self.screen_manager.set_is_alternate_screen(value);
|
||||
}
|
||||
|
||||
pub fn is_raw_screen(&self) -> bool {
|
||||
self.screen_manager.is_raw_screen()
|
||||
}
|
||||
|
||||
/// Toggle a boolean to whether alternate screen is on or of.
|
||||
pub fn is_alternate_screen(&self) -> bool {
|
||||
self.screen_manager.is_alternate_screen()
|
||||
}
|
||||
|
||||
/// Write an ANSI code as String.
|
||||
|
@ -33,8 +33,12 @@ use std::any::Any;
|
||||
use std::io;
|
||||
|
||||
pub trait IScreenManager {
|
||||
/// Toggle the value if alternatescreen is on.
|
||||
fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool);
|
||||
fn set_is_raw_screen(&mut self, value: bool);
|
||||
fn set_is_alternate_screen(&mut self, value: bool);
|
||||
|
||||
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.
|
||||
|
@ -8,15 +8,29 @@ use std::io::{self, Write};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct WinApiScreenManager {
|
||||
pub is_alternate_screen: bool,
|
||||
is_alternate_screen: bool,
|
||||
is_raw_screen: bool,
|
||||
output: HANDLE,
|
||||
alternate_handle: HANDLE,
|
||||
}
|
||||
|
||||
impl IScreenManager for WinApiScreenManager {
|
||||
fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool) {
|
||||
self.is_alternate_screen = is_alternate_screen;
|
||||
|
||||
fn set_is_raw_screen(&mut self, value: bool) {
|
||||
self.is_raw_screen = value;
|
||||
}
|
||||
fn set_is_alternate_screen(&mut self, value: bool) {
|
||||
self.is_alternate_screen = value;
|
||||
}
|
||||
|
||||
fn is_raw_screen(&self) -> bool {
|
||||
self.is_raw_screen
|
||||
}
|
||||
|
||||
fn is_alternate_screen(&self) -> bool {
|
||||
self.is_alternate_screen
|
||||
}
|
||||
|
||||
|
||||
fn write_string(&mut self, string: String) -> io::Result<usize> {
|
||||
self.write(string.as_bytes())
|
||||
@ -49,6 +63,7 @@ impl WinApiScreenManager {
|
||||
WinApiScreenManager {
|
||||
output: handle::get_output_handle().unwrap(),
|
||||
is_alternate_screen: false,
|
||||
is_raw_screen: false,
|
||||
alternate_handle: handle::get_output_handle().unwrap(),
|
||||
}
|
||||
}
|
||||
@ -56,7 +71,6 @@ impl WinApiScreenManager {
|
||||
/// Set the alternate handle to the given handle.
|
||||
pub fn set_alternate_handle(&mut self, alternate_handle: HANDLE) {
|
||||
self.alternate_handle = alternate_handle;
|
||||
|
||||
// needs to be turned on so that escape characters like \n and \t will be processed.
|
||||
kernel::set_console_mode(&self.alternate_handle, ENABLE_PROCESSED_OUTPUT as u32);
|
||||
}
|
||||
|
@ -6,10 +6,10 @@ use Context;
|
||||
use ScreenManager;
|
||||
|
||||
#[cfg(windows)]
|
||||
use kernel::windows_kernel::terminal::{exit, terminal_size};
|
||||
use kernel::windows_kernel::terminal::{exit, terminal_size, buffer_size};
|
||||
|
||||
#[cfg(windows)]
|
||||
use kernel::windows_kernel::cursor::pos;
|
||||
use kernel::windows_kernel::cursor::{pos, absolute_cursor_pos};
|
||||
|
||||
#[cfg(unix)]
|
||||
use kernel::unix_kernel::terminal::{exit, pos, terminal_size};
|
||||
@ -32,6 +32,16 @@ pub fn get_cursor_position(context: Rc<Context>) -> (u16, u16) {
|
||||
return pos(&context.screen_manager);
|
||||
}
|
||||
|
||||
pub fn get_buffer_size(context: &Rc<Context>) -> (u16, u16)
|
||||
{
|
||||
return buffer_size(&context.screen_manager);
|
||||
}
|
||||
|
||||
pub fn get_absolute_cursor_pos(context: &Rc<Context>) -> (u16, u16)
|
||||
{
|
||||
return absolute_cursor_pos(&context.screen_manager);
|
||||
}
|
||||
|
||||
/// exit the current terminal.
|
||||
pub fn exit_terminal() {
|
||||
#[cfg(unix)]
|
||||
|
@ -40,10 +40,22 @@ impl RawTerminal {
|
||||
}
|
||||
|
||||
pub fn enable(&self) -> bool {
|
||||
{
|
||||
let mutex = &self.context.screen_manager;
|
||||
let mut screen = mutex.lock().unwrap();
|
||||
screen.set_is_raw_screen(true);
|
||||
}
|
||||
|
||||
CommandManager::execute(self.context.clone(), self.command_id)
|
||||
}
|
||||
|
||||
pub fn disable(&self) -> bool {
|
||||
{
|
||||
let mutex = &self.context.screen_manager;
|
||||
let mut screen = mutex.lock().unwrap();
|
||||
screen.set_is_raw_screen(false);
|
||||
}
|
||||
|
||||
CommandManager::undo(self.context.clone(), self.command_id)
|
||||
}
|
||||
}
|
||||
@ -60,16 +72,22 @@ impl<W: Write> IntoRawMode for W {
|
||||
fn into_raw_mode(&self, context: Rc<Context>) -> io::Result<RawTerminal> {
|
||||
let command_id = EnableRawModeCommand::new(&context.state_manager);
|
||||
|
||||
let success = CommandManager::execute(context.clone(), command_id);
|
||||
{
|
||||
let mutex = &context.screen_manager;
|
||||
let mut screen = mutex.lock().unwrap();
|
||||
screen.set_is_raw_screen(true);
|
||||
}
|
||||
|
||||
if success {
|
||||
Ok(RawTerminal {
|
||||
let raw_terminal = RawTerminal {
|
||||
context: context.clone(),
|
||||
command_id: command_id,
|
||||
})
|
||||
} else {
|
||||
panic!("cannot move into raw mode")
|
||||
};
|
||||
|
||||
if raw_terminal.enable()
|
||||
{
|
||||
return Ok(raw_terminal);
|
||||
}
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "Could not enter raw mode."))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@
|
||||
|
||||
use shared::functions;
|
||||
use state::commands::*;
|
||||
use Context;
|
||||
use {CommandManager, Context};
|
||||
|
||||
use std::convert::From;
|
||||
use std::io::{self, Write};
|
||||
@ -109,36 +109,29 @@ impl AlternateScreen {
|
||||
};
|
||||
|
||||
screen.to_alternate();
|
||||
|
||||
return screen;
|
||||
}
|
||||
|
||||
/// Change the current screen to the mainscreen.
|
||||
pub fn to_main(&self) {
|
||||
let mut mutex = &self.context.state_manager;
|
||||
{
|
||||
let mut state_manager = mutex.lock().unwrap();
|
||||
let mutex = &self.context.screen_manager;
|
||||
let mut screen = mutex.lock().unwrap();
|
||||
screen.set_is_alternate_screen(false);
|
||||
}
|
||||
|
||||
let mut mx = &state_manager.get(self.command_id);
|
||||
{
|
||||
let mut command = mx.lock().unwrap();
|
||||
command.undo();
|
||||
}
|
||||
}
|
||||
CommandManager::undo(self.context.clone(), self.command_id);
|
||||
}
|
||||
|
||||
/// Change the current screen to alternate screen.
|
||||
pub fn to_alternate(&self) {
|
||||
let mut mutex = &self.context.state_manager;
|
||||
{
|
||||
let mut state_manager = mutex.lock().unwrap();
|
||||
|
||||
let mut mx = &state_manager.get(self.command_id);
|
||||
{
|
||||
let mut command = mx.lock().unwrap();
|
||||
|
||||
command.execute();
|
||||
}
|
||||
let mutex = &self.context.screen_manager;
|
||||
let mut screen = mutex.lock().unwrap();
|
||||
screen.set_is_alternate_screen(true);
|
||||
}
|
||||
CommandManager::execute(self.context.clone(), self.command_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,6 @@ impl IStateCommand for ToAlternateScreenBufferCommand {
|
||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
||||
{
|
||||
screen.write_str(csi!("?1049h"));
|
||||
screen.toggle_is_alternate_screen(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -50,7 +49,6 @@ impl IStateCommand for ToAlternateScreenBufferCommand {
|
||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
||||
{
|
||||
screen.write_str(csi!("?1049l"));
|
||||
screen.toggle_is_alternate_screen(false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -163,10 +163,11 @@ impl IStateCommand for ToAlternateScreenBufferCommand {
|
||||
// Make the new screen buffer the active screen buffer.
|
||||
csbi::set_active_screen_buffer(new_handle);
|
||||
|
||||
let mut screen_manager = self.context.screen_manager.lock().unwrap();
|
||||
screen_manager.toggle_is_alternate_screen(true);
|
||||
{
|
||||
let mutex = &self.context.screen_manager;
|
||||
let mut screen = mutex.lock().unwrap();
|
||||
|
||||
let b: &mut WinApiScreenManager = match screen_manager
|
||||
let b: &mut WinApiScreenManager = match screen
|
||||
.as_any()
|
||||
.downcast_mut::<WinApiScreenManager>()
|
||||
{
|
||||
@ -175,7 +176,7 @@ impl IStateCommand for ToAlternateScreenBufferCommand {
|
||||
};
|
||||
|
||||
b.set_alternate_handle(new_handle);
|
||||
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
@ -183,11 +184,6 @@ impl IStateCommand for ToAlternateScreenBufferCommand {
|
||||
let handle = handle::get_output_handle().unwrap();
|
||||
csbi::set_active_screen_buffer(handle);
|
||||
|
||||
{
|
||||
let mut screen_manager = self.context.screen_manager.lock().unwrap();
|
||||
screen_manager.toggle_is_alternate_screen(false);
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,8 @@ impl ITerminal for AnsiTerminal {
|
||||
functions::get_terminal_size(&self.context.screen_manager)
|
||||
}
|
||||
|
||||
fn buffer_size(&self) -> (u16, u16) { functions::get_buffer_size(&self.context) }
|
||||
|
||||
fn scroll_up(&self, count: i16) {
|
||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
||||
{
|
||||
|
@ -42,6 +42,10 @@ pub trait ITerminal {
|
||||
fn clear(&self, clear_type: ClearType);
|
||||
/// Get the terminal size (x,y)
|
||||
fn terminal_size(&self) -> (u16, u16);
|
||||
|
||||
// get the size of the current buffer
|
||||
fn buffer_size(&self) -> (u16, u16);
|
||||
|
||||
/// Scroll `n` lines up in the current terminal.
|
||||
fn scroll_up(&self, count: i16);
|
||||
/// Scroll `n` lines down in the current terminal.
|
||||
|
@ -85,6 +85,10 @@ impl Terminal {
|
||||
return self.terminal.terminal_size();
|
||||
}
|
||||
|
||||
pub fn buffer_size(&self) -> (u16, u16) {
|
||||
return self.terminal.buffer_size();
|
||||
}
|
||||
|
||||
/// Scroll `n` lines up in the current terminal.
|
||||
///
|
||||
/// #Example
|
||||
|
@ -40,6 +40,8 @@ impl ITerminal for WinApiTerminal {
|
||||
terminal::terminal_size(&self.context.screen_manager)
|
||||
}
|
||||
|
||||
fn buffer_size(&self) -> (u16, u16) {terminal::buffer_size(&self.context.screen_manager)}
|
||||
|
||||
fn scroll_up(&self, count: i16) {
|
||||
let csbi = csbi::get_csbi(&self.context.screen_manager).unwrap();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user