@@ -23,15 +23,29 @@ use Terminal;
23
23
/// A Terminal implementation which uses the Win32 Console API.
24
24
pub struct WinConsole < T > {
25
25
buf : T ,
26
+ def_foreground : color:: Color ,
27
+ def_background : color:: Color ,
26
28
foreground : color:: Color ,
27
29
background : color:: Color ,
28
30
}
29
31
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
+
30
42
#[ allow( non_snake_case) ]
31
43
#[ link( name = "kernel32" ) ]
32
44
extern "system" {
33
45
fn SetConsoleTextAttribute ( handle : libc:: HANDLE , attr : libc:: WORD ) -> libc:: BOOL ;
34
46
fn GetStdHandle ( which : libc:: DWORD ) -> libc:: HANDLE ;
47
+ fn GetConsoleScreenBufferInfo ( handle : libc:: HANDLE ,
48
+ info : * mut CONSOLE_SCREEN_BUFFER_INFO ) -> libc:: BOOL ;
35
49
}
36
50
37
51
fn color_to_bits ( color : color:: Color ) -> u16 {
@@ -56,6 +70,26 @@ fn color_to_bits(color: color::Color) -> u16 {
56
70
}
57
71
}
58
72
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
+
59
93
impl < T : Writer > WinConsole < T > {
60
94
fn apply ( & mut self ) {
61
95
let _unused = self . buf . flush ( ) ;
@@ -91,7 +125,21 @@ impl<T: Writer> Writer for WinConsole<T> {
91
125
92
126
impl < T : Writer > Terminal < T > for WinConsole < T > {
93
127
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 } )
95
143
}
96
144
97
145
fn fg ( & mut self , color : color:: Color ) -> IoResult < bool > {
@@ -134,8 +182,8 @@ impl<T: Writer> Terminal<T> for WinConsole<T> {
134
182
}
135
183
136
184
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 ;
139
187
self . apply ( ) ;
140
188
141
189
Ok ( ( ) )
0 commit comments