diff options
author | Jesse Luehrs <doy@tozt.net> | 2019-11-02 12:33:54 -0400 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2019-11-02 12:35:52 -0400 |
commit | e50e3c4fe311d03d90c7bfb43b7612317fe183c0 (patch) | |
tree | 9b47b60dbd0e4d5c793a2f23c334c17f41cd81a8 | |
parent | e688ce7f57f126c5fa183ec74cc09f37df0bae8b (diff) | |
download | vt100-rust-e50e3c4fe311d03d90c7bfb43b7612317fe183c0.tar.gz vt100-rust-e50e3c4fe311d03d90c7bfb43b7612317fe183c0.zip |
improve mouse mode handling
-rw-r--r-- | src/screen.rs | 109 | ||||
-rw-r--r-- | tests/escape.rs | 10 | ||||
-rw-r--r-- | tests/mode.rs | 126 |
3 files changed, 203 insertions, 42 deletions
diff --git a/src/screen.rs b/src/screen.rs index 54e27a2..7e6f07b 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -12,14 +12,41 @@ enum Output { enum Mode { KeypadApplication, ApplicationCursor, - MouseReportingPress, HideCursor, - MouseReportingPressRelease, - MouseReportingButtonMotion, - MouseReportingSgr, BracketedPaste, } +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +enum MouseProtocolMode { + None, + Press, + PressRelease, + // Highlight, + ButtonMotion, + AnyMotion, + // DecLocator, +} + +impl Default for MouseProtocolMode { + fn default() -> Self { + Self::None + } +} + +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +enum MouseProtocolEncoding { + Default, + Utf8, + Sgr, + // Urxvt, +} + +impl Default for MouseProtocolEncoding { + fn default() -> Self { + Self::Default + } +} + struct State { grid: crate::grid::Grid, alternate_grid: Option<crate::grid::Grid>, @@ -31,6 +58,8 @@ struct State { outputs: enumset::EnumSet<Output>, modes: enumset::EnumSet<Mode>, + mouse_protocol_mode: MouseProtocolMode, + mouse_protocol_encoding: MouseProtocolEncoding, } impl State { @@ -47,6 +76,8 @@ impl State { outputs: enumset::EnumSet::default(), modes: enumset::EnumSet::default(), + mouse_protocol_mode: MouseProtocolMode::default(), + mouse_protocol_encoding: MouseProtocolEncoding::default(), } } @@ -124,6 +155,26 @@ impl State { fn mode(&self, mode: Mode) -> bool { self.modes.contains(mode) } + + fn set_mouse_mode(&mut self, mode: MouseProtocolMode) { + self.mouse_protocol_mode = mode; + } + + fn clear_mouse_mode(&mut self, mode: MouseProtocolMode) { + if self.mouse_protocol_mode == mode { + self.mouse_protocol_mode = MouseProtocolMode::default(); + } + } + + fn set_mouse_encoding(&mut self, encoding: MouseProtocolEncoding) { + self.mouse_protocol_encoding = encoding; + } + + fn clear_mouse_encoding(&mut self, encoding: MouseProtocolEncoding) { + if self.mouse_protocol_encoding == encoding { + self.mouse_protocol_encoding = MouseProtocolEncoding::default(); + } + } } impl State { @@ -244,6 +295,8 @@ impl State { self.alternate_grid = None; self.attrs = crate::attrs::Attrs::default(); self.modes = enumset::EnumSet::default(); + self.mouse_protocol_mode = MouseProtocolMode::default(); + self.mouse_protocol_encoding = MouseProtocolEncoding::default(); } // ESC g @@ -374,11 +427,13 @@ impl State { match param { 1 => self.set_mode(Mode::ApplicationCursor), 6 => self.grid_mut().set_origin_mode(true), - 9 => self.set_mode(Mode::MouseReportingPress), + 9 => self.set_mouse_mode(MouseProtocolMode::Press), 25 => self.clear_mode(Mode::HideCursor), - 1000 => self.set_mode(Mode::MouseReportingPressRelease), - 1002 => self.set_mode(Mode::MouseReportingButtonMotion), - 1006 => self.set_mode(Mode::MouseReportingSgr), + 1000 => self.set_mouse_mode(MouseProtocolMode::PressRelease), + 1002 => self.set_mouse_mode(MouseProtocolMode::ButtonMotion), + 1003 => self.set_mouse_mode(MouseProtocolMode::AnyMotion), + 1005 => self.set_mouse_encoding(MouseProtocolEncoding::Utf8), + 1006 => self.set_mouse_encoding(MouseProtocolEncoding::Sgr), 1049 => self.enter_alternate_grid(), 2004 => self.set_mode(Mode::BracketedPaste), _ => {} @@ -397,11 +452,19 @@ impl State { match param { 1 => self.clear_mode(Mode::ApplicationCursor), 6 => self.grid_mut().set_origin_mode(false), - 9 => self.clear_mode(Mode::MouseReportingPress), + 9 => self.clear_mouse_mode(MouseProtocolMode::Press), 25 => self.set_mode(Mode::HideCursor), - 1000 => self.clear_mode(Mode::MouseReportingPressRelease), - 1002 => self.clear_mode(Mode::MouseReportingButtonMotion), - 1006 => self.clear_mode(Mode::MouseReportingSgr), + 1000 => { + self.clear_mouse_mode(MouseProtocolMode::PressRelease) + } + 1002 => { + self.clear_mouse_mode(MouseProtocolMode::ButtonMotion) + } + 1003 => self.clear_mouse_mode(MouseProtocolMode::AnyMotion), + 1005 => { + self.clear_mouse_encoding(MouseProtocolEncoding::Utf8) + } + 1006 => self.clear_mouse_encoding(MouseProtocolEncoding::Sgr), 1049 => self.exit_alternate_grid(), 2004 => self.clear_mode(Mode::BracketedPaste), _ => {} @@ -756,20 +819,28 @@ impl Screen { self.state.mode(Mode::BracketedPaste) } + pub fn mouse_reporting_press(&self) -> bool { + self.state.mouse_protocol_mode == MouseProtocolMode::Press + } + + pub fn mouse_reporting_press_release(&self) -> bool { + self.state.mouse_protocol_mode == MouseProtocolMode::PressRelease + } + pub fn mouse_reporting_button_motion(&self) -> bool { - self.state.mode(Mode::MouseReportingButtonMotion) + self.state.mouse_protocol_mode == MouseProtocolMode::ButtonMotion } - pub fn mouse_reporting_sgr_mode(&self) -> bool { - self.state.mode(Mode::MouseReportingSgr) + pub fn mouse_reporting_any_motion(&self) -> bool { + self.state.mouse_protocol_mode == MouseProtocolMode::AnyMotion } - pub fn mouse_reporting_press(&self) -> bool { - self.state.mode(Mode::MouseReportingPress) + pub fn mouse_reporting_utf8_mode(&self) -> bool { + self.state.mouse_protocol_encoding == MouseProtocolEncoding::Utf8 } - pub fn mouse_reporting_press_release(&self) -> bool { - self.state.mode(Mode::MouseReportingPressRelease) + pub fn mouse_reporting_sgr_mode(&self) -> bool { + self.state.mouse_protocol_encoding == MouseProtocolEncoding::Sgr } pub fn check_audible_bell(&mut self) -> bool { diff --git a/tests/escape.rs b/tests/escape.rs index 1651ee5..cf46241 100644 --- a/tests/escape.rs +++ b/tests/escape.rs @@ -59,7 +59,7 @@ fn ris() { assert!(!screen.check_visual_bell()); assert!(!screen.check_audible_bell()); - screen.process(b"f\x1b[31m\x1b[47;1;3;4moo\x1b[7m\x1b[21;21H\x1b]2;window title\x07\x1b]1;window icon name\x07\x1b[?25l\x1b[?1h\x1b=\x1b[?9h\x1b[?1000h\x1b[?1002h\x1b[?1006h\x1b[?2004h\x07\x1bg"); + screen.process(b"f\x1b[31m\x1b[47;1;3;4moo\x1b[7m\x1b[21;21H\x1b]2;window title\x07\x1b]1;window icon name\x07\x1b[?25l\x1b[?1h\x1b=\x1b[?9h\x1b[?1000h\x1b[?1006h\x1b[?2004h\x07\x1bg"); assert_eq!(screen.cursor_position(), (20, 20)); @@ -86,10 +86,12 @@ fn ris() { assert!(screen.hide_cursor()); assert!(screen.application_keypad()); assert!(screen.application_cursor()); - assert!(screen.mouse_reporting_press()); + assert!(!screen.mouse_reporting_press()); assert!(screen.mouse_reporting_press_release()); - assert!(screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_any_motion()); assert!(screen.mouse_reporting_sgr_mode()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(screen.bracketed_paste()); assert!(screen.check_visual_bell()); assert!(screen.check_audible_bell()); @@ -127,6 +129,8 @@ fn ris() { assert!(!screen.mouse_reporting_press()); assert!(!screen.mouse_reporting_press_release()); assert!(!screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(!screen.mouse_reporting_sgr_mode()); assert!(!screen.bracketed_paste()); assert!(!screen.check_visual_bell()); diff --git a/tests/mode.rs b/tests/mode.rs index 9658ad3..fb97e43 100644 --- a/tests/mode.rs +++ b/tests/mode.rs @@ -9,6 +9,8 @@ fn modes() { assert!(!screen.mouse_reporting_press()); assert!(!screen.mouse_reporting_press_release()); assert!(!screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(!screen.mouse_reporting_sgr_mode()); assert!(!screen.bracketed_paste()); @@ -20,6 +22,8 @@ fn modes() { assert!(!screen.mouse_reporting_press()); assert!(!screen.mouse_reporting_press_release()); assert!(!screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(!screen.mouse_reporting_sgr_mode()); assert!(!screen.bracketed_paste()); @@ -31,6 +35,8 @@ fn modes() { assert!(screen.mouse_reporting_press()); assert!(!screen.mouse_reporting_press_release()); assert!(!screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(!screen.mouse_reporting_sgr_mode()); assert!(!screen.bracketed_paste()); @@ -42,6 +48,8 @@ fn modes() { assert!(screen.mouse_reporting_press()); assert!(!screen.mouse_reporting_press_release()); assert!(!screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(!screen.mouse_reporting_sgr_mode()); assert!(!screen.bracketed_paste()); @@ -50,9 +58,11 @@ fn modes() { assert!(screen.hide_cursor()); assert!(!screen.application_keypad()); assert!(screen.application_cursor()); - assert!(screen.mouse_reporting_press()); + assert!(!screen.mouse_reporting_press()); assert!(screen.mouse_reporting_press_release()); assert!(!screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(!screen.mouse_reporting_sgr_mode()); assert!(!screen.bracketed_paste()); @@ -61,9 +71,37 @@ fn modes() { assert!(screen.hide_cursor()); assert!(!screen.application_keypad()); assert!(screen.application_cursor()); - assert!(screen.mouse_reporting_press()); - assert!(screen.mouse_reporting_press_release()); + assert!(!screen.mouse_reporting_press()); + assert!(!screen.mouse_reporting_press_release()); assert!(screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); + assert!(!screen.mouse_reporting_sgr_mode()); + assert!(!screen.bracketed_paste()); + + screen.process(b"\x1b[?1003h"); + + assert!(screen.hide_cursor()); + assert!(!screen.application_keypad()); + assert!(screen.application_cursor()); + assert!(!screen.mouse_reporting_press()); + assert!(!screen.mouse_reporting_press_release()); + assert!(!screen.mouse_reporting_button_motion()); + assert!(screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); + assert!(!screen.mouse_reporting_sgr_mode()); + assert!(!screen.bracketed_paste()); + + screen.process(b"\x1b[?1005h"); + + assert!(screen.hide_cursor()); + assert!(!screen.application_keypad()); + assert!(screen.application_cursor()); + assert!(!screen.mouse_reporting_press()); + assert!(!screen.mouse_reporting_press_release()); + assert!(!screen.mouse_reporting_button_motion()); + assert!(screen.mouse_reporting_any_motion()); + assert!(screen.mouse_reporting_utf8_mode()); assert!(!screen.mouse_reporting_sgr_mode()); assert!(!screen.bracketed_paste()); @@ -72,9 +110,11 @@ fn modes() { assert!(screen.hide_cursor()); assert!(!screen.application_keypad()); assert!(screen.application_cursor()); - assert!(screen.mouse_reporting_press()); - assert!(screen.mouse_reporting_press_release()); - assert!(screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_press()); + assert!(!screen.mouse_reporting_press_release()); + assert!(!screen.mouse_reporting_button_motion()); + assert!(screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(screen.mouse_reporting_sgr_mode()); assert!(!screen.bracketed_paste()); @@ -83,9 +123,11 @@ fn modes() { assert!(screen.hide_cursor()); assert!(!screen.application_keypad()); assert!(screen.application_cursor()); - assert!(screen.mouse_reporting_press()); - assert!(screen.mouse_reporting_press_release()); - assert!(screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_press()); + assert!(!screen.mouse_reporting_press_release()); + assert!(!screen.mouse_reporting_button_motion()); + assert!(screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(screen.mouse_reporting_sgr_mode()); assert!(screen.bracketed_paste()); @@ -94,9 +136,11 @@ fn modes() { assert!(screen.hide_cursor()); assert!(screen.application_keypad()); assert!(screen.application_cursor()); - assert!(screen.mouse_reporting_press()); - assert!(screen.mouse_reporting_press_release()); - assert!(screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_press()); + assert!(!screen.mouse_reporting_press_release()); + assert!(!screen.mouse_reporting_button_motion()); + assert!(screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(screen.mouse_reporting_sgr_mode()); assert!(screen.bracketed_paste()); @@ -105,9 +149,11 @@ fn modes() { assert!(screen.hide_cursor()); assert!(screen.application_keypad()); assert!(!screen.application_cursor()); - assert!(screen.mouse_reporting_press()); - assert!(screen.mouse_reporting_press_release()); - assert!(screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_press()); + assert!(!screen.mouse_reporting_press_release()); + assert!(!screen.mouse_reporting_button_motion()); + assert!(screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(screen.mouse_reporting_sgr_mode()); assert!(screen.bracketed_paste()); @@ -117,8 +163,10 @@ fn modes() { assert!(screen.application_keypad()); assert!(!screen.application_cursor()); assert!(!screen.mouse_reporting_press()); - assert!(screen.mouse_reporting_press_release()); - assert!(screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_press_release()); + assert!(!screen.mouse_reporting_button_motion()); + assert!(screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(screen.mouse_reporting_sgr_mode()); assert!(screen.bracketed_paste()); @@ -128,8 +176,10 @@ fn modes() { assert!(screen.application_keypad()); assert!(!screen.application_cursor()); assert!(!screen.mouse_reporting_press()); - assert!(screen.mouse_reporting_press_release()); - assert!(screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_press_release()); + assert!(!screen.mouse_reporting_button_motion()); + assert!(screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(screen.mouse_reporting_sgr_mode()); assert!(screen.bracketed_paste()); @@ -140,7 +190,9 @@ fn modes() { assert!(!screen.application_cursor()); assert!(!screen.mouse_reporting_press()); assert!(!screen.mouse_reporting_press_release()); - assert!(screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_button_motion()); + assert!(screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(screen.mouse_reporting_sgr_mode()); assert!(screen.bracketed_paste()); @@ -152,6 +204,34 @@ fn modes() { assert!(!screen.mouse_reporting_press()); assert!(!screen.mouse_reporting_press_release()); assert!(!screen.mouse_reporting_button_motion()); + assert!(screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); + assert!(screen.mouse_reporting_sgr_mode()); + assert!(screen.bracketed_paste()); + + screen.process(b"\x1b[?1003l"); + + assert!(!screen.hide_cursor()); + assert!(screen.application_keypad()); + assert!(!screen.application_cursor()); + assert!(!screen.mouse_reporting_press()); + assert!(!screen.mouse_reporting_press_release()); + assert!(!screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); + assert!(screen.mouse_reporting_sgr_mode()); + assert!(screen.bracketed_paste()); + + screen.process(b"\x1b[?1005l"); + + assert!(!screen.hide_cursor()); + assert!(screen.application_keypad()); + assert!(!screen.application_cursor()); + assert!(!screen.mouse_reporting_press()); + assert!(!screen.mouse_reporting_press_release()); + assert!(!screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(screen.mouse_reporting_sgr_mode()); assert!(screen.bracketed_paste()); @@ -163,6 +243,8 @@ fn modes() { assert!(!screen.mouse_reporting_press()); assert!(!screen.mouse_reporting_press_release()); assert!(!screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(!screen.mouse_reporting_sgr_mode()); assert!(screen.bracketed_paste()); @@ -174,6 +256,8 @@ fn modes() { assert!(!screen.mouse_reporting_press()); assert!(!screen.mouse_reporting_press_release()); assert!(!screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(!screen.mouse_reporting_sgr_mode()); assert!(!screen.bracketed_paste()); @@ -185,6 +269,8 @@ fn modes() { assert!(!screen.mouse_reporting_press()); assert!(!screen.mouse_reporting_press_release()); assert!(!screen.mouse_reporting_button_motion()); + assert!(!screen.mouse_reporting_any_motion()); + assert!(!screen.mouse_reporting_utf8_mode()); assert!(!screen.mouse_reporting_sgr_mode()); assert!(!screen.bracketed_paste()); } |