diff src/libvterm/src/mouse.c @ 11621:b8299e742f41 v8.0.0693

patch 8.0.0693: no terminal emulator support commit https://github.com/vim/vim/commit/e4f25e4a8db2c8a8a71a4ba2a68540b3ab341e42 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Jul 7 11:54:15 2017 +0200 patch 8.0.0693: no terminal emulator support Problem: No terminal emulator support. Cannot properly run commands in the GUI. Cannot run a job interactively with an ssh connection. Solution: Very early implementation of the :terminal command. Includes libvterm converted to ANSI C. Many parts still missing.
author Christian Brabandt <cb@256bit.org>
date Fri, 07 Jul 2017 12:00:04 +0200
parents
children c76b672df584
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/src/libvterm/src/mouse.c
@@ -0,0 +1,96 @@
+#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);
+  }
+}