mirror of
https://github.com/neovim/neovim.git
synced 2025-10-17 23:31:51 +00:00
refactor: adopt vterm
We have changed too much to consider it a mere bundled dependency (such
as unicode handling in e3bfcf2fd4
), and
can consider it our own at this point.
This commit is contained in:
113
src/nvim/vterm/mouse.c
Normal file
113
src/nvim/vterm/mouse.c
Normal file
@@ -0,0 +1,113 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
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)) {
|
||||
int button = state->mouse_buttons & 0x01 ? 1
|
||||
: state->mouse_buttons & 0x02 ? 2
|
||||
: state->mouse_buttons &
|
||||
0x04 ? 3 : 4;
|
||||
output_mouse(state, button - 1 + 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) {
|
||||
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
|
||||
if (state->mouse_buttons == old_buttons && button < 4) {
|
||||
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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user