diff options
author | Jesse Luehrs <doy@tozt.net> | 2019-11-01 14:56:36 -0400 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2019-11-01 14:58:08 -0400 |
commit | 34f476000424bb59650105f9b33e682b2eeb40ea (patch) | |
tree | c15077b0363142ea72caf92f5a4b81cd4ffd0f72 /src | |
parent | aadfe4f9155818054c52140bc5f919cea4fde9cb (diff) | |
download | vt100-rust-34f476000424bb59650105f9b33e682b2eeb40ea.tar.gz vt100-rust-34f476000424bb59650105f9b33e682b2eeb40ea.zip |
more consistent parameter handling
Diffstat (limited to 'src')
-rw-r--r-- | src/screen.rs | 265 |
1 files changed, 147 insertions, 118 deletions
diff --git a/src/screen.rs b/src/screen.rs index 9381e6b..b72347c 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -1,3 +1,7 @@ +use std::convert::TryInto as _; + +const DEFAULT_MULTI_PARAMS: &[i64] = &[0]; + struct State { grid: crate::grid::Grid, alternate_grid: Option<crate::grid::Grid>, @@ -88,8 +92,6 @@ impl State { } impl State { - const DEFAULT_SGR_PARAMS: &'static [i64] = &[0]; - fn text(&mut self, c: char) { let pos = *self.grid().pos(); if pos.col > 0 { @@ -221,61 +223,48 @@ impl State { // csi codes // CSI @ - fn ich(&mut self, params: &[i64]) { - let count = params.get(0).copied().unwrap_or(1); + fn ich(&mut self, count: u16) { let pos = *self.grid().pos(); - self.grid_mut().insert_cells(pos, count as u16); + self.grid_mut().insert_cells(pos, count); } // CSI A - fn cuu(&mut self, params: &[i64]) { - let offset = params.get(0).copied().unwrap_or(1); - self.grid_mut().row_dec_clamp(offset as u16); + fn cuu(&mut self, offset: u16) { + self.grid_mut().row_dec_clamp(offset); } // CSI B - fn cud(&mut self, params: &[i64]) { - let offset = params.get(0).copied().unwrap_or(1); - self.grid_mut().row_inc_clamp(offset as u16); + fn cud(&mut self, offset: u16) { + self.grid_mut().row_inc_clamp(offset); } // CSI C - fn cuf(&mut self, params: &[i64]) { - let offset = params.get(0).copied().unwrap_or(1); - self.grid_mut().col_inc_clamp(offset as u16); + fn cuf(&mut self, offset: u16) { + self.grid_mut().col_inc_clamp(offset); } // CSI D - fn cub(&mut self, params: &[i64]) { - let offset = params.get(0).copied().unwrap_or(1); - self.grid_mut().col_dec(offset as u16); + fn cub(&mut self, offset: u16) { + self.grid_mut().col_dec(offset); } // CSI G - fn cha(&mut self, params: &[i64]) { - // XXX need to handle value overflow - self.grid_mut().col_set(normalize_absolute_position( - params.get(0).map(|i| *i as u16), - )); + fn cha(&mut self, col: u16) { + self.grid_mut().col_set(col - 1); } // CSI H - fn cup(&mut self, params: &[i64]) { - // XXX need to handle value overflow + fn cup(&mut self, (row, col): (u16, u16)) { self.grid_mut().set_pos(crate::grid::Pos { - row: normalize_absolute_position( - params.get(0).map(|i| *i as u16), - ), - col: normalize_absolute_position( - params.get(1).map(|i| *i as u16), - ), + row: row - 1, + col: col - 1, }); } // CSI J - fn ed(&mut self, params: &[i64]) { + fn ed(&mut self, mode: u16) { let pos = *self.grid().pos(); - match params.get(0).copied().unwrap_or(0) { + match mode { 0 => self.grid_mut().erase_all_forward(pos), 1 => self.grid_mut().erase_all_backward(pos), 2 => self.grid_mut().erase_all(), @@ -284,14 +273,14 @@ impl State { } // CSI ? J - fn decsed(&mut self, params: &[i64]) { - self.ed(params); + fn decsed(&mut self, mode: u16) { + self.ed(mode); } // CSI K - fn el(&mut self, params: &[i64]) { + fn el(&mut self, mode: u16) { let pos = *self.grid().pos(); - match params.get(0).copied().unwrap_or(0) { + match mode { 0 => self.grid_mut().erase_row_forward(pos), 1 => self.grid_mut().erase_row_backward(pos), 2 => self.grid_mut().erase_row(pos), @@ -300,56 +289,47 @@ impl State { } // CSI ? K - fn decsel(&mut self, params: &[i64]) { - self.el(params); + fn decsel(&mut self, mode: u16) { + self.el(mode); } // CSI L - fn il(&mut self, params: &[i64]) { - let count = params.get(0).copied().unwrap_or(1); + fn il(&mut self, count: u16) { let pos = *self.grid().pos(); - self.grid_mut().insert_lines(pos, count as u16); + self.grid_mut().insert_lines(pos, count); } // CSI M - fn dl(&mut self, params: &[i64]) { - let count = params.get(0).copied().unwrap_or(1); + fn dl(&mut self, count: u16) { let pos = *self.grid().pos(); - self.grid_mut().delete_lines(pos, count as u16); + self.grid_mut().delete_lines(pos, count); } // CSI P - fn dch(&mut self, params: &[i64]) { - let count = params.get(0).copied().unwrap_or(1); + fn dch(&mut self, count: u16) { let pos = *self.grid().pos(); - self.grid_mut().delete_cells(pos, count as u16); + self.grid_mut().delete_cells(pos, count); } // CSI S - fn su(&mut self, params: &[i64]) { - let count = params.get(0).copied().unwrap_or(1); - self.grid_mut().scroll_up(count as u16); + fn su(&mut self, count: u16) { + self.grid_mut().scroll_up(count); } // CSI T - fn sd(&mut self, params: &[i64]) { - let count = params.get(0).copied().unwrap_or(1); - self.grid_mut().scroll_down(count as u16); + fn sd(&mut self, count: u16) { + self.grid_mut().scroll_down(count); } // CSI X - fn ech(&mut self, params: &[i64]) { - let count = params.get(0).copied().unwrap_or(1); + fn ech(&mut self, count: u16) { let pos = *self.grid().pos(); - self.grid_mut().erase_cells(pos, count as u16); + self.grid_mut().erase_cells(pos, count); } // CSI d - fn vpa(&mut self, params: &[i64]) { - // XXX need to handle value overflow - self.grid_mut().row_set(normalize_absolute_position( - params.get(0).map(|i| *i as u16), - )); + fn vpa(&mut self, row: u16) { + self.grid_mut().row_set(row - 1); } // CSI h @@ -398,14 +378,8 @@ impl State { // CSI m fn sgr(&mut self, params: &[i64]) { - // XXX need to handle value overflow // XXX need to handle incorrect numbers of parameters for some of the // fancier options - let params = if params.is_empty() { - Self::DEFAULT_SGR_PARAMS - } else { - params - }; let mut i = 0; while i < params.len() { match params[i] { @@ -503,24 +477,13 @@ impl State { } // CSI r - fn csr(&mut self, params: &[i64]) { - let top = if let Some(top) = params.get(0).map(|i| *i as u16) { - top as u16 - 1 - } else { - return; - }; - let bottom = if let Some(bottom) = params.get(1).map(|i| *i as u16) { - bottom as u16 - 1 - } else { - return; - }; - let left = params.get(2).map(|i| *i as u16).unwrap_or(1) - 1; - let right = params - .get(3) - .map(|i| *i as u16) - .unwrap_or(self.grid().size().cols) - - 1; - self.grid_mut().set_scroll_region(top, bottom, left, right); + fn csr(&mut self, (top, bottom, left, right): (u16, u16, u16, u16)) { + self.grid_mut().set_scroll_region( + top - 1, + bottom - 1, + left - 1, + right - 1, + ); } // osc codes @@ -592,33 +555,36 @@ impl vte::Perform for State { ) { match intermediates.get(0) { None => 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), - 'h' => self.sm(params), - 'l' => self.rm(params), - 'm' => self.sgr(params), - 'r' => self.csr(params), + '@' => self.ich(canonicalize_params_1(params, 1)), + 'A' => self.cuu(canonicalize_params_1(params, 1)), + 'B' => self.cud(canonicalize_params_1(params, 1)), + 'C' => self.cuf(canonicalize_params_1(params, 1)), + 'D' => self.cub(canonicalize_params_1(params, 1)), + 'G' => self.cha(canonicalize_params_1(params, 1)), + 'H' => self.cup(canonicalize_params_2(params, 1, 1)), + 'J' => self.ed(canonicalize_params_1(params, 0)), + 'K' => self.el(canonicalize_params_1(params, 0)), + 'L' => self.il(canonicalize_params_1(params, 1)), + 'M' => self.dl(canonicalize_params_1(params, 1)), + 'P' => self.dch(canonicalize_params_1(params, 1)), + 'S' => self.su(canonicalize_params_1(params, 1)), + 'T' => self.sd(canonicalize_params_1(params, 1)), + 'X' => self.ech(canonicalize_params_1(params, 1)), + 'd' => self.vpa(canonicalize_params_1(params, 1)), + 'h' => self.sm(canonicalize_params_multi(params)), + 'l' => self.rm(canonicalize_params_multi(params)), + 'm' => self.sgr(canonicalize_params_multi(params)), + 'r' => self.csr(canonicalize_params_csr( + params, + *self.grid().size(), + )), _ => {} }, Some(b'?') => match c { - 'J' => self.decsed(params), - 'K' => self.decsel(params), - 'h' => self.decset(params), - 'l' => self.decrst(params), + 'J' => self.decsed(canonicalize_params_1(params, 0)), + 'K' => self.decsel(canonicalize_params_1(params, 0)), + 'h' => self.decset(canonicalize_params_multi(params)), + 'l' => self.decrst(canonicalize_params_multi(params)), _ => {} }, _ => {} @@ -786,15 +752,78 @@ impl Screen { } } -fn normalize_absolute_position(i: Option<u16>) -> u16 { - let i = if let Some(i) = i { - if i == 0 { - 1 - } else { - i - } +fn canonicalize_params_1(params: &[i64], default: u16) -> u16 { + let first = params.get(0).copied().unwrap_or(0); + if first == 0 { + default + } else { + i64_to_u16(first) + } +} + +fn canonicalize_params_2( + params: &[i64], + default1: u16, + default2: u16, +) -> (u16, u16) { + let first = params.get(0).copied().unwrap_or(0); + let first = if first == 0 { + default1 + } else { + i64_to_u16(first) + }; + + let second = params.get(1).copied().unwrap_or(0); + let second = if second == 0 { + default2 + } else { + i64_to_u16(second) + }; + + (first, second) +} + +fn canonicalize_params_multi(params: &[i64]) -> &[i64] { + if params.is_empty() { + DEFAULT_MULTI_PARAMS } else { - 1 + params + } +} + +fn canonicalize_params_csr( + params: &[i64], + size: crate::grid::Size, +) -> (u16, u16, u16, u16) { + let top = params.get(0).copied().unwrap_or(0); + let top = if top == 0 { 1 } else { i64_to_u16(top) }; + + let bottom = params.get(1).copied().unwrap_or(0); + let bottom = if bottom == 0 { + size.rows + } else { + i64_to_u16(bottom) }; - i - 1 + + let left = params.get(2).copied().unwrap_or(0); + let left = if left == 0 { 1 } else { i64_to_u16(left) }; + + let right = params.get(3).copied().unwrap_or(0); + let right = if right == 0 { + size.cols + } else { + i64_to_u16(right) + }; + + (top, bottom, left, right) +} + +fn i64_to_u16(i: i64) -> u16 { + if i < 0 { + 0 + } else if i > i64::from(u16::max_value()) { + u16::max_value() + } else { + i.try_into().unwrap() + } } |