aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2019-10-30 03:58:02 -0400
committerJesse Luehrs <doy@tozt.net>2019-10-30 03:58:02 -0400
commitf5dd2080f2533d0c927d23d3aef53d43ed2070db (patch)
treeb103357473e5b84af7a90b985101cb923bdb243b
parent0a08887fec51d6926eb7fa35b5c2625388b71184 (diff)
downloadvt100-rust-f5dd2080f2533d0c927d23d3aef53d43ed2070db.tar.gz
vt100-rust-f5dd2080f2533d0c927d23d3aef53d43ed2070db.zip
more passing tests
-rw-r--r--src/grid.rs108
-rw-r--r--src/row.rs16
-rw-r--r--src/screen.rs111
3 files changed, 227 insertions, 8 deletions
diff --git a/src/grid.rs b/src/grid.rs
index 52a4a9e..ad1ecdc 100644
--- a/src/grid.rs
+++ b/src/grid.rs
@@ -14,6 +14,10 @@ impl Grid {
}
}
+ pub fn pos(&self, rows: u16, cols: u16) -> Pos {
+ Pos::new(rows, cols, self.size)
+ }
+
pub fn size(&self) -> &Size {
&self.size
}
@@ -57,6 +61,103 @@ impl Grid {
) -> String {
unimplemented!()
}
+
+ pub fn erase_all(&mut self) {
+ self.rows = vec![
+ crate::row::Row::new(self.size.cols());
+ self.size.rows() as usize
+ ];
+ }
+
+ pub fn erase_all_forward(&mut self, pos: Pos) {
+ for i in (pos.row() + 1)..self.size.rows() {
+ self.rows[i as usize] = crate::row::Row::new(self.size.cols());
+ }
+ let row = &mut self.rows[pos.row() as usize];
+ for i in pos.col()..self.size.cols() {
+ *row.get_mut(i).unwrap() = crate::cell::Cell::default();
+ }
+ }
+
+ pub fn erase_all_backward(&mut self, pos: Pos) {
+ for i in 0..pos.row() {
+ self.rows[i as usize] = crate::row::Row::new(self.size.cols());
+ }
+ let row = &mut self.rows[pos.row() as usize];
+ for i in 0..pos.col() {
+ *row.get_mut(i).unwrap() = crate::cell::Cell::default();
+ }
+ }
+
+ pub fn erase_row(&mut self, pos: Pos) {
+ self.rows[pos.row() as usize] =
+ crate::row::Row::new(self.size.cols());
+ }
+
+ pub fn erase_row_forward(&mut self, pos: Pos) {
+ let row = &mut self.rows[pos.row() as usize];
+ for i in pos.col()..self.size.cols() {
+ *row.get_mut(i).unwrap() = crate::cell::Cell::default();
+ }
+ }
+
+ pub fn erase_row_backward(&mut self, pos: Pos) {
+ let row = &mut self.rows[pos.row() as usize];
+ for i in 0..pos.col() {
+ *row.get_mut(i).unwrap() = crate::cell::Cell::default();
+ }
+ }
+
+ pub fn insert_cells(&mut self, pos: Pos, count: u16) {
+ let row = &mut self.rows[pos.row() as usize];
+ for _ in 0..count {
+ row.insert(pos.col() as usize, crate::cell::Cell::default());
+ }
+ row.truncate(pos.size.cols() as usize);
+ }
+
+ pub fn delete_cells(&mut self, pos: Pos, count: u16) {
+ let row = &mut self.rows[pos.row() as usize];
+ for _ in 0..(count.min(pos.size.cols() - pos.col())) {
+ row.remove(pos.col() as usize);
+ }
+ row.resize(pos.size.cols() as usize, crate::cell::Cell::default());
+ }
+
+ pub fn erase_cells(&mut self, pos: Pos, count: u16) {
+ let row = &mut self.rows[pos.row() as usize];
+ for i in pos.col()..(pos.col() + count).min(pos.size.cols() - 1) {
+ *row.get_mut(i).unwrap() = crate::cell::Cell::default();
+ }
+ }
+
+ pub fn insert_lines(&mut self, pos: Pos, count: u16) {
+ for _ in 0..count {
+ self.rows.insert(
+ pos.row() as usize,
+ crate::row::Row::new(pos.size.cols()),
+ );
+ }
+ self.rows.truncate(pos.size.rows() as usize)
+ }
+
+ pub fn delete_lines(&mut self, pos: Pos, count: u16) {
+ for _ in 0..(count.min(pos.size.rows() - pos.row())) {
+ self.rows.remove(pos.row() as usize);
+ }
+ self.rows.resize(
+ pos.size.rows() as usize,
+ crate::row::Row::new(pos.size.cols()),
+ )
+ }
+
+ pub fn scroll_up(&mut self, count: u16) {
+ self.delete_lines(self.pos(0, 0), count);
+ }
+
+ pub fn scroll_down(&mut self, count: u16) {
+ self.insert_lines(self.pos(0, 0), count);
+ }
}
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
@@ -126,11 +227,16 @@ impl Pos {
self.col
}
- pub fn col_inc(&mut self, count: u16) {
+ pub fn col_inc_wrap(&mut self, count: u16) {
self.col = self.col.saturating_add(count);
self.col_wrap();
}
+ pub fn col_inc_clamp(&mut self, count: u16) {
+ self.col = self.col.saturating_add(count);
+ self.col_clamp();
+ }
+
pub fn col_dec(&mut self, count: u16) {
self.col = self.col.saturating_sub(count);
}
diff --git a/src/row.rs b/src/row.rs
index 1526ebc..878529e 100644
--- a/src/row.rs
+++ b/src/row.rs
@@ -20,6 +20,22 @@ impl Row {
self.cells.get_mut(col as usize)
}
+ pub fn insert(&mut self, i: usize, cell: crate::cell::Cell) {
+ self.cells.insert(i, cell);
+ }
+
+ pub fn remove(&mut self, i: usize) {
+ self.cells.remove(i);
+ }
+
+ pub fn truncate(&mut self, len: usize) {
+ self.cells.truncate(len);
+ }
+
+ pub fn resize(&mut self, len: usize, cell: crate::cell::Cell) {
+ self.cells.resize(len, cell);
+ }
+
pub fn contents(&self, col_start: u16, col_end: u16) -> String {
// XXX very inefficient
let mut max_col = None;
diff --git a/src/screen.rs b/src/screen.rs
index dc210c1..514309c 100644
--- a/src/screen.rs
+++ b/src/screen.rs
@@ -38,7 +38,7 @@ impl State {
}
fn pos(&self, row: u16, col: u16) -> crate::grid::Pos {
- crate::grid::Pos::new(row, col, *self.grid.size())
+ self.grid.pos(row, col)
}
}
@@ -51,7 +51,7 @@ impl State {
let attrs = self.attrs;
if let Some(cell) = self.current_cell_mut() {
cell.set(c.to_string(), attrs);
- self.cursor_position.col_inc(1);
+ self.cursor_position.col_inc_wrap(1);
} else {
panic!("couldn't find current cell")
}
@@ -82,12 +82,44 @@ impl State {
// csi codes
+ // CSI @
+ fn ich(&mut self, params: &[i64]) {
+ let count = params.get(0).copied().unwrap_or(1);
+ self.grid.insert_cells(self.cursor_position, count as u16);
+ }
+
+ // CSI A
+ fn cuu(&mut self, params: &[i64]) {
+ let offset = params.get(0).copied().unwrap_or(1);
+ self.cursor_position.row_dec(offset as u16);
+ }
+
+ // CSI B
+ fn cud(&mut self, params: &[i64]) {
+ let offset = params.get(0).copied().unwrap_or(1);
+ self.cursor_position.row_inc(offset as u16);
+ }
+
+ // CSI C
+ fn cuf(&mut self, params: &[i64]) {
+ let offset = params.get(0).copied().unwrap_or(1);
+ self.cursor_position.col_inc_clamp(offset as u16);
+ }
+
// CSI D
fn cub(&mut self, params: &[i64]) {
let offset = params.get(0).copied().unwrap_or(1);
self.cursor_position.col_dec(offset as u16);
}
+ // CSI G
+ fn cha(&mut self, params: &[i64]) {
+ // XXX need to handle value overflow
+ self.cursor_position.col_set(normalize_absolute_position(
+ params.get(0).map(|i| *i as u16),
+ ));
+ }
+
// CSI H
fn cup(&mut self, params: &[i64]) {
// XXX need to handle value overflow
@@ -100,15 +132,67 @@ impl State {
// CSI J
fn ed(&mut self, params: &[i64]) {
match params.get(0).copied().unwrap_or(0) {
- 0 => unimplemented!(),
- 1 => unimplemented!(),
- 2 => {
- self.grid = crate::grid::Grid::new(*self.grid.size());
- }
+ 0 => self.grid.erase_all_forward(self.cursor_position),
+ 1 => self.grid.erase_all_backward(self.cursor_position),
+ 2 => self.grid.erase_all(),
_ => {}
}
}
+ // CSI K
+ fn el(&mut self, params: &[i64]) {
+ match params.get(0).copied().unwrap_or(0) {
+ 0 => self.grid.erase_row_forward(self.cursor_position),
+ 1 => self.grid.erase_row_backward(self.cursor_position),
+ 2 => self.grid.erase_row(self.cursor_position),
+ _ => {}
+ }
+ }
+
+ // CSI L
+ fn il(&mut self, params: &[i64]) {
+ let count = params.get(0).copied().unwrap_or(1);
+ self.grid.insert_lines(self.cursor_position, count as u16);
+ }
+
+ // CSI M
+ fn dl(&mut self, params: &[i64]) {
+ let count = params.get(0).copied().unwrap_or(1);
+ self.grid.delete_lines(self.cursor_position, count as u16);
+ }
+
+ // CSI P
+ fn dch(&mut self, params: &[i64]) {
+ let count = params.get(0).copied().unwrap_or(1);
+ self.grid.delete_cells(self.cursor_position, count as u16);
+ }
+
+ // CSI S
+ fn su(&mut self, params: &[i64]) {
+ let count = params.get(0).copied().unwrap_or(1);
+ self.grid.scroll_up(count as u16);
+ }
+
+ // CSI T
+ fn sd(&mut self, params: &[i64]) {
+ let count = params.get(0).copied().unwrap_or(1);
+ self.grid.scroll_down(count as u16);
+ }
+
+ // CSI X
+ fn ech(&mut self, params: &[i64]) {
+ let count = params.get(0).copied().unwrap_or(1);
+ self.grid.erase_cells(self.cursor_position, count as u16);
+ }
+
+ // CSI d
+ fn vpa(&mut self, params: &[i64]) {
+ // XXX need to handle value overflow
+ self.cursor_position.row_set(normalize_absolute_position(
+ params.get(0).map(|i| *i as u16),
+ ));
+ }
+
// CSI m
fn sgr(&mut self, params: &[i64]) {
// XXX need to handle value overflow
@@ -237,9 +321,22 @@ impl vte::Perform for State {
c: char,
) {
match c {
+ '@' => self.ich(params),
+ 'A' => self.cuu(params),
+ 'B' => self.cud(params),
+ 'C' => self.cuf(params),
'D' => self.cub(params),
+ 'G' => self.cha(params),
'H' => self.cup(params),
'J' => self.ed(params),
+ 'K' => self.el(params),
+ 'L' => self.il(params),
+ 'M' => self.dl(params),
+ 'P' => self.dch(params),
+ 'S' => self.su(params),
+ 'T' => self.sd(params),
+ 'X' => self.ech(params),
+ 'd' => self.vpa(params),
'm' => self.sgr(params),
_ => {}
}