1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
#include "nvim/math.h"
#include "nvim/tui/termkey/termkey.h"
#include "nvim/vterm/mouse.h"
#include "nvim/vterm/vterm.h"
#include "nvim/vterm/vterm_internal_defs.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "vterm/mouse.c.generated.h"
#endif
static void output_mouse(VTermState *state, int code, int pressed, int modifiers, int col, int row)
{
modifiers <<= 2;
switch (state->mouse_protocol) {
case MOUSE_X10:
if (col + 0x21 > 0xff) {
col = 0xff - 0x21;
}
if (row + 0x21 > 0xff) {
row = 0xff - 0x21;
}
if (!pressed) {
code = 3;
}
if (code & 0x80) {
break;
}
vterm_push_output_sprintf_ctrl(state->vt, C1_CSI, "M%c%c%c",
(code | modifiers) + 0x20, col + 0x21, row + 0x21);
break;
case MOUSE_UTF8: {
char utf8[18];
size_t len = 0;
if (!pressed) {
code = 3;
}
len += (size_t)fill_utf8((code | modifiers) + 0x20, utf8 + len);
len += (size_t)fill_utf8(col + 0x21, utf8 + len);
len += (size_t)fill_utf8(row + 0x21, utf8 + len);
utf8[len] = 0;
vterm_push_output_sprintf_ctrl(state->vt, C1_CSI, "M%s", utf8);
}
break;
case MOUSE_SGR:
vterm_push_output_sprintf_ctrl(state->vt, C1_CSI, "<%d;%d;%d%c",
code | modifiers, col + 1, row + 1, pressed ? 'M' : 'm');
break;
case MOUSE_RXVT:
if (!pressed) {
code = 3;
}
vterm_push_output_sprintf_ctrl(state->vt, C1_CSI, "%d;%d;%dM",
code | modifiers, col + 1, row + 1);
break;
}
}
void vterm_mouse_move(VTerm *vt, int row, int col, VTermModifier mod)
{
VTermState *state = vt->state;
if (col == state->mouse_col && row == state->mouse_row) {
return;
}
state->mouse_col = col;
state->mouse_row = row;
if ((state->mouse_flags & MOUSE_WANT_DRAG && state->mouse_buttons)
|| (state->mouse_flags & MOUSE_WANT_MOVE)) {
if (state->mouse_buttons) {
int button = xctz((uint64_t)state->mouse_buttons) + 1;
if (button < 4) {
output_mouse(state, button - 1 + 0x20, 1, (int)mod, col, row);
} else if (button >= 8 && button < 12) {
output_mouse(state, button - 8 + 0x80 + 0x20, 1, (int)mod, col, row);
}
} else {
output_mouse(state, 3 + 0x20, 1, (int)mod, col, row);
}
}
}
void vterm_mouse_button(VTerm *vt, int button, bool pressed, VTermModifier mod)
{
VTermState *state = vt->state;
int old_buttons = state->mouse_buttons;
if ((button > 0 && button <= 3) || (button >= 8 && button <= 11)) {
if (pressed) {
state->mouse_buttons |= (1 << (button - 1));
} else {
state->mouse_buttons &= ~(1 << (button - 1));
}
}
// Most of the time we don't get button releases from 4/5/6/7
if (state->mouse_buttons == old_buttons && (button < 4 || button > 7)) {
return;
}
if (!state->mouse_flags) {
return;
}
if (button < 4) {
output_mouse(state, button - 1, pressed, (int)mod, state->mouse_col, state->mouse_row);
} else if (button < 8) {
output_mouse(state, button - 4 + 0x40, pressed, (int)mod, state->mouse_col, state->mouse_row);
} else if (button < 12) {
output_mouse(state, button - 8 + 0x80, pressed, (int)mod, state->mouse_col, state->mouse_row);
}
}
|