Home | History | Annotate | Download | only in src
      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