Restore original terminal colors after error messages on Windows.
This commit is contained in:
parent
5d335c94bd
commit
b11c5722f8
@ -23,15 +23,29 @@ use Terminal;
|
|||||||
/// A Terminal implementation which uses the Win32 Console API.
|
/// A Terminal implementation which uses the Win32 Console API.
|
||||||
pub struct WinConsole<T> {
|
pub struct WinConsole<T> {
|
||||||
buf: T,
|
buf: T,
|
||||||
|
def_foreground: color::Color,
|
||||||
|
def_background: color::Color,
|
||||||
foreground: color::Color,
|
foreground: color::Color,
|
||||||
background: color::Color,
|
background: color::Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[repr(C)]
|
||||||
|
struct CONSOLE_SCREEN_BUFFER_INFO {
|
||||||
|
dwSize: [libc::c_short, ..2],
|
||||||
|
dwCursorPosition: [libc::c_short, ..2],
|
||||||
|
wAttributes: libc::WORD,
|
||||||
|
srWindow: [libc::c_short, ..4],
|
||||||
|
dwMaximumWindowSize: [libc::c_short, ..2],
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[link(name = "kernel32")]
|
#[link(name = "kernel32")]
|
||||||
extern "system" {
|
extern "system" {
|
||||||
fn SetConsoleTextAttribute(handle: libc::HANDLE, attr: libc::WORD) -> libc::BOOL;
|
fn SetConsoleTextAttribute(handle: libc::HANDLE, attr: libc::WORD) -> libc::BOOL;
|
||||||
fn GetStdHandle(which: libc::DWORD) -> libc::HANDLE;
|
fn GetStdHandle(which: libc::DWORD) -> libc::HANDLE;
|
||||||
|
fn GetConsoleScreenBufferInfo(handle: libc::HANDLE,
|
||||||
|
info: *mut CONSOLE_SCREEN_BUFFER_INFO) -> libc::BOOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn color_to_bits(color: color::Color) -> u16 {
|
fn color_to_bits(color: color::Color) -> u16 {
|
||||||
@ -56,6 +70,26 @@ fn color_to_bits(color: color::Color) -> u16 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bits_to_color(bits: u16) -> color::Color {
|
||||||
|
let color = match bits & 0x7 {
|
||||||
|
0 => color::BLACK,
|
||||||
|
0x1 => color::BLUE,
|
||||||
|
0x2 => color::GREEN,
|
||||||
|
0x4 => color::RED,
|
||||||
|
0x6 => color::YELLOW,
|
||||||
|
0x5 => color::MAGENTA,
|
||||||
|
0x3 => color::CYAN,
|
||||||
|
0x7 => color::WHITE,
|
||||||
|
_ => unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
if bits >= 8 {
|
||||||
|
color | 0x8
|
||||||
|
} else {
|
||||||
|
color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Writer> WinConsole<T> {
|
impl<T: Writer> WinConsole<T> {
|
||||||
fn apply(&mut self) {
|
fn apply(&mut self) {
|
||||||
let _unused = self.buf.flush();
|
let _unused = self.buf.flush();
|
||||||
@ -91,7 +125,21 @@ impl<T: Writer> Writer for WinConsole<T> {
|
|||||||
|
|
||||||
impl<T: Writer> Terminal<T> for WinConsole<T> {
|
impl<T: Writer> Terminal<T> for WinConsole<T> {
|
||||||
fn new(out: T) -> Option<WinConsole<T>> {
|
fn new(out: T) -> Option<WinConsole<T>> {
|
||||||
Some(WinConsole { buf: out, foreground: color::WHITE, background: color::BLACK })
|
let fg;
|
||||||
|
let bg;
|
||||||
|
unsafe {
|
||||||
|
let mut buffer_info = ::std::mem::uninitialized();
|
||||||
|
if GetConsoleScreenBufferInfo(GetStdHandle(-11), &mut buffer_info) != 0 {
|
||||||
|
fg = bits_to_color(buffer_info.wAttributes);
|
||||||
|
bg = bits_to_color(buffer_info.wAttributes >> 4);
|
||||||
|
} else {
|
||||||
|
fg = color::WHITE;
|
||||||
|
bg = color::BLACK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(WinConsole { buf: out,
|
||||||
|
def_foreground: fg, def_background: bg,
|
||||||
|
foreground: fg, background: bg } )
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fg(&mut self, color: color::Color) -> IoResult<bool> {
|
fn fg(&mut self, color: color::Color) -> IoResult<bool> {
|
||||||
@ -134,8 +182,8 @@ impl<T: Writer> Terminal<T> for WinConsole<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn reset(&mut self) -> IoResult<()> {
|
fn reset(&mut self) -> IoResult<()> {
|
||||||
self.foreground = color::WHITE;
|
self.foreground = self.def_foreground;
|
||||||
self.background = color::BLACK;
|
self.background = self.def_background;
|
||||||
self.apply();
|
self.apply();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user