#include "vterm_internal.h"
|
|
#include "utf8.h"
|
|
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 += fill_utf8((code | modifiers) + 0x20, utf8 + len);
|
len += fill_utf8(col + 0x21, utf8 + len);
|
len += 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, 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(button < 4) {
|
output_mouse(state, button-1, pressed, mod, state->mouse_col, state->mouse_row);
|
}
|
else if(button < 6) {
|
output_mouse(state, button-4 + 0x40, pressed, mod, state->mouse_col, state->mouse_row);
|
}
|
}
|