• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "vterm_internal.h"
2 
3 #include "utf8.h"
4 
output_mouse(VTermState * state,int code,int pressed,int modifiers,int col,int row)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 
vterm_mouse_move(VTerm * vt,int row,int col,VTermModifier mod)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 
vterm_mouse_button(VTerm * vt,int button,bool pressed,VTermModifier mod)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