aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml1
-rw-r--r--build.rs19
-rw-r--r--src/ffi.c12
-rw-r--r--src/ffi.rs3
-rw-r--r--src/screen.rs52
-rw-r--r--tests/basic.rs4
6 files changed, 70 insertions, 21 deletions
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 <doy@tozt.net>"]
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 <stdlib.h>
+#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);