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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#[cfg(windows)]
use winapi;
#[cfg(windows)]
use advapi32;
#[cfg(windows)]
use kernel32;
use Handle;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct WinSize {
pub cols: u16,
pub rows: u16,
}
impl Default for WinSize {
fn default() -> WinSize {
WinSize { cols: 80, rows: 24 }
}
}
#[cfg(windows)]
pub fn get_size(handle: Handle) -> Option<WinSize> {
get_screen_buffer_size(handle.win_handle())
}
#[cfg(windows)]
pub fn get_screen_buffer_size(hndl: winapi::HANDLE) -> Option<WinSize> {
let mut csbi: winapi::CONSOLE_SCREEN_BUFFER_INFO =
unsafe { ::std::mem::uninitialized() };
let res = unsafe { kernel32::GetConsoleScreenBufferInfo(hndl, &mut csbi) };
if res == 0 {
return None;
}
Some(WinSize {
cols: (csbi.srWindow.Right - csbi.srWindow.Left + 1) as u16,
rows: (csbi.srWindow.Bottom - csbi.srWindow.Top + 1) as u16,
})
}
#[cfg(windows)]
use std::io;
#[cfg(windows)]
pub fn get_cygwin_size(w: &io::Write, defsz: WinSize) -> WinSize {
let _ = w;
let _ = defsz;
Default::default()
}
#[cfg(not(windows))]
pub fn get_size(handle: Handle) -> Option<WinSize> {
let win: ::libc::winsize = unsafe { ::std::mem::uninitialized() };
let res = unsafe { ::libc::ioctl(handle.fd(), ::libc::TIOCGWINSZ, &win) };
if res != 0 {
return None;
}
Some(WinSize {
cols: u16::from(win.ws_col),
rows: u16::from(win.ws_row),
})
}
#[cfg(windows)]
pub fn get_default_console_size() -> WinSize {
use std::ptr;
let mut key: winapi::HKEY = ptr::null_mut();
let res = unsafe {
advapi32::RegOpenKeyExA(
winapi::HKEY_CURRENT_USER,
"Console\x00".as_ptr() as *const _ as winapi::LPCSTR,
0,
winapi::KEY_READ,
&mut key,
)
};
if res != 0 {
return Default::default();
}
let mut data = 0u32;
let mut data_size = 4u32;
let res = unsafe {
advapi32::RegQueryValueExA(
key,
"WindowSize\x00".as_ptr() as *const _ as winapi::LPCSTR,
ptr::null_mut(),
ptr::null_mut(),
&mut data as *mut _ as *mut u8,
&mut data_size,
)
};
if res != 0 {
return Default::default();
}
WinSize {
cols: (data & 0xffff) as u16,
rows: (data >> 16) as u16,
}
}