diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index 1ee57434fb9..8ee3806d7f5 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -84,6 +84,32 @@ pub fn fd_set(set: &mut fd_set, s: libc::SOCKET) { set.fd_count += 1; } +pub type SHORT = libc::c_short; + +#[repr(C)] +pub struct COORD { + pub X: SHORT, + pub Y: SHORT, +} + +#[repr(C)] +pub struct SMALL_RECT { + pub Left: SHORT, + pub Top: SHORT, + pub Right: SHORT, + pub Bottom: SHORT, +} + +#[repr(C)] +pub struct CONSOLE_SCREEN_BUFFER_INFO { + pub dwSize: COORD, + pub dwCursorPosition: COORD, + pub wAttributes: libc::WORD, + pub srWindow: SMALL_RECT, + pub dwMaximumWindowSize: COORD, +} +pub type PCONSOLE_SCREEN_BUFFER_INFO = *mut CONSOLE_SCREEN_BUFFER_INFO; + #[link(name = "ws2_32")] extern "system" { pub fn WSAStartup(wVersionRequested: libc::WORD, @@ -247,4 +273,8 @@ extern "system" { pub fn SetConsoleMode(hConsoleHandle: libc::HANDLE, lpMode: libc::DWORD) -> libc::BOOL; + pub fn GetConsoleScreenBufferInfo( + hConsoleOutput: libc::HANDLE, + lpConsoleScreenBufferInfo: PCONSOLE_SCREEN_BUFFER_INFO, + ) -> libc::BOOL; } diff --git a/src/libstd/sys/windows/tty.rs b/src/libstd/sys/windows/tty.rs index 4305f7743b5..f9e1f0d3ed0 100644 --- a/src/libstd/sys/windows/tty.rs +++ b/src/libstd/sys/windows/tty.rs @@ -32,13 +32,15 @@ use iter::repeat; use libc::types::os::arch::extra::LPCVOID; use libc::{c_int, HANDLE, LPDWORD, DWORD, LPVOID}; use libc::{get_osfhandle, CloseHandle}; +use mem; use ptr; use str::from_utf8; use super::c::{ENABLE_ECHO_INPUT, ENABLE_EXTENDED_FLAGS}; use super::c::{ENABLE_INSERT_MODE, ENABLE_LINE_INPUT}; use super::c::{ENABLE_PROCESSED_INPUT, ENABLE_QUICK_EDIT_MODE}; -use super::c::{ERROR_ILLEGAL_CHARACTER}; +use super::c::{ERROR_ILLEGAL_CHARACTER, CONSOLE_SCREEN_BUFFER_INFO}; use super::c::{ReadConsoleW, WriteConsoleW, GetConsoleMode, SetConsoleMode}; +use super::c::{GetConsoleScreenBufferInfo}; fn invalid_encoding() -> IoError { IoError { @@ -146,12 +148,12 @@ impl TTY { } pub fn get_winsize(&mut self) -> IoResult<(int, int)> { - // FIXME - // Get console buffer via CreateFile with CONOUT$ - // Make a CONSOLE_SCREEN_BUFFER_INFO - // Call GetConsoleScreenBufferInfo - // Maybe call GetLargestConsoleWindowSize instead? - Err(super::unimpl()) + let mut info: CONSOLE_SCREEN_BUFFER_INFO = unsafe { mem::zeroed() }; + match unsafe { GetConsoleScreenBufferInfo(self.handle, &mut info as *mut _) } { + 0 => Err(super::last_error()), + _ => Ok(((info.srWindow.Right + 1 - info.srWindow.Left) as int, + (info.srWindow.Bottom + 1 - info.srWindow.Top) as int)), + } } // Let us magically declare this as a TTY