summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bindings.rs5
-rw-r--r--src/lib.rs192
2 files changed, 197 insertions, 0 deletions
diff --git a/src/bindings.rs b/src/bindings.rs
new file mode 100644
index 0000000..565964f
--- /dev/null
+++ b/src/bindings.rs
@@ -0,0 +1,5 @@
+#![allow(non_upper_case_globals)]
+// #![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+
+include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..5a86bdf
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,192 @@
+use std::char;
+use std::ffi::{self, CStr};
+use std::io;
+use libc;
+
+mod bindings;
+
+// #[cfg(test)]
+// mod tests {
+// #[test]
+// fn it_works() {
+// assert_eq!(2 + 2, 4);
+// }
+// }
+
+// All positions are represented using a tuple (x, y): (u32, u32).
+// Positions are zero-based.
+
+pub const KEY_TAB: i32 = bindings::KEY_TAB as i32;
+pub const KEY_LF: i32 = bindings::KEY_LF as i32;
+pub const KEY_CR: i32 = bindings::KEY_CR as i32;
+pub const KEY_ESC: i32 = bindings::KEY_ESC as i32;
+pub const KEY_BACKSPACE: i32 = bindings::KEY_BACKSPACE as i32;
+
+pub const KEY_RIGHT: i32 = bindings::KEY_RIGHT as i32;
+pub const KEY_UP: i32 = bindings::KEY_UP as i32;
+pub const KEY_LEFT: i32 = bindings::KEY_LEFT as i32;
+pub const KEY_DOWN: i32 = bindings::KEY_DOWN as i32;
+pub const KEY_PAGEUP: i32 = bindings::KEY_PAGEUP as i32;
+pub const KEY_PAGEDOWN: i32 = bindings::KEY_PAGEDOWN as i32;
+pub const KEY_DELETE: i32 = bindings::KEY_DELETE as i32;
+pub const KEY_SHIFTTAB: i32 = bindings::KEY_SHIFTTAB as i32;
+
+pub const KEY_CTRL: i32 = bindings::KEY_CTRL as i32;
+pub const KEY_SHIFT: i32 = bindings::KEY_SHIFT as i32;
+pub const KEY_ALT: i32 = bindings::KEY_ALT as i32;
+pub const KEY_CTRLALT: i32 = bindings::KEY_CTRLALT as i32;
+pub const KEY_CTRLSHIFT: i32 = bindings::KEY_CTRLSHIFT as i32;
+
+#[derive(Debug, Copy, Clone)]
+pub struct Size {
+ pub w: u32,
+ pub h: u32,
+}
+
+#[derive(Debug, Copy, Clone)]
+pub struct Style {
+ pub fg: u8, // 0-7, 9
+ pub bg: u8, // 0-7, 9
+ pub bold: bool,
+ pub ul: bool
+}
+
+pub fn init_keyboard(nosigkeys: bool) {
+ unsafe { bindings::initkeyboard(nosigkeys); }
+}
+
+pub fn end_keyboard() {
+ unsafe { bindings::endkeyboard(); }
+}
+
+pub fn init_screen() {
+ unsafe { bindings::initscreen(); }
+}
+
+pub fn end_screen() {
+ unsafe { bindings::endscreen(); }
+}
+
+pub fn install_cl_handler(install: bool) {
+ unsafe { bindings::installCLhandler(install); }
+}
+
+pub fn install_redraw_handler(handler: extern "C" fn(full_redraw: bool)) {
+ unsafe { bindings::installredrawhandler(Some(handler)); }
+}
+
+pub fn clear_screen() {
+ unsafe { bindings::clearscreen(); }
+}
+
+pub fn get_term_size() -> Size {
+ let sz = unsafe { bindings::gettermsize() };
+ Size { w: sz.w as u32, h: sz.h as u32 }
+}
+
+pub fn set_style(style: Style) {
+ let sty = bindings::Style {
+ fg: style.fg as i32,
+ bg: style.bg as i32,
+ bold: style.bold,
+ ul: style.ul,
+ };
+ unsafe { bindings::setstyle(&sty as *const bindings::Style); }
+}
+
+pub fn set_fg(fg: u8) {
+ unsafe { bindings::setfg(fg as i32); }
+}
+
+pub fn set_bg(bg: u8) {
+ unsafe { bindings::setbg(bg as i32); }
+}
+
+pub fn set_bold(bold: bool) {
+ unsafe { bindings::setbold(bold); }
+}
+
+pub fn set_ul(ul: bool) {
+ unsafe { bindings::setul(ul); }
+}
+
+pub fn putc(c: char) {
+ unsafe { bindings::tputc(c as i32); }
+}
+
+pub fn print(s: &str) {
+ unsafe { bindings::tprintf(
+ "%s".as_bytes().as_ptr() as *const i8,
+ s.as_bytes().as_ptr() as *const i8); }
+}
+
+pub fn fillrect(lefttop: (u32, u32), size: (u32, u32), c: char) {
+ unsafe { bindings::fillrect(
+ lefttop.0 as i32, lefttop.1 as i32,
+ size.0 as i32, size.1 as i32,
+ c as i32); }
+}
+
+pub fn redraw() {
+ unsafe { bindings::redraw(); }
+}
+
+pub fn redraw_full() {
+ unsafe { bindings::redrawfull(); }
+}
+
+pub fn scroll_term(lefttop: (u32, u32), size: (u32, u32), c: char) {
+ unsafe { bindings::scrollterm(
+ lefttop.0 as i32, lefttop.1 as i32,
+ size.0 as i32, size.1 as i32,
+ c as i32); }
+}
+
+pub fn get_buffer_char(pos: (u32, u32)) -> char {
+ unsafe {
+ char::from_u32(
+ bindings::getbufferchar(pos.0 as i32, pos.1 as i32) as u32
+ ).unwrap()
+ }
+}
+
+pub fn move_to(pos: (u32, u32)) {
+ unsafe { bindings::moveto(pos.0 as i32, pos.1 as i32); }
+}
+
+pub fn push_cursor() {
+ unsafe { bindings::pushcursor(); }
+}
+
+pub fn pop_cursor() {
+ unsafe { bindings::popcursor(); }
+}
+
+pub fn bel() {
+ unsafe { bindings::bel(); }
+}
+
+pub fn cursor_visible(visible: bool) {
+ unsafe { bindings::cursorvisible(visible); }
+}
+
+// None on EOF, otherwise a combination of the KEY_* constants
+pub fn get_key() -> io::Result<Option<i32>> {
+ match unsafe { bindings::tgetkey() } {
+ -2 => Err(io::Error::last_os_error()),
+ -1 => Ok(None),
+ value => Ok(Some(value)),
+ }
+}
+
+pub fn get_line() -> Option<String> {
+ let ptr = unsafe { bindings::tgetline() };
+ if ptr.is_null() {
+ None
+ } else {
+ let bytes = unsafe { CStr::from_ptr(ptr).to_bytes() };
+ let res = Some(String::from_utf8(bytes.to_vec()).unwrap());
+ unsafe { libc::free(ptr as *mut ffi::c_void); }
+ res
+ }
+}