diff options
author | Ben S <ogham@bsago.me> | 2014-07-22 15:41:20 +0100 |
---|---|---|
committer | Ben S <ogham@bsago.me> | 2014-07-22 15:41:20 +0100 |
commit | cf3e32c9c166c16aa57a3ce2c0eff34796c5cd0a (patch) | |
tree | e71fa7ecc27a7f367508e9d5bd3f4cdb5a6f5ea2 /src/term.rs | |
parent | b1560edb854d0e0d1f0c37f176f6bce6571d00a5 (diff) |
Get terminal width for grid view (resolve #1)
Diffstat (limited to 'src/term.rs')
-rw-r--r-- | src/term.rs | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/src/term.rs b/src/term.rs new file mode 100644 index 0000000..9e88adf --- /dev/null +++ b/src/term.rs @@ -0,0 +1,57 @@ + +mod c { + #![allow(non_camel_case_types)] + extern crate libc; + pub use self::libc::{ + c_int, + c_ushort, + c_ulong, + STDOUT_FILENO, + }; + use std::mem::zeroed; + + // Getting the terminal size is done using an ioctl command that + // takes the file handle to the terminal (which in our case is + // stdout), and populates a structure with the values. + + pub struct winsize { + pub ws_row: c_ushort, + pub ws_col: c_ushort, + } + + // Unfortunately the actual command is not standardised... + + #[cfg(target_os = "linux")] + #[cfg(target_os = "android")] + static TIOCGWINSZ: c_ulong = 0x5413; + + #[cfg(target_os = "freebsd")] + #[cfg(target_os = "macos")] + static TIOCGWINSZ: c_ulong = 0x40087468; + + extern { + pub fn ioctl(fd: c_int, request: c_ulong, ...) -> c_int; + } + + pub fn dimensions() -> winsize { + unsafe { + let mut window: winsize = zeroed(); + ioctl(STDOUT_FILENO, TIOCGWINSZ, &mut window as *mut winsize); + window + } + } +} + +pub fn dimensions() -> Option<(uint, uint)> { + let w = c::dimensions(); + + // If either of the dimensions is 0 then the command failed, + // usually because output isn't to a terminal (instead to a file + // or pipe or something) + if w.ws_col == 0 || w.ws_row == 0 { + None + } + else { + Some((w.ws_col as uint, w.ws_row as uint)) + } +} |