aboutsummaryrefslogtreecommitdiff
path: root/alacritty_terminal/src/ansi.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty_terminal/src/ansi.rs')
-rw-r--r--alacritty_terminal/src/ansi.rs41
1 files changed, 39 insertions, 2 deletions
diff --git a/alacritty_terminal/src/ansi.rs b/alacritty_terminal/src/ansi.rs
index 55492d36..7eb87910 100644
--- a/alacritty_terminal/src/ansi.rs
+++ b/alacritty_terminal/src/ansi.rs
@@ -10,6 +10,7 @@ use vte::{Params, ParamsIter};
use alacritty_config_derive::ConfigDeserialize;
+use crate::graphics::{sixel, GraphicData};
use crate::index::{Column, Line};
use crate::term::color::Rgb;
@@ -136,6 +137,9 @@ enum Dcs {
/// End of the synchronized update.
SyncEnd,
+
+ /// Sixel data
+ SixelData(Box<sixel::Parser>),
}
/// The processor wraps a `vte::Parser` to ultimately call methods on a Handler.
@@ -240,6 +244,7 @@ impl Processor {
self.state.sync_state.timeout = Some(Instant::now() + SYNC_UPDATE_TIMEOUT);
},
Some(Dcs::SyncEnd) => self.stop_sync(handler),
+ Some(Dcs::SixelData(_)) => (),
None => (),
},
}
@@ -456,6 +461,14 @@ pub trait Handler {
/// Report text area size in characters.
fn text_area_size_chars(&mut self) {}
+
+ /// Create a parser for Sixel data.
+ fn start_sixel_graphic(&mut self, _params: &Params) -> Option<Box<sixel::Parser>> {
+ None
+ }
+
+ /// Insert a new graphic item.
+ fn insert_graphic(&mut self, _data: GraphicData, _palette: Option<Vec<Rgb>>) {}
}
/// Terminal cursor configuration.
@@ -529,6 +542,8 @@ pub enum Mode {
LineFeedNewLine = 20,
/// ?25
ShowCursor = 25,
+ /// ?80
+ SixelScrolling = 80,
/// ?1000
ReportMouseClicks = 1000,
/// ?1002
@@ -547,6 +562,8 @@ pub enum Mode {
UrgencyHints = 1042,
/// ?1049
SwapScreenAndSetRestoreCursor = 1049,
+ /// Use a private palette for each new graphic.
+ SixelPrivateColorRegisters = 1070,
/// ?2004
BracketedPaste = 2004,
}
@@ -568,6 +585,7 @@ impl Mode {
7 => Mode::LineWrap,
12 => Mode::BlinkingCursor,
25 => Mode::ShowCursor,
+ 80 => Mode::SixelScrolling,
1000 => Mode::ReportMouseClicks,
1002 => Mode::ReportCellMouseMotion,
1003 => Mode::ReportAllMouseMotion,
@@ -577,6 +595,7 @@ impl Mode {
1007 => Mode::AlternateScroll,
1042 => Mode::UrgencyHints,
1049 => Mode::SwapScreenAndSetRestoreCursor,
+ 1070 => Mode::SixelPrivateColorRegisters,
2004 => Mode::BracketedPaste,
_ => {
trace!("[unimplemented] primitive mode: {}", num);
@@ -908,6 +927,10 @@ where
self.state.dcs = Some(Dcs::SyncStart);
}
},
+ ('q', []) => {
+ let parser = self.handler.start_sixel_graphic(params);
+ self.state.dcs = parser.map(Dcs::SixelData);
+ },
_ => debug!(
"[unhandled hook] params={:?}, ints: {:?}, ignore: {:?}, action: {:?}",
params, intermediates, ignore, action
@@ -917,16 +940,29 @@ where
#[inline]
fn put(&mut self, byte: u8) {
- debug!("[unhandled put] byte={:?}", byte);
+ match self.state.dcs {
+ Some(Dcs::SixelData(ref mut parser)) => {
+ if let Err(err) = parser.put(byte) {
+ log::warn!("Failed to parse Sixel data: {}", err);
+ self.state.dcs = None;
+ }
+ },
+
+ _ => debug!("[unhandled put] byte={:?}", byte),
+ }
}
#[inline]
fn unhook(&mut self) {
- match self.state.dcs {
+ match self.state.dcs.take() {
Some(Dcs::SyncStart) => {
self.state.sync_state.timeout = Some(Instant::now() + SYNC_UPDATE_TIMEOUT);
},
Some(Dcs::SyncEnd) => (),
+ Some(Dcs::SixelData(parser)) => match parser.finish() {
+ Ok((graphic, palette)) => self.handler.insert_graphic(graphic, Some(palette)),
+ Err(err) => log::warn!("Failed to parse Sixel data: {}", err),
+ },
_ => debug!("[unhandled unhook]"),
}
}
@@ -1235,6 +1271,7 @@ where
handler.set_scrolling_region(top, bottom);
},
('S', []) => handler.scroll_up(next_param_or(1) as usize),
+ ('S', [b'?']) => handler.graphics_attribute(next_param_or(0), next_param_or(0)),
('s', []) => handler.save_cursor_position(),
('T', []) => handler.scroll_down(next_param_or(1) as usize),
('t', []) => match next_param_or(1) as usize {