aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2023-03-09 01:55:49 -0500
committerJesse Luehrs <doy@tozt.net>2023-03-09 01:55:49 -0500
commit23d8ba67f77d6310fc3982f2642897a14cf040fb (patch)
treee1e98b5cc756c836810710c701e8b82993bbc02c
parentb615e03beb20cb836fe643b57291657b9c2845d8 (diff)
downloadvt100-rust-23d8ba67f77d6310fc3982f2642897a14cf040fb.tar.gz
vt100-rust-23d8ba67f77d6310fc3982f2642897a14cf040fb.zip
remove Perform implementation from the screen directly
now that people can get mutable screens, this exposes api surface that i don't really want
-rw-r--r--CHANGELOG.md1
-rw-r--r--src/lib.rs1
-rw-r--r--src/parser.rs10
-rw-r--r--src/perform.rs222
-rw-r--r--src/screen.rs320
-rw-r--r--src/state.rs19
6 files changed, 294 insertions, 279 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 96e29d4..54c3b83 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,7 @@
`Screen::visual_bell_count`, and `Screen::errors` have been removed in favor
of the new callback api described above.
* `Cell` no longer implements `Default`.
+* `Screen` no longer implements `vte::Perform`.
### Changed
diff --git a/src/lib.rs b/src/lib.rs
index 92256f2..1c5cadd 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -51,6 +51,7 @@ mod callbacks;
mod cell;
mod grid;
mod parser;
+mod perform;
mod row;
mod screen;
mod state;
diff --git a/src/parser.rs b/src/parser.rs
index 10ebf10..77c95c3 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -2,7 +2,7 @@
/// the terminal contents.
pub struct Parser {
parser: vte::Parser,
- screen: crate::Screen,
+ screen: crate::perform::WrappedScreen,
}
impl Parser {
@@ -12,10 +12,10 @@ impl Parser {
pub fn new(rows: u16, cols: u16, scrollback_len: usize) -> Self {
Self {
parser: vte::Parser::new(),
- screen: crate::Screen::new(
+ screen: crate::perform::WrappedScreen(crate::Screen::new(
crate::grid::Size { rows, cols },
scrollback_len,
- ),
+ )),
}
}
@@ -45,14 +45,14 @@ impl Parser {
/// state.
#[must_use]
pub fn screen(&self) -> &crate::Screen {
- &self.screen
+ &self.screen.0
}
/// Returns a mutable reference to a `Screen` object containing the
/// terminal state.
#[must_use]
pub fn screen_mut(&mut self) -> &mut crate::Screen {
- &mut self.screen
+ &mut self.screen.0
}
}
diff --git a/src/perform.rs b/src/perform.rs
new file mode 100644
index 0000000..1c172f1
--- /dev/null
+++ b/src/perform.rs
@@ -0,0 +1,222 @@
+pub struct WrappedScreen(pub crate::Screen);
+
+impl vte::Perform for WrappedScreen {
+ fn print(&mut self, c: char) {
+ if c == '\u{fffd}' || ('\u{80}'..'\u{a0}').contains(&c) {
+ log::debug!("unhandled text character: {c}");
+ }
+ self.0.text(c);
+ }
+
+ fn execute(&mut self, b: u8) {
+ match b {
+ 8 => self.0.bs(),
+ 9 => self.0.tab(),
+ 10 => self.0.lf(),
+ 11 => self.0.vt(),
+ 12 => self.0.ff(),
+ 13 => self.0.cr(),
+ // we don't implement shift in/out alternate character sets, but
+ // it shouldn't count as an "error"
+ 7 | 14 | 15 => {}
+ _ => {
+ log::debug!("unhandled control character: {b}");
+ }
+ }
+ }
+
+ fn esc_dispatch(&mut self, intermediates: &[u8], _ignore: bool, b: u8) {
+ intermediates.first().map_or_else(
+ || match b {
+ b'7' => self.0.decsc(),
+ b'8' => self.0.decrc(),
+ b'=' => self.0.deckpam(),
+ b'>' => self.0.deckpnm(),
+ b'M' => self.0.ri(),
+ b'c' => self.0.ris(),
+ b'g' => {}
+ _ => {
+ log::debug!("unhandled escape code: ESC {b}");
+ }
+ },
+ |i| {
+ log::debug!("unhandled escape code: ESC {i} {b}");
+ },
+ );
+ }
+
+ fn csi_dispatch(
+ &mut self,
+ params: &vte::Params,
+ intermediates: &[u8],
+ _ignore: bool,
+ c: char,
+ ) {
+ match intermediates.first() {
+ None => match c {
+ '@' => self.0.ich(canonicalize_params_1(params, 1)),
+ 'A' => self.0.cuu(canonicalize_params_1(params, 1)),
+ 'B' => self.0.cud(canonicalize_params_1(params, 1)),
+ 'C' => self.0.cuf(canonicalize_params_1(params, 1)),
+ 'D' => self.0.cub(canonicalize_params_1(params, 1)),
+ 'G' => self.0.cha(canonicalize_params_1(params, 1)),
+ 'H' => self.0.cup(canonicalize_params_2(params, 1, 1)),
+ 'J' => self.0.ed(canonicalize_params_1(params, 0)),
+ 'K' => self.0.el(canonicalize_params_1(params, 0)),
+ 'L' => self.0.il(canonicalize_params_1(params, 1)),
+ 'M' => self.0.dl(canonicalize_params_1(params, 1)),
+ 'P' => self.0.dch(canonicalize_params_1(params, 1)),
+ 'S' => self.0.su(canonicalize_params_1(params, 1)),
+ 'T' => self.0.sd(canonicalize_params_1(params, 1)),
+ 'X' => self.0.ech(canonicalize_params_1(params, 1)),
+ 'd' => self.0.vpa(canonicalize_params_1(params, 1)),
+ 'h' => self.0.sm(params),
+ 'l' => self.0.rm(params),
+ 'm' => self.0.sgr(params),
+ 'r' => self.0.decstbm(canonicalize_params_decstbm(
+ params,
+ self.0.grid().size(),
+ )),
+ 't' => self.0.xtwinops(params),
+ _ => {
+ if log::log_enabled!(log::Level::Debug) {
+ log::debug!(
+ "unhandled csi sequence: CSI {} {}",
+ param_str(params),
+ c
+ );
+ }
+ }
+ },
+ Some(b'?') => match c {
+ 'J' => self.0.decsed(canonicalize_params_1(params, 0)),
+ 'K' => self.0.decsel(canonicalize_params_1(params, 0)),
+ 'h' => self.0.decset(params),
+ 'l' => self.0.decrst(params),
+ _ => {
+ if log::log_enabled!(log::Level::Debug) {
+ log::debug!(
+ "unhandled csi sequence: CSI ? {} {}",
+ param_str(params),
+ c
+ );
+ }
+ }
+ },
+ Some(i) => {
+ if log::log_enabled!(log::Level::Debug) {
+ log::debug!(
+ "unhandled csi sequence: CSI {} {} {}",
+ i,
+ param_str(params),
+ c
+ );
+ }
+ }
+ }
+ }
+
+ fn osc_dispatch(&mut self, params: &[&[u8]], _bel_terminated: bool) {
+ match (params.get(0), params.get(1)) {
+ (Some(&b"0"), Some(s)) => self.0.osc0(s),
+ (Some(&b"1"), Some(s)) => self.0.osc1(s),
+ (Some(&b"2"), Some(s)) => self.0.osc2(s),
+ _ => {
+ if log::log_enabled!(log::Level::Debug) {
+ log::debug!(
+ "unhandled osc sequence: OSC {}",
+ osc_param_str(params),
+ );
+ }
+ }
+ }
+ }
+
+ fn hook(
+ &mut self,
+ params: &vte::Params,
+ intermediates: &[u8],
+ _ignore: bool,
+ action: char,
+ ) {
+ if log::log_enabled!(log::Level::Debug) {
+ intermediates.first().map_or_else(
+ || {
+ log::debug!(
+ "unhandled dcs sequence: DCS {} {}",
+ param_str(params),
+ action,
+ );
+ },
+ |i| {
+ log::debug!(
+ "unhandled dcs sequence: DCS {} {} {}",
+ i,
+ param_str(params),
+ action,
+ );
+ },
+ );
+ }
+ }
+}
+
+fn canonicalize_params_1(params: &vte::Params, default: u16) -> u16 {
+ let first = params.iter().next().map_or(0, |x| *x.first().unwrap_or(&0));
+ if first == 0 {
+ default
+ } else {
+ first
+ }
+}
+
+fn canonicalize_params_2(
+ params: &vte::Params,
+ default1: u16,
+ default2: u16,
+) -> (u16, u16) {
+ let mut iter = params.iter();
+ let first = iter.next().map_or(0, |x| *x.first().unwrap_or(&0));
+ let first = if first == 0 { default1 } else { first };
+
+ let second = iter.next().map_or(0, |x| *x.first().unwrap_or(&0));
+ let second = if second == 0 { default2 } else { second };
+
+ (first, second)
+}
+
+fn canonicalize_params_decstbm(
+ params: &vte::Params,
+ size: crate::grid::Size,
+) -> (u16, u16) {
+ let mut iter = params.iter();
+ let top = iter.next().map_or(0, |x| *x.first().unwrap_or(&0));
+ let top = if top == 0 { 1 } else { top };
+
+ let bottom = iter.next().map_or(0, |x| *x.first().unwrap_or(&0));
+ let bottom = if bottom == 0 { size.rows } else { bottom };
+
+ (top, bottom)
+}
+
+pub fn param_str(params: &vte::Params) -> String {
+ let strs: Vec<_> = params
+ .iter()
+ .map(|subparams| {
+ let subparam_strs: Vec<_> = subparams
+ .iter()
+ .map(std::string::ToString::to_string)
+ .collect();
+ subparam_strs.join(" : ")
+ })
+ .collect();
+ strs.join(" ; ")
+}
+
+fn osc_param_str(params: &[&[u8]]) -> String {
+ let strs: Vec<_> = params
+ .iter()
+ .map(|b| format!("\"{}\"", std::string::String::from_utf8_lossy(b)))
+ .collect();
+ strs.join(" ; ")
+}
diff --git a/src/screen.rs b/src/screen.rs
index c64f8e9..ad54694 100644
--- a/src/screen.rs
+++ b/src/screen.rs
@@ -683,7 +683,7 @@ impl Screen {
self.attrs.inverse()
}
- fn grid(&self) -> &crate::grid::Grid {
+ pub(crate) fn grid(&self) -> &crate::grid::Grid {
if self.mode(MODE_ALTERNATE_SCREEN) {
&self.alternate_grid
} else {
@@ -753,7 +753,7 @@ impl Screen {
}
impl Screen {
- fn text(&mut self, c: char) {
+ pub(crate) fn text(&mut self, c: char) {
let pos = self.grid().pos();
let size = self.grid().size();
let attrs = self.attrs;
@@ -994,59 +994,59 @@ impl Screen {
// control codes
- fn bs(&mut self) {
+ pub(crate) fn bs(&mut self) {
self.grid_mut().col_dec(1);
}
- fn tab(&mut self) {
+ pub(crate) fn tab(&mut self) {
self.grid_mut().col_tab();
}
- fn lf(&mut self) {
+ pub(crate) fn lf(&mut self) {
self.grid_mut().row_inc_scroll(1);
}
- fn vt(&mut self) {
+ pub(crate) fn vt(&mut self) {
self.lf();
}
- fn ff(&mut self) {
+ pub(crate) fn ff(&mut self) {
self.lf();
}
- fn cr(&mut self) {
+ pub(crate) fn cr(&mut self) {
self.grid_mut().col_set(0);
}
// escape codes
// ESC 7
- fn decsc(&mut self) {
+ pub(crate) fn decsc(&mut self) {
self.save_cursor();
}
// ESC 8
- fn decrc(&mut self) {
+ pub(crate) fn decrc(&mut self) {
self.restore_cursor();
}
// ESC =
- fn deckpam(&mut self) {
+ pub(crate) fn deckpam(&mut self) {
self.set_mode(MODE_APPLICATION_KEYPAD);
}
// ESC >
- fn deckpnm(&mut self) {
+ pub(crate) fn deckpnm(&mut self) {
self.clear_mode(MODE_APPLICATION_KEYPAD);
}
// ESC M
- fn ri(&mut self) {
+ pub(crate) fn ri(&mut self) {
self.grid_mut().row_dec_scroll(1);
}
// ESC c
- fn ris(&mut self) {
+ pub(crate) fn ris(&mut self) {
let title = self.title.clone();
let icon_name = self.icon_name.clone();
@@ -1059,37 +1059,37 @@ impl Screen {
// csi codes
// CSI @
- fn ich(&mut self, count: u16) {
+ pub(crate) fn ich(&mut self, count: u16) {
self.grid_mut().insert_cells(count);
}
// CSI A
- fn cuu(&mut self, offset: u16) {
+ pub(crate) fn cuu(&mut self, offset: u16) {
self.grid_mut().row_dec_clamp(offset);
}
// CSI B
- fn cud(&mut self, offset: u16) {
+ pub(crate) fn cud(&mut self, offset: u16) {
self.grid_mut().row_inc_clamp(offset);
}
// CSI C
- fn cuf(&mut self, offset: u16) {
+ pub(crate) fn cuf(&mut self, offset: u16) {
self.grid_mut().col_inc_clamp(offset);
}
// CSI D
- fn cub(&mut self, offset: u16) {
+ pub(crate) fn cub(&mut self, offset: u16) {
self.grid_mut().col_dec(offset);
}
// CSI G
- fn cha(&mut self, col: u16) {
+ pub(crate) fn cha(&mut self, col: u16) {
self.grid_mut().col_set(col - 1);
}
// CSI H
- fn cup(&mut self, (row, col): (u16, u16)) {
+ pub(crate) fn cup(&mut self, (row, col): (u16, u16)) {
self.grid_mut().set_pos(crate::grid::Pos {
row: row - 1,
col: col - 1,
@@ -1097,7 +1097,7 @@ impl Screen {
}
// CSI J
- fn ed(&mut self, mode: u16) {
+ pub(crate) fn ed(&mut self, mode: u16) {
let attrs = self.attrs;
match mode {
0 => self.grid_mut().erase_all_forward(attrs),
@@ -1110,12 +1110,12 @@ impl Screen {
}
// CSI ? J
- fn decsed(&mut self, mode: u16) {
+ pub(crate) fn decsed(&mut self, mode: u16) {
self.ed(mode);
}
// CSI K
- fn el(&mut self, mode: u16) {
+ pub(crate) fn el(&mut self, mode: u16) {
let attrs = self.attrs;
match mode {
0 => self.grid_mut().erase_row_forward(attrs),
@@ -1128,57 +1128,60 @@ impl Screen {
}
// CSI ? K
- fn decsel(&mut self, mode: u16) {
+ pub(crate) fn decsel(&mut self, mode: u16) {
self.el(mode);
}
// CSI L
- fn il(&mut self, count: u16) {
+ pub(crate) fn il(&mut self, count: u16) {
self.grid_mut().insert_lines(count);
}
// CSI M
- fn dl(&mut self, count: u16) {
+ pub(crate) fn dl(&mut self, count: u16) {
self.grid_mut().delete_lines(count);
}
// CSI P
- fn dch(&mut self, count: u16) {
+ pub(crate) fn dch(&mut self, count: u16) {
self.grid_mut().delete_cells(count);
}
// CSI S
- fn su(&mut self, count: u16) {
+ pub(crate) fn su(&mut self, count: u16) {
self.grid_mut().scroll_up(count);
}
// CSI T
- fn sd(&mut self, count: u16) {
+ pub(crate) fn sd(&mut self, count: u16) {
self.grid_mut().scroll_down(count);
}
// CSI X
- fn ech(&mut self, count: u16) {
+ pub(crate) fn ech(&mut self, count: u16) {
let attrs = self.attrs;
self.grid_mut().erase_cells(count, attrs);
}
// CSI d
- fn vpa(&mut self, row: u16) {
+ pub(crate) fn vpa(&mut self, row: u16) {
self.grid_mut().row_set(row - 1);
}
// CSI h
#[allow(clippy::unused_self)]
- fn sm(&mut self, params: &vte::Params) {
+ pub(crate) fn sm(&mut self, params: &vte::Params) {
// nothing, i think?
if log::log_enabled!(log::Level::Debug) {
- log::debug!("unhandled SM mode: {}", param_str(params));
+ log::debug!(
+ "unhandled SM mode: {}",
+ crate::perform::param_str(params)
+ );
}
}
// CSI ? h
- fn decset(&mut self, params: &vte::Params) {
+ pub(crate) fn decset(&mut self, params: &vte::Params) {
for param in params {
match param {
&[1] => self.set_mode(MODE_APPLICATION_CURSOR),
@@ -1226,15 +1229,18 @@ impl Screen {
// CSI l
#[allow(clippy::unused_self)]
- fn rm(&mut self, params: &vte::Params) {
+ pub(crate) fn rm(&mut self, params: &vte::Params) {
// nothing, i think?
if log::log_enabled!(log::Level::Debug) {
- log::debug!("unhandled RM mode: {}", param_str(params));
+ log::debug!(
+ "unhandled RM mode: {}",
+ crate::perform::param_str(params)
+ );
}
}
// CSI ? l
- fn decrst(&mut self, params: &vte::Params) {
+ pub(crate) fn decrst(&mut self, params: &vte::Params) {
for param in params {
match param {
&[1] => self.clear_mode(MODE_APPLICATION_CURSOR),
@@ -1284,7 +1290,7 @@ impl Screen {
}
// CSI m
- fn sgr(&mut self, params: &vte::Params) {
+ pub(crate) fn sgr(&mut self, params: &vte::Params) {
// XXX really i want to just be able to pass in a default Params
// instance with a 0 in it, but vte doesn't allow creating new Params
// instances
@@ -1443,242 +1449,46 @@ impl Screen {
}
// CSI r
- fn decstbm(&mut self, (top, bottom): (u16, u16)) {
+ pub(crate) fn decstbm(&mut self, (top, bottom): (u16, u16)) {
self.grid_mut().set_scroll_region(top - 1, bottom - 1);
}
// CSI t
#[allow(clippy::unused_self)]
- fn xtwinops(&self, params: &vte::Params) {
+ pub(crate) fn xtwinops(&self, params: &vte::Params) {
let mut iter = params.iter();
let op = iter.next().and_then(|x| x.first().copied());
match op {
Some(8) => {}
_ => {
- log::debug!("unhandled XTWINOPS: {}", param_str(params));
+ log::debug!(
+ "unhandled XTWINOPS: {}",
+ crate::perform::param_str(params)
+ );
}
}
}
// osc codes
- fn osc0(&mut self, s: &[u8]) {
+ pub(crate) fn osc0(&mut self, s: &[u8]) {
self.osc1(s);
self.osc2(s);
}
- fn osc1(&mut self, s: &[u8]) {
+ pub(crate) fn osc1(&mut self, s: &[u8]) {
if let Ok(s) = std::str::from_utf8(s) {
self.icon_name = s.to_string();
}
}
- fn osc2(&mut self, s: &[u8]) {
+ pub(crate) fn osc2(&mut self, s: &[u8]) {
if let Ok(s) = std::str::from_utf8(s) {
self.title = s.to_string();
}
}
}
-impl vte::Perform for Screen {
- fn print(&mut self, c: char) {
- if c == '\u{fffd}' || ('\u{80}'..'\u{a0}').contains(&c) {
- log::debug!("unhandled text character: {c}");
- }
- self.text(c);
- }
-
- fn execute(&mut self, b: u8) {
- match b {
- 8 => self.bs(),
- 9 => self.tab(),
- 10 => self.lf(),
- 11 => self.vt(),
- 12 => self.ff(),
- 13 => self.cr(),
- // we don't implement shift in/out alternate character sets, but
- // it shouldn't count as an "error"
- 7 | 14 | 15 => {}
- _ => {
- log::debug!("unhandled control character: {b}");
- }
- }
- }
-
- fn esc_dispatch(&mut self, intermediates: &[u8], _ignore: bool, b: u8) {
- intermediates.first().map_or_else(
- || match b {
- b'7' => self.decsc(),
- b'8' => self.decrc(),
- b'=' => self.deckpam(),
- b'>' => self.deckpnm(),
- b'M' => self.ri(),
- b'c' => self.ris(),
- b'g' => {}
- _ => {
- log::debug!("unhandled escape code: ESC {b}");
- }
- },
- |i| {
- log::debug!("unhandled escape code: ESC {i} {b}");
- },
- );
- }
-
- fn csi_dispatch(
- &mut self,
- params: &vte::Params,
- intermediates: &[u8],
- _ignore: bool,
- c: char,
- ) {
- match intermediates.first() {
- None => match c {
- '@' => 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(params),
- 'l' => self.rm(params),
- 'm' => self.sgr(params),
- 'r' => self.decstbm(canonicalize_params_decstbm(
- params,
- self.grid().size(),
- )),
- 't' => self.xtwinops(params),
- _ => {
- if log::log_enabled!(log::Level::Debug) {
- log::debug!(
- "unhandled csi sequence: CSI {} {}",
- param_str(params),
- c
- );
- }
- }
- },
- Some(b'?') => match c {
- 'J' => self.decsed(canonicalize_params_1(params, 0)),
- 'K' => self.decsel(canonicalize_params_1(params, 0)),
- 'h' => self.decset(params),
- 'l' => self.decrst(params),
- _ => {
- if log::log_enabled!(log::Level::Debug) {
- log::debug!(
- "unhandled csi sequence: CSI ? {} {}",
- param_str(params),
- c
- );
- }
- }
- },
- Some(i) => {
- if log::log_enabled!(log::Level::Debug) {
- log::debug!(
- "unhandled csi sequence: CSI {} {} {}",
- i,
- param_str(params),
- c
- );
- }
- }
- }
- }
-
- fn osc_dispatch(&mut self, params: &[&[u8]], _bel_terminated: bool) {
- match (params.get(0), params.get(1)) {
- (Some(&b"0"), Some(s)) => self.osc0(s),
- (Some(&b"1"), Some(s)) => self.osc1(s),
- (Some(&b"2"), Some(s)) => self.osc2(s),
- _ => {
- if log::log_enabled!(log::Level::Debug) {
- log::debug!(
- "unhandled osc sequence: OSC {}",
- osc_param_str(params),
- );
- }
- }
- }
- }
-
- fn hook(
- &mut self,
- params: &vte::Params,
- intermediates: &[u8],
- _ignore: bool,
- action: char,
- ) {
- if log::log_enabled!(log::Level::Debug) {
- intermediates.first().map_or_else(
- || {
- log::debug!(
- "unhandled dcs sequence: DCS {} {}",
- param_str(params),
- action,
- );
- },
- |i| {
- log::debug!(
- "unhandled dcs sequence: DCS {} {} {}",
- i,
- param_str(params),
- action,
- );
- },
- );
- }
- }
-}
-
-fn canonicalize_params_1(params: &vte::Params, default: u16) -> u16 {
- let first = params.iter().next().map_or(0, |x| *x.first().unwrap_or(&0));
- if first == 0 {
- default
- } else {
- first
- }
-}
-
-fn canonicalize_params_2(
- params: &vte::Params,
- default1: u16,
- default2: u16,
-) -> (u16, u16) {
- let mut iter = params.iter();
- let first = iter.next().map_or(0, |x| *x.first().unwrap_or(&0));
- let first = if first == 0 { default1 } else { first };
-
- let second = iter.next().map_or(0, |x| *x.first().unwrap_or(&0));
- let second = if second == 0 { default2 } else { second };
-
- (first, second)
-}
-
-fn canonicalize_params_decstbm(
- params: &vte::Params,
- size: crate::grid::Size,
-) -> (u16, u16) {
- let mut iter = params.iter();
- let top = iter.next().map_or(0, |x| *x.first().unwrap_or(&0));
- let top = if top == 0 { 1 } else { top };
-
- let bottom = iter.next().map_or(0, |x| *x.first().unwrap_or(&0));
- let bottom = if bottom == 0 { size.rows } else { bottom };
-
- (top, bottom)
-}
-
fn u16_to_u8(i: u16) -> Option<u8> {
if i > u16::from(u8::max_value()) {
None
@@ -1687,25 +1497,3 @@ fn u16_to_u8(i: u16) -> Option<u8> {
Some(i.try_into().unwrap())
}
}
-
-fn param_str(params: &vte::Params) -> String {
- let strs: Vec<_> = params
- .iter()
- .map(|subparams| {
- let subparam_strs: Vec<_> = subparams
- .iter()
- .map(std::string::ToString::to_string)
- .collect();
- subparam_strs.join(" : ")
- })
- .collect();
- strs.join(" ; ")
-}
-
-fn osc_param_str(params: &[&[u8]]) -> String {
- let strs: Vec<_> = params
- .iter()
- .map(|b| format!("\"{}\"", std::string::String::from_utf8_lossy(b)))
- .collect();
- strs.join(" ; ")
-}
diff --git a/src/state.rs b/src/state.rs
index 5471bdd..1268574 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -1,10 +1,13 @@
pub struct State<'a, T: crate::callbacks::Callbacks> {
- screen: &'a mut crate::Screen,
+ screen: &'a mut crate::perform::WrappedScreen,
callbacks: &'a mut T,
}
impl<'a, T: crate::callbacks::Callbacks> State<'a, T> {
- pub fn new(screen: &'a mut crate::Screen, callbacks: &'a mut T) -> Self {
+ pub fn new(
+ screen: &'a mut crate::perform::WrappedScreen,
+ callbacks: &'a mut T,
+ ) -> Self {
Self { screen, callbacks }
}
}
@@ -12,17 +15,17 @@ impl<'a, T: crate::callbacks::Callbacks> State<'a, T> {
impl<'a, T: crate::callbacks::Callbacks> vte::Perform for State<'a, T> {
fn print(&mut self, c: char) {
if c == '\u{fffd}' || ('\u{80}'..'\u{a0}').contains(&c) {
- self.callbacks.error(self.screen);
+ self.callbacks.error(&mut self.screen.0);
}
self.screen.print(c);
}
fn execute(&mut self, b: u8) {
match b {
- 7 => self.callbacks.audible_bell(self.screen),
+ 7 => self.callbacks.audible_bell(&mut self.screen.0),
8..=15 => {}
_ => {
- self.callbacks.error(self.screen);
+ self.callbacks.error(&mut self.screen.0);
}
}
self.screen.execute(b);
@@ -30,7 +33,7 @@ impl<'a, T: crate::callbacks::Callbacks> vte::Perform for State<'a, T> {
fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, b: u8) {
if intermediates.is_empty() && b == b'g' {
- self.callbacks.visual_bell(self.screen);
+ self.callbacks.visual_bell(&mut self.screen.0);
}
self.screen.esc_dispatch(intermediates, ignore, b);
}
@@ -46,14 +49,14 @@ impl<'a, T: crate::callbacks::Callbacks> vte::Perform for State<'a, T> {
let mut iter = params.iter();
let op = iter.next().and_then(|x| x.first().copied());
if op == Some(8) {
- let (screen_rows, screen_cols) = self.screen.size();
+ let (screen_rows, screen_cols) = self.screen.0.size();
let rows = iter.next().map_or(screen_rows, |x| {
*x.first().unwrap_or(&screen_rows)
});
let cols = iter.next().map_or(screen_cols, |x| {
*x.first().unwrap_or(&screen_cols)
});
- self.callbacks.resize(self.screen, (rows, cols));
+ self.callbacks.resize(&mut self.screen.0, (rows, cols));
}
}
self.screen.csi_dispatch(params, intermediates, ignore, c);