From 60a7ec2ecf621ebb6f3376f71b27cdc61d7fc5a1 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Tue, 26 Apr 2016 04:15:33 -0400 Subject: stop tracking terminal size separately --- Cargo.toml | 1 + build.rs | 19 ++++++++++++++++++- src/ffi.c | 12 ++++++++++++ src/ffi.rs | 3 +++ src/screen.rs | 52 ++++++++++++++++++++++++++++++++++------------------ tests/basic.rs | 4 ++-- 6 files changed, 70 insertions(+), 21 deletions(-) create mode 100644 src/ffi.c diff --git a/Cargo.toml b/Cargo.toml index c703990..e3b7ca8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ authors = ["Jesse Luehrs "] build = "build.rs" [build-dependencies] +gcc = "0.3.27" pkg-config = "0.3.8" [dependencies] diff --git a/build.rs b/build.rs index e5bb100..b5b3423 100644 --- a/build.rs +++ b/build.rs @@ -1,12 +1,17 @@ +extern crate gcc; extern crate pkg_config; -fn main() { +fn libvt100() { + let dir = std::env::current_dir() + .unwrap_or_else(|e| { panic!("couldn't get cwd: {}", e) });; std::env::set_current_dir("libvt100") .unwrap_or_else(|e| { panic!("failed to chdir: {}", e) }); let out = std::process::Command::new("make") .arg("static") .output() .unwrap_or_else(|e| { panic!("failed to exec: {}", e) }); + std::env::set_current_dir(dir) + .unwrap_or_else(|e| { panic!("failed to chdir: {}", e) }); if !out.status.success() { println!("{}", std::string::String::from_utf8_lossy(&out.stderr)); std::process::exit(out.status.code().unwrap_or(255)); @@ -14,7 +19,9 @@ fn main() { println!("cargo:rustc-link-search=native=libvt100"); println!("cargo:rustc-link-lib=static=vt100"); +} +fn glib() { let lib_def = pkg_config::probe_library("glib-2.0") .unwrap_or_else(|e| { panic!("Couldn't find required dependency glib-2.0: {}", e); @@ -26,3 +33,13 @@ fn main() { println!("cargo:rustc-link-lib={}", lib); } } + +fn libvt100_wrappers() { + gcc::compile_library("libvt100wrappers.a", &["src/ffi.c"]); +} + +fn main() { + libvt100(); + glib(); + libvt100_wrappers(); +} diff --git a/src/ffi.c b/src/ffi.c new file mode 100644 index 0000000..a4af5ba --- /dev/null +++ b/src/ffi.c @@ -0,0 +1,12 @@ +#include +#include "../libvt100/src/vt100.h" + +int vt100_wrapper_rows(VT100Screen *vt) +{ + return vt->grid->max.row; +} + +int vt100_wrapper_cols(VT100Screen *vt) +{ + return vt->grid->max.col; +} diff --git a/src/ffi.rs b/src/ffi.rs index ceb8f35..47281ba 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -21,6 +21,9 @@ extern "C" { outp: *mut *mut libc::c_char, outlen: *mut libc::size_t, ); + + pub fn vt100_wrapper_rows(screen: *mut types::ScreenImpl) -> libc::c_int; + pub fn vt100_wrapper_cols(screen: *mut types::ScreenImpl) -> libc::c_int; } #[cfg(test)] diff --git a/src/screen.rs b/src/screen.rs index 698a6af..296f2dc 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -4,29 +4,31 @@ use std; use ffi; use types; -pub struct Screen { - pub rows: i32, - pub cols: i32, - - screen_impl: *mut types::ScreenImpl, -} +pub struct Screen(*mut types::ScreenImpl); impl Screen { pub fn new(rows: i32, cols: i32) -> Screen { let screen_impl = unsafe { ffi::vt100_screen_new(rows as libc::c_int, cols as libc::c_int) }; - Screen { - rows: rows, - cols: cols, - screen_impl: screen_impl, - } + Screen(screen_impl) + } + + pub fn rows(&self) -> i32 { + let Screen(screen_impl) = *self; + unsafe { ffi::vt100_wrapper_rows(screen_impl) } + } + + pub fn cols(&self) -> i32 { + let Screen(screen_impl) = *self; + unsafe { ffi::vt100_wrapper_cols(screen_impl) } } pub fn process(&mut self, s: &str) -> u64 { + let Screen(screen_impl) = *self; unsafe { ffi::vt100_screen_process_string( - self.screen_impl, + screen_impl, s.as_ptr() as *const libc::c_char, s.len() ) as u64 @@ -39,10 +41,23 @@ impl Screen { row_end: i32, col_end: i32 ) -> String { - let row_start = std::cmp::min(std::cmp::max(row_start, 0), self.rows - 1); - let col_start = std::cmp::min(std::cmp::max(col_start, 0), self.cols - 1); - let row_end = std::cmp::min(std::cmp::max(row_end, 0), self.rows - 1); - let col_end = std::cmp::min(std::cmp::max(col_end, 0), self.cols - 1); + let Screen(screen_impl) = *self; + let row_start = std::cmp::min( + std::cmp::max(row_start, 0), + self.rows() - 1 + ); + let col_start = std::cmp::min( + std::cmp::max(col_start, 0), + self.cols() - 1 + ); + let row_end = std::cmp::min( + std::cmp::max(row_end, 0), + self.rows() - 1 + ); + let col_end = std::cmp::min( + std::cmp::max(col_end, 0), + self.cols() - 1 + ); let start_loc = types::Loc { row: row_start, col: col_start }; let end_loc = types::Loc { row: row_end, col: col_end }; @@ -51,7 +66,7 @@ impl Screen { let mut len: libc::size_t = unsafe { std::mem::uninitialized() }; unsafe { ffi::vt100_screen_get_string_plaintext( - self.screen_impl, + screen_impl, &start_loc as *const types::Loc, &end_loc as *const types::Loc, &mut plaintext as *mut *mut libc::c_char, @@ -70,6 +85,7 @@ impl Screen { impl Drop for Screen { fn drop(&mut self) { - unsafe { ffi::vt100_screen_delete(self.screen_impl) }; + let Screen(screen_impl) = *self; + unsafe { ffi::vt100_screen_delete(screen_impl) }; } } diff --git a/tests/basic.rs b/tests/basic.rs index 9178ded..739b75c 100644 --- a/tests/basic.rs +++ b/tests/basic.rs @@ -7,8 +7,8 @@ mod tests { #[test] fn object_creation() { let mut screen = vt100::Screen::new(24, 80); - assert_eq!(screen.rows, 24); - assert_eq!(screen.cols, 80); + assert_eq!(screen.rows(), 24); + assert_eq!(screen.cols(), 80); let input = "foo\x1b[31m\x1b[32mb\x1b[3;7;42ma\x1b[23mr"; screen.process(input); -- cgit v1.2.3