mike-jumper commented on code in PR #406:
URL: https://github.com/apache/guacamole-server/pull/406#discussion_r1053978880
##########
src/protocols/ssh/input.c:
##########
@@ -58,7 +174,7 @@ int guac_ssh_user_key_handler(guac_user* user, int keysym,
int pressed) {
/* Report key state within recording */
if (ssh_client->recording != NULL)
- guac_recording_report_key(ssh_client->recording,
+ guac_common_recording_report_key(ssh_client->recording,
Review Comment:
This should remain `guac_recording_report_key()`. There is no
`guac_common_recording_report_key()` function.
##########
src/protocols/ssh/click.h:
##########
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef GUAC_SSH_CLICK_H
+#define GUAC_SSH_CLICK_H
+
+#include "config.h"
+
+#include <guacamole/user.h>
+#include "terminal/terminal.h"
+
+typedef struct guac_click {
+
+ int select_row;
+
+ int select_col;
+
+ int select_head;
+
+ int select_tail;
+
+ guac_terminal* term;
+
+ guac_client* client;
+
+ guac_socket* socket;
+
+ guac_layer* select_layer;
+
+} guac_click;
+
+/* Display selection effect */
+void guac_click_draw_select(guac_click* click);
+
+void guac_click_draw_blank(guac_click* click);
Review Comment:
1. All functions, parameters, return values, structures, and members need to
be documented.
2. This would make more sense as part of the terminal, rather than being
SSH-specific. In that case, each of these functions and structures should be
renamed to be within the `guac_terminal_` namespace.
##########
src/protocols/ssh/click.c:
##########
@@ -0,0 +1,457 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+
+#include "common/cursor.h"
+#include "common/display.h"
+#include "common/recording.h"
+#include "click.h"
+#include "ssh.h"
+#include "terminal/terminal.h"
+#include "terminal/select.h"
+
+#include <guacamole/client.h>
+#include <guacamole/unicode.h>
+#include <guacamole/user.h>
+#include <libssh2.h>
+
+#include <pthread.h>
+
+void guac_click_draw_select(guac_click* click){
+
+ int height = click->term->display->char_height;
+ int width = click->term->display->char_width;
+
+ guac_protocol_send_rect(click->socket, click->select_layer,
+ click->select_head * width, click->select_row * height,
+ (click->select_tail - click->select_head + 1) * width, height);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x80, 0xFF, 0x60);
+
+}
+
+void guac_click_draw_blank(guac_click* click){
+
+ guac_protocol_send_rect(click->socket, click->select_layer, 0, 0, 1, 1);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x00, 0x00, 0x00);
+
+}
+
+void guac_click_select_word(guac_click* click){
+
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+ int i = head;
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int length = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ if(head < 0 || head > length - 1)
+ return;
+
+ if(tail < 0 || tail > length - 1)
+ tail = length - 1;
+
+ /* Write each character to clipboard */
+
+
+ while (i <= tail){
+
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = head; i <= tail; i++) {
+ int codepoint = buffer_row->characters[i].value;
+
+ if (codepoint == 0 || codepoint == GUAC_CHAR_CONTINUATION)
+ continue;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+void guac_click_select_blank(guac_click* click){
+
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int l = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ if(head < 0 || head > l - 1)
+ return;
+
+ if(tail < 0 || tail > l - 1)
+ tail = l - 1;
+
+ int i = head;
+
+ /* Write blank to clipboard */
+ while (i <= tail)
+ {
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = head; i <= tail; i++) {
+ int codepoint = 32;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+void guac_click_select_mark(guac_click* click){
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+ char* current = buffer;
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+
+ /* Write char to clipboard */
+ int bytes =
guac_utf8_write(buffer_row->characters[click->select_col].value, current,
sizeof(buffer));
+ current += bytes;
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+}
+
+void guac_click_select_line(guac_click* click){
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int i = 0;
+ int length = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ /* Write each character to clipboard */
+
+ while (i <= length){
+
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = 0; i <= length; i++) {
+ int codepoint = buffer_row->characters[i].value;
+
+ if (codepoint == 0)
+ codepoint = 32;
+
+ if (codepoint == GUAC_CHAR_CONTINUATION)
+ continue;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+guac_click* guac_click_get_word_border(guac_click* click){
+
+ /* Get select information */
+
+ guac_terminal* term = click->term;
+
+ int row = click->select_row;
+ int col = click->select_col;
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+ int flag = sentinel;
+
+ /* Get head */
+ while (((flag > 64 && flag < 91) || (flag > 96 && flag < 123) || (flag >
47 && flag < 58) || (flag == 95)) && (head >= 0 && head <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
head].character.value;
+ head--;
+ }
+
+
+ /* Reset flag */
+ flag = sentinel;
+
+ /* Get tail */
+ while (((flag > 64 && flag < 91) || (flag > 96 && flag < 123) || (flag >
47 && flag < 58) || (flag == 95)) &&(tail >= 0 && tail <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
tail].character.value;
+ tail++;
+ }
+
+
+
+ head += 2;
+ tail -= 2;
+
+ int h = term->display->operations[row * term->display->width + head -
1].character.value;
+ if (head == 1 && ((h > 64 && h < 91) || (h > 96 && h < 123) || (h > 47 &&
h < 58) || (h == 95)))
+ head = 0;
+
+ printf("Head: %d\n", head);
+ printf("Tail: %d\n", tail);
Review Comment:
Please do not include debug `printf()` calls.
##########
src/protocols/ssh/input.c:
##########
@@ -88,8 +204,7 @@ int guac_ssh_user_size_handler(guac_user* user, int width,
int height) {
if (ssh_client->term_channel != NULL) {
pthread_mutex_lock(&(ssh_client->term_channel_lock));
libssh2_channel_request_pty_size(ssh_client->term_channel,
- guac_terminal_get_columns(terminal),
- guac_terminal_get_rows(terminal));
+ terminal->term_width, terminal->term_height);
Review Comment:
This shouldn't change to `terminal->term_width`, etc. which are now internal
members of the terminal struct. The getter functions are the public interface.
##########
src/protocols/ssh/click.c:
##########
@@ -0,0 +1,457 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+
+#include "common/cursor.h"
+#include "common/display.h"
+#include "common/recording.h"
+#include "click.h"
+#include "ssh.h"
+#include "terminal/terminal.h"
+#include "terminal/select.h"
+
+#include <guacamole/client.h>
+#include <guacamole/unicode.h>
+#include <guacamole/user.h>
+#include <libssh2.h>
+
+#include <pthread.h>
+
+void guac_click_draw_select(guac_click* click){
+
+ int height = click->term->display->char_height;
+ int width = click->term->display->char_width;
+
+ guac_protocol_send_rect(click->socket, click->select_layer,
+ click->select_head * width, click->select_row * height,
+ (click->select_tail - click->select_head + 1) * width, height);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x80, 0xFF, 0x60);
+
+}
+
+void guac_click_draw_blank(guac_click* click){
+
+ guac_protocol_send_rect(click->socket, click->select_layer, 0, 0, 1, 1);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x00, 0x00, 0x00);
+
+}
+
+void guac_click_select_word(guac_click* click){
+
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+ int i = head;
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int length = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ if(head < 0 || head > length - 1)
+ return;
+
+ if(tail < 0 || tail > length - 1)
+ tail = length - 1;
+
+ /* Write each character to clipboard */
+
+
+ while (i <= tail){
+
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = head; i <= tail; i++) {
+ int codepoint = buffer_row->characters[i].value;
+
+ if (codepoint == 0 || codepoint == GUAC_CHAR_CONTINUATION)
+ continue;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+void guac_click_select_blank(guac_click* click){
+
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int l = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ if(head < 0 || head > l - 1)
+ return;
+
+ if(tail < 0 || tail > l - 1)
+ tail = l - 1;
+
+ int i = head;
+
+ /* Write blank to clipboard */
+ while (i <= tail)
+ {
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = head; i <= tail; i++) {
+ int codepoint = 32;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+void guac_click_select_mark(guac_click* click){
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+ char* current = buffer;
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+
+ /* Write char to clipboard */
+ int bytes =
guac_utf8_write(buffer_row->characters[click->select_col].value, current,
sizeof(buffer));
+ current += bytes;
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+}
+
+void guac_click_select_line(guac_click* click){
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int i = 0;
+ int length = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ /* Write each character to clipboard */
+
+ while (i <= length){
+
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = 0; i <= length; i++) {
+ int codepoint = buffer_row->characters[i].value;
+
+ if (codepoint == 0)
+ codepoint = 32;
+
+ if (codepoint == GUAC_CHAR_CONTINUATION)
+ continue;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+guac_click* guac_click_get_word_border(guac_click* click){
+
+ /* Get select information */
+
+ guac_terminal* term = click->term;
+
+ int row = click->select_row;
+ int col = click->select_col;
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+ int flag = sentinel;
+
+ /* Get head */
+ while (((flag > 64 && flag < 91) || (flag > 96 && flag < 123) || (flag >
47 && flag < 58) || (flag == 95)) && (head >= 0 && head <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
head].character.value;
+ head--;
+ }
+
+
+ /* Reset flag */
+ flag = sentinel;
+
+ /* Get tail */
+ while (((flag > 64 && flag < 91) || (flag > 96 && flag < 123) || (flag >
47 && flag < 58) || (flag == 95)) &&(tail >= 0 && tail <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
tail].character.value;
+ tail++;
+ }
+
+
+
+ head += 2;
+ tail -= 2;
+
+ int h = term->display->operations[row * term->display->width + head -
1].character.value;
+ if (head == 1 && ((h > 64 && h < 91) || (h > 96 && h < 123) || (h > 47 &&
h < 58) || (h == 95)))
+ head = 0;
+
+ printf("Head: %d\n", head);
+ printf("Tail: %d\n", tail);
+
+ click->select_head = head;
+ click->select_tail = tail;
+
+ return click;
+
+}
+
+guac_click* guac_click_get_blank_border(guac_click* click){
+
+ /* Get select information */
+ guac_terminal* term = click->term;
+
+ int row = click->select_row;
+ int col = click->select_col;
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+ int flag = sentinel;
+
+ /* Get head */
+ while ((flag == 0 || flag == 32) && (head >= 0 && head <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
head].character.value;
+ head--;
+ }
+
+ /* Reset flag */
+ flag = sentinel;
+
+ /* Get tail */
+ while ((flag == 0 || flag == 32) && (tail >= 0 && tail <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
tail].character.value;
+ tail++;
+ }
+
+ head += 2;
+ tail -= 2;
+
+ if(head == 1 && (term->display->operations[row * term->display->width +
head].character.value == 0 ||
+ term->display->operations[row * term->display->width +
head].character.value == 32))
+ head = 0;
+
+ click->select_head = head;
+ click->select_tail = tail;
+
+ return click;
+}
+
+void guac_double_click(guac_click* click){
+
+ /* Set selection variables */
+ guac_terminal* term = click->term;
+ int row = click->select_row;
+ int col = click->select_col;
+ printf("Row: %d, Col: %d\n", row, col);
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+
+ /* Determination */
+
+ /* Words */
+
+ if ((sentinel > 64 && sentinel < 91) || (sentinel > 96 && sentinel < 123)
|| (sentinel > 47 && sentinel < 58) || (sentinel == 95)){
+
+ /* get border */
+ guac_click* selection = guac_click_get_word_border(click);
+
+ /* Copy to clipboard */
+ guac_click_select_word(selection);
+
+ /* Draw selection */
+ guac_click_draw_select(selection);
+
+ return;
+
+ }
+
+ /* Marks */
+
+ else if ((sentinel > 32 && sentinel < 48) || (sentinel > 57 && sentinel <
65) || (sentinel > 90 && sentinel < 95) || (sentinel > 122 && sentinel < 127)
||(sentinel == 96)){
+
+ /* Copy to clipboard */
+ guac_click_select_mark(click);
+
+ /* Draw selection */
+ click->select_head = click->select_col;
+ click->select_tail = click->select_col;
+
+ guac_click_draw_select(click);
+
+ return;
+
+ }
+
+ /* Blank */
+
+ else if (sentinel == 0 || sentinel == 32){
+
+ /* Get blank border */
+ guac_click* selection = guac_click_get_blank_border(click);
+
+ /* Blank position */
+ int head = selection->select_head;
+ int tail = selection->select_tail;
+ int width = selection->term->display->width;
+
+ if (head == 0 || tail < width - 1){
+
+ /* get border */
+ guac_click* selection = guac_click_get_blank_border(click);
+
+ /* Copy to clipboard */
+ guac_click_select_blank(selection);
+
+ /* Draw selection */
+ guac_click_draw_select(selection);
+
+ return;
+ }
+
+ else if (head > 0 && tail == width - 1){
+
+ /* Move selected column */
+ sentinel = term->display->operations[row * term->display->width +
col].character.value;
+ while(sentinel == 0 || sentinel == 32){
+ col--;
+ sentinel = term->display->operations[row *
term->display->width + col].character.value;
+ }
+
+ selection->select_col = col;
+ selection->select_head = col;
+ selection->select_tail = col;
+ sentinel = term->display->operations[row * term->display->width +
col].character.value;
+
+ /* Determination */
+
+ /* Words */
+
+ if ((sentinel > 64 && sentinel < 91) || (sentinel > 96 && sentinel
< 123) || (sentinel > 47 && sentinel < 58) || (sentinel == 95)){
+
+ /* get border */
+ guac_click* moved_selection =
guac_click_get_word_border(selection);
+
+ /* Copy to clipboard */
+ guac_click_select_word(moved_selection);
+
+ /* Draw selection */
+ guac_click_draw_select(moved_selection);
+
+ return;
+
+ }
+
+ /* Marks */
+
+ else if ((sentinel > 32 && sentinel < 48) || (sentinel > 57 &&
sentinel < 65) || (sentinel > 90 && sentinel < 95) || (sentinel > 122 &&
sentinel < 127) ||(sentinel == 96)){
Review Comment:
There are a lot of magic numbers here and elsewhere in this function. Is
there a better way to write this that would make things more readable and
verifiable?
##########
src/protocols/ssh/input.c:
##########
@@ -31,6 +33,20 @@
#include <pthread.h>
+#include <stdio.h>
+#include <sys/timeb.h>
+
+
+int state = 0;
+long long start_1, start_2, start_3 = 0;
+long long end_1, end_2, end_3 = 0;
Review Comment:
Global state should be avoided where possible. This would make more sense
within the state representation of the internal terminal struct, and needs to
be documented.
##########
src/protocols/ssh/input.c:
##########
@@ -31,6 +33,20 @@
#include <pthread.h>
+#include <stdio.h>
+#include <sys/timeb.h>
+
+
+int state = 0;
+long long start_1, start_2, start_3 = 0;
+long long end_1, end_2, end_3 = 0;
+
+long long getSystemTime() {
+ struct timeb t;
+ ftime(&t);
+ return 1000 * t.time + t.millitm;
+}
Review Comment:
You do not need to declare your own function for this - libguac provides
`guac_timestamp_current()`.
##########
src/protocols/ssh/click.c:
##########
@@ -0,0 +1,457 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+
+#include "common/cursor.h"
+#include "common/display.h"
+#include "common/recording.h"
+#include "click.h"
+#include "ssh.h"
+#include "terminal/terminal.h"
+#include "terminal/select.h"
+
+#include <guacamole/client.h>
+#include <guacamole/unicode.h>
+#include <guacamole/user.h>
+#include <libssh2.h>
+
+#include <pthread.h>
+
+void guac_click_draw_select(guac_click* click){
+
+ int height = click->term->display->char_height;
+ int width = click->term->display->char_width;
+
+ guac_protocol_send_rect(click->socket, click->select_layer,
+ click->select_head * width, click->select_row * height,
+ (click->select_tail - click->select_head + 1) * width, height);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x80, 0xFF, 0x60);
+
+}
+
+void guac_click_draw_blank(guac_click* click){
+
+ guac_protocol_send_rect(click->socket, click->select_layer, 0, 0, 1, 1);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x00, 0x00, 0x00);
+
+}
+
+void guac_click_select_word(guac_click* click){
+
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+ int i = head;
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int length = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ if(head < 0 || head > length - 1)
+ return;
+
+ if(tail < 0 || tail > length - 1)
+ tail = length - 1;
+
+ /* Write each character to clipboard */
+
+
+ while (i <= tail){
+
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = head; i <= tail; i++) {
+ int codepoint = buffer_row->characters[i].value;
+
+ if (codepoint == 0 || codepoint == GUAC_CHAR_CONTINUATION)
+ continue;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+void guac_click_select_blank(guac_click* click){
+
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int l = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ if(head < 0 || head > l - 1)
+ return;
+
+ if(tail < 0 || tail > l - 1)
+ tail = l - 1;
+
+ int i = head;
+
+ /* Write blank to clipboard */
+ while (i <= tail)
+ {
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = head; i <= tail; i++) {
+ int codepoint = 32;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+void guac_click_select_mark(guac_click* click){
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+ char* current = buffer;
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+
+ /* Write char to clipboard */
+ int bytes =
guac_utf8_write(buffer_row->characters[click->select_col].value, current,
sizeof(buffer));
+ current += bytes;
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+}
+
+void guac_click_select_line(guac_click* click){
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int i = 0;
+ int length = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ /* Write each character to clipboard */
+
+ while (i <= length){
+
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = 0; i <= length; i++) {
+ int codepoint = buffer_row->characters[i].value;
+
+ if (codepoint == 0)
+ codepoint = 32;
+
+ if (codepoint == GUAC_CHAR_CONTINUATION)
+ continue;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+guac_click* guac_click_get_word_border(guac_click* click){
+
+ /* Get select information */
+
+ guac_terminal* term = click->term;
+
+ int row = click->select_row;
+ int col = click->select_col;
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+ int flag = sentinel;
+
+ /* Get head */
+ while (((flag > 64 && flag < 91) || (flag > 96 && flag < 123) || (flag >
47 && flag < 58) || (flag == 95)) && (head >= 0 && head <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
head].character.value;
+ head--;
+ }
+
+
+ /* Reset flag */
+ flag = sentinel;
+
+ /* Get tail */
+ while (((flag > 64 && flag < 91) || (flag > 96 && flag < 123) || (flag >
47 && flag < 58) || (flag == 95)) &&(tail >= 0 && tail <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
tail].character.value;
+ tail++;
+ }
+
+
+
+ head += 2;
+ tail -= 2;
+
+ int h = term->display->operations[row * term->display->width + head -
1].character.value;
+ if (head == 1 && ((h > 64 && h < 91) || (h > 96 && h < 123) || (h > 47 &&
h < 58) || (h == 95)))
+ head = 0;
+
+ printf("Head: %d\n", head);
+ printf("Tail: %d\n", tail);
+
+ click->select_head = head;
+ click->select_tail = tail;
+
+ return click;
+
+}
+
+guac_click* guac_click_get_blank_border(guac_click* click){
+
+ /* Get select information */
+ guac_terminal* term = click->term;
+
+ int row = click->select_row;
+ int col = click->select_col;
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+ int flag = sentinel;
+
+ /* Get head */
+ while ((flag == 0 || flag == 32) && (head >= 0 && head <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
head].character.value;
+ head--;
+ }
+
+ /* Reset flag */
+ flag = sentinel;
+
+ /* Get tail */
+ while ((flag == 0 || flag == 32) && (tail >= 0 && tail <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
tail].character.value;
+ tail++;
+ }
+
+ head += 2;
+ tail -= 2;
+
+ if(head == 1 && (term->display->operations[row * term->display->width +
head].character.value == 0 ||
+ term->display->operations[row * term->display->width +
head].character.value == 32))
+ head = 0;
+
+ click->select_head = head;
+ click->select_tail = tail;
+
+ return click;
+}
+
+void guac_double_click(guac_click* click){
+
+ /* Set selection variables */
+ guac_terminal* term = click->term;
+ int row = click->select_row;
+ int col = click->select_col;
+ printf("Row: %d, Col: %d\n", row, col);
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+
+ /* Determination */
Review Comment:
What do you mean by this?
##########
src/protocols/ssh/click.c:
##########
@@ -0,0 +1,457 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+
+#include "common/cursor.h"
+#include "common/display.h"
+#include "common/recording.h"
+#include "click.h"
+#include "ssh.h"
+#include "terminal/terminal.h"
+#include "terminal/select.h"
+
+#include <guacamole/client.h>
+#include <guacamole/unicode.h>
+#include <guacamole/user.h>
+#include <libssh2.h>
+
+#include <pthread.h>
+
+void guac_click_draw_select(guac_click* click){
+
+ int height = click->term->display->char_height;
+ int width = click->term->display->char_width;
+
+ guac_protocol_send_rect(click->socket, click->select_layer,
+ click->select_head * width, click->select_row * height,
+ (click->select_tail - click->select_head + 1) * width, height);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x80, 0xFF, 0x60);
+
+}
+
+void guac_click_draw_blank(guac_click* click){
+
+ guac_protocol_send_rect(click->socket, click->select_layer, 0, 0, 1, 1);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x00, 0x00, 0x00);
+
+}
+
+void guac_click_select_word(guac_click* click){
+
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+ int i = head;
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int length = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ if(head < 0 || head > length - 1)
+ return;
+
+ if(tail < 0 || tail > length - 1)
+ tail = length - 1;
+
+ /* Write each character to clipboard */
+
+
+ while (i <= tail){
+
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = head; i <= tail; i++) {
+ int codepoint = buffer_row->characters[i].value;
+
+ if (codepoint == 0 || codepoint == GUAC_CHAR_CONTINUATION)
+ continue;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+void guac_click_select_blank(guac_click* click){
+
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int l = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ if(head < 0 || head > l - 1)
+ return;
+
+ if(tail < 0 || tail > l - 1)
+ tail = l - 1;
+
+ int i = head;
+
+ /* Write blank to clipboard */
+ while (i <= tail)
+ {
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = head; i <= tail; i++) {
+ int codepoint = 32;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+void guac_click_select_mark(guac_click* click){
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+ char* current = buffer;
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+
+ /* Write char to clipboard */
+ int bytes =
guac_utf8_write(buffer_row->characters[click->select_col].value, current,
sizeof(buffer));
+ current += bytes;
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+}
+
+void guac_click_select_line(guac_click* click){
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int i = 0;
+ int length = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ /* Write each character to clipboard */
+
+ while (i <= length){
+
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = 0; i <= length; i++) {
+ int codepoint = buffer_row->characters[i].value;
+
+ if (codepoint == 0)
+ codepoint = 32;
+
+ if (codepoint == GUAC_CHAR_CONTINUATION)
+ continue;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+guac_click* guac_click_get_word_border(guac_click* click){
+
+ /* Get select information */
+
+ guac_terminal* term = click->term;
+
+ int row = click->select_row;
+ int col = click->select_col;
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+ int flag = sentinel;
+
+ /* Get head */
+ while (((flag > 64 && flag < 91) || (flag > 96 && flag < 123) || (flag >
47 && flag < 58) || (flag == 95)) && (head >= 0 && head <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
head].character.value;
+ head--;
+ }
+
+
+ /* Reset flag */
+ flag = sentinel;
+
+ /* Get tail */
+ while (((flag > 64 && flag < 91) || (flag > 96 && flag < 123) || (flag >
47 && flag < 58) || (flag == 95)) &&(tail >= 0 && tail <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
tail].character.value;
+ tail++;
+ }
+
+
+
+ head += 2;
+ tail -= 2;
+
+ int h = term->display->operations[row * term->display->width + head -
1].character.value;
+ if (head == 1 && ((h > 64 && h < 91) || (h > 96 && h < 123) || (h > 47 &&
h < 58) || (h == 95)))
+ head = 0;
+
+ printf("Head: %d\n", head);
+ printf("Tail: %d\n", tail);
+
+ click->select_head = head;
+ click->select_tail = tail;
+
+ return click;
+
+}
+
+guac_click* guac_click_get_blank_border(guac_click* click){
+
+ /* Get select information */
+ guac_terminal* term = click->term;
+
+ int row = click->select_row;
+ int col = click->select_col;
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+ int flag = sentinel;
+
+ /* Get head */
+ while ((flag == 0 || flag == 32) && (head >= 0 && head <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
head].character.value;
+ head--;
+ }
+
+ /* Reset flag */
+ flag = sentinel;
+
+ /* Get tail */
+ while ((flag == 0 || flag == 32) && (tail >= 0 && tail <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
tail].character.value;
+ tail++;
+ }
+
+ head += 2;
+ tail -= 2;
+
+ if(head == 1 && (term->display->operations[row * term->display->width +
head].character.value == 0 ||
+ term->display->operations[row * term->display->width +
head].character.value == 32))
+ head = 0;
+
+ click->select_head = head;
+ click->select_tail = tail;
+
+ return click;
+}
+
+void guac_double_click(guac_click* click){
+
+ /* Set selection variables */
+ guac_terminal* term = click->term;
+ int row = click->select_row;
+ int col = click->select_col;
+ printf("Row: %d, Col: %d\n", row, col);
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+
+ /* Determination */
+
+ /* Words */
+
+ if ((sentinel > 64 && sentinel < 91) || (sentinel > 96 && sentinel < 123)
|| (sentinel > 47 && sentinel < 58) || (sentinel == 95)){
+
+ /* get border */
+ guac_click* selection = guac_click_get_word_border(click);
+
+ /* Copy to clipboard */
+ guac_click_select_word(selection);
+
+ /* Draw selection */
+ guac_click_draw_select(selection);
+
+ return;
+
+ }
+
+ /* Marks */
+
+ else if ((sentinel > 32 && sentinel < 48) || (sentinel > 57 && sentinel <
65) || (sentinel > 90 && sentinel < 95) || (sentinel > 122 && sentinel < 127)
||(sentinel == 96)){
+
+ /* Copy to clipboard */
+ guac_click_select_mark(click);
+
+ /* Draw selection */
+ click->select_head = click->select_col;
+ click->select_tail = click->select_col;
+
+ guac_click_draw_select(click);
+
+ return;
+
+ }
+
+ /* Blank */
+
+ else if (sentinel == 0 || sentinel == 32){
+
+ /* Get blank border */
+ guac_click* selection = guac_click_get_blank_border(click);
+
+ /* Blank position */
+ int head = selection->select_head;
+ int tail = selection->select_tail;
+ int width = selection->term->display->width;
+
+ if (head == 0 || tail < width - 1){
+
+ /* get border */
+ guac_click* selection = guac_click_get_blank_border(click);
+
+ /* Copy to clipboard */
+ guac_click_select_blank(selection);
+
+ /* Draw selection */
+ guac_click_draw_select(selection);
+
+ return;
+ }
+
+ else if (head > 0 && tail == width - 1){
Review Comment:
Please watch out for the spacing - there should be a space between the
parenthesis and the opening brace. Same elsewhere between `if`/`while` and the
opening paren.
##########
src/protocols/ssh/click.c:
##########
@@ -0,0 +1,457 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+
+#include "common/cursor.h"
+#include "common/display.h"
+#include "common/recording.h"
+#include "click.h"
+#include "ssh.h"
+#include "terminal/terminal.h"
+#include "terminal/select.h"
+
+#include <guacamole/client.h>
+#include <guacamole/unicode.h>
+#include <guacamole/user.h>
+#include <libssh2.h>
+
+#include <pthread.h>
+
+void guac_click_draw_select(guac_click* click){
+
+ int height = click->term->display->char_height;
+ int width = click->term->display->char_width;
+
+ guac_protocol_send_rect(click->socket, click->select_layer,
+ click->select_head * width, click->select_row * height,
+ (click->select_tail - click->select_head + 1) * width, height);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x80, 0xFF, 0x60);
+
+}
+
+void guac_click_draw_blank(guac_click* click){
+
+ guac_protocol_send_rect(click->socket, click->select_layer, 0, 0, 1, 1);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x00, 0x00, 0x00);
+
+}
+
+void guac_click_select_word(guac_click* click){
+
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+ int i = head;
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int length = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ if(head < 0 || head > length - 1)
+ return;
+
+ if(tail < 0 || tail > length - 1)
+ tail = length - 1;
+
+ /* Write each character to clipboard */
+
+
+ while (i <= tail){
+
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = head; i <= tail; i++) {
+ int codepoint = buffer_row->characters[i].value;
+
+ if (codepoint == 0 || codepoint == GUAC_CHAR_CONTINUATION)
+ continue;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+void guac_click_select_blank(guac_click* click){
+
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int l = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ if(head < 0 || head > l - 1)
+ return;
+
+ if(tail < 0 || tail > l - 1)
+ tail = l - 1;
+
+ int i = head;
+
+ /* Write blank to clipboard */
+ while (i <= tail)
+ {
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = head; i <= tail; i++) {
+ int codepoint = 32;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+void guac_click_select_mark(guac_click* click){
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+ char* current = buffer;
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+
+ /* Write char to clipboard */
+ int bytes =
guac_utf8_write(buffer_row->characters[click->select_col].value, current,
sizeof(buffer));
+ current += bytes;
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+}
+
+void guac_click_select_line(guac_click* click){
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int i = 0;
+ int length = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ /* Write each character to clipboard */
+
+ while (i <= length){
+
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = 0; i <= length; i++) {
+ int codepoint = buffer_row->characters[i].value;
+
+ if (codepoint == 0)
+ codepoint = 32;
+
+ if (codepoint == GUAC_CHAR_CONTINUATION)
+ continue;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+guac_click* guac_click_get_word_border(guac_click* click){
+
+ /* Get select information */
+
+ guac_terminal* term = click->term;
+
+ int row = click->select_row;
+ int col = click->select_col;
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+ int flag = sentinel;
+
+ /* Get head */
+ while (((flag > 64 && flag < 91) || (flag > 96 && flag < 123) || (flag >
47 && flag < 58) || (flag == 95)) && (head >= 0 && head <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
head].character.value;
+ head--;
+ }
+
+
+ /* Reset flag */
+ flag = sentinel;
+
+ /* Get tail */
+ while (((flag > 64 && flag < 91) || (flag > 96 && flag < 123) || (flag >
47 && flag < 58) || (flag == 95)) &&(tail >= 0 && tail <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
tail].character.value;
+ tail++;
+ }
+
+
+
+ head += 2;
+ tail -= 2;
+
+ int h = term->display->operations[row * term->display->width + head -
1].character.value;
+ if (head == 1 && ((h > 64 && h < 91) || (h > 96 && h < 123) || (h > 47 &&
h < 58) || (h == 95)))
+ head = 0;
+
+ printf("Head: %d\n", head);
+ printf("Tail: %d\n", tail);
+
+ click->select_head = head;
+ click->select_tail = tail;
+
+ return click;
+
+}
+
+guac_click* guac_click_get_blank_border(guac_click* click){
+
+ /* Get select information */
+ guac_terminal* term = click->term;
+
+ int row = click->select_row;
+ int col = click->select_col;
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+ int flag = sentinel;
+
+ /* Get head */
+ while ((flag == 0 || flag == 32) && (head >= 0 && head <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
head].character.value;
+ head--;
+ }
+
+ /* Reset flag */
+ flag = sentinel;
+
+ /* Get tail */
+ while ((flag == 0 || flag == 32) && (tail >= 0 && tail <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
tail].character.value;
+ tail++;
+ }
+
+ head += 2;
+ tail -= 2;
+
+ if(head == 1 && (term->display->operations[row * term->display->width +
head].character.value == 0 ||
+ term->display->operations[row * term->display->width +
head].character.value == 32))
+ head = 0;
+
+ click->select_head = head;
+ click->select_tail = tail;
+
+ return click;
+}
+
+void guac_double_click(guac_click* click){
+
+ /* Set selection variables */
+ guac_terminal* term = click->term;
+ int row = click->select_row;
+ int col = click->select_col;
+ printf("Row: %d, Col: %d\n", row, col);
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+
+ /* Determination */
+
+ /* Words */
+
+ if ((sentinel > 64 && sentinel < 91) || (sentinel > 96 && sentinel < 123)
|| (sentinel > 47 && sentinel < 58) || (sentinel == 95)){
+
+ /* get border */
+ guac_click* selection = guac_click_get_word_border(click);
+
+ /* Copy to clipboard */
+ guac_click_select_word(selection);
+
+ /* Draw selection */
+ guac_click_draw_select(selection);
+
+ return;
+
+ }
+
+ /* Marks */
Review Comment:
Same here - what do you mean by "marks"?
##########
src/protocols/ssh/click.c:
##########
@@ -0,0 +1,457 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+
+#include "common/cursor.h"
+#include "common/display.h"
+#include "common/recording.h"
+#include "click.h"
+#include "ssh.h"
+#include "terminal/terminal.h"
+#include "terminal/select.h"
+
+#include <guacamole/client.h>
+#include <guacamole/unicode.h>
+#include <guacamole/user.h>
+#include <libssh2.h>
+
+#include <pthread.h>
+
+void guac_click_draw_select(guac_click* click){
+
+ int height = click->term->display->char_height;
+ int width = click->term->display->char_width;
+
+ guac_protocol_send_rect(click->socket, click->select_layer,
+ click->select_head * width, click->select_row * height,
+ (click->select_tail - click->select_head + 1) * width, height);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x80, 0xFF, 0x60);
+
+}
+
+void guac_click_draw_blank(guac_click* click){
+
+ guac_protocol_send_rect(click->socket, click->select_layer, 0, 0, 1, 1);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x00, 0x00, 0x00);
+
+}
+
+void guac_click_select_word(guac_click* click){
+
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+ int i = head;
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int length = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ if(head < 0 || head > length - 1)
+ return;
+
+ if(tail < 0 || tail > length - 1)
+ tail = length - 1;
+
+ /* Write each character to clipboard */
+
+
+ while (i <= tail){
+
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = head; i <= tail; i++) {
+ int codepoint = buffer_row->characters[i].value;
+
+ if (codepoint == 0 || codepoint == GUAC_CHAR_CONTINUATION)
+ continue;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+void guac_click_select_blank(guac_click* click){
+
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int l = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ if(head < 0 || head > l - 1)
+ return;
+
+ if(tail < 0 || tail > l - 1)
+ tail = l - 1;
+
+ int i = head;
+
+ /* Write blank to clipboard */
+ while (i <= tail)
+ {
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = head; i <= tail; i++) {
+ int codepoint = 32;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+void guac_click_select_mark(guac_click* click){
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+ char* current = buffer;
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+
+ /* Write char to clipboard */
+ int bytes =
guac_utf8_write(buffer_row->characters[click->select_col].value, current,
sizeof(buffer));
+ current += bytes;
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+}
+
+void guac_click_select_line(guac_click* click){
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int i = 0;
+ int length = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ /* Write each character to clipboard */
+
+ while (i <= length){
+
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = 0; i <= length; i++) {
+ int codepoint = buffer_row->characters[i].value;
+
+ if (codepoint == 0)
+ codepoint = 32;
+
+ if (codepoint == GUAC_CHAR_CONTINUATION)
+ continue;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+guac_click* guac_click_get_word_border(guac_click* click){
+
+ /* Get select information */
+
+ guac_terminal* term = click->term;
+
+ int row = click->select_row;
+ int col = click->select_col;
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+ int flag = sentinel;
+
+ /* Get head */
+ while (((flag > 64 && flag < 91) || (flag > 96 && flag < 123) || (flag >
47 && flag < 58) || (flag == 95)) && (head >= 0 && head <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
head].character.value;
+ head--;
+ }
+
+
+ /* Reset flag */
+ flag = sentinel;
+
+ /* Get tail */
+ while (((flag > 64 && flag < 91) || (flag > 96 && flag < 123) || (flag >
47 && flag < 58) || (flag == 95)) &&(tail >= 0 && tail <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
tail].character.value;
+ tail++;
+ }
+
+
+
+ head += 2;
+ tail -= 2;
+
+ int h = term->display->operations[row * term->display->width + head -
1].character.value;
+ if (head == 1 && ((h > 64 && h < 91) || (h > 96 && h < 123) || (h > 47 &&
h < 58) || (h == 95)))
+ head = 0;
+
+ printf("Head: %d\n", head);
+ printf("Tail: %d\n", tail);
+
+ click->select_head = head;
+ click->select_tail = tail;
+
+ return click;
+
+}
+
+guac_click* guac_click_get_blank_border(guac_click* click){
+
+ /* Get select information */
+ guac_terminal* term = click->term;
+
+ int row = click->select_row;
+ int col = click->select_col;
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+ int flag = sentinel;
+
+ /* Get head */
+ while ((flag == 0 || flag == 32) && (head >= 0 && head <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
head].character.value;
+ head--;
+ }
+
+ /* Reset flag */
+ flag = sentinel;
+
+ /* Get tail */
+ while ((flag == 0 || flag == 32) && (tail >= 0 && tail <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
tail].character.value;
+ tail++;
+ }
+
+ head += 2;
+ tail -= 2;
+
+ if(head == 1 && (term->display->operations[row * term->display->width +
head].character.value == 0 ||
+ term->display->operations[row * term->display->width +
head].character.value == 32))
+ head = 0;
+
+ click->select_head = head;
+ click->select_tail = tail;
+
+ return click;
+}
+
+void guac_double_click(guac_click* click){
+
+ /* Set selection variables */
+ guac_terminal* term = click->term;
+ int row = click->select_row;
+ int col = click->select_col;
+ printf("Row: %d, Col: %d\n", row, col);
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+
+ /* Determination */
+
+ /* Words */
Review Comment:
It's unclear to me what is meant by this comment. Can you rephrase to
clarify?
##########
src/protocols/ssh/click.c:
##########
@@ -0,0 +1,457 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+
+#include "common/cursor.h"
+#include "common/display.h"
+#include "common/recording.h"
+#include "click.h"
+#include "ssh.h"
+#include "terminal/terminal.h"
+#include "terminal/select.h"
+
+#include <guacamole/client.h>
+#include <guacamole/unicode.h>
+#include <guacamole/user.h>
+#include <libssh2.h>
+
+#include <pthread.h>
+
+void guac_click_draw_select(guac_click* click){
+
+ int height = click->term->display->char_height;
+ int width = click->term->display->char_width;
+
+ guac_protocol_send_rect(click->socket, click->select_layer,
+ click->select_head * width, click->select_row * height,
+ (click->select_tail - click->select_head + 1) * width, height);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x80, 0xFF, 0x60);
+
+}
+
+void guac_click_draw_blank(guac_click* click){
+
+ guac_protocol_send_rect(click->socket, click->select_layer, 0, 0, 1, 1);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x00, 0x00, 0x00);
Review Comment:
Why does the double/triple click behavior need its own dedicated selection
redraw code, its own dedicated select layer, etc.? Can the existing terminal
selection code not be used as-is?
##########
src/protocols/ssh/click.c:
##########
@@ -0,0 +1,457 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+
+#include "common/cursor.h"
+#include "common/display.h"
+#include "common/recording.h"
+#include "click.h"
+#include "ssh.h"
+#include "terminal/terminal.h"
+#include "terminal/select.h"
+
+#include <guacamole/client.h>
+#include <guacamole/unicode.h>
+#include <guacamole/user.h>
+#include <libssh2.h>
+
+#include <pthread.h>
+
+void guac_click_draw_select(guac_click* click){
+
+ int height = click->term->display->char_height;
+ int width = click->term->display->char_width;
+
+ guac_protocol_send_rect(click->socket, click->select_layer,
+ click->select_head * width, click->select_row * height,
+ (click->select_tail - click->select_head + 1) * width, height);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x80, 0xFF, 0x60);
+
+}
+
+void guac_click_draw_blank(guac_click* click){
+
+ guac_protocol_send_rect(click->socket, click->select_layer, 0, 0, 1, 1);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x00, 0x00, 0x00);
+
+}
+
+void guac_click_select_word(guac_click* click){
+
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+ int i = head;
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int length = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ if(head < 0 || head > length - 1)
+ return;
+
+ if(tail < 0 || tail > length - 1)
+ tail = length - 1;
+
+ /* Write each character to clipboard */
+
+
+ while (i <= tail){
+
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = head; i <= tail; i++) {
+ int codepoint = buffer_row->characters[i].value;
+
+ if (codepoint == 0 || codepoint == GUAC_CHAR_CONTINUATION)
+ continue;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+void guac_click_select_blank(guac_click* click){
+
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int l = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ if(head < 0 || head > l - 1)
+ return;
+
+ if(tail < 0 || tail > l - 1)
+ tail = l - 1;
+
+ int i = head;
+
+ /* Write blank to clipboard */
+ while (i <= tail)
+ {
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = head; i <= tail; i++) {
+ int codepoint = 32;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+void guac_click_select_mark(guac_click* click){
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+ char* current = buffer;
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+
+ /* Write char to clipboard */
+ int bytes =
guac_utf8_write(buffer_row->characters[click->select_col].value, current,
sizeof(buffer));
+ current += bytes;
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+}
+
+void guac_click_select_line(guac_click* click){
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int i = 0;
+ int length = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ /* Write each character to clipboard */
+
+ while (i <= length){
+
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = 0; i <= length; i++) {
+ int codepoint = buffer_row->characters[i].value;
+
+ if (codepoint == 0)
+ codepoint = 32;
+
+ if (codepoint == GUAC_CHAR_CONTINUATION)
+ continue;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+guac_click* guac_click_get_word_border(guac_click* click){
+
+ /* Get select information */
+
+ guac_terminal* term = click->term;
+
+ int row = click->select_row;
+ int col = click->select_col;
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+ int flag = sentinel;
+
+ /* Get head */
+ while (((flag > 64 && flag < 91) || (flag > 96 && flag < 123) || (flag >
47 && flag < 58) || (flag == 95)) && (head >= 0 && head <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
head].character.value;
+ head--;
+ }
+
+
+ /* Reset flag */
+ flag = sentinel;
+
+ /* Get tail */
+ while (((flag > 64 && flag < 91) || (flag > 96 && flag < 123) || (flag >
47 && flag < 58) || (flag == 95)) &&(tail >= 0 && tail <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
tail].character.value;
+ tail++;
+ }
+
+
+
+ head += 2;
+ tail -= 2;
+
+ int h = term->display->operations[row * term->display->width + head -
1].character.value;
+ if (head == 1 && ((h > 64 && h < 91) || (h > 96 && h < 123) || (h > 47 &&
h < 58) || (h == 95)))
+ head = 0;
+
+ printf("Head: %d\n", head);
+ printf("Tail: %d\n", tail);
+
+ click->select_head = head;
+ click->select_tail = tail;
+
+ return click;
+
+}
+
+guac_click* guac_click_get_blank_border(guac_click* click){
+
+ /* Get select information */
+ guac_terminal* term = click->term;
+
+ int row = click->select_row;
+ int col = click->select_col;
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+ int flag = sentinel;
+
+ /* Get head */
+ while ((flag == 0 || flag == 32) && (head >= 0 && head <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
head].character.value;
+ head--;
+ }
+
+ /* Reset flag */
+ flag = sentinel;
Review Comment:
Please rephrase to capture the intent of what's happening here, rather than
the literal English equivalent of the relevant statement.
##########
src/protocols/ssh/click.c:
##########
@@ -0,0 +1,457 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+
+#include "common/cursor.h"
+#include "common/display.h"
+#include "common/recording.h"
+#include "click.h"
+#include "ssh.h"
+#include "terminal/terminal.h"
+#include "terminal/select.h"
+
+#include <guacamole/client.h>
+#include <guacamole/unicode.h>
+#include <guacamole/user.h>
+#include <libssh2.h>
+
+#include <pthread.h>
+
+void guac_click_draw_select(guac_click* click){
+
+ int height = click->term->display->char_height;
+ int width = click->term->display->char_width;
+
+ guac_protocol_send_rect(click->socket, click->select_layer,
+ click->select_head * width, click->select_row * height,
+ (click->select_tail - click->select_head + 1) * width, height);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x80, 0xFF, 0x60);
+
+}
+
+void guac_click_draw_blank(guac_click* click){
+
+ guac_protocol_send_rect(click->socket, click->select_layer, 0, 0, 1, 1);
+
+ guac_protocol_send_cfill(click->socket, GUAC_COMP_SRC, click->select_layer,
+ 0x00, 0x00, 0x00, 0x00);
+
+}
+
+void guac_click_select_word(guac_click* click){
+
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+ int i = head;
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int length = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ if(head < 0 || head > length - 1)
+ return;
+
+ if(tail < 0 || tail > length - 1)
+ tail = length - 1;
+
+ /* Write each character to clipboard */
+
+
+ while (i <= tail){
+
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = head; i <= tail; i++) {
+ int codepoint = buffer_row->characters[i].value;
+
+ if (codepoint == 0 || codepoint == GUAC_CHAR_CONTINUATION)
+ continue;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+void guac_click_select_blank(guac_click* click){
+
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int l = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ if(head < 0 || head > l - 1)
+ return;
+
+ if(tail < 0 || tail > l - 1)
+ tail = l - 1;
+
+ int i = head;
+
+ /* Write blank to clipboard */
+ while (i <= tail)
+ {
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = head; i <= tail; i++) {
+ int codepoint = 32;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+void guac_click_select_mark(guac_click* click){
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+ char* current = buffer;
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+
+ /* Write char to clipboard */
+ int bytes =
guac_utf8_write(buffer_row->characters[click->select_col].value, current,
sizeof(buffer));
+ current += bytes;
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+}
+
+void guac_click_select_line(guac_click* click){
+
+ /* Clear clipboard for new selection */
+ guac_common_clipboard_reset(click->term->clipboard, "text/plain");
+ char buffer[1024];
+
+ /* Get information of selected row */
+ guac_terminal_buffer_row* buffer_row =
guac_terminal_buffer_get_row(click->term->buffer, click->select_row, 0);
+ int index = (click->term->buffer->top + click->select_row) %
click->term->buffer->available;
+ int i = 0;
+ int length = buffer_row->length;
+
+ if(index < 0)
+ index += click->term->buffer->available;
+
+ /* Write each character to clipboard */
+
+ while (i <= length){
+
+ int remaining = sizeof(buffer);
+ char* current = buffer;
+
+ for(i = 0; i <= length; i++) {
+ int codepoint = buffer_row->characters[i].value;
+
+ if (codepoint == 0)
+ codepoint = 32;
+
+ if (codepoint == GUAC_CHAR_CONTINUATION)
+ continue;
+
+ int bytes = guac_utf8_write(codepoint, current, remaining);
+
+ if (bytes == 0)
+ break;
+
+ current += bytes;
+ remaining -= bytes;
+ }
+
+ guac_common_clipboard_append(click->term->clipboard, buffer, current -
buffer);
+ guac_common_clipboard_send(click->term->clipboard, click->client);
+
+ }
+
+}
+
+guac_click* guac_click_get_word_border(guac_click* click){
+
+ /* Get select information */
+
+ guac_terminal* term = click->term;
+
+ int row = click->select_row;
+ int col = click->select_col;
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+ int flag = sentinel;
+
+ /* Get head */
+ while (((flag > 64 && flag < 91) || (flag > 96 && flag < 123) || (flag >
47 && flag < 58) || (flag == 95)) && (head >= 0 && head <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
head].character.value;
+ head--;
+ }
+
+
+ /* Reset flag */
+ flag = sentinel;
+
+ /* Get tail */
+ while (((flag > 64 && flag < 91) || (flag > 96 && flag < 123) || (flag >
47 && flag < 58) || (flag == 95)) &&(tail >= 0 && tail <=
term->display->width)){
+ flag = term->display->operations[row * term->display->width +
tail].character.value;
+ tail++;
+ }
+
+
+
+ head += 2;
+ tail -= 2;
+
+ int h = term->display->operations[row * term->display->width + head -
1].character.value;
+ if (head == 1 && ((h > 64 && h < 91) || (h > 96 && h < 123) || (h > 47 &&
h < 58) || (h == 95)))
+ head = 0;
+
+ printf("Head: %d\n", head);
+ printf("Tail: %d\n", tail);
+
+ click->select_head = head;
+ click->select_tail = tail;
+
+ return click;
+
+}
+
+guac_click* guac_click_get_blank_border(guac_click* click){
+
+ /* Get select information */
+ guac_terminal* term = click->term;
+
+ int row = click->select_row;
+ int col = click->select_col;
+ int head = click->select_head;
+ int tail = click->select_tail;
+
+ int sentinel = term->display->operations[row * term->display->width +
col].character.value;
+ int flag = sentinel;
+
+ /* Get head */
Review Comment:
What do you mean by "head"?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]