libtui 0.1.0

A crate to create TUIs.
Documentation
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use std::mem;

use libc::*;

pub struct Terminal {
    previous: libc::termios
}

impl Terminal {
    pub fn get_size(&self) -> (u16, u16) {
        // This is way simpler than I remember...
        let mut win_size = winsize { ws_row: 0, ws_col: 0, ws_xpixel: 0, ws_ypixel: 0 };
        unsafe {
            ioctl(STDOUT_FILENO, TIOCGWINSZ, &mut win_size);
        }
        (win_size.ws_col, win_size.ws_row)
    }
}

impl Default for Terminal {
    fn default() -> Terminal {
        raw()
    }
}

impl Drop for Terminal {
    fn drop(&mut self) {
        drop(self.previous);
    }
}

pub fn drop(termios: libc::termios) {
    print!("\x1b[?1049l\x1b[?7h");
    unsafe {
        libc::tcsetattr(libc::STDIN_FILENO, libc::TCSAFLUSH, &termios);
    }
}

pub fn raw() -> Terminal {
    let mut previous;
    unsafe {
        previous = mem::zeroed();
        libc::tcgetattr(libc::STDIN_FILENO, &mut previous);
    }
    // Copyright (c) 2016, Salvatore Sanfilippo <antirez at gmail dot com>
    //
    // All rights reserved.
    //
    // Redistribution and use in source and binary forms, with or without
    // modification, are permitted provided that the following conditions are met:
    //
    //* Redistributions of source code must retain the above copyright notice,
    //  this list of conditions and the following disclaimer.
    //
    //* Redistributions in binary form must reproduce the above copyright notice,
    //  this list of conditions and the following disclaimer in the documentation
    //  and/or other materials provided with the distribution.
    //
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
    // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
    // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    //(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

    // Here we make the new termios and disable a ton of stuff
    let mut new = previous;
    new.c_iflag &= !(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
    new.c_oflag &= !OPOST;
    new.c_lflag &= !(ECHO | ICANON | IEXTEN | ISIG);
    new.c_cc[VMIN] = 0;
    new.c_cc[VTIME] = 1;
    unsafe {
        // Set the new attributes into effect.
        libc::tcsetattr(libc::STDIN_FILENO, libc::TCSAFLUSH, &new);
    }
    print!("\x1b[?1049h\x1b[?7l");
    Terminal { previous }
}