mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 13:21:38 +03:00
parse and respond to XTSMGRAPHICS queries
refs: https://github.com/wez/wezterm/issues/609
This commit is contained in:
parent
c4cac94aab
commit
3dfdd08b79
@ -15,7 +15,8 @@ use std::sync::mpsc::{channel, Sender};
|
||||
use std::sync::Arc;
|
||||
use termwiz::escape::csi::{
|
||||
Cursor, CursorStyle, DecPrivateMode, DecPrivateModeCode, Device, Edit, EraseInDisplay,
|
||||
EraseInLine, Mode, Sgr, TabulationClear, TerminalMode, TerminalModeCode, Window,
|
||||
EraseInLine, Mode, Sgr, TabulationClear, TerminalMode, TerminalModeCode, Window, XtSmGraphics,
|
||||
XtSmGraphicsAction, XtSmGraphicsItem, XtSmGraphicsStatus,
|
||||
};
|
||||
use termwiz::escape::osc::{
|
||||
ChangeColorPair, ColorOrQuery, FinalTermSemanticPrompt, ITermFileData, ITermProprietary,
|
||||
@ -1778,6 +1779,48 @@ impl TerminalState {
|
||||
self.writer.write(b"\x1b[0n").ok();
|
||||
self.writer.flush().ok();
|
||||
}
|
||||
Device::XtSmGraphics(g) => {
|
||||
let response = if matches!(g.item, XtSmGraphicsItem::Unspecified(_)) {
|
||||
XtSmGraphics {
|
||||
item: g.item,
|
||||
action_or_status: XtSmGraphicsStatus::InvalidItem.to_i64(),
|
||||
value: vec![],
|
||||
}
|
||||
} else {
|
||||
match g.action() {
|
||||
None | Some(XtSmGraphicsAction::SetToValue) => XtSmGraphics {
|
||||
item: g.item,
|
||||
action_or_status: XtSmGraphicsStatus::InvalidAction.to_i64(),
|
||||
value: vec![],
|
||||
},
|
||||
Some(XtSmGraphicsAction::ResetToDefault) => XtSmGraphics {
|
||||
item: g.item,
|
||||
action_or_status: XtSmGraphicsStatus::Success.to_i64(),
|
||||
value: vec![],
|
||||
},
|
||||
Some(XtSmGraphicsAction::ReadMaximumAllowedValue)
|
||||
| Some(XtSmGraphicsAction::ReadAttribute) => match g.item {
|
||||
XtSmGraphicsItem::Unspecified(_) => unreachable!("checked above"),
|
||||
XtSmGraphicsItem::NumberOfColorRegisters => XtSmGraphics {
|
||||
item: g.item,
|
||||
action_or_status: XtSmGraphicsStatus::Success.to_i64(),
|
||||
value: vec![65536],
|
||||
},
|
||||
XtSmGraphicsItem::RegisGraphicsGeometry
|
||||
| XtSmGraphicsItem::SixelGraphicsGeometry => XtSmGraphics {
|
||||
item: g.item,
|
||||
action_or_status: XtSmGraphicsStatus::Success.to_i64(),
|
||||
value: vec![self.pixel_width as i64, self.pixel_height as i64],
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
let dev = Device::XtSmGraphics(response);
|
||||
|
||||
write!(self.writer, "\x1b[{}", dev).ok();
|
||||
self.writer.flush().ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,6 +169,115 @@ pub enum DeviceAttributes {
|
||||
Vt420(DeviceAttributeFlags),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum XtSmGraphicsItem {
|
||||
NumberOfColorRegisters,
|
||||
SixelGraphicsGeometry,
|
||||
RegisGraphicsGeometry,
|
||||
Unspecified(i64),
|
||||
}
|
||||
|
||||
impl Display for XtSmGraphicsItem {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
||||
match self {
|
||||
Self::NumberOfColorRegisters => write!(f, "1"),
|
||||
Self::SixelGraphicsGeometry => write!(f, "2"),
|
||||
Self::RegisGraphicsGeometry => write!(f, "3"),
|
||||
Self::Unspecified(n) => write!(f, "{}", n),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum XtSmGraphicsAction {
|
||||
ReadAttribute,
|
||||
ResetToDefault,
|
||||
SetToValue,
|
||||
ReadMaximumAllowedValue,
|
||||
}
|
||||
|
||||
impl XtSmGraphicsAction {
|
||||
pub fn to_i64(&self) -> i64 {
|
||||
match self {
|
||||
Self::ReadAttribute => 1,
|
||||
Self::ResetToDefault => 2,
|
||||
Self::SetToValue => 3,
|
||||
Self::ReadMaximumAllowedValue => 4,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum XtSmGraphicsStatus {
|
||||
Success,
|
||||
InvalidItem,
|
||||
InvalidAction,
|
||||
Failure,
|
||||
}
|
||||
|
||||
impl XtSmGraphicsStatus {
|
||||
pub fn to_i64(&self) -> i64 {
|
||||
match self {
|
||||
Self::Success => 0,
|
||||
Self::InvalidItem => 1,
|
||||
Self::InvalidAction => 2,
|
||||
Self::Failure => 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct XtSmGraphics {
|
||||
pub item: XtSmGraphicsItem,
|
||||
pub action_or_status: i64,
|
||||
pub value: Vec<i64>,
|
||||
}
|
||||
|
||||
impl XtSmGraphics {
|
||||
pub fn action(&self) -> Option<XtSmGraphicsAction> {
|
||||
match self.action_or_status {
|
||||
1 => Some(XtSmGraphicsAction::ReadAttribute),
|
||||
2 => Some(XtSmGraphicsAction::ResetToDefault),
|
||||
3 => Some(XtSmGraphicsAction::SetToValue),
|
||||
4 => Some(XtSmGraphicsAction::ReadMaximumAllowedValue),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn status(&self) -> Option<XtSmGraphicsStatus> {
|
||||
match self.action_or_status {
|
||||
0 => Some(XtSmGraphicsStatus::Success),
|
||||
1 => Some(XtSmGraphicsStatus::InvalidItem),
|
||||
2 => Some(XtSmGraphicsStatus::InvalidAction),
|
||||
3 => Some(XtSmGraphicsStatus::Failure),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(params: &[CsiParam]) -> Result<CSI, ()> {
|
||||
Ok(CSI::Device(Box::new(Device::XtSmGraphics(XtSmGraphics {
|
||||
item: match params.get(0).ok_or(())? {
|
||||
CsiParam::Integer(1) => XtSmGraphicsItem::NumberOfColorRegisters,
|
||||
CsiParam::Integer(2) => XtSmGraphicsItem::SixelGraphicsGeometry,
|
||||
CsiParam::Integer(3) => XtSmGraphicsItem::RegisGraphicsGeometry,
|
||||
CsiParam::Integer(n) => XtSmGraphicsItem::Unspecified(*n),
|
||||
_ => return Err(()),
|
||||
},
|
||||
action_or_status: match params.get(1).ok_or(())? {
|
||||
CsiParam::Integer(n) => *n,
|
||||
_ => return Err(()),
|
||||
},
|
||||
value: params[2..]
|
||||
.iter()
|
||||
.filter_map(|p| match p {
|
||||
CsiParam::Integer(n) => Some(*n),
|
||||
_ => None,
|
||||
})
|
||||
.collect(),
|
||||
}))))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Device {
|
||||
DeviceAttributes(DeviceAttributes),
|
||||
@ -180,6 +289,7 @@ pub enum Device {
|
||||
/// https://github.com/mintty/mintty/issues/881
|
||||
/// https://gitlab.gnome.org/GNOME/vte/-/issues/235
|
||||
RequestTerminalNameAndVersion,
|
||||
XtSmGraphics(XtSmGraphics),
|
||||
}
|
||||
|
||||
impl Display for Device {
|
||||
@ -198,6 +308,13 @@ impl Display for Device {
|
||||
Device::RequestSecondaryDeviceAttributes => write!(f, ">c")?,
|
||||
Device::RequestTerminalNameAndVersion => write!(f, ">q")?,
|
||||
Device::StatusReport => write!(f, "5n")?,
|
||||
Device::XtSmGraphics(g) => {
|
||||
write!(f, "?{};{}", g.item, g.action_or_status)?;
|
||||
for v in &g.value {
|
||||
write!(f, ";{}", v)?;
|
||||
}
|
||||
write!(f, "S")?;
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
@ -1369,6 +1486,7 @@ impl<'a> CSIParser<'a> {
|
||||
('P', &[]) => parse!(Edit, DeleteCharacter, params),
|
||||
('R', &[]) => parse!(Cursor, ActivePositionReport, line, col, params),
|
||||
('S', &[]) => parse!(Edit, ScrollUp, params),
|
||||
('S', &[b'?']) => XtSmGraphics::parse(params),
|
||||
('T', &[]) => parse!(Edit, ScrollDown, params),
|
||||
('W', &[]) => parse!(Cursor, TabulationControl, params),
|
||||
('X', &[]) => parse!(Edit, EraseCharacter, params),
|
||||
|
Loading…
Reference in New Issue
Block a user