1
- // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
1
+ // Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
2
2
// file at the top-level directory of this distribution and at
3
3
// http://rust-lang.org/COPYRIGHT.
4
4
//
@@ -17,10 +17,11 @@ extern crate winapi;
17
17
18
18
use std:: io:: prelude:: * ;
19
19
use std:: io;
20
+ use std:: ptr;
20
21
21
22
use Attr ;
22
23
use color;
23
- use { Terminal , UnwrappableTerminal } ;
24
+ use { Terminal , UnwrappableTerminal } ;
24
25
25
26
/// A Terminal implementation which uses the Win32 Console API.
26
27
pub struct WinConsole < T > {
@@ -69,45 +70,54 @@ fn bits_to_color(bits: u16) -> color::Color {
69
70
color | ( bits & 0x8 ) // copy the hi-intensity bit
70
71
}
71
72
73
+ // Just get a handle to the current console buffer whatever it is
74
+ fn conout ( ) -> io:: Result < winapi:: HANDLE > {
75
+ let handle = unsafe {
76
+ kernel32:: CreateFileA ( "CONOUT$\0 " . as_ptr ( ) as winapi:: LPCSTR , winapi:: GENERIC_WRITE ,
77
+ winapi:: FILE_SHARE_WRITE , ptr:: null_mut ( ) , winapi:: OPEN_EXISTING , 0 , ptr:: null_mut ( ) )
78
+ } ;
79
+ if handle == winapi:: INVALID_HANDLE_VALUE {
80
+ Err ( io:: Error :: last_os_error ( ) )
81
+ } else {
82
+ Ok ( handle)
83
+ }
84
+ }
85
+
86
+ // This test will only pass if it is running in an actual console, probably
87
+ #[ test]
88
+ fn test_conout ( ) {
89
+ assert ! ( conout( ) . is_ok( ) )
90
+ }
91
+
72
92
impl < T : Write +Send > WinConsole < T > {
73
- fn apply ( & mut self ) {
93
+ fn apply ( & mut self ) -> io:: Result < ( ) > {
94
+ let out = try!( conout ( ) ) ;
74
95
let _unused = self . buf . flush ( ) ;
75
96
let mut accum: winapi:: WORD = 0 ;
76
97
accum |= color_to_bits ( self . foreground ) ;
77
98
accum |= color_to_bits ( self . background ) << 4 ;
78
-
79
99
unsafe {
80
- // Magic -11 means stdout, from
81
- // http://msdn.microsoft.com/en-us/library/windows/desktop/ms683231%28v=vs.85%29.aspx
82
- //
83
- // You may be wondering, "but what about stderr?", and the answer
84
- // to that is that setting terminal attributes on the stdout
85
- // handle also sets them for stderr, since they go to the same
86
- // terminal! Admittedly, this is fragile, since stderr could be
87
- // redirected to a different console. This is good enough for
88
- // rustc though. See #13400.
89
- let out = kernel32:: GetStdHandle ( -11i32 as winapi:: DWORD ) ;
90
100
kernel32:: SetConsoleTextAttribute ( out, accum) ;
91
101
}
102
+ Ok ( ( ) )
92
103
}
93
104
94
105
/// Returns `None` whenever the terminal cannot be created for some
95
106
/// reason.
96
- pub fn new ( out : T ) -> Option < WinConsole < T > > {
107
+ pub fn new ( out : T ) -> io :: Result < WinConsole < T > > {
97
108
let fg;
98
109
let bg;
110
+ let handle = try!( conout ( ) ) ;
99
111
unsafe {
100
112
let mut buffer_info = :: std:: mem:: uninitialized ( ) ;
101
- let out = kernel32:: GetStdHandle ( -11i32 as winapi:: DWORD ) ;
102
- if kernel32:: GetConsoleScreenBufferInfo ( out, & mut buffer_info) != 0 {
113
+ if kernel32:: GetConsoleScreenBufferInfo ( handle, & mut buffer_info) != 0 {
103
114
fg = bits_to_color ( buffer_info. wAttributes ) ;
104
115
bg = bits_to_color ( buffer_info. wAttributes >> 4 ) ;
105
116
} else {
106
- fg = color:: WHITE ;
107
- bg = color:: BLACK ;
117
+ return Err ( io:: Error :: last_os_error ( ) ) ;
108
118
}
109
119
}
110
- Some ( WinConsole {
120
+ Ok ( WinConsole {
111
121
buf : out,
112
122
def_foreground : fg,
113
123
def_background : bg,
@@ -130,14 +140,14 @@ impl<T: Write> Write for WinConsole<T> {
130
140
impl < T : Write +Send > Terminal < T > for WinConsole < T > {
131
141
fn fg ( & mut self , color : color:: Color ) -> io:: Result < bool > {
132
142
self . foreground = color;
133
- self . apply ( ) ;
143
+ try! ( self . apply ( ) ) ;
134
144
135
145
Ok ( true )
136
146
}
137
147
138
148
fn bg ( & mut self , color : color:: Color ) -> io:: Result < bool > {
139
149
self . background = color;
140
- self . apply ( ) ;
150
+ try! ( self . apply ( ) ) ;
141
151
142
152
Ok ( true )
143
153
}
@@ -146,12 +156,12 @@ impl<T: Write+Send> Terminal<T> for WinConsole<T> {
146
156
match attr {
147
157
Attr :: ForegroundColor ( f) => {
148
158
self . foreground = f;
149
- self . apply ( ) ;
159
+ try! ( self . apply ( ) ) ;
150
160
Ok ( true )
151
161
} ,
152
162
Attr :: BackgroundColor ( b) => {
153
163
self . background = b;
154
- self . apply ( ) ;
164
+ try! ( self . apply ( ) ) ;
155
165
Ok ( true )
156
166
} ,
157
167
_ => Ok ( false )
@@ -170,11 +180,24 @@ impl<T: Write+Send> Terminal<T> for WinConsole<T> {
170
180
fn reset ( & mut self ) -> io:: Result < bool > {
171
181
self . foreground = self . def_foreground ;
172
182
self . background = self . def_background ;
173
- self . apply ( ) ;
183
+ try! ( self . apply ( ) ) ;
174
184
175
185
Ok ( true )
176
186
}
177
-
187
+
188
+ fn cursor_up ( & mut self ) -> io:: Result < bool > {
189
+ unimplemented ! ( )
190
+ //if GetConsoleScreenBufferInfo(
191
+ }
192
+
193
+ fn delete_line ( & mut self ) -> io:: Result < bool > {
194
+ unimplemented ! ( )
195
+ }
196
+
197
+ fn carriage_return ( & mut self ) -> io:: Result < bool > {
198
+ unimplemented ! ( )
199
+ }
200
+
178
201
fn get_ref < ' a > ( & ' a self ) -> & ' a T { & self . buf }
179
202
180
203
fn get_mut < ' a > ( & ' a mut self ) -> & ' a mut T { & mut self . buf }
0 commit comments