diff options
author | Jesse Luehrs <doy@tozt.net> | 2013-03-20 21:33:19 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2013-03-20 21:33:19 -0500 |
commit | d00c8ec76c498196be8bfe2d58f27697bda9de69 (patch) | |
tree | c3126e111332355683d533d7741afbaca7f36cd4 | |
parent | 8fc473d033a4c38f7c0024bd259ff54b9867d50d (diff) | |
download | rust-term-d00c8ec76c498196be8bfe2d58f27697bda9de69.tar.gz rust-term-d00c8ec76c498196be8bfe2d58f27697bda9de69.zip |
start working on a terminfo wrapper
-rw-r--r-- | Makefile | 13 | ||||
-rw-r--r-- | src/curses_helper.c | 7 | ||||
-rw-r--r-- | src/info.rs | 103 | ||||
-rw-r--r-- | test/rl.rs | 18 |
4 files changed, 138 insertions, 3 deletions
@@ -2,7 +2,7 @@ RUSTC = rustc MAIN_SOURCE = src/term.rs OTHER_SOURCES = src/ios.rs src/info.rs -TESTS = bin/termios bin/termios2 bin/termios3 +TESTS = bin/termios bin/termios2 bin/termios3 bin/rl all: build tests @@ -14,17 +14,24 @@ bin/%: test/%.rs @mkdir -p bin $(RUSTC) --out-dir bin -L lib $< -lib/built: $(MAIN_SOURCE) $(OTHER_SOURCES) tmp/libtermios_wrapper.a +lib/built: $(MAIN_SOURCE) $(OTHER_SOURCES) tmp/libtermios_wrapper.a tmp/libcurses_helper.a @mkdir -p lib $(RUSTC) --out-dir lib -L tmp $(MAIN_SOURCE) && touch tmp/built tmp/libtermios_wrapper.a: tmp/termios_wrapper.o - ar cr tmp/libtermios_wrapper.a tmp/termios_wrapper.o + ar cr $@ $< tmp/termios_wrapper.o: src/termios_wrapper.c @mkdir -p tmp cc -fPIC -c -o $@ $< +tmp/libcurses_helper.a: tmp/curses_helper.o + ar cr $@ $< + +tmp/curses_helper.o: src/curses_helper.c + @mkdir -p tmp + cc -fPIC -c -o $@ $< + clean: -@rm -rf lib/ bin/ tmp/ diff --git a/src/curses_helper.c b/src/curses_helper.c new file mode 100644 index 0000000..2e71e0a --- /dev/null +++ b/src/curses_helper.c @@ -0,0 +1,7 @@ +#include <curses.h> +#include <term.h> + +char *tiparm2(const char *name, int p1, int p2) +{ + return tiparm(name, p1, p2); +} diff --git a/src/info.rs b/src/info.rs index e69de29..d1b3695 100644 --- a/src/info.rs +++ b/src/info.rs @@ -0,0 +1,103 @@ +use core::libc::{c_char,c_int}; + +pub fn init () { + unsafe { c::setupterm(ptr::null(), 1, ptr::null()) }; +} + +pub fn clear () { + write_escape("clear"); +} + +pub fn move (col: uint, row: uint) { + if col == 0u && row == 0u { + write_escape("home"); + } + else { + write_escape2("cup", row as int, col as int); + } +} + +/* +pub fn color_name (name: &str) -> u8 { +} + +pub fn color_rgb (r: u8, g: u8, b: u8) -> u8 { +} + +pub fn color (color: u8) { +} + +pub fn bold (enabled: bool) { +} + +pub fn reverse (enabled: bool) { +} +*/ + +pub fn cursor (enabled: bool) { + if enabled { + write_escape("civis"); + } + else { + write_escape("cnorm"); + } +} + +pub fn with_alternate_screen<T> (body: &fn () -> T) -> T { + write_escape("smcup"); + let ret = body(); + write_escape("rmcup"); + ret +} + +fn write_escape (name: &str) { + let output = do str::as_c_str(name) |c_name| { + unsafe { + str::raw::from_c_str(tigetstr(c_name)) + } + }; + io::print(output); +} + +fn write_escape2 (name: &str, p1: int, p2: int) { + let output = do str::as_c_str(name) |c_name| { + unsafe { + str::raw::from_c_str(tiparm2(tigetstr(c_name), p1, p2)) + } + }; + io::print(output); +} + +unsafe fn tigetstr (name: *c_char) -> *c_char { + let c_out = c::tigetstr(name); + if c_out as int == -1 { + fail!(fmt!("%s is not a terminal capability", + unsafe { str::raw::from_c_str(name) })); + } + else if c_out == ptr::null() { + fail!(fmt!("The current terminal doesn't support %s", + unsafe { str::raw::from_c_str(name) })); + } + c_out +} + +unsafe fn tiparm2 (name: *c_char, p1: int, p2: int) -> *c_char { + let ret = helper::tiparm2(name, p1 as c_int, p2 as c_int); + if ret == ptr::null() { + fail!(fmt!("Couldn't assemble parameters with %s %d %d", + unsafe { str::raw::from_c_str(name) }, p1, p2)); + } + ret +} + +#[link_name = "curses"] +extern mod c { + fn setupterm (term: *c_char, fd: c_int, errret: *c_int) -> c_int; + fn tigetstr (s: *c_char) -> *c_char; +} + +// tiparm uses varargs, which you can't bind from rust yet +#[link_name = "curses_helper"] +extern mod helper { + fn tiparm2(s: *c_char, p1: c_int, p2: c_int) -> *c_char; +} diff --git a/test/rl.rs b/test/rl.rs new file mode 100644 index 0000000..2ea664f --- /dev/null +++ b/test/rl.rs @@ -0,0 +1,18 @@ +extern mod term; +use core::io::ReaderUtil; + +fn main () { + term::info::init(); + let (rows, cols) = term::ios::size(); + do term::ios::preserve { + term::ios::cbreak(); + do term::info::with_alternate_screen { + term::info::clear(); + for uint::range(0, rows) |i| { + term::info::move(0, i); + io::print(str::repeat(".", cols)); + } + io::stdin().read_char(); + } + } +} |