1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
use super::{Height, Width};
use std::os::windows::io::RawHandle;
/// Returns the size of the terminal.
///
/// This function checks the stdout, stderr, and stdin streams (in that order).
/// The size of the first stream that is a TTY will be returned. If nothing
/// is a TTY, then `None` is returned.
///
/// Note that this returns the size of the actual command window, and
/// not the overall size of the command window buffer
pub fn terminal_size() -> Option<(Width, Height)> {
use windows_sys::Win32::System::Console::{
GetStdHandle, STD_ERROR_HANDLE, STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
};
if let Some(size) =
terminal_size_using_handle(unsafe { GetStdHandle(STD_OUTPUT_HANDLE) as RawHandle })
{
Some(size)
} else if let Some(size) =
terminal_size_using_handle(unsafe { GetStdHandle(STD_ERROR_HANDLE) as RawHandle })
{
Some(size)
} else if let Some(size) =
terminal_size_using_handle(unsafe { GetStdHandle(STD_INPUT_HANDLE) as RawHandle })
{
Some(size)
} else {
None
}
}
/// Returns the size of the terminal using the given handle, if available.
///
/// If the given handle is not a tty, returns `None`
pub fn terminal_size_using_handle(handle: RawHandle) -> Option<(Width, Height)> {
use windows_sys::Win32::Foundation::INVALID_HANDLE_VALUE;
use windows_sys::Win32::System::Console::{
GetConsoleScreenBufferInfo, CONSOLE_SCREEN_BUFFER_INFO, COORD, SMALL_RECT,
};
// convert between windows_sys::Win32::Foundation::HANDLE and std::os::windows::raw::HANDLE
let hand = handle as windows_sys::Win32::Foundation::HANDLE;
if hand == INVALID_HANDLE_VALUE {
return None;
}
let zc = COORD { X: 0, Y: 0 };
let mut csbi = CONSOLE_SCREEN_BUFFER_INFO {
dwSize: zc,
dwCursorPosition: zc,
wAttributes: 0,
srWindow: SMALL_RECT {
Left: 0,
Top: 0,
Right: 0,
Bottom: 0,
},
dwMaximumWindowSize: zc,
};
if unsafe { GetConsoleScreenBufferInfo(hand, &mut csbi) } == 0 {
return None;
}
let w: Width = Width((csbi.srWindow.Right - csbi.srWindow.Left + 1) as u16);
let h: Height = Height((csbi.srWindow.Bottom - csbi.srWindow.Top + 1) as u16);
Some((w, h))
}
|