1 // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Windows console handling
13 // FIXME (#13400): this is only a tiny fraction of the Windows console api
18 use std
::io
::prelude
::*;
24 /// A Terminal implementation which uses the Win32 Console API.
25 pub struct WinConsole
<T
> {
27 def_foreground
: color
::Color
,
28 def_background
: color
::Color
,
29 foreground
: color
::Color
,
30 background
: color
::Color
,
36 type HANDLE
= *mut u8;
38 #[allow(non_snake_case)]
40 struct CONSOLE_SCREEN_BUFFER_INFO
{
41 dwSize
: [libc
::c_short
; 2],
42 dwCursorPosition
: [libc
::c_short
; 2],
44 srWindow
: [libc
::c_short
; 4],
45 dwMaximumWindowSize
: [libc
::c_short
; 2],
48 #[allow(non_snake_case)]
49 #[link(name = "kernel32")]
51 fn SetConsoleTextAttribute(handle
: HANDLE
, attr
: WORD
) -> BOOL
;
52 fn GetStdHandle(which
: DWORD
) -> HANDLE
;
53 fn GetConsoleScreenBufferInfo(handle
: HANDLE
, info
: *mut CONSOLE_SCREEN_BUFFER_INFO
) -> BOOL
;
56 fn color_to_bits(color
: color
::Color
) -> u16 {
57 // magic numbers from mingw-w64's wincon.h
59 let bits
= match color
% 8 {
64 color
::YELLOW
=> 0x2 | 0x4,
65 color
::MAGENTA
=> 0x1 | 0x4,
66 color
::CYAN
=> 0x1 | 0x2,
67 color
::WHITE
=> 0x1 | 0x2 | 0x4,
78 fn bits_to_color(bits
: u16) -> color
::Color
{
79 let color
= match bits
& 0x7 {
85 0x5 => color
::MAGENTA
,
91 color
| (bits
& 0x8) // copy the hi-intensity bit
94 impl<T
: Write
+Send
+'
static> WinConsole
<T
> {
96 let _unused
= self.buf
.flush();
97 let mut accum
: WORD
= 0;
98 accum
|= color_to_bits(self.foreground
);
99 accum
|= color_to_bits(self.background
) << 4;
102 // Magic -11 means stdout, from
103 // http://msdn.microsoft.com/en-us/library/windows/desktop/ms683231%28v=vs.85%29.aspx
105 // You may be wondering, "but what about stderr?", and the answer
106 // to that is that setting terminal attributes on the stdout
107 // handle also sets them for stderr, since they go to the same
108 // terminal! Admittedly, this is fragile, since stderr could be
109 // redirected to a different console. This is good enough for
110 // rustc though. See #13400.
111 let out
= GetStdHandle(-11i32 as DWORD
);
112 SetConsoleTextAttribute(out
, accum
);
116 /// Returns `None` whenever the terminal cannot be created for some
118 pub fn new(out
: T
) -> io
::Result
<WinConsole
<T
>> {
122 let mut buffer_info
= ::std
::mem
::uninitialized();
123 if GetConsoleScreenBufferInfo(GetStdHandle(-11i32 as DWORD
), &mut buffer_info
) != 0 {
124 fg
= bits_to_color(buffer_info
.wAttributes
);
125 bg
= bits_to_color(buffer_info
.wAttributes
>> 4);
141 impl<T
: Write
> Write
for WinConsole
<T
> {
142 fn write(&mut self, buf
: &[u8]) -> io
::Result
<usize> {
146 fn flush(&mut self) -> io
::Result
<()> {
151 impl<T
: Write
+Send
+'
static> Terminal
for WinConsole
<T
> {
154 fn fg(&mut self, color
: color
::Color
) -> io
::Result
<bool
> {
155 self.foreground
= color
;
161 fn bg(&mut self, color
: color
::Color
) -> io
::Result
<bool
> {
162 self.background
= color
;
168 fn attr(&mut self, attr
: Attr
) -> io
::Result
<bool
> {
170 Attr
::ForegroundColor(f
) => {
175 Attr
::BackgroundColor(b
) => {
184 fn supports_attr(&self, attr
: Attr
) -> bool
{
185 // it claims support for underscore and reverse video, but I can't get
186 // it to do anything -cmr
188 Attr
::ForegroundColor(_
) | Attr
::BackgroundColor(_
) => true,
193 fn reset(&mut self) -> io
::Result
<bool
> {
194 self.foreground
= self.def_foreground
;
195 self.background
= self.def_background
;
201 fn get_ref
<'a
>(&'a
self) -> &'a T
{
205 fn get_mut
<'a
>(&'a
mut self) -> &'a
mut T
{
209 fn into_inner(self) -> T