in src/terminal/terminal.c [1722:1834]
static int __guac_terminal_send_mouse(guac_terminal* term, guac_user* user,
int x, int y, int mask) {
/* Ignore user input if terminal is not started */
if (!term->started) {
guac_client_log(term->client, GUAC_LOG_DEBUG, "Ignoring user input "
"while terminal has not yet started.");
return 0;
}
/* Determine which buttons were just released and pressed */
int released_mask = term->mouse_mask & ~mask;
int pressed_mask = ~term->mouse_mask & mask;
/* Store current mouse location/state */
guac_common_cursor_update(term->cursor, user, x, y, mask);
/* Notify scrollbar, do not handle anything handled by scrollbar */
if (guac_terminal_scrollbar_handle_mouse(term->scrollbar, x, y, mask)) {
/* Set pointer cursor if mouse is over scrollbar */
if (term->current_cursor != GUAC_TERMINAL_CURSOR_POINTER) {
term->current_cursor = GUAC_TERMINAL_CURSOR_POINTER;
guac_common_cursor_set_pointer(term->cursor);
guac_terminal_notify(term);
}
guac_terminal_notify(term);
return 0;
}
/* Remove display margin from mouse position without going below 0 */
y = y >= term->display->margin ? y - term->display->margin : 0;
x = x >= term->display->margin ? x - term->display->margin : 0;
term->mouse_mask = mask;
/* Show mouse cursor if not already shown */
if (term->current_cursor != GUAC_TERMINAL_CURSOR_IBAR) {
term->current_cursor = GUAC_TERMINAL_CURSOR_IBAR;
guac_common_cursor_set_ibar(term->cursor);
guac_terminal_notify(term);
}
/* Paste contents of clipboard on right or middle mouse button up */
if ((released_mask & GUAC_CLIENT_MOUSE_RIGHT) || (released_mask & GUAC_CLIENT_MOUSE_MIDDLE))
return guac_terminal_send_data(term, term->clipboard->buffer, term->clipboard->length);
/* If left mouse button was just released, stop selection */
if (released_mask & GUAC_CLIENT_MOUSE_LEFT)
guac_terminal_select_end(term);
/* Update selection state contextually while the left mouse button is
* pressed */
else if (mask & GUAC_CLIENT_MOUSE_LEFT) {
int row = y / term->display->char_height - term->scroll_offset;
int col = x / term->display->char_width;
/* If mouse button was already just pressed, start a new selection or
* resume the existing selection depending on whether shift is held */
if (pressed_mask & GUAC_CLIENT_MOUSE_LEFT) {
if (term->mod_shift)
guac_terminal_select_resume(term, row, col);
else {
/* Reset click counter if last click was 300ms before */
if (guac_timestamp_current() - term->click_timer > 300)
term->click_counter = 0;
/* New click time */
term->click_timer = guac_timestamp_current();
switch (term->click_counter++) {
/* First click = start selection */
case 0:
guac_terminal_select_start(term, row, col);
break;
/* Second click = word selection */
case 1:
guac_terminal_double_click(term, row, col);
break;
/* third click or more = line selection */
default:
guac_terminal_select_start(term, row, 0);
guac_terminal_select_update(term, row, term->display->width);
break;
}
}
}
/* In all other cases, simply update the existing selection as long as
* the mouse button is pressed */
else
guac_terminal_select_update(term, row, col);
}
/* Scroll up if wheel moved up */
if (released_mask & GUAC_CLIENT_MOUSE_SCROLL_UP)
guac_terminal_scroll_display_up(term, GUAC_TERMINAL_WHEEL_SCROLL_AMOUNT);
/* Scroll down if wheel moved down */
if (released_mask & GUAC_CLIENT_MOUSE_SCROLL_DOWN)
guac_terminal_scroll_display_down(term, GUAC_TERMINAL_WHEEL_SCROLL_AMOUNT);
return 0;
}