1use alacritty_terminal::term::TermMode;
2
3#[derive(Debug, Clone, Copy, PartialEq)]
5pub enum TerminalMouseButton {
6 Left,
7 Middle,
8 Right,
9}
10
11impl TerminalMouseButton {
12 fn code(self) -> u8 {
14 match self {
15 Self::Left => 0,
16 Self::Middle => 1,
17 Self::Right => 2,
18 }
19 }
20}
21
22fn encode(
30 sgr_code: u8,
31 x11_code: u8,
32 row: usize,
33 col: usize,
34 mode: TermMode,
35 release_in_sgr: bool,
36) -> String {
37 let row = row.saturating_add(1);
38 let col = col.saturating_add(1);
39 if mode.contains(TermMode::SGR_MOUSE) {
40 let action = if release_in_sgr { 'm' } else { 'M' };
41 format!("\x1b[<{sgr_code};{col};{row}{action}")
42 } else {
43 let button_byte = x11_code.saturating_add(32);
44 let col_byte = col.min(255) as u8;
45 let row_byte = row.min(255) as u8;
46 format!(
47 "\x1b[M{}{}{}",
48 button_byte as char, col_byte as char, row_byte as char
49 )
50 }
51}
52
53pub fn encode_mouse_press(
54 row: usize,
55 col: usize,
56 button: TerminalMouseButton,
57 mode: TermMode,
58) -> String {
59 encode(button.code(), button.code(), row, col, mode, false)
60}
61
62pub fn encode_mouse_release(
63 row: usize,
64 col: usize,
65 button: TerminalMouseButton,
66 mode: TermMode,
67) -> String {
68 encode(button.code(), 3, row, col, mode, true)
71}
72
73pub fn encode_mouse_move(
75 row: usize,
76 col: usize,
77 button: Option<TerminalMouseButton>,
78 mode: TermMode,
79) -> String {
80 let code = button.map_or(3, TerminalMouseButton::code) + 32;
81 encode(code, code, row, col, mode, false)
82}
83
84pub fn encode_wheel_event(row: usize, col: usize, delta_y: f64, mode: TermMode) -> String {
86 let code = if delta_y > 0.0 { 64 } else { 65 };
87 encode(code, code, row, col, mode, false)
88}