Patch 8.1.2070
Problem: Mouse code is spread out.
Solution: Move mouse terminal code parsing to mouse.c. (Yegappan Lakshmanan,
closes #4966)
Files: src/mouse.c, src/proto/
mouse.pro, src/proto/
term.pro, src/term.c
*** ../vim-8.1.2069/src/mouse.c 2019-09-22 14:11:42.796083779 +0200
--- src/mouse.c 2019-09-23 21:16:30.439643464 +0200
***************
*** 2089,2094 ****
--- 2089,2815 ----
{
(void)do_mouse(cap->oap, cap->cmdchar, BACKWARD, cap->count1, 0);
}
+
+ /*
+ * Check if typebuf 'tp' contains a terminal mouse code and returns the
+ * modifiers found in typebuf in 'modifiers'.
+ */
+ int
+ check_termcode_mouse(
+ char_u *tp,
+ int *slen,
+ char_u *key_name,
+ char_u *modifiers_start,
+ int idx,
+ int *modifiers)
+ {
+ int j;
+ char_u *p;
+ # if !defined(UNIX) || defined(FEAT_MOUSE_XTERM) || defined(FEAT_GUI) \
+ || defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE)
+ char_u bytes[6];
+ int num_bytes;
+ # endif
+ int mouse_code = 0; // init for GCC
+ int is_click, is_drag;
+ int wheel_code = 0;
+ int current_button;
+ static int held_button = MOUSE_RELEASE;
+ static int orig_num_clicks = 1;
+ static int orig_mouse_code = 0x0;
+ # ifdef CHECK_DOUBLE_CLICK
+ static int orig_mouse_col = 0;
+ static int orig_mouse_row = 0;
+ static struct timeval orig_mouse_time = {0, 0};
+ // time of previous mouse click
+ struct timeval mouse_time; // time of current mouse click
+ long timediff; // elapsed time in msec
+ # endif
+
+ is_click = is_drag = FALSE;
+
+ # if !defined(UNIX) || defined(FEAT_MOUSE_XTERM) || defined(FEAT_GUI) \
+ || defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE)
+ if (key_name[0] == KS_MOUSE
+ # ifdef FEAT_MOUSE_GPM
+ || key_name[0] == KS_GPM_MOUSE
+ # endif
+ )
+ {
+ /*
+ * For xterm we get "<t_mouse>scr", where
+ * s == encoded button state:
+ * 0x20 = left button down
+ * 0x21 = middle button down
+ * 0x22 = right button down
+ * 0x23 = any button release
+ * 0x60 = button 4 down (scroll wheel down)
+ * 0x61 = button 5 down (scroll wheel up)
+ * add 0x04 for SHIFT
+ * add 0x08 for ALT
+ * add 0x10 for CTRL
+ * add 0x20 for mouse drag (0x40 is drag with left button)
+ * add 0x40 for mouse move (0x80 is move, 0x81 too)
+ * 0x43 (drag + release) is also move
+ * c == column + ' ' + 1 == column + 33
+ * r == row + ' ' + 1 == row + 33
+ *
+ * The coordinates are passed on through global variables.
+ * Ugly, but this avoids trouble with mouse clicks at an
+ * unexpected moment and allows for mapping them.
+ */
+ for (;;)
+ {
+ # ifdef FEAT_GUI
+ if (gui.in_use)
+ {
+ // GUI uses more bits for columns > 223
+ num_bytes = get_bytes_from_buf(tp + *slen, bytes, 5);
+ if (num_bytes == -1) // not enough coordinates
+ return -1;
+ mouse_code = bytes[0];
+ mouse_col = 128 * (bytes[1] - ' ' - 1)
+ + bytes[2] - ' ' - 1;
+ mouse_row = 128 * (bytes[3] - ' ' - 1)
+ + bytes[4] - ' ' - 1;
+ }
+ else
+ # endif
+ {
+ num_bytes = get_bytes_from_buf(tp + *slen, bytes, 3);
+ if (num_bytes == -1) // not enough coordinates
+ return -1;
+ mouse_code = bytes[0];
+ mouse_col = bytes[1] - ' ' - 1;
+ mouse_row = bytes[2] - ' ' - 1;
+ }
+ *slen += num_bytes;
+
+ // If the following bytes is also a mouse code and it has
+ // the same code, dump this one and get the next. This
+ // makes dragging a whole lot faster.
+ # ifdef FEAT_GUI
+ if (gui.in_use)
+ j = 3;
+ else
+ # endif
+ j = get_termcode_len(idx);
+ if (STRNCMP(tp, tp + *slen, (size_t)j) == 0
+ && tp[*slen + j] == mouse_code
+ && tp[*slen + j + 1] != NUL
+ && tp[*slen + j + 2] != NUL
+ # ifdef FEAT_GUI
+ && (!gui.in_use
+ || (tp[*slen + j + 3] != NUL
+ && tp[*slen + j + 4] != NUL))
+ # endif
+ )
+ *slen += j;
+ else
+ break;
+ }
+ }
+
+ if (key_name[0] == KS_URXVT_MOUSE
+ || key_name[0] == KS_SGR_MOUSE
+ || key_name[0] == KS_SGR_MOUSE_RELEASE)
+ {
+ // URXVT 1015 mouse reporting mode:
+ // Almost identical to xterm mouse mode, except the values
+ // are decimal instead of bytes.
+ //
+ // \033[%d;%d;%dM
+ // ^-- row
+ // ^----- column
+ // ^-------- code
+ //
+ // SGR 1006 mouse reporting mode:
+ // Almost identical to xterm mouse mode, except the values
+ // are decimal instead of bytes.
+ //
+ // \033[<%d;%d;%dM
+ // ^-- row
+ // ^----- column
+ // ^-------- code
+ //
+ // \033[<%d;%d;%dm : mouse release event
+ // ^-- row
+ // ^----- column
+ // ^-------- code
+ p = modifiers_start;
+ if (p == NULL)
+ return -1;
+
+ mouse_code = getdigits(&p);
+ if (*p++ != ';')
+ return -1;
+
+ // when mouse reporting is SGR, add 32 to mouse code
+ if (key_name[0] == KS_SGR_MOUSE
+ || key_name[0] == KS_SGR_MOUSE_RELEASE)
+ mouse_code += 32;
+
+ if (key_name[0] == KS_SGR_MOUSE_RELEASE)
+ mouse_code |= MOUSE_RELEASE;
+
+ mouse_col = getdigits(&p) - 1;
+ if (*p++ != ';')
+ return -1;
+
+ mouse_row = getdigits(&p) - 1;
+
+ // The modifiers were the mouse coordinates, not the
+ // modifier keys (alt/shift/ctrl/meta) state.
+ *modifiers = 0;
+ }
+
+ if (key_name[0] == KS_MOUSE
+ # ifdef FEAT_MOUSE_GPM
+ || key_name[0] == KS_GPM_MOUSE
+ # endif
+ # ifdef FEAT_MOUSE_URXVT
+ || key_name[0] == KS_URXVT_MOUSE
+ # endif
+ || key_name[0] == KS_SGR_MOUSE
+ || key_name[0] == KS_SGR_MOUSE_RELEASE)
+ {
+ # if !defined(MSWIN)
+ /*
+ * Handle mouse events.
+ * Recognize the xterm mouse wheel, but not in the GUI, the
+ * Linux console with GPM and the MS-DOS or Win32 console
+ * (multi-clicks use >= 0x60).
+ */
+ if (mouse_code >= MOUSEWHEEL_LOW
+ # ifdef FEAT_GUI
+ && !gui.in_use
+ # endif
+ # ifdef FEAT_MOUSE_GPM
+ && key_name[0] != KS_GPM_MOUSE
+ # endif
+ )
+ {
+ # if defined(UNIX) && defined(FEAT_MOUSE_TTY)
+ if (use_xterm_mouse() > 1 && mouse_code >= 0x80)
+ // mouse-move event, using MOUSE_DRAG works
+ mouse_code = MOUSE_DRAG;
+ else
+ # endif
+ // Keep the mouse_code before it's changed, so that we
+ // remember that it was a mouse wheel click.
+ wheel_code = mouse_code;
+ }
+ # ifdef FEAT_MOUSE_XTERM
+ else if (held_button == MOUSE_RELEASE
+ # ifdef FEAT_GUI
+ && !gui.in_use
+ # endif
+ && (mouse_code == 0x23 || mouse_code == 0x24
+ || mouse_code == 0x40 || mouse_code == 0x41))
+ {
+ // Apparently 0x23 and 0x24 are used by rxvt scroll wheel.
+ // And 0x40 and 0x41 are used by some xterm emulator.
+ wheel_code = mouse_code - (mouse_code >= 0x40 ? 0x40 : 0x23)
+ + MOUSEWHEEL_LOW;
+ }
+ # endif
+
+ # if defined(UNIX) && defined(FEAT_MOUSE_TTY)
+ else if (use_xterm_mouse() > 1)
+ {
+ if (mouse_code & MOUSE_DRAG_XTERM)
+ mouse_code |= MOUSE_DRAG;
+ }
+ # endif
+ # ifdef FEAT_XCLIPBOARD
+ else if (!(mouse_code & MOUSE_DRAG & ~MOUSE_CLICK_MASK))
+ {
+ if ((mouse_code & MOUSE_RELEASE) == MOUSE_RELEASE)
+ stop_xterm_trace();
+ else
+ start_xterm_trace(mouse_code);
+ }
+ # endif
+ # endif
+ }
+ # endif // !UNIX || FEAT_MOUSE_XTERM
+ # ifdef FEAT_MOUSE_NET
+ if (key_name[0] == KS_NETTERM_MOUSE)
+ {
+ int mc, mr;
+
+ // expect a rather limited sequence like: balancing {
+ // \033}6,45\r
+ // '6' is the row, 45 is the column
+ p = tp + *slen;
+ mr = getdigits(&p);
+ if (*p++ != ',')
+ return -1;
+ mc = getdigits(&p);
+ if (*p++ != '\r')
+ return -1;
+
+ mouse_col = mc - 1;
+ mouse_row = mr - 1;
+ mouse_code = MOUSE_LEFT;
+ *slen += (int)(p - (tp + *slen));
+ }
+ # endif // FEAT_MOUSE_NET
+ # ifdef FEAT_MOUSE_JSB
+ if (key_name[0] == KS_JSBTERM_MOUSE)
+ {
+ int mult, val, iter, button, status;
+
+ /*
+ * JSBTERM Input Model
+ * \033[0~zw uniq escape sequence
+ * (L-x) Left button pressed - not pressed x not reporting
+ * (M-x) Middle button pressed - not pressed x not reporting
+ * (R-x) Right button pressed - not pressed x not reporting
+ * (SDmdu) Single , Double click, m mouse move d button down
+ * u button up
+ * ### X cursor position padded to 3 digits
+ * ### Y cursor position padded to 3 digits
+ * (s-x) SHIFT key pressed - not pressed x not reporting
+ * (c-x) CTRL key pressed - not pressed x not reporting
+ * \033\\ terminating sequence
+ */
+ p = tp + *slen;
+ button = mouse_code = 0;
+ switch (*p++)
+ {
+ case 'L': button = 1; break;
+ case '-': break;
+ case 'x': break; // ignore sequence
+ default: return -1; // Unknown Result
+ }
+ switch (*p++)
+ {
+ case 'M': button |= 2; break;
+ case '-': break;
+ case 'x': break; // ignore sequence
+ default: return -1; // Unknown Result
+ }
+ switch (*p++)
+ {
+ case 'R': button |= 4; break;
+ case '-': break;
+ case 'x': break; // ignore sequence
+ default: return -1; // Unknown Result
+ }
+ status = *p++;
+ for (val = 0, mult = 100, iter = 0; iter < 3; iter++,
+ mult /= 10, p++)
+ if (*p >= '0' && *p <= '9')
+ val += (*p - '0') * mult;
+ else
+ return -1;
+ mouse_col = val;
+ for (val = 0, mult = 100, iter = 0; iter < 3; iter++,
+ mult /= 10, p++)
+ if (*p >= '0' && *p <= '9')
+ val += (*p - '0') * mult;
+ else
+ return -1;
+ mouse_row = val;
+ switch (*p++)
+ {
+ case 's': button |= 8; break; // SHIFT key Pressed
+ case '-': break; // Not Pressed
+ case 'x': break; // Not Reporting
+ default: return -1; // Unknown Result
+ }
+ switch (*p++)
+ {
+ case 'c': button |= 16; break; // CTRL key Pressed
+ case '-': break; // Not Pressed
+ case 'x': break; // Not Reporting
+ default: return -1; // Unknown Result
+ }
+ if (*p++ != '\033')
+ return -1;
+ if (*p++ != '\\')
+ return -1;
+ switch (status)
+ {
+ case 'D': // Double Click
+ case 'S': // Single Click
+ if (button & 1) mouse_code |= MOUSE_LEFT;
+ if (button & 2) mouse_code |= MOUSE_MIDDLE;
+ if (button & 4) mouse_code |= MOUSE_RIGHT;
+ if (button & 8) mouse_code |= MOUSE_SHIFT;
+ if (button & 16) mouse_code |= MOUSE_CTRL;
+ break;
+ case 'm': // Mouse move
+ if (button & 1) mouse_code |= MOUSE_LEFT;
+ if (button & 2) mouse_code |= MOUSE_MIDDLE;
+ if (button & 4) mouse_code |= MOUSE_RIGHT;
+ if (button & 8) mouse_code |= MOUSE_SHIFT;
+ if (button & 16) mouse_code |= MOUSE_CTRL;
+ if ((button & 7) != 0)
+ {
+ held_button = mouse_code;
+ mouse_code |= MOUSE_DRAG;
+ }
+ is_drag = TRUE;
+ showmode();
+ break;
+ case 'd': // Button Down
+ if (button & 1) mouse_code |= MOUSE_LEFT;
+ if (button & 2) mouse_code |= MOUSE_MIDDLE;
+ if (button & 4) mouse_code |= MOUSE_RIGHT;
+ if (button & 8) mouse_code |= MOUSE_SHIFT;
+ if (button & 16) mouse_code |= MOUSE_CTRL;
+ break;
+ case 'u': // Button Up
+ if (button & 1)
+ mouse_code |= MOUSE_LEFT | MOUSE_RELEASE;
+ if (button & 2)
+ mouse_code |= MOUSE_MIDDLE | MOUSE_RELEASE;
+ if (button & 4)
+ mouse_code |= MOUSE_RIGHT | MOUSE_RELEASE;
+ if (button & 8)
+ mouse_code |= MOUSE_SHIFT;
+ if (button & 16)
+ mouse_code |= MOUSE_CTRL;
+ break;
+ default: return -1; // Unknown Result
+ }
+
+ *slen += (p - (tp + *slen));
+ }
+ # endif // FEAT_MOUSE_JSB
+ # ifdef FEAT_MOUSE_DEC
+ if (key_name[0] == KS_DEC_MOUSE)
+ {
+ /*
+ * The DEC Locator Input Model
+ * Netterm delivers the code sequence:
+ * \033[2;4;24;80&w (left button down)
+ * \033[3;0;24;80&w (left button up)
+ * \033[6;1;24;80&w (right button down)
+ * \033[7;0;24;80&w (right button up)
+ * CSI Pe ; Pb ; Pr ; Pc ; Pp & w
+ * Pe is the event code
+ * Pb is the button code
+ * Pr is the row coordinate
+ * Pc is the column coordinate
+ * Pp is the third coordinate (page number)
+ * Pe, the event code indicates what event caused this report
+ * The following event codes are defined:
+ * 0 - request, the terminal received an explicit request
+ * for a locator report, but the locator is unavailable
+ * 1 - request, the terminal received an explicit request
+ * for a locator report
+ * 2 - left button down
+ * 3 - left button up
+ * 4 - middle button down
+ * 5 - middle button up
+ * 6 - right button down
+ * 7 - right button up
+ * 8 - fourth button down
+ * 9 - fourth button up
+ * 10 - locator outside filter rectangle
+ * Pb, the button code, ASCII decimal 0-15 indicating which
+ * buttons are down if any. The state of the four buttons
+ * on the locator correspond to the low four bits of the
+ * decimal value,
+ * "1" means button depressed
+ * 0 - no buttons down,
+ * 1 - right,
+ * 2 - middle,
+ * 4 - left,
+ * 8 - fourth
+ * Pr is the row coordinate of the locator position in the page,
+ * encoded as an ASCII decimal value.
+ * If Pr is omitted, the locator position is undefined
+ * (outside the terminal window for example).
+ * Pc is the column coordinate of the locator position in the
+ * page, encoded as an ASCII decimal value.
+ * If Pc is omitted, the locator position is undefined
+ * (outside the terminal window for example).
+ * Pp is the page coordinate of the locator position
+ * encoded as an ASCII decimal value.
+ * The page coordinate may be omitted if the locator is on
+ * page one (the default). We ignore it anyway.
+ */
+ int Pe, Pb, Pr, Pc;
+
+ p = tp + *slen;
+
+ // get event status
+ Pe = getdigits(&p);
+ if (*p++ != ';')
+ return -1;
+
+ // get button status
+ Pb = getdigits(&p);
+ if (*p++ != ';')
+ return -1;
+
+ // get row status
+ Pr = getdigits(&p);
+ if (*p++ != ';')
+ return -1;
+
+ // get column status
+ Pc = getdigits(&p);
+
+ // the page parameter is optional
+ if (*p == ';')
+ {
+ p++;
+ (void)getdigits(&p);
+ }
+ if (*p++ != '&')
+ return -1;
+ if (*p++ != 'w')
+ return -1;
+
+ mouse_code = 0;
+ switch (Pe)
+ {
+ case 0: return -1; // position request while unavailable
+ case 1: // a response to a locator position request includes
+ // the status of all buttons
+ Pb &= 7; // mask off and ignore fourth button
+ if (Pb & 4)
+ mouse_code = MOUSE_LEFT;
+ if (Pb & 2)
+ mouse_code = MOUSE_MIDDLE;
+ if (Pb & 1)
+ mouse_code = MOUSE_RIGHT;
+ if (Pb)
+ {
+ held_button = mouse_code;
+ mouse_code |= MOUSE_DRAG;
+ WantQueryMouse = TRUE;
+ }
+ is_drag = TRUE;
+ showmode();
+ break;
+ case 2: mouse_code = MOUSE_LEFT;
+ WantQueryMouse = TRUE;
+ break;
+ case 3: mouse_code = MOUSE_RELEASE | MOUSE_LEFT;
+ break;
+ case 4: mouse_code = MOUSE_MIDDLE;
+ WantQueryMouse = TRUE;
+ break;
+ case 5: mouse_code = MOUSE_RELEASE | MOUSE_MIDDLE;
+ break;
+ case 6: mouse_code = MOUSE_RIGHT;
+ WantQueryMouse = TRUE;
+ break;
+ case 7: mouse_code = MOUSE_RELEASE | MOUSE_RIGHT;
+ break;
+ case 8: return -1; // fourth button down
+ case 9: return -1; // fourth button up
+ case 10: return -1; // mouse outside of filter rectangle
+ default: return -1; // should never occur
+ }
+
+ mouse_col = Pc - 1;
+ mouse_row = Pr - 1;
+
+ *slen += (int)(p - (tp + *slen));
+ }
+ # endif // FEAT_MOUSE_DEC
+ # ifdef FEAT_MOUSE_PTERM
+ if (key_name[0] == KS_PTERM_MOUSE)
+ {
+ int button, num_clicks, action;
+
+ p = tp + *slen;
+
+ action = getdigits(&p);
+ if (*p++ != ';')
+ return -1;
+
+ mouse_row = getdigits(&p);
+ if (*p++ != ';')
+ return -1;
+ mouse_col = getdigits(&p);
+ if (*p++ != ';')
+ return -1;
+
+ button = getdigits(&p);
+ mouse_code = 0;
+
+ switch (button)
+ {
+ case 4: mouse_code = MOUSE_LEFT; break;
+ case 1: mouse_code = MOUSE_RIGHT; break;
+ case 2: mouse_code = MOUSE_MIDDLE; break;
+ default: return -1;
+ }
+
+ switch (action)
+ {
+ case 31: // Initial press
+ if (*p++ != ';')
+ return -1;
+
+ num_clicks = getdigits(&p); // Not used
+ break;
+
+ case 32: // Release
+ mouse_code |= MOUSE_RELEASE;
+ break;
+
+ case 33: // Drag
+ held_button = mouse_code;
+ mouse_code |= MOUSE_DRAG;
+ break;
+
+ default:
+ return -1;
+ }
+
+ if (*p++ != 't')
+ return -1;
+
+ *slen += (p - (tp + *slen));
+ }
+ # endif // FEAT_MOUSE_PTERM
+
+ // Interpret the mouse code
+ current_button = (mouse_code & MOUSE_CLICK_MASK);
+ if (current_button == MOUSE_RELEASE
+ # ifdef FEAT_MOUSE_XTERM
+ && wheel_code == 0
+ # endif
+ )
+ {
+ /*
+ * If we get a mouse drag or release event when
+ * there is no mouse button held down (held_button ==
+ * MOUSE_RELEASE), produce a K_IGNORE below.
+ * (can happen when you hold down two buttons
+ * and then let them go, or click in the menu bar, but not
+ * on a menu, and drag into the text).
+ */
+ if ((mouse_code & MOUSE_DRAG) == MOUSE_DRAG)
+ is_drag = TRUE;
+ current_button = held_button;
+ }
+ else if (wheel_code == 0)
+ {
+ # ifdef CHECK_DOUBLE_CLICK
+ # ifdef FEAT_MOUSE_GPM
+ /*
+ * Only for Unix, when GUI not active, we handle
+ * multi-clicks here, but not for GPM mouse events.
+ */
+ # ifdef FEAT_GUI
+ if (key_name[0] != KS_GPM_MOUSE && !gui.in_use)
+ # else
+ if (key_name[0] != KS_GPM_MOUSE)
+ # endif
+ # else
+ # ifdef FEAT_GUI
+ if (!gui.in_use)
+ # endif
+ # endif
+ {
+ /*
+ * Compute the time elapsed since the previous mouse click.
+ */
+ gettimeofday(&mouse_time, NULL);
+ if (orig_mouse_time.tv_sec == 0)
+ {
+ /*
+ * Avoid computing the difference between mouse_time
+ * and orig_mouse_time for the first click, as the
+ * difference would be huge and would cause
+ * multiplication overflow.
+ */
+ timediff = p_mouset;
+ }
+ else
+ {
+ timediff = (mouse_time.tv_usec
+ - orig_mouse_time.tv_usec) / 1000;
+ if (timediff < 0)
+ --orig_mouse_time.tv_sec;
+ timediff += (mouse_time.tv_sec
+ - orig_mouse_time.tv_sec) * 1000;
+ }
+ orig_mouse_time = mouse_time;
+ if (mouse_code == orig_mouse_code
+ && timediff < p_mouset
+ && orig_num_clicks != 4
+ && orig_mouse_col == mouse_col
+ && orig_mouse_row == mouse_row
+ && (is_mouse_topline(curwin)
+ // Double click in tab pages line also works
+ // when window contents changes.
+ || (mouse_row == 0 && firstwin->w_winrow > 0))
+ )
+ ++orig_num_clicks;
+ else
+ orig_num_clicks = 1;
+ orig_mouse_col = mouse_col;
+ orig_mouse_row = mouse_row;
+ set_mouse_topline(curwin);
+ }
+ # if defined(FEAT_GUI) || defined(FEAT_MOUSE_GPM)
+ else
+ orig_num_clicks = NUM_MOUSE_CLICKS(mouse_code);
+ # endif
+ # else
+ orig_num_clicks = NUM_MOUSE_CLICKS(mouse_code);
+ # endif
+ is_click = TRUE;
+ orig_mouse_code = mouse_code;
+ }
+ if (!is_drag)
+ held_button = mouse_code & MOUSE_CLICK_MASK;
+
+ /*
+ * Translate the actual mouse event into a pseudo mouse event.
+ * First work out what modifiers are to be used.
+ */
+ if (orig_mouse_code & MOUSE_SHIFT)
+ *modifiers |= MOD_MASK_SHIFT;
+ if (orig_mouse_code & MOUSE_CTRL)
+ *modifiers |= MOD_MASK_CTRL;
+ if (orig_mouse_code & MOUSE_ALT)
+ *modifiers |= MOD_MASK_ALT;
+ if (orig_num_clicks == 2)
+ *modifiers |= MOD_MASK_2CLICK;
+ else if (orig_num_clicks == 3)
+ *modifiers |= MOD_MASK_3CLICK;
+ else if (orig_num_clicks == 4)
+ *modifiers |= MOD_MASK_4CLICK;
+
+ // Work out our pseudo mouse event. Note that MOUSE_RELEASE gets
+ // added, then it's not mouse up/down.
+ key_name[0] = KS_EXTRA;
+ if (wheel_code != 0
+ && (wheel_code & MOUSE_RELEASE) != MOUSE_RELEASE)
+ {
+ if (wheel_code & MOUSE_CTRL)
+ *modifiers |= MOD_MASK_CTRL;
+ if (wheel_code & MOUSE_ALT)
+ *modifiers |= MOD_MASK_ALT;
+ key_name[1] = (wheel_code & 1)
+ ? (int)KE_MOUSEUP : (int)KE_MOUSEDOWN;
+ held_button = MOUSE_RELEASE;
+ }
+ else
+ key_name[1] = get_pseudo_mouse_code(current_button,
+ is_click, is_drag);
+
+ // Make sure the mouse position is valid. Some terminals may
+ // return weird values.
+ if (mouse_col >= Columns)
+ mouse_col = Columns - 1;
+ if (mouse_row >= Rows)
+ mouse_row = Rows - 1;
+
+ return 0;
+ }
#endif // FEAT_MOUSE
// Functions also used for popup windows.
*** ../vim-8.1.2069/src/proto/
mouse.pro 2019-09-21 20:46:14.728275744 +0200
--- src/proto/
mouse.pro 2019-09-23 21:03:33.423409913 +0200
***************
*** 13,18 ****
--- 13,19 ----
int jump_to_mouse(int flags, int *inclusive, int which_button);
void nv_mousescroll(cmdarg_T *cap);
void nv_mouse(cmdarg_T *cap);
+ int check_termcode_mouse(char_u *tp, int *slen, char_u *key_name, char_u *modifiers_start, int idx, int *modifiers);
int mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump, int *plines_cache);
win_T *mouse_find_win(int *rowp, int *colp, mouse_find_T popup);
int vcol2col(win_T *wp, linenr_T lnum, int vcol);
*** ../vim-8.1.2069/src/proto/
term.pro 2019-09-21 20:46:14.728275744 +0200
--- src/proto/
term.pro 2019-09-23 21:03:33.423409913 +0200
***************
*** 32,37 ****
--- 32,38 ----
void term_pop_title(int which);
void ttest(int pairs);
void add_long_to_buf(long_u val, char_u *dst);
+ int get_bytes_from_buf(char_u *buf, char_u *bytes, int num_bytes);
void check_shellsize(void);
void limit_screen_size(void);
void win_new_shellsize(void);
***************
*** 59,66 ****
--- 60,69 ----
void add_termcode(char_u *name, char_u *string, int flags);
char_u *find_termcode(char_u *name);
char_u *get_termcode(int i);
+ int get_termcode_len(int idx);
void del_termcode(char_u *name);
void set_mouse_topline(win_T *wp);
+ int is_mouse_topline(win_T *wp);
int check_termcode(int max_offset, char_u *buf, int bufsize, int *buflen);
void term_get_fg_color(char_u *r, char_u *g, char_u *b);
void term_get_bg_color(char_u *r, char_u *g, char_u *b);
*** ../vim-8.1.2069/src/term.c 2019-09-21 20:46:14.728275744 +0200
--- src/term.c 2019-09-23 21:08:57.549810238 +0200
***************
*** 82,92 ****
static void got_code_from_term(char_u *code, int len);
static void check_for_codes_from_term(void);
#endif
- #if defined(FEAT_GUI) \
- || (defined(FEAT_MOUSE) && (!defined(UNIX) || defined(FEAT_MOUSE_XTERM) \
- || defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE)))
- static int get_bytes_from_buf(char_u *, char_u *, int);
- #endif
static void del_termcode_idx(int idx);
static int find_term_bykeys(char_u *src);
static int term_is_builtin(char_u *name);
--- 82,87 ----
***************
*** 3160,3166 ****
* from buf (between num_bytes and num_bytes*2), or -1 if not enough bytes were
* available.
*/
! static int
get_bytes_from_buf(char_u *buf, char_u *bytes, int num_bytes)
{
int len = 0;
--- 3155,3161 ----
* from buf (between num_bytes and num_bytes*2), or -1 if not enough bytes were
* available.
*/
! int
get_bytes_from_buf(char_u *buf, char_u *bytes, int num_bytes)
{
int len = 0;
***************
*** 4094,4099 ****
--- 4089,4103 ----
return &termcodes[i].name[0];
}
+ /*
+ * Returns the length of the terminal code at index 'idx'.
+ */
+ int
+ get_termcode_len(int idx)
+ {
+ return termcodes[idx].len;
+ }
+
void
del_termcode(char_u *name)
{
***************
*** 4178,4183 ****
--- 4182,4201 ----
orig_topfill = wp->w_topfill;
# endif
}
+
+ /*
+ * Returns TRUE if the top line and top fill of window 'wp' matches the saved
+ * topline and topfill.
+ */
+ int
+ is_mouse_topline(win_T *wp)
+ {
+ return orig_topline == wp->w_topline
+ #ifdef FEAT_DIFF
+ && orig_topfill == wp->w_topfill
+ #endif
+ ;
+ }
#endif
/*
***************
*** 4216,4243 ****
char_u string[MAX_KEY_CODE_LEN + 1];
int i, j;
int idx = 0;
- #ifdef FEAT_MOUSE
- # if !defined(UNIX) || defined(FEAT_MOUSE_XTERM) || defined(FEAT_GUI) \
- || defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE)
- char_u bytes[6];
- int num_bytes;
- # endif
- int mouse_code = 0; /* init for GCC */
- int is_click, is_drag;
- int wheel_code = 0;
- int current_button;
- static int held_button = MOUSE_RELEASE;
- static int orig_num_clicks = 1;
- static int orig_mouse_code = 0x0;
- # ifdef CHECK_DOUBLE_CLICK
- static int orig_mouse_col = 0;
- static int orig_mouse_row = 0;
- static struct timeval orig_mouse_time = {0, 0};
- /* time of previous mouse click */
- struct timeval mouse_time; /* time of current mouse click */
- long timediff; /* elapsed time in msec */
- # endif
- #endif
int cpo_koffset;
cpo_koffset = (vim_strchr(p_cpo, CPO_KOFFSET) != NULL);
--- 4234,4239 ----
***************
*** 4958,4965 ****
|| key_name[1] == (int)KE_MOUSEDOWN
|| key_name[1] == (int)KE_MOUSEUP))
{
! num_bytes = get_bytes_from_buf(tp + slen, bytes, 4);
! if (num_bytes == -1) /* not enough coordinates */
return -1;
mouse_col = 128 * (bytes[0] - ' ' - 1) + bytes[1] - ' ' - 1;
mouse_row = 128 * (bytes[2] - ' ' - 1) + bytes[3] - ' ' - 1;
--- 4954,4963 ----
|| key_name[1] == (int)KE_MOUSEDOWN
|| key_name[1] == (int)KE_MOUSEUP))
{
! char_u bytes[6];
! int num_bytes = get_bytes_from_buf(tp + slen, bytes, 4);
!
! if (num_bytes == -1) // not enough coordinates
return -1;
mouse_col = 128 * (bytes[0] - ' ' - 1) + bytes[1] - ' ' - 1;
mouse_row = 128 * (bytes[2] - ' ' - 1) + bytes[3] - ' ' - 1;
***************
*** 4992,5686 ****
|| key_name[0] == KS_SGR_MOUSE
|| key_name[0] == KS_SGR_MOUSE_RELEASE)
{
! is_click = is_drag = FALSE;
!
! # if !defined(UNIX) || defined(FEAT_MOUSE_XTERM) || defined(FEAT_GUI) \
! || defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE)
! if (key_name[0] == KS_MOUSE
! # ifdef FEAT_MOUSE_GPM
! || key_name[0] == KS_GPM_MOUSE
! # endif
! )
! {
! /*
! * For xterm we get "<t_mouse>scr", where
! * s == encoded button state:
! * 0x20 = left button down
! * 0x21 = middle button down
! * 0x22 = right button down
! * 0x23 = any button release
! * 0x60 = button 4 down (scroll wheel down)
! * 0x61 = button 5 down (scroll wheel up)
! * add 0x04 for SHIFT
! * add 0x08 for ALT
! * add 0x10 for CTRL
! * add 0x20 for mouse drag (0x40 is drag with left button)
! * add 0x40 for mouse move (0x80 is move, 0x81 too)
! * 0x43 (drag + release) is also move
! * c == column + ' ' + 1 == column + 33
! * r == row + ' ' + 1 == row + 33
! *
! * The coordinates are passed on through global variables.
! * Ugly, but this avoids trouble with mouse clicks at an
! * unexpected moment and allows for mapping them.
! */
! for (;;)
! {
! # ifdef FEAT_GUI
! if (gui.in_use)
! {
! /* GUI uses more bits for columns > 223 */
! num_bytes = get_bytes_from_buf(tp + slen, bytes, 5);
! if (num_bytes == -1) /* not enough coordinates */
! return -1;
! mouse_code = bytes[0];
! mouse_col = 128 * (bytes[1] - ' ' - 1)
! + bytes[2] - ' ' - 1;
! mouse_row = 128 * (bytes[3] - ' ' - 1)
! + bytes[4] - ' ' - 1;
! }
! else
! # endif
! {
! num_bytes = get_bytes_from_buf(tp + slen, bytes, 3);
! if (num_bytes == -1) /* not enough coordinates */
! return -1;
! mouse_code = bytes[0];
! mouse_col = bytes[1] - ' ' - 1;
! mouse_row = bytes[2] - ' ' - 1;
! }
! slen += num_bytes;
!
! /* If the following bytes is also a mouse code and it has
! * the same code, dump this one and get the next. This
! * makes dragging a whole lot faster. */
! # ifdef FEAT_GUI
! if (gui.in_use)
! j = 3;
! else
! # endif
! j = termcodes[idx].len;
! if (STRNCMP(tp, tp + slen, (size_t)j) == 0
! && tp[slen + j] == mouse_code
! && tp[slen + j + 1] != NUL
! && tp[slen + j + 2] != NUL
! # ifdef FEAT_GUI
! && (!gui.in_use
! || (tp[slen + j + 3] != NUL
! && tp[slen + j + 4] != NUL))
! # endif
! )
! slen += j;
! else
! break;
! }
! }
!
! if (key_name[0] == KS_URXVT_MOUSE
! || key_name[0] == KS_SGR_MOUSE
! || key_name[0] == KS_SGR_MOUSE_RELEASE)
! {
! /* URXVT 1015 mouse reporting mode:
! * Almost identical to xterm mouse mode, except the values
! * are decimal instead of bytes.
! *
! * \033[%d;%d;%dM
! * ^-- row
! * ^----- column
! * ^-------- code
! *
! * SGR 1006 mouse reporting mode:
! * Almost identical to xterm mouse mode, except the values
! * are decimal instead of bytes.
! *
! * \033[<%d;%d;%dM
! * ^-- row
! * ^----- column
! * ^-------- code
! *
! * \033[<%d;%d;%dm : mouse release event
! * ^-- row
! * ^----- column
! * ^-------- code
! */
! p = modifiers_start;
! if (p == NULL)
! return -1;
!
! mouse_code = getdigits(&p);
! if (*p++ != ';')
! return -1;
!
! /* when mouse reporting is SGR, add 32 to mouse code */
! if (key_name[0] == KS_SGR_MOUSE
! || key_name[0] == KS_SGR_MOUSE_RELEASE)
! mouse_code += 32;
!
! if (key_name[0] == KS_SGR_MOUSE_RELEASE)
! mouse_code |= MOUSE_RELEASE;
!
! mouse_col = getdigits(&p) - 1;
! if (*p++ != ';')
! return -1;
!
! mouse_row = getdigits(&p) - 1;
!
! /* The modifiers were the mouse coordinates, not the
! * modifier keys (alt/shift/ctrl/meta) state. */
! modifiers = 0;
! }
!
! if (key_name[0] == KS_MOUSE
! # ifdef FEAT_MOUSE_GPM
! || key_name[0] == KS_GPM_MOUSE
! # endif
! # ifdef FEAT_MOUSE_URXVT
! || key_name[0] == KS_URXVT_MOUSE
! # endif
! || key_name[0] == KS_SGR_MOUSE
! || key_name[0] == KS_SGR_MOUSE_RELEASE)
! {
! # if !defined(MSWIN)
! /*
! * Handle mouse events.
! * Recognize the xterm mouse wheel, but not in the GUI, the
! * Linux console with GPM and the MS-DOS or Win32 console
! * (multi-clicks use >= 0x60).
! */
! if (mouse_code >= MOUSEWHEEL_LOW
! # ifdef FEAT_GUI
! && !gui.in_use
! # endif
! # ifdef FEAT_MOUSE_GPM
! && key_name[0] != KS_GPM_MOUSE
! # endif
! )
! {
! # if defined(UNIX) && defined(FEAT_MOUSE_TTY)
! if (use_xterm_mouse() > 1 && mouse_code >= 0x80)
! /* mouse-move event, using MOUSE_DRAG works */
! mouse_code = MOUSE_DRAG;
! else
! # endif
! /* Keep the mouse_code before it's changed, so that we
! * remember that it was a mouse wheel click. */
! wheel_code = mouse_code;
! }
! # ifdef FEAT_MOUSE_XTERM
! else if (held_button == MOUSE_RELEASE
! # ifdef FEAT_GUI
! && !gui.in_use
! # endif
! && (mouse_code == 0x23 || mouse_code == 0x24
! || mouse_code == 0x40 || mouse_code == 0x41))
! {
! /* Apparently 0x23 and 0x24 are used by rxvt scroll wheel.
! * And 0x40 and 0x41 are used by some xterm emulator. */
! wheel_code = mouse_code - (mouse_code >= 0x40 ? 0x40 : 0x23)
! + MOUSEWHEEL_LOW;
! }
! # endif
!
! # if defined(UNIX) && defined(FEAT_MOUSE_TTY)
! else if (use_xterm_mouse() > 1)
! {
! if (mouse_code & MOUSE_DRAG_XTERM)
! mouse_code |= MOUSE_DRAG;
! }
! # endif
! # ifdef FEAT_XCLIPBOARD
! else if (!(mouse_code & MOUSE_DRAG & ~MOUSE_CLICK_MASK))
! {
! if ((mouse_code & MOUSE_RELEASE) == MOUSE_RELEASE)
! stop_xterm_trace();
! else
! start_xterm_trace(mouse_code);
! }
! # endif
! # endif
! }
! # endif /* !UNIX || FEAT_MOUSE_XTERM */
! # ifdef FEAT_MOUSE_NET
! if (key_name[0] == KS_NETTERM_MOUSE)
! {
! int mc, mr;
!
! /* expect a rather limited sequence like: balancing {
! * \033}6,45\r
! * '6' is the row, 45 is the column
! */
! p = tp + slen;
! mr = getdigits(&p);
! if (*p++ != ',')
! return -1;
! mc = getdigits(&p);
! if (*p++ != '\r')
! return -1;
!
! mouse_col = mc - 1;
! mouse_row = mr - 1;
! mouse_code = MOUSE_LEFT;
! slen += (int)(p - (tp + slen));
! }
! # endif /* FEAT_MOUSE_NET */
! # ifdef FEAT_MOUSE_JSB
! if (key_name[0] == KS_JSBTERM_MOUSE)
! {
! int mult, val, iter, button, status;
!
! /* JSBTERM Input Model
! * \033[0~zw uniq escape sequence
! * (L-x) Left button pressed - not pressed x not reporting
! * (M-x) Middle button pressed - not pressed x not reporting
! * (R-x) Right button pressed - not pressed x not reporting
! * (SDmdu) Single , Double click, m mouse move d button down
! * u button up
! * ### X cursor position padded to 3 digits
! * ### Y cursor position padded to 3 digits
! * (s-x) SHIFT key pressed - not pressed x not reporting
! * (c-x) CTRL key pressed - not pressed x not reporting
! * \033\\ terminating sequence
! */
!
! p = tp + slen;
! button = mouse_code = 0;
! switch (*p++)
! {
! case 'L': button = 1; break;
! case '-': break;
! case 'x': break; /* ignore sequence */
! default: return -1; /* Unknown Result */
! }
! switch (*p++)
! {
! case 'M': button |= 2; break;
! case '-': break;
! case 'x': break; /* ignore sequence */
! default: return -1; /* Unknown Result */
! }
! switch (*p++)
! {
! case 'R': button |= 4; break;
! case '-': break;
! case 'x': break; /* ignore sequence */
! default: return -1; /* Unknown Result */
! }
! status = *p++;
! for (val = 0, mult = 100, iter = 0; iter < 3; iter++,
! mult /= 10, p++)
! if (*p >= '0' && *p <= '9')
! val += (*p - '0') * mult;
! else
! return -1;
! mouse_col = val;
! for (val = 0, mult = 100, iter = 0; iter < 3; iter++,
! mult /= 10, p++)
! if (*p >= '0' && *p <= '9')
! val += (*p - '0') * mult;
! else
! return -1;
! mouse_row = val;
! switch (*p++)
! {
! case 's': button |= 8; break; /* SHIFT key Pressed */
! case '-': break; /* Not Pressed */
! case 'x': break; /* Not Reporting */
! default: return -1; /* Unknown Result */
! }
! switch (*p++)
! {
! case 'c': button |= 16; break; /* CTRL key Pressed */
! case '-': break; /* Not Pressed */
! case 'x': break; /* Not Reporting */
! default: return -1; /* Unknown Result */
! }
! if (*p++ != '\033')
! return -1;
! if (*p++ != '\\')
! return -1;
! switch (status)
! {
! case 'D': /* Double Click */
! case 'S': /* Single Click */
! if (button & 1) mouse_code |= MOUSE_LEFT;
! if (button & 2) mouse_code |= MOUSE_MIDDLE;
! if (button & 4) mouse_code |= MOUSE_RIGHT;
! if (button & 8) mouse_code |= MOUSE_SHIFT;
! if (button & 16) mouse_code |= MOUSE_CTRL;
! break;
! case 'm': /* Mouse move */
! if (button & 1) mouse_code |= MOUSE_LEFT;
! if (button & 2) mouse_code |= MOUSE_MIDDLE;
! if (button & 4) mouse_code |= MOUSE_RIGHT;
! if (button & 8) mouse_code |= MOUSE_SHIFT;
! if (button & 16) mouse_code |= MOUSE_CTRL;
! if ((button & 7) != 0)
! {
! held_button = mouse_code;
! mouse_code |= MOUSE_DRAG;
! }
! is_drag = TRUE;
! showmode();
! break;
! case 'd': /* Button Down */
! if (button & 1) mouse_code |= MOUSE_LEFT;
! if (button & 2) mouse_code |= MOUSE_MIDDLE;
! if (button & 4) mouse_code |= MOUSE_RIGHT;
! if (button & 8) mouse_code |= MOUSE_SHIFT;
! if (button & 16) mouse_code |= MOUSE_CTRL;
! break;
! case 'u': /* Button Up */
! if (button & 1)
! mouse_code |= MOUSE_LEFT | MOUSE_RELEASE;
! if (button & 2)
! mouse_code |= MOUSE_MIDDLE | MOUSE_RELEASE;
! if (button & 4)
! mouse_code |= MOUSE_RIGHT | MOUSE_RELEASE;
! if (button & 8)
! mouse_code |= MOUSE_SHIFT;
! if (button & 16)
! mouse_code |= MOUSE_CTRL;
! break;
! default: return -1; /* Unknown Result */
! }
!
! slen += (p - (tp + slen));
! }
! # endif /* FEAT_MOUSE_JSB */
! # ifdef FEAT_MOUSE_DEC
! if (key_name[0] == KS_DEC_MOUSE)
! {
! /* The DEC Locator Input Model
! * Netterm delivers the code sequence:
! * \033[2;4;24;80&w (left button down)
! * \033[3;0;24;80&w (left button up)
! * \033[6;1;24;80&w (right button down)
! * \033[7;0;24;80&w (right button up)
! * CSI Pe ; Pb ; Pr ; Pc ; Pp & w
! * Pe is the event code
! * Pb is the button code
! * Pr is the row coordinate
! * Pc is the column coordinate
! * Pp is the third coordinate (page number)
! * Pe, the event code indicates what event caused this report
! * The following event codes are defined:
! * 0 - request, the terminal received an explicit request
! * for a locator report, but the locator is unavailable
! * 1 - request, the terminal received an explicit request
! * for a locator report
! * 2 - left button down
! * 3 - left button up
! * 4 - middle button down
! * 5 - middle button up
! * 6 - right button down
! * 7 - right button up
! * 8 - fourth button down
! * 9 - fourth button up
! * 10 - locator outside filter rectangle
! * Pb, the button code, ASCII decimal 0-15 indicating which
! * buttons are down if any. The state of the four buttons
! * on the locator correspond to the low four bits of the
! * decimal value,
! * "1" means button depressed
! * 0 - no buttons down,
! * 1 - right,
! * 2 - middle,
! * 4 - left,
! * 8 - fourth
! * Pr is the row coordinate of the locator position in the page,
! * encoded as an ASCII decimal value.
! * If Pr is omitted, the locator position is undefined
! * (outside the terminal window for example).
! * Pc is the column coordinate of the locator position in the
! * page, encoded as an ASCII decimal value.
! * If Pc is omitted, the locator position is undefined
! * (outside the terminal window for example).
! * Pp is the page coordinate of the locator position
! * encoded as an ASCII decimal value.
! * The page coordinate may be omitted if the locator is on
! * page one (the default). We ignore it anyway.
! */
! int Pe, Pb, Pr, Pc;
!
! p = tp + slen;
!
! /* get event status */
! Pe = getdigits(&p);
! if (*p++ != ';')
! return -1;
!
! /* get button status */
! Pb = getdigits(&p);
! if (*p++ != ';')
! return -1;
!
! /* get row status */
! Pr = getdigits(&p);
! if (*p++ != ';')
! return -1;
!
! /* get column status */
! Pc = getdigits(&p);
!
! /* the page parameter is optional */
! if (*p == ';')
! {
! p++;
! (void)getdigits(&p);
! }
! if (*p++ != '&')
! return -1;
! if (*p++ != 'w')
! return -1;
!
! mouse_code = 0;
! switch (Pe)
! {
! case 0: return -1; /* position request while unavailable */
! case 1: /* a response to a locator position request includes
! the status of all buttons */
! Pb &= 7; /* mask off and ignore fourth button */
! if (Pb & 4)
! mouse_code = MOUSE_LEFT;
! if (Pb & 2)
! mouse_code = MOUSE_MIDDLE;
! if (Pb & 1)
! mouse_code = MOUSE_RIGHT;
! if (Pb)
! {
! held_button = mouse_code;
! mouse_code |= MOUSE_DRAG;
! WantQueryMouse = TRUE;
! }
! is_drag = TRUE;
! showmode();
! break;
! case 2: mouse_code = MOUSE_LEFT;
! WantQueryMouse = TRUE;
! break;
! case 3: mouse_code = MOUSE_RELEASE | MOUSE_LEFT;
! break;
! case 4: mouse_code = MOUSE_MIDDLE;
! WantQueryMouse = TRUE;
! break;
! case 5: mouse_code = MOUSE_RELEASE | MOUSE_MIDDLE;
! break;
! case 6: mouse_code = MOUSE_RIGHT;
! WantQueryMouse = TRUE;
! break;
! case 7: mouse_code = MOUSE_RELEASE | MOUSE_RIGHT;
! break;
! case 8: return -1; /* fourth button down */
! case 9: return -1; /* fourth button up */
! case 10: return -1; /* mouse outside of filter rectangle */
! default: return -1; /* should never occur */
! }
!
! mouse_col = Pc - 1;
! mouse_row = Pr - 1;
!
! slen += (int)(p - (tp + slen));
! }
! # endif /* FEAT_MOUSE_DEC */
! # ifdef FEAT_MOUSE_PTERM
! if (key_name[0] == KS_PTERM_MOUSE)
! {
! int button, num_clicks, action;
!
! p = tp + slen;
!
! action = getdigits(&p);
! if (*p++ != ';')
! return -1;
!
! mouse_row = getdigits(&p);
! if (*p++ != ';')
! return -1;
! mouse_col = getdigits(&p);
! if (*p++ != ';')
! return -1;
!
! button = getdigits(&p);
! mouse_code = 0;
!
! switch (button)
! {
! case 4: mouse_code = MOUSE_LEFT; break;
! case 1: mouse_code = MOUSE_RIGHT; break;
! case 2: mouse_code = MOUSE_MIDDLE; break;
! default: return -1;
! }
!
! switch (action)
! {
! case 31: /* Initial press */
! if (*p++ != ';')
! return -1;
!
! num_clicks = getdigits(&p); /* Not used */
! break;
!
! case 32: /* Release */
! mouse_code |= MOUSE_RELEASE;
! break;
!
! case 33: /* Drag */
! held_button = mouse_code;
! mouse_code |= MOUSE_DRAG;
! break;
!
! default:
! return -1;
! }
!
! if (*p++ != 't')
! return -1;
!
! slen += (p - (tp + slen));
! }
! # endif /* FEAT_MOUSE_PTERM */
!
! /* Interpret the mouse code */
! current_button = (mouse_code & MOUSE_CLICK_MASK);
! if (current_button == MOUSE_RELEASE
! # ifdef FEAT_MOUSE_XTERM
! && wheel_code == 0
! # endif
! )
! {
! /*
! * If we get a mouse drag or release event when
! * there is no mouse button held down (held_button ==
! * MOUSE_RELEASE), produce a K_IGNORE below.
! * (can happen when you hold down two buttons
! * and then let them go, or click in the menu bar, but not
! * on a menu, and drag into the text).
! */
! if ((mouse_code & MOUSE_DRAG) == MOUSE_DRAG)
! is_drag = TRUE;
! current_button = held_button;
! }
! else if (wheel_code == 0)
! {
! # ifdef CHECK_DOUBLE_CLICK
! # ifdef FEAT_MOUSE_GPM
! /*
! * Only for Unix, when GUI not active, we handle
! * multi-clicks here, but not for GPM mouse events.
! */
! # ifdef FEAT_GUI
! if (key_name[0] != KS_GPM_MOUSE && !gui.in_use)
! # else
! if (key_name[0] != KS_GPM_MOUSE)
! # endif
! # else
! # ifdef FEAT_GUI
! if (!gui.in_use)
! # endif
! # endif
! {
! /*
! * Compute the time elapsed since the previous mouse click.
! */
! gettimeofday(&mouse_time, NULL);
! if (orig_mouse_time.tv_sec == 0)
! {
! /*
! * Avoid computing the difference between mouse_time
! * and orig_mouse_time for the first click, as the
! * difference would be huge and would cause
! * multiplication overflow.
! */
! timediff = p_mouset;
! }
! else
! {
! timediff = (mouse_time.tv_usec
! - orig_mouse_time.tv_usec) / 1000;
! if (timediff < 0)
! --orig_mouse_time.tv_sec;
! timediff += (mouse_time.tv_sec
! - orig_mouse_time.tv_sec) * 1000;
! }
! orig_mouse_time = mouse_time;
! if (mouse_code == orig_mouse_code
! && timediff < p_mouset
! && orig_num_clicks != 4
! && orig_mouse_col == mouse_col
! && orig_mouse_row == mouse_row
! && ((orig_topline == curwin->w_topline
! #ifdef FEAT_DIFF
! && orig_topfill == curwin->w_topfill
! #endif
! )
! /* Double click in tab pages line also works
! * when window contents changes. */
! || (mouse_row == 0 && firstwin->w_winrow > 0))
! )
! ++orig_num_clicks;
! else
! orig_num_clicks = 1;
! orig_mouse_col = mouse_col;
! orig_mouse_row = mouse_row;
! orig_topline = curwin->w_topline;
! #ifdef FEAT_DIFF
! orig_topfill = curwin->w_topfill;
! #endif
! }
! # if defined(FEAT_GUI) || defined(FEAT_MOUSE_GPM)
! else
! orig_num_clicks = NUM_MOUSE_CLICKS(mouse_code);
! # endif
! # else
! orig_num_clicks = NUM_MOUSE_CLICKS(mouse_code);
! # endif
! is_click = TRUE;
! orig_mouse_code = mouse_code;
! }
! if (!is_drag)
! held_button = mouse_code & MOUSE_CLICK_MASK;
!
! /*
! * Translate the actual mouse event into a pseudo mouse event.
! * First work out what modifiers are to be used.
! */
! if (orig_mouse_code & MOUSE_SHIFT)
! modifiers |= MOD_MASK_SHIFT;
! if (orig_mouse_code & MOUSE_CTRL)
! modifiers |= MOD_MASK_CTRL;
! if (orig_mouse_code & MOUSE_ALT)
! modifiers |= MOD_MASK_ALT;
! if (orig_num_clicks == 2)
! modifiers |= MOD_MASK_2CLICK;
! else if (orig_num_clicks == 3)
! modifiers |= MOD_MASK_3CLICK;
! else if (orig_num_clicks == 4)
! modifiers |= MOD_MASK_4CLICK;
!
! /* Work out our pseudo mouse event. Note that MOUSE_RELEASE gets
! * added, then it's not mouse up/down. */
! key_name[0] = KS_EXTRA;
! if (wheel_code != 0
! && (wheel_code & MOUSE_RELEASE) != MOUSE_RELEASE)
! {
! if (wheel_code & MOUSE_CTRL)
! modifiers |= MOD_MASK_CTRL;
! if (wheel_code & MOUSE_ALT)
! modifiers |= MOD_MASK_ALT;
! key_name[1] = (wheel_code & 1)
! ? (int)KE_MOUSEUP : (int)KE_MOUSEDOWN;
! held_button = MOUSE_RELEASE;
! }
! else
! key_name[1] = get_pseudo_mouse_code(current_button,
! is_click, is_drag);
!
! /* Make sure the mouse position is valid. Some terminals may
! * return weird values. */
! if (mouse_col >= Columns)
! mouse_col = Columns - 1;
! if (mouse_row >= Rows)
! mouse_row = Rows - 1;
}
#endif /* FEAT_MOUSE */
--- 4990,4998 ----
|| key_name[0] == KS_SGR_MOUSE
|| key_name[0] == KS_SGR_MOUSE_RELEASE)
{
! if (check_termcode_mouse(tp, &slen, key_name, modifiers_start, idx,
! &modifiers) == -1)
! return -1;
}
#endif /* FEAT_MOUSE */
***************
*** 5707,5714 ****
else if (key_name[0] == (int)KS_MENU)
{
long_u val;
- num_bytes = get_long_from_buf(tp + slen, &val);
if (num_bytes == -1)
return -1;
current_menu = (vimmenu_T *)val;
--- 5019,5026 ----
else if (key_name[0] == (int)KS_MENU)
{
long_u val;
+ int num_bytes = get_long_from_buf(tp + slen, &val);
if (num_bytes == -1)
return -1;
current_menu = (vimmenu_T *)val;
***************
*** 5726,5733 ****
# ifdef FEAT_GUI_TABLINE
else if (key_name[0] == (int)KS_TABLINE)
{
! /* Selecting tabline tab or using its menu. */
! num_bytes = get_bytes_from_buf(tp + slen, bytes, 1);
if (num_bytes == -1)
return -1;
current_tab = (int)bytes[0];
--- 5038,5047 ----
# ifdef FEAT_GUI_TABLINE
else if (key_name[0] == (int)KS_TABLINE)
{
! // Selecting tabline tab or using its menu.
! char_u bytes[6];
! int num_bytes = get_bytes_from_buf(tp + slen, bytes, 1);
!
if (num_bytes == -1)
return -1;
current_tab = (int)bytes[0];
***************
*** 5737,5744 ****
}
else if (key_name[0] == (int)KS_TABMENU)
{
! /* Selecting tabline tab or using its menu. */
! num_bytes = get_bytes_from_buf(tp + slen, bytes, 2);
if (num_bytes == -1)
return -1;
current_tab = (int)bytes[0];
--- 5051,5060 ----
}
else if (key_name[0] == (int)KS_TABMENU)
{
! // Selecting tabline tab or using its menu.
! char_u bytes[6];
! int num_bytes = get_bytes_from_buf(tp + slen, bytes, 2);
!
if (num_bytes == -1)
return -1;
current_tab = (int)bytes[0];
***************
*** 5750,5755 ****
--- 5066,5073 ----
else if (key_name[0] == (int)KS_VER_SCROLLBAR)
{
long_u val;
+ char_u bytes[6];
+ int num_bytes;
/* Get the last scrollbar event in the queue of the same type */
j = 0;
***************
*** 5778,5783 ****
--- 5096,5102 ----
else if (key_name[0] == (int)KS_HOR_SCROLLBAR)
{
long_u val;
+ int num_bytes;
/* Get the last horiz. scrollbar event in the queue */
j = 0;
*** ../vim-8.1.2069/src/version.c 2019-09-22 23:24:09.810153903 +0200
--- src/version.c 2019-09-23 21:04:36.619093086 +0200
***************
*** 759,760 ****
--- 759,762 ----
{ /* Add new patch number below this line */
+ /**/
+ 2070,
/**/
--
Not too long ago, a keyboard was something to make music with...
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language --
http://www.Zimbu.org ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///