void guac_vnc_cut_text(rfbClient* client, const char* text, int textlen) { guac_client* gc = rfbClientGetClientData(client, GUAC_VNC_CLIENT_KEY); guac_vnc_client* vnc_client = (guac_vnc_client*) gc->data; /* Ignore received text if outbound clipboard transfer is disabled */ if (vnc_client->settings->disable_copy) return; char received_data[GUAC_VNC_CLIPBOARD_MAX_LENGTH]; const char* input = text; char* output = received_data; guac_iconv_read* reader = vnc_client->clipboard_reader; /* Convert clipboard contents */ guac_iconv(reader, &input, textlen, GUAC_WRITE_UTF8, &output, sizeof(received_data)); /* Send converted data */ guac_common_clipboard_reset(vnc_client->clipboard, "text/plain"); guac_common_clipboard_append(vnc_client->clipboard, received_data, output - received_data); guac_common_clipboard_send(vnc_client->clipboard, gc); }
void guac_terminal_select_end(guac_terminal* terminal) { guac_client* client = terminal->client; guac_socket* socket = client->socket; /* If no text is selected, nothing to do */ if (!terminal->text_selected) return; /* Selection is now committed */ terminal->selection_committed = true; /* Reset current clipboard contents */ guac_common_clipboard_reset(terminal->clipboard, "text/plain"); int start_row, start_col; int end_row, end_col; /* Ensure proper ordering of start and end coords */ guac_terminal_select_normalized_range(terminal, &start_row, &start_col, &end_row, &end_col); /* If only one row, simply copy */ if (end_row == start_row) guac_terminal_clipboard_append_row(terminal, start_row, start_col, end_col); /* Otherwise, copy multiple rows */ else { /* Store first row */ guac_terminal_clipboard_append_row(terminal, start_row, start_col, -1); /* Store all middle rows */ for (int row = start_row + 1; row < end_row; row++) { guac_common_clipboard_append(terminal->clipboard, "\n", 1); guac_terminal_clipboard_append_row(terminal, row, 0, -1); } /* Store last row */ guac_common_clipboard_append(terminal->clipboard, "\n", 1); guac_terminal_clipboard_append_row(terminal, end_row, 0, end_col); } /* Send data */ if (!terminal->disable_copy) { guac_common_clipboard_send(terminal->clipboard, client); guac_socket_flush(socket); } guac_terminal_notify(terminal); }
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; }