1
+ use winapi:: shared:: minwindef:: DWORD ;
1
2
use winapi:: um:: processenv:: GetStdHandle ;
2
- use winapi:: um:: winbase:: STD_OUTPUT_HANDLE ;
3
+ use winapi:: um:: winbase:: { STD_ERROR_HANDLE , STD_INPUT_HANDLE , STD_OUTPUT_HANDLE } ;
3
4
use winapi:: um:: wincon:: GetConsoleScreenBufferInfo ;
4
5
use winapi:: um:: wincon:: { CONSOLE_SCREEN_BUFFER_INFO , COORD , SMALL_RECT } ;
5
6
6
- /// Query the current processes's output, returning its width and height as a
7
- /// number of characters.
8
- ///
9
- /// # Errors
10
- ///
11
- /// Returns `None` if the output isn't to a terminal.
12
- ///
13
- /// # Example
14
- ///
15
- /// To get the dimensions of your terminal window, simply use the following:
16
- ///
17
- /// ```no_run
18
- /// # use term_size;
19
- /// if let Some((w, h)) = term_size::dimensions() {
20
- /// println!("Width: {}\nHeight: {}", w, h);
21
- /// } else {
22
- /// println!("Unable to get term size :(")
23
- /// }
24
- /// ```
25
- pub fn dimensions ( ) -> Option < ( usize , usize ) > {
7
+ /// Calls GetConsoleScreenBufferInfo. Returns None if all of the streams are
8
+ /// not to a terminal, or there is an error.
9
+ fn get_dimensions_any ( ) -> Option < ( usize , usize ) > {
26
10
let null_coord = COORD { X : 0 , Y : 0 } ;
27
11
let null_smallrect = SMALL_RECT {
28
12
Left : 0 ,
@@ -31,7 +15,6 @@ pub fn dimensions() -> Option<(usize, usize)> {
31
15
Bottom : 0 ,
32
16
} ;
33
17
34
- let stdout_h = unsafe { GetStdHandle ( STD_OUTPUT_HANDLE ) } ;
35
18
let mut console_data = CONSOLE_SCREEN_BUFFER_INFO {
36
19
dwSize : null_coord,
37
20
dwCursorPosition : null_coord,
@@ -40,25 +23,79 @@ pub fn dimensions() -> Option<(usize, usize)> {
40
23
dwMaximumWindowSize : null_coord,
41
24
} ;
42
25
43
- if unsafe { GetConsoleScreenBufferInfo ( stdout_h, & mut console_data) } != 0 {
26
+ if unsafe { GetConsoleScreenBufferInfo ( GetStdHandle ( STD_OUTPUT_HANDLE ) , & mut console_data) } != 0 ||
27
+ unsafe { GetConsoleScreenBufferInfo ( GetStdHandle ( STD_INPUT_HANDLE ) , & mut console_data) } != 0 ||
28
+ unsafe { GetConsoleScreenBufferInfo ( GetStdHandle ( STD_ERROR_HANDLE ) , & mut console_data) } != 0 {
44
29
Some ( ( ( console_data. srWindow . Right - console_data. srWindow . Left + 1 ) as usize ,
45
30
( console_data. srWindow . Bottom - console_data. srWindow . Top + 1 ) as usize ) )
46
31
} else {
47
32
None
48
33
}
49
34
}
50
35
51
- /// Query the current processes's output, returning its width and height as a
52
- /// number of characters. Returns `None` if the output isn't to a terminal.
36
+ /// Calls GetConsoleScreenBufferInfo. Returns None if the stream is not to a
37
+ /// terminal, or there is an error.
38
+ fn get_dimensions ( hdl : DWORD ) -> Option < ( usize , usize ) > {
39
+ let null_coord = COORD { X : 0 , Y : 0 } ;
40
+ let null_smallrect = SMALL_RECT {
41
+ Left : 0 ,
42
+ Top : 0 ,
43
+ Right : 0 ,
44
+ Bottom : 0 ,
45
+ } ;
46
+
47
+ let mut console_data = CONSOLE_SCREEN_BUFFER_INFO {
48
+ dwSize : null_coord,
49
+ dwCursorPosition : null_coord,
50
+ wAttributes : 0 ,
51
+ srWindow : null_smallrect,
52
+ dwMaximumWindowSize : null_coord,
53
+ } ;
54
+
55
+ if unsafe { GetConsoleScreenBufferInfo ( GetStdHandle ( hdl) , & mut console_data) } != 0 {
56
+ Some ( ( ( console_data. srWindow . Right - console_data. srWindow . Left + 1 ) as usize ,
57
+ ( console_data. srWindow . Bottom - console_data. srWindow . Top + 1 ) as usize ) )
58
+ } else {
59
+ None
60
+ }
61
+ }
62
+
63
+ /// Query the current processes's output (`stdout`), input (`stdin`), and
64
+ /// error (`stderr`) in that order, returning its width and height as a
65
+ /// number of characters.
66
+ ///
67
+ /// # Errors
68
+ ///
69
+ /// Returns `None` if the output isn't to a terminal.
70
+ ///
71
+ /// # Example
72
+ ///
73
+ /// To get the dimensions of your terminal window, simply use the following:
74
+ ///
75
+ /// ```no_run
76
+ /// # use term_size;
77
+ /// if let Some((w, h)) = term_size::dimensions() {
78
+ /// println!("Width: {}\nHeight: {}", w, h);
79
+ /// } else {
80
+ /// println!("Unable to get term size :(")
81
+ /// }
82
+ /// ```
83
+ pub fn dimensions ( ) -> Option < ( usize , usize ) > {
84
+ get_dimensions_any ( )
85
+ }
86
+
87
+ /// Query the current processes's output (`stdout`) *only*, returning its
88
+ /// width and height as a number of characters. Returns `None` if the output
89
+ /// isn't to a terminal.
53
90
///
54
91
/// # Errors
55
- ///
92
+ ///
56
93
/// Returns `None` if the output isn't to a terminal.
57
- ///
94
+ ///
58
95
/// # Example
59
- ///
96
+ ///
60
97
/// To get the dimensions of your terminal window, simply use the following:
61
- ///
98
+ ///
62
99
/// ```no_run
63
100
/// # use term_size;
64
101
/// if let Some((w, h)) = term_size::dimensions() {
@@ -67,20 +104,54 @@ pub fn dimensions() -> Option<(usize, usize)> {
67
104
/// println!("Unable to get term size :(")
68
105
/// }
69
106
/// ```
70
- pub fn dimensions_stdout ( ) -> Option < ( usize , usize ) > { dimensions ( ) }
107
+ pub fn dimensions_stdout ( ) -> Option < ( usize , usize ) > {
108
+ get_dimensions ( STD_OUTPUT_HANDLE )
109
+ }
71
110
72
- /// This isn't implemented for Windows
73
- ///
74
- /// # Panics
75
- ///
76
- /// This function `panic!`s unconditionally with the `unimplemented!`
77
- /// macro
78
- pub fn dimensions_stdin ( ) -> Option < ( usize , usize ) > { unimplemented ! ( ) }
111
+ /// Query the current processes's input (`stdin`) *only*, returning its width
112
+ /// and height as a number of characters. Returns `None` if the output isn't
113
+ /// to a terminal.
114
+ ///
115
+ /// # Errors
116
+ ///
117
+ /// Returns `None` if the output isn't to a terminal.
118
+ ///
119
+ /// # Example
120
+ ///
121
+ /// To get the dimensions of your terminal window, simply use the following:
122
+ ///
123
+ /// ```no_run
124
+ /// # use term_size;
125
+ /// if let Some((w, h)) = term_size::dimensions() {
126
+ /// println!("Width: {}\nHeight: {}", w, h);
127
+ /// } else {
128
+ /// println!("Unable to get term size :(")
129
+ /// }
130
+ /// ```
131
+ pub fn dimensions_stdin ( ) -> Option < ( usize , usize ) > {
132
+ get_dimensions ( STD_INPUT_HANDLE )
133
+ }
79
134
80
- /// This isn't implemented for Windows
81
- ///
82
- /// # Panics
83
- ///
84
- /// This function `panic!`s unconditionally with the `unimplemented!`
85
- /// macro
86
- pub fn dimensions_stderr ( ) -> Option < ( usize , usize ) > { unimplemented ! ( ) }
135
+ /// Query the current processes's error output (`stderr`) *only*, returning
136
+ /// its width and height as a number of characters. Returns `None` if the
137
+ /// output isn't to a terminal.
138
+ ///
139
+ /// # Errors
140
+ ///
141
+ /// Returns `None` if the output isn't to a terminal.
142
+ ///
143
+ /// # Example
144
+ ///
145
+ /// To get the dimensions of your terminal window, simply use the following:
146
+ ///
147
+ /// ```no_run
148
+ /// # use term_size;
149
+ /// if let Some((w, h)) = term_size::dimensions() {
150
+ /// println!("Width: {}\nHeight: {}", w, h);
151
+ /// } else {
152
+ /// println!("Unable to get term size :(")
153
+ /// }
154
+ /// ```
155
+ pub fn dimensions_stderr ( ) -> Option < ( usize , usize ) > {
156
+ get_dimensions ( STD_ERROR_HANDLE )
157
+ }
0 commit comments