void guac_terminal_select_resume(guac_terminal* terminal, int row, int column) { int selection_start_row; int selection_start_column; int selection_end_row; int selection_end_column; /* No need to test coordinates if no text is selected at all */ if (!terminal->text_selected) return; /* Use normalized coordinates for sake of simple comparison */ guac_terminal_select_normalized_range(terminal, &selection_start_row, &selection_start_column, &selection_end_row, &selection_end_column); /* Prefer to expand from start, such that attempting to resume a selection * within the existing selection preserves the top-most portion of the * selection */ if (row > selection_start_row || (row == selection_start_row && column > selection_start_column)) { terminal->selection_start_row = selection_start_row; terminal->selection_start_column = selection_start_column; } /* Expand from bottom-most portion of selection if doing otherwise would * reduce the size of the selection */ else { terminal->selection_start_row = selection_end_row; terminal->selection_start_column = selection_end_column; } /* Selection is again in-progress */ terminal->selection_committed = false; /* Update selection to contain given character */ guac_terminal_select_update(terminal, row, column); }
int ssh_guac_client_mouse_handler(guac_client* client, int x, int y, int mask) { ssh_guac_client_data* client_data = (ssh_guac_client_data*) client->data; guac_terminal* term = client_data->term; /* Determine which buttons were just released and pressed */ int released_mask = client_data->mouse_mask & ~mask; int pressed_mask = ~client_data->mouse_mask & mask; client_data->mouse_mask = mask; /* Show mouse cursor if not already shown */ if (client_data->current_cursor != client_data->ibar_cursor) { pthread_mutex_lock(&(term->lock)); client_data->current_cursor = client_data->ibar_cursor; guac_ssh_set_cursor(client, client_data->ibar_cursor); guac_socket_flush(client->socket); pthread_mutex_unlock(&(term->lock)); } /* 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, client_data->clipboard->buffer, client_data->clipboard->length); /* If text selected, change state based on left mouse mouse button */ if (term->text_selected) { pthread_mutex_lock(&(term->lock)); /* If mouse button released, stop selection */ if (released_mask & GUAC_CLIENT_MOUSE_LEFT) { int selected_length; /* End selection and get selected text */ int selectable_size = term->term_width * term->term_height * sizeof(char); char* string = malloc(selectable_size); guac_terminal_select_end(term, string); selected_length = strnlen(string, selectable_size); /* Store new data */ guac_common_clipboard_reset(client_data->clipboard, "text/plain"); guac_common_clipboard_append(client_data->clipboard, string, selected_length); free(string); /* Send data */ guac_common_clipboard_send(client_data->clipboard, client); guac_socket_flush(client->socket); } /* Otherwise, just update */ else guac_terminal_select_update(term, y / term->display->char_height - term->scroll_offset, x / term->display->char_width); pthread_mutex_unlock(&(term->lock)); } /* Otherwise, if mouse button pressed AND moved, start selection */ else if (!(pressed_mask & GUAC_CLIENT_MOUSE_LEFT) && mask & GUAC_CLIENT_MOUSE_LEFT) { pthread_mutex_lock(&(term->lock)); guac_terminal_select_start(term, y / term->display->char_height - term->scroll_offset, x / term->display->char_width); pthread_mutex_unlock(&(term->lock)); } /* Scroll up if wheel moved up */ if (released_mask & GUAC_CLIENT_MOUSE_SCROLL_UP) { pthread_mutex_lock(&(term->lock)); guac_terminal_scroll_display_up(term, GUAC_SSH_WHEEL_SCROLL_AMOUNT); pthread_mutex_unlock(&(term->lock)); } /* Scroll down if wheel moved down */ if (released_mask & GUAC_CLIENT_MOUSE_SCROLL_DOWN) { pthread_mutex_lock(&(term->lock)); guac_terminal_scroll_display_down(term, GUAC_SSH_WHEEL_SCROLL_AMOUNT); pthread_mutex_unlock(&(term->lock)); } return 0; }