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