Removed downcast for HANDLE WinAPi. Also we do not need to keep track of current HANDLE since this will now be gotton from CreateFileW

This commit is contained in:
TimonPost 2018-08-22 19:58:30 +02:00
parent c848beb721
commit cc55c190d8
19 changed files with 110 additions and 178 deletions

View File

@ -19,19 +19,6 @@ use std::io::Write;
use std::{thread,time}; use std::{thread,time};
fn main() fn main()
{ {
use crossterm::screen::RawScreen; terminal::raw_mode::print_wait_screen_on_alternate_window();
use crossterm::Screen;
let mut screen = Screen::new(true);
cursor::goto();
// write!(screen, "text \n\r");
let a = screen.enable_alternate_modes(true).unwrap();
// cursor::goto();
thread::sleep(time::Duration::from_millis(2000)); thread::sleep(time::Duration::from_millis(2000));
drop(a);
cursor::goto();
//
// write!(a, "text \n\r");
} }

View File

@ -25,14 +25,10 @@ fn main()
/// run the program /// run the program
pub fn run() pub fn run()
{ {
print_welcome_screen();
// This is represents the current screen. // This is represents the current screen.
let screen = Screen::new(true); let screen = Screen::new(true);
// set size of terminal so the map we are going to draw is fitting the screen.
terminal(&screen).set_size(60,110);
print_welcome_screen(&screen);
start_algorithm(&screen); start_algorithm(&screen);
drop(screen); drop(screen);
} }
@ -56,8 +52,9 @@ fn start_algorithm(screen: &Screen)
} }
} }
fn print_welcome_screen(screen: &Screen) fn print_welcome_screen()
{ {
let screen = Screen::default();
let crossterm = Crossterm::new(&screen); let crossterm = Crossterm::new(&screen);
// create the handle for the cursor and terminal. // create the handle for the cursor and terminal.
@ -65,17 +62,20 @@ fn print_welcome_screen(screen: &Screen)
let cursor = crossterm.cursor(); let cursor = crossterm.cursor();
let input = crossterm.input(); let input = crossterm.input();
// set size of terminal so the map we are going to draw is fitting the screen.
terminal.set_size(60,110);
// clear the screen and print the welcome message. // clear the screen and print the welcome message.
terminal.clear(ClearType::All); terminal.clear(ClearType::All);
cursor.goto(0, 0); cursor.goto(0, 0);
terminal.write(WELCOME_MESSAGE.join("\n\r")); terminal.write(WELCOME_MESSAGE.join("\r\n"));
cursor.hide(); cursor.hide();
cursor.goto(0, 10); cursor.goto(0, 10);
terminal.write("The first depth search algorithm will start in: Seconds"); terminal.write("The first depth search algorithm will start in: Seconds");
cursor.goto(0, 11); cursor.goto(0, 11);
terminal.write("\nPress `q` to abort the program"); terminal.write("Press `q` to abort the program");
let mut stdin = input.read_async().bytes(); let mut stdin = input.read_async().bytes();

View File

@ -73,14 +73,10 @@ fn main() {
snake.draw_snake(&screen); snake.draw_snake(&screen);
if snake.has_eaten_food(map.foot_pos) if snake.has_eaten_food(map.foot_pos)
{ {
map.spawn_food(&free_positions, &screen); map.spawn_food(&free_positions, &screen);
} }
} }
} }
game_over_screen(); game_over_screen();

View File

@ -7,20 +7,21 @@ use crossterm::style::{style, Color};
use std::io::{stdout, Write}; use std::io::{stdout, Write};
use std::{thread, time}; use std::{thread, time};
fn print_wait_screen(screen: &Screen) { fn print_wait_screen(screen: &mut Screen) {
let crossterm = Crossterm::new(screen); let crossterm = Crossterm::new(screen);
let terminal = crossterm.terminal(); let terminal = crossterm.terminal();
let cursor = crossterm.cursor(); let cursor = crossterm.cursor();
terminal.clear(ClearType::All); terminal.clear(ClearType::All);
cursor.goto(0, 0);
cursor.hide();
terminal.write( cursor.hide();
"Welcome to the wait screen.\n\ cursor.goto(0, 0);
Please wait a few seconds until we arrive back at the main screen.\n\ screen.write(b"Welcome to the wait screen.");
Progress: ", cursor.goto(0, 1);
); screen.write(b"Please wait a few seconds until we arrive back at the main screen.");
cursor.goto(0, 2);
screen.write(b"Progress:");
cursor.goto(0, 3);
// print some progress example. // print some progress example.
for i in 1..5 { for i in 1..5 {
@ -37,9 +38,9 @@ fn print_wait_screen(screen: &Screen) {
pub fn print_wait_screen_on_alternate_window() { pub fn print_wait_screen_on_alternate_window() {
let screen = Screen::default(); let screen = Screen::default();
if let Ok(alternate) = screen.enable_alternate_modes(true) if let Ok(ref mut alternate) = screen.enable_alternate_modes(true)
{ {
print_wait_screen(&alternate.screen); print_wait_screen(&mut alternate.screen);
} }
println!("Whe are back at the main screen"); println!("Whe are back at the main screen");

View File

@ -88,7 +88,7 @@ impl RawModeCommand {
/// Enables raw mode. /// Enables raw mode.
pub fn enable(&mut self) -> Result<()> { pub fn enable(&mut self) -> Result<()> {
let mut dw_mode: DWORD = 0; let mut dw_mode: DWORD = 0;
let stdout = handle::get_current_handle_1().unwrap(); let stdout = handle::get_current_handle().unwrap();
if !kernel::get_console_mode(&stdout, &mut dw_mode) { if !kernel::get_console_mode(&stdout, &mut dw_mode) {
return Err(Error::new( return Err(Error::new(
@ -111,7 +111,7 @@ impl RawModeCommand {
/// Disables raw mode. /// Disables raw mode.
pub fn disable(&self) -> Result<()> { pub fn disable(&self) -> Result<()> {
let stdout = handle::get_current_handle_1().unwrap(); let stdout = handle::get_current_handle().unwrap();
let mut dw_mode: DWORD = 0; let mut dw_mode: DWORD = 0;
if !kernel::get_console_mode(&stdout, &mut dw_mode) { if !kernel::get_console_mode(&stdout, &mut dw_mode) {
@ -156,16 +156,6 @@ impl IAlternateScreenCommand for ToAlternateScreenCommand {
// Make the new screen buffer the active screen buffer. // Make the new screen buffer the active screen buffer.
csbi::set_active_screen_buffer(new_handle)?; csbi::set_active_screen_buffer(new_handle)?;
let b: &mut WinApiOutput = match stdout
.as_any_mut()
.downcast_mut::<WinApiOutput>()
{
Some(b) => b,
None => return Err(Error::new(ErrorKind::Other, "Invalid cast exception")),
};
b.set(new_handle);
Ok(()) Ok(())
} }

View File

@ -22,7 +22,10 @@ pub fn get_terminal_size() -> (u16, u16) {
/// Get the cursor position based on the current platform. /// Get the cursor position based on the current platform.
pub fn get_cursor_position(stdout: &Arc<TerminalOutput>) -> (u16, u16) { pub fn get_cursor_position(stdout: &Arc<TerminalOutput>) -> (u16, u16) {
#[cfg(unix)]
return pos(stdout); return pos(stdout);
#[cfg(windows)]
return pos();
} }
/// exit the current terminal. /// exit the current terminal.

View File

@ -10,7 +10,7 @@
//! The characters are not processed by the terminal driver, but are sent straight through. //! The characters are not processed by the terminal driver, but are sent straight through.
//! Special character have no meaning, like backspace will not be interpret as backspace but instead will be directly send to the terminal. //! Special character have no meaning, like backspace will not be interpret as backspace but instead will be directly send to the terminal.
//! - Escape characters //! - Escape characters
//! Note that in raw modes `\n` will move to the new line but the cursor will be at the same position as before on the new line therefor use `\n\r` to start at the new line at the first cell. //! Note that in raw modes `\n` `\r` will move to the new line but the cursor will be at the same position as before on the new line therefor use `\n\r` to start at the new line at the first cell.
//! //!
//! With these modes you can easier design the terminal screen. //! With these modes you can easier design the terminal screen.

View File

@ -55,7 +55,7 @@ impl Screen
{ {
if raw_mode if raw_mode
{ {
let screen = Screen { stdout: Arc::new(TerminalOutput::new()), buffer: Vec::new() }; let screen = Screen { stdout: Arc::new(TerminalOutput::new(true)), buffer: Vec::new() };
RawScreen::into_raw_mode(); RawScreen::into_raw_mode();
return screen; return screen;
} }
@ -71,11 +71,25 @@ impl Screen
/// For an example of this behavior, consider when vim is launched from bash. /// For an example of this behavior, consider when vim is launched from bash.
/// Vim uses the entirety of the screen to edit the file, then returning to bash leaves the original buffer unchanged. /// Vim uses the entirety of the screen to edit the file, then returning to bash leaves the original buffer unchanged.
pub fn enable_alternate_modes(&self, raw_mode: bool) -> Result<AlternateScreen> { pub fn enable_alternate_modes(&self, raw_mode: bool) -> Result<AlternateScreen> {
let stdout = TerminalOutput::new(); let stdout = TerminalOutput::new(raw_mode);
let alternate_screen = AlternateScreen::to_alternate_screen(stdout, raw_mode)?; let alternate_screen = AlternateScreen::to_alternate_screen(stdout, raw_mode)?;
return Ok(alternate_screen); return Ok(alternate_screen);
} }
/// Write buffer to an internal buffer. When you want to write the buffer to screen use `flush()`.
///
/// This function is useful if you want to build up some output and when you are ready you could flush the output to the screen.
pub fn write_buf(&mut self, buf: &[u8]) -> Result<usize> {
self.buffer.write(buf);
Ok(buf.len())
}
/// Flush the internal buffer to the screen.
pub fn flush_buf(&mut self) -> Result<()> {
self.stdout.write_buf(&self.buffer);
self.stdout.flush()
}
} }
impl From<TerminalOutput> for Screen impl From<TerminalOutput> for Screen
@ -98,7 +112,7 @@ impl Default for Screen
{ {
/// Create an new screen which will not be in raw mode or alternate mode. /// Create an new screen which will not be in raw mode or alternate mode.
fn default() -> Self { fn default() -> Self {
return Screen { stdout: Arc::new(TerminalOutput::new()), buffer: Vec::new() }; return Screen { stdout: Arc::new(TerminalOutput::new(false)), buffer: Vec::new() };
} }
} }
@ -115,17 +129,11 @@ impl Drop for Screen
impl Write for Screen impl Write for Screen
{ {
/// Write buffer to an internal buffer. When you want to write the buffer to screen use `flush()`.
///
/// This function is useful if you want to build up some output and when you are ready you could flush the output to the screen.
fn write(&mut self, buf: &[u8]) -> Result<usize> { fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.buffer.write(buf); self.stdout.write_buf(buf)
Ok(buf.len())
} }
/// Flush the internal buffer to the screen.
fn flush(&mut self) -> Result<()> { fn flush(&mut self) -> Result<()> {
self.stdout.write_buf(&self.buffer);
self.stdout.flush() self.stdout.flush()
} }
} }

View File

@ -18,12 +18,12 @@ use std::mem::size_of;
use std::sync::Arc; use std::sync::Arc;
/// Create a new console screen buffer info struct. /// Create a new console screen buffer info struct.
pub fn get_csbi(stdout: &Arc<TerminalOutput>) -> Result<CONSOLE_SCREEN_BUFFER_INFO> { pub fn get_csbi() -> Result<CONSOLE_SCREEN_BUFFER_INFO> {
let mut csbi = CONSOLE_SCREEN_BUFFER_INFO::empty(); let mut csbi = CONSOLE_SCREEN_BUFFER_INFO::empty();
let success; let success;
unsafe { unsafe {
success = GetConsoleScreenBufferInfo(handle::get_current_handle(stdout)?, &mut csbi) success = GetConsoleScreenBufferInfo(handle::get_current_handle()?, &mut csbi)
} }
if success == 0 { if success == 0 {
@ -37,10 +37,8 @@ pub fn get_csbi(stdout: &Arc<TerminalOutput>) -> Result<CONSOLE_SCREEN_BUFFER_IN
} }
/// Get buffer info and handle of the current screen. /// Get buffer info and handle of the current screen.
pub fn get_csbi_and_handle( pub fn get_csbi_and_handle() -> Result<(CONSOLE_SCREEN_BUFFER_INFO, HANDLE)> {
stdout: &Arc<TerminalOutput>, let handle = handle::get_current_handle()?;
) -> Result<(CONSOLE_SCREEN_BUFFER_INFO, HANDLE)> {
let handle = handle::get_current_handle(stdout)?;
let csbi = get_csbi_by_handle(&handle)?; let csbi = get_csbi_by_handle(&handle)?;
return Ok((csbi, handle)); return Ok((csbi, handle));
@ -63,8 +61,8 @@ pub fn get_csbi_by_handle(handle: &HANDLE) -> Result<CONSOLE_SCREEN_BUFFER_INFO>
} }
/// Set the console screen buffer size /// Set the console screen buffer size
pub fn set_console_screen_buffer_size(size: COORD, stdout: &Arc<TerminalOutput>) -> bool { pub fn set_console_screen_buffer_size(size: COORD) -> bool {
let handle = handle::get_current_handle(stdout).unwrap(); let handle = handle::get_current_handle().unwrap();
unsafe { unsafe {
if !kernel::is_true(SetConsoleScreenBufferSize(handle, size)) { if !kernel::is_true(SetConsoleScreenBufferSize(handle, size)) {

View File

@ -14,19 +14,18 @@ use std::sync::Arc;
static mut SAVED_CURSOR_POS: (u16, u16) = (0, 0); static mut SAVED_CURSOR_POS: (u16, u16) = (0, 0);
/// Reset to saved cursor position /// Reset to saved cursor position
pub fn reset_to_saved_position(stdout: &Arc<TerminalOutput>) { pub fn reset_to_saved_position() {
unsafe { unsafe {
set_console_cursor_position( set_console_cursor_position(
SAVED_CURSOR_POS.0 as i16, SAVED_CURSOR_POS.0 as i16,
SAVED_CURSOR_POS.1 as i16, SAVED_CURSOR_POS.1 as i16,
stdout,
); );
} }
} }
/// Save current cursor position to recall later. /// Save current cursor position to recall later.
pub fn save_cursor_pos(stdout: &Arc<TerminalOutput>) { pub fn save_cursor_pos() {
let position = pos(stdout); let position = pos();
unsafe { unsafe {
SAVED_CURSOR_POS = (position.0, position.1); SAVED_CURSOR_POS = (position.0, position.1);
@ -34,8 +33,8 @@ pub fn save_cursor_pos(stdout: &Arc<TerminalOutput>) {
} }
/// get the current cursor position. /// get the current cursor position.
pub fn pos(stdout: &Arc<TerminalOutput>) -> (u16, u16) { pub fn pos() -> (u16, u16) {
let handle = handle::get_current_handle(stdout).unwrap(); let handle = handle::get_current_handle().unwrap();
if let Ok(csbi) = csbi::get_csbi_by_handle(&handle) { if let Ok(csbi) = csbi::get_csbi_by_handle(&handle) {
( (
@ -48,7 +47,7 @@ pub fn pos(stdout: &Arc<TerminalOutput>) -> (u16, u16) {
} }
/// Set the cursor position to the given x and y. Note that this is 0 based. /// 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, stdout: &Arc<TerminalOutput>) { pub fn set_console_cursor_position(x: i16, y: i16) {
if x < 0 || x >= <i16>::max_value() { if x < 0 || x >= <i16>::max_value() {
panic!( panic!(
"Argument Out of Range Exception when setting cursor position to X: {}", "Argument Out of Range Exception when setting cursor position to X: {}",
@ -63,7 +62,7 @@ pub fn set_console_cursor_position(x: i16, y: i16, stdout: &Arc<TerminalOutput>)
); );
} }
let handle = handle::get_current_handle(stdout).unwrap(); let handle = handle::get_current_handle().unwrap();
let position = COORD { X: x, Y: y }; let position = COORD { X: x, Y: y };
@ -77,8 +76,8 @@ pub fn set_console_cursor_position(x: i16, y: i16, stdout: &Arc<TerminalOutput>)
} }
/// change the cursor visibility. /// change the cursor visibility.
pub fn cursor_visibility(visable: bool, stdout: &Arc<TerminalOutput>) -> io::Result<()> { pub fn cursor_visibility(visable: bool) -> io::Result<()> {
let handle = handle::get_current_handle(stdout).unwrap(); let handle = handle::get_current_handle().unwrap();
let cursor_info = CONSOLE_CURSOR_INFO { let cursor_info = CONSOLE_CURSOR_INFO {
dwSize: 100, dwSize: 100,

View File

@ -15,22 +15,11 @@ use std::ptr::null_mut;
use winapi::ctypes::c_void; use winapi::ctypes::c_void;
/// Get the global stored handle whits provides access to the current screen. /// Get the handle of the active screen.
pub fn get_current_handle(stdout: &Arc<TerminalOutput>) -> Result<HANDLE> { pub fn get_current_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 dw: DWORD = 0; let dw: DWORD = 0;
unsafe { unsafe {
let utf16: Vec<u16> = "CONOUT$\0".encode_utf16().collect();
let utf16: Vec<u16> = "CONOUT$".encode_utf16().collect();
let utf16_ptr: *const u16 = utf16.as_ptr(); 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()); let handle = CreateFileW(utf16_ptr, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, null_mut(), OPEN_EXISTING, dw, null_mut());
@ -51,30 +40,6 @@ pub fn get_current_handle(stdout: &Arc<TerminalOutput>) -> Result<HANDLE> {
} }
} }
pub fn get_current_handle_1() -> Result<HANDLE>
{
let handle: Result<HANDLE>;
use std::str;
unsafe
{
let dw: DWORD = 0;
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 /// Get the std_output_handle of the console
pub fn get_output_handle() -> Result<HANDLE> { pub fn get_output_handle() -> Result<HANDLE> {
unsafe { unsafe {

View File

@ -30,8 +30,8 @@ pub fn get_console_mode(handle: &HANDLE, current_mode: &mut u32) -> bool {
} }
/// Change the console text attribute. /// Change the console text attribute.
pub fn set_console_text_attribute(value: u16, stdout: &Arc<TerminalOutput>) -> bool { pub fn set_console_text_attribute(value: u16) -> bool {
let handle = handle::get_current_handle(stdout).unwrap(); let handle = handle::get_current_handle().unwrap();
unsafe { unsafe {
return is_true(SetConsoleTextAttribute(handle, value)); return is_true(SetConsoleTextAttribute(handle, value));
@ -39,8 +39,8 @@ pub fn set_console_text_attribute(value: u16, stdout: &Arc<TerminalOutput>) -> b
} }
/// Change console info. /// Change console info.
pub fn set_console_info(absolute: bool, rect: &SMALL_RECT, stdout: &Arc<TerminalOutput>) -> bool { pub fn set_console_info(absolute: bool, rect: &SMALL_RECT) -> bool {
let handle = handle::get_current_handle(stdout).unwrap(); let handle = handle::get_current_handle().unwrap();
let absolute = match absolute { let absolute = match absolute {
true => 1, true => 1,

View File

@ -17,7 +17,7 @@ pub fn terminal_size() -> (u16, u16) {
} }
} }
pub fn buffer_size(stdout: &Arc<TerminalOutput>) -> (u16, u16) { pub fn buffer_size() -> (u16, u16) {
let handle = handle::get_output_handle().unwrap(); let handle = handle::get_output_handle().unwrap();
if let Ok(csbi) = csbi::get_csbi_by_handle(&handle) { if let Ok(csbi) = csbi::get_csbi_by_handle(&handle) {

View File

@ -18,10 +18,9 @@ use std::sync::Arc;
pub fn fill_console_output_character( pub fn fill_console_output_character(
cells_written: &mut u32, cells_written: &mut u32,
start_location: COORD, start_location: COORD,
cells_to_write: u32, cells_to_write: u32
stdout: &Arc<TerminalOutput>,
) -> bool { ) -> bool {
let handle = handle::get_current_handle(stdout).unwrap(); let handle = handle::get_current_handle().unwrap();
unsafe { unsafe {
// fill the cells in console with blanks // fill the cells in console with blanks
@ -40,12 +39,11 @@ pub fn fill_console_output_character(
pub fn fill_console_output_attribute( pub fn fill_console_output_attribute(
cells_written: &mut u32, cells_written: &mut u32,
start_location: COORD, start_location: COORD,
cells_to_write: u32, cells_to_write: u32
stdout: &Arc<TerminalOutput>,
) -> bool { ) -> bool {
// Get the position of the current console window // Get the position of the current console window
let (csbi, handle) = csbi::get_csbi_and_handle(stdout).unwrap(); let (csbi, handle) = csbi::get_csbi_and_handle().unwrap();
let success; let success;

View File

@ -17,11 +17,11 @@ impl WinApiCursor {
impl ITerminalCursor for WinApiCursor { impl ITerminalCursor for WinApiCursor {
fn goto(&self, x: u16, y: u16, stdout: &Arc<TerminalOutput>) { fn goto(&self, x: u16, y: u16, stdout: &Arc<TerminalOutput>) {
cursor::set_console_cursor_position(x as i16, y as i16, stdout); cursor::set_console_cursor_position(x as i16, y as i16);
} }
fn pos(&self, stdout: &Arc<TerminalOutput>) -> (u16, u16) { fn pos(&self, stdout: &Arc<TerminalOutput>) -> (u16, u16) {
cursor::pos(stdout) cursor::pos()
} }
fn move_up(&self, count: u16, stdout: &Arc<TerminalOutput>) { fn move_up(&self, count: u16, stdout: &Arc<TerminalOutput>) {
@ -45,19 +45,19 @@ impl ITerminalCursor for WinApiCursor {
} }
fn save_position(&self, stdout: &Arc<TerminalOutput>) { fn save_position(&self, stdout: &Arc<TerminalOutput>) {
cursor::save_cursor_pos(stdout); cursor::save_cursor_pos();
} }
fn reset_position(&self, stdout: &Arc<TerminalOutput>) { fn reset_position(&self, stdout: &Arc<TerminalOutput>) {
cursor::reset_to_saved_position(stdout); cursor::reset_to_saved_position();
} }
fn hide(&self, stdout: &Arc<TerminalOutput>) { fn hide(&self, stdout: &Arc<TerminalOutput>) {
cursor::cursor_visibility(false, stdout); cursor::cursor_visibility(false);
} }
fn show(&self, stdout: &Arc<TerminalOutput>) { fn show(&self, stdout: &Arc<TerminalOutput>) {
cursor::cursor_visibility(true, stdout); cursor::cursor_visibility(true);
} }
fn blink(&self, blink: bool, stdout: &Arc<TerminalOutput>) {} fn blink(&self, blink: bool, stdout: &Arc<TerminalOutput>) {}
} }

View File

@ -35,7 +35,7 @@ pub struct TerminalOutput {
impl TerminalOutput { impl TerminalOutput {
/// Create new screen write instance whereon screen related actions can be performed. /// Create new screen write instance whereon screen related actions can be performed.
pub fn new() -> Self { pub fn new(raw_mode: bool) -> Self {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
let stdout: Box<IStdout + Send + Sync> = functions::get_module::<Box<IStdout + Send + Sync>>( let stdout: Box<IStdout + Send + Sync> = functions::get_module::<Box<IStdout + Send + Sync>>(
Box::from(WinApiOutput::new()), Box::from(WinApiOutput::new()),
@ -45,7 +45,7 @@ impl TerminalOutput {
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
let stdout = Box::from(AnsiOutput::new()) as Box<IStdout + Send + Sync>; let stdout = Box::from(AnsiOutput::new()) as Box<IStdout + Send + Sync>;
TerminalOutput { stdout , is_in_raw_mode: false} TerminalOutput { stdout , is_in_raw_mode: raw_mode}
} }
/// Write String to the current screen. /// Write String to the current screen.

View File

@ -9,9 +9,14 @@ use std::any::Any;
use std::io; use std::io;
/// This struct is a wrapper for WINAPI `HANDLE` /// This struct is a wrapper for WINAPI `HANDLE`
pub struct WinApiOutput { pub struct WinApiOutput;
pub handle: Mutex<HANDLE>,
raw_mode: bool, impl WinApiOutput
{
pub fn new() -> WinApiOutput
{
WinApiOutput {}
}
} }
impl IStdout for WinApiOutput { impl IStdout for WinApiOutput {
@ -21,7 +26,8 @@ impl IStdout for WinApiOutput {
} }
fn write(&self, buf: &[u8]) -> io::Result<usize> { fn write(&self, buf: &[u8]) -> io::Result<usize> {
writing::write_char_buffer(&self.handle.lock().unwrap(), buf) let handle = handle::get_current_handle().unwrap();
writing::write_char_buffer(&handle, buf)
} }
fn flush(&self) -> io::Result<()> { fn flush(&self) -> io::Result<()> {
@ -37,23 +43,6 @@ impl IStdout for WinApiOutput {
} }
} }
impl WinApiOutput {
pub fn new() -> Self {
let handle = handle::get_output_handle().unwrap();
WinApiOutput { raw_mode: false, handle: Mutex::new(handle) }
}
pub fn set(&mut self, handle: HANDLE)
{
self.handle = Mutex::new(handle);
}
pub fn get_handle(&self) -> HANDLE
{
return self.handle.lock().unwrap().clone();
}
}
unsafe impl Send for WinApiOutput {} unsafe impl Send for WinApiOutput {}
unsafe impl Sync for WinApiOutput {} unsafe impl Sync for WinApiOutput {}

View File

@ -23,7 +23,7 @@ impl ITerminalColor for WinApiColor {
fn set_fg(&self, fg_color: Color, stdout: &Arc<TerminalOutput>) { fn set_fg(&self, fg_color: Color, stdout: &Arc<TerminalOutput>) {
let color_value = &self.color_value(fg_color, ColorType::Foreground); let color_value = &self.color_value(fg_color, ColorType::Foreground);
let csbi = csbi::get_csbi(stdout).unwrap(); let csbi = csbi::get_csbi().unwrap();
// Notice that the color values are stored in wAttribute. // Notice that the color values are stored in wAttribute.
// So we need to use bitwise operators to check if the values exists or to get current console colors. // So we need to use bitwise operators to check if the values exists or to get current console colors.
@ -38,13 +38,13 @@ impl ITerminalColor for WinApiColor {
color = color | wincon::BACKGROUND_INTENSITY as u16; color = color | wincon::BACKGROUND_INTENSITY as u16;
} }
kernel::set_console_text_attribute(color, stdout); kernel::set_console_text_attribute(color);
} }
fn set_bg(&self, bg_color: Color, stdout: &Arc<TerminalOutput>) { fn set_bg(&self, bg_color: Color, stdout: &Arc<TerminalOutput>) {
let color_value = &self.color_value(bg_color, ColorType::Background); let color_value = &self.color_value(bg_color, ColorType::Background);
let (csbi, handle) = csbi::get_csbi_and_handle(stdout).unwrap(); let (csbi, handle) = csbi::get_csbi_and_handle().unwrap();
// Notice that the color values are stored in wAttribute. // Notice that the color values are stored in wAttribute.
// So wee need to use bitwise operators to check if the values exists or to get current console colors. // So wee need to use bitwise operators to check if the values exists or to get current console colors.
@ -59,11 +59,11 @@ impl ITerminalColor for WinApiColor {
color = color | wincon::FOREGROUND_INTENSITY as u16; color = color | wincon::FOREGROUND_INTENSITY as u16;
} }
kernel::set_console_text_attribute(color, stdout); kernel::set_console_text_attribute(color);
} }
fn reset(&self, stdout: &Arc<TerminalOutput>) { fn reset(&self, stdout: &Arc<TerminalOutput>) {
kernel::set_console_text_attribute(self.original_color, stdout); kernel::set_console_text_attribute(self.original_color);
} }
/// This will get the winapi color value from the Color and ColorType struct /// This will get the winapi color value from the Color and ColorType struct

View File

@ -20,7 +20,7 @@ impl WinApiTerminal {
impl ITerminal for WinApiTerminal { impl ITerminal for WinApiTerminal {
fn clear(&self, clear_type: ClearType, stdout: &Arc<TerminalOutput>) { fn clear(&self, clear_type: ClearType, stdout: &Arc<TerminalOutput>) {
let csbi = csbi::get_csbi(stdout).unwrap(); let csbi = csbi::get_csbi().unwrap();
let pos = TerminalCursor::new(stdout).pos(); let pos = TerminalCursor::new(stdout).pos();
match clear_type { match clear_type {
@ -39,7 +39,7 @@ impl ITerminal for WinApiTerminal {
} }
fn scroll_up(&self, count: i16, stdout: &Arc<TerminalOutput>) { fn scroll_up(&self, count: i16, stdout: &Arc<TerminalOutput>) {
let csbi = csbi::get_csbi(&stdout).unwrap(); let csbi = csbi::get_csbi().unwrap();
// Set srctWindow to the current window size and location. // Set srctWindow to the current window size and location.
let mut srct_window = csbi.srWindow; let mut srct_window = csbi.srWindow;
@ -49,7 +49,7 @@ impl ITerminal for WinApiTerminal {
srct_window.Top -= count; // move top down srct_window.Top -= count; // move top down
srct_window.Bottom = count; // move bottom down srct_window.Bottom = count; // move bottom down
let success = kernel::set_console_info(false, &mut srct_window, &stdout); let success = kernel::set_console_info(false, &mut srct_window);
if success { if success {
panic!("Something went wrong when scrolling down"); panic!("Something went wrong when scrolling down");
} }
@ -57,7 +57,7 @@ impl ITerminal for WinApiTerminal {
} }
fn scroll_down(&self, count: i16, stdout: &Arc<TerminalOutput>) { fn scroll_down(&self, count: i16, stdout: &Arc<TerminalOutput>) {
let csbi = csbi::get_csbi(&stdout).unwrap(); let csbi = csbi::get_csbi().unwrap();
// Set srctWindow to the current window size and location. // Set srctWindow to the current window size and location.
let mut srct_window = csbi.srWindow; let mut srct_window = csbi.srWindow;
@ -66,7 +66,7 @@ impl ITerminal for WinApiTerminal {
srct_window.Top += count; // move top down srct_window.Top += count; // move top down
srct_window.Bottom += count; // move bottom down srct_window.Bottom += count; // move bottom down
let success = kernel::set_console_info(true, &mut srct_window, &stdout); let success = kernel::set_console_info(true, &mut srct_window);
if success { if success {
panic!("Something went wrong when scrolling down"); panic!("Something went wrong when scrolling down");
} }
@ -84,7 +84,7 @@ impl ITerminal for WinApiTerminal {
} }
// Get the position of the current console window // Get the position of the current console window
let csbi = csbi::get_csbi(&stdout).unwrap(); let csbi = csbi::get_csbi().unwrap();
let mut success = false; let mut success = false;
// If the buffer is smaller than this new window size, resize the // If the buffer is smaller than this new window size, resize the
@ -113,7 +113,7 @@ impl ITerminal for WinApiTerminal {
} }
if resize_buffer { if resize_buffer {
success = csbi::set_console_screen_buffer_size(size, &stdout); success = csbi::set_console_screen_buffer_size(size);
if !success { if !success {
panic!("Something went wrong when setting screen buffer size."); panic!("Something went wrong when setting screen buffer size.");
@ -125,12 +125,12 @@ impl ITerminal for WinApiTerminal {
fsr_window.Bottom = fsr_window.Top + height; fsr_window.Bottom = fsr_window.Top + height;
fsr_window.Right = fsr_window.Left + width; fsr_window.Right = fsr_window.Left + width;
let success = kernel::set_console_info(true, &fsr_window, &stdout); let success = kernel::set_console_info(true, &fsr_window);
if success { if success {
// If we resized the buffer, un-resize it. // If we resized the buffer, un-resize it.
if resize_buffer { if resize_buffer {
csbi::set_console_screen_buffer_size(csbi.dwSize, &stdout); csbi::set_console_screen_buffer_size(csbi.dwSize);
} }
let bounds = kernel::get_largest_console_window_size(); let bounds = kernel::get_largest_console_window_size();
@ -179,7 +179,7 @@ pub fn clear_after_cursor(
// get sum cells before cursor // get sum cells before cursor
let cells_to_write = csbi.dwSize.X as u32 * csbi.dwSize.Y as u32; let cells_to_write = csbi.dwSize.X as u32 * csbi.dwSize.Y as u32;
clear(start_location, cells_to_write, stdout); clear(start_location, cells_to_write);
} }
pub fn clear_before_cursor( pub fn clear_before_cursor(
@ -202,7 +202,7 @@ pub fn clear_before_cursor(
// get sum cells before cursor // get sum cells before cursor
let cells_to_write = (csbi.dwSize.X as u32 * ypos as u32) + (xpos as u32 + 1); let cells_to_write = (csbi.dwSize.X as u32 * ypos as u32) + (xpos as u32 + 1);
clear(start_location, cells_to_write, stdout); clear(start_location, cells_to_write);
} }
pub fn clear_entire_screen(csbi: CONSOLE_SCREEN_BUFFER_INFO, stdout: &Arc<TerminalOutput>) { pub fn clear_entire_screen(csbi: CONSOLE_SCREEN_BUFFER_INFO, stdout: &Arc<TerminalOutput>) {
@ -220,7 +220,7 @@ pub fn clear_entire_screen(csbi: CONSOLE_SCREEN_BUFFER_INFO, stdout: &Arc<Termin
let cells_to_write = csbi.dwSize.X as u32 * csbi.dwSize.Y as u32; let cells_to_write = csbi.dwSize.X as u32 * csbi.dwSize.Y as u32;
clear(start_location, cells_to_write, &stdout); clear(start_location, cells_to_write);
// put the cursor back at (0, 0) // put the cursor back at (0, 0)
TerminalCursor::new(stdout).goto(0, 0); TerminalCursor::new(stdout).goto(0, 0);
@ -245,7 +245,7 @@ pub fn clear_current_line(
let cells_to_write = csbi.dwSize.X as u32; let cells_to_write = csbi.dwSize.X as u32;
clear(start_location, cells_to_write, stdout); clear(start_location, cells_to_write);
// put the cursor back at 1 cell on current row // put the cursor back at 1 cell on current row
TerminalCursor::new(stdout).goto(0, y); TerminalCursor::new(stdout).goto(0, y);
@ -266,13 +266,13 @@ pub fn clear_until_line(
// get sum cells before cursor // get sum cells before cursor
let cells_to_write = (csbi.dwSize.X - x as i16) as u32; let cells_to_write = (csbi.dwSize.X - x as i16) as u32;
clear(start_location, cells_to_write, &stdout); clear(start_location, cells_to_write);
// put the cursor back at original cursor position // put the cursor back at original cursor position
TerminalCursor::new(stdout).goto(x, y); TerminalCursor::new(stdout).goto(x, y);
} }
fn clear(start_loaction: COORD, cells_to_write: u32, stdout: &Arc<TerminalOutput>) { fn clear(start_loaction: COORD, cells_to_write: u32) {
let mut cells_written = 0; let mut cells_written = 0;
let mut success = false; let mut success = false;
@ -280,7 +280,6 @@ fn clear(start_loaction: COORD, cells_to_write: u32, stdout: &Arc<TerminalOutput
&mut cells_written, &mut cells_written,
start_loaction, start_loaction,
cells_to_write, cells_to_write,
stdout,
); );
if !success { if !success {
@ -293,7 +292,6 @@ fn clear(start_loaction: COORD, cells_to_write: u32, stdout: &Arc<TerminalOutput
&mut cells_written, &mut cells_written,
start_loaction, start_loaction,
cells_to_write, cells_to_write,
stdout,
); );
if !success { if !success {