@@ -23,15 +23,29 @@ use Terminal;
2323/// A Terminal implementation which uses the Win32 Console API.
2424pub struct WinConsole < T > {
2525 buf : T ,
26+ def_foreground : color:: Color ,
27+ def_background : color:: Color ,
2628 foreground : color:: Color ,
2729 background : color:: Color ,
2830}
2931
32+ #[ allow( non_snake_case) ]
33+ #[ repr( C ) ]
34+ struct CONSOLE_SCREEN_BUFFER_INFO {
35+ dwSize : [ libc:: c_short , ..2 ] ,
36+ dwCursorPosition : [ libc:: c_short , ..2 ] ,
37+ wAttributes : libc:: WORD ,
38+ srWindow : [ libc:: c_short , ..4 ] ,
39+ dwMaximumWindowSize : [ libc:: c_short , ..2 ] ,
40+ }
41+
3042#[ allow( non_snake_case) ]
3143#[ link( name = "kernel32" ) ]
3244extern "system" {
3345 fn SetConsoleTextAttribute ( handle : libc:: HANDLE , attr : libc:: WORD ) -> libc:: BOOL ;
3446 fn GetStdHandle ( which : libc:: DWORD ) -> libc:: HANDLE ;
47+ fn GetConsoleScreenBufferInfo ( handle : libc:: HANDLE ,
48+ info : * mut CONSOLE_SCREEN_BUFFER_INFO ) -> libc:: BOOL ;
3549}
3650
3751fn color_to_bits ( color : color:: Color ) -> u16 {
@@ -56,6 +70,26 @@ fn color_to_bits(color: color::Color) -> u16 {
5670 }
5771}
5872
73+ fn bits_to_color ( bits : u16 ) -> color:: Color {
74+ let color = match bits & 0x7 {
75+ 0 => color:: BLACK ,
76+ 0x1 => color:: BLUE ,
77+ 0x2 => color:: GREEN ,
78+ 0x4 => color:: RED ,
79+ 0x6 => color:: YELLOW ,
80+ 0x5 => color:: MAGENTA ,
81+ 0x3 => color:: CYAN ,
82+ 0x7 => color:: WHITE ,
83+ _ => unreachable ! ( )
84+ } ;
85+
86+ if bits >= 8 {
87+ color | 0x8
88+ } else {
89+ color
90+ }
91+ }
92+
5993impl < T : Writer > WinConsole < T > {
6094 fn apply ( & mut self ) {
6195 let _unused = self . buf . flush ( ) ;
@@ -91,7 +125,21 @@ impl<T: Writer> Writer for WinConsole<T> {
91125
92126impl < T : Writer > Terminal < T > for WinConsole < T > {
93127 fn new ( out : T ) -> Option < WinConsole < T > > {
94- Some ( WinConsole { buf : out, foreground : color:: WHITE , background : color:: BLACK } )
128+ let fg;
129+ let bg;
130+ unsafe {
131+ let mut buffer_info = :: std:: mem:: uninitialized ( ) ;
132+ if GetConsoleScreenBufferInfo ( GetStdHandle ( -11 ) , & mut buffer_info) != 0 {
133+ fg = bits_to_color ( buffer_info. wAttributes ) ;
134+ bg = bits_to_color ( buffer_info. wAttributes >> 4 ) ;
135+ } else {
136+ fg = color:: WHITE ;
137+ bg = color:: BLACK ;
138+ }
139+ }
140+ Some ( WinConsole { buf : out,
141+ def_foreground : fg, def_background : bg,
142+ foreground : fg, background : bg } )
95143 }
96144
97145 fn fg ( & mut self , color : color:: Color ) -> IoResult < bool > {
@@ -134,8 +182,8 @@ impl<T: Writer> Terminal<T> for WinConsole<T> {
134182 }
135183
136184 fn reset ( & mut self ) -> IoResult < ( ) > {
137- self . foreground = color :: WHITE ;
138- self . background = color :: BLACK ;
185+ self . foreground = self . def_foreground ;
186+ self . background = self . def_background ;
139187 self . apply ( ) ;
140188
141189 Ok ( ( ) )
0 commit comments