From e750ca9499c94f80d89441507f03b98ebab2161e Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 29 Feb 2016 21:41:56 -0800 Subject: [PATCH] GUAC-1389: Update terminal to support screen sharing. --- Makefile.am | 2 +- src/terminal/Makefile.am | 8 -- src/terminal/blank.c | 51 ------- src/terminal/blank.h | 42 ------ src/terminal/cursor.c | 61 --------- src/terminal/cursor.h | 78 ----------- src/terminal/display.c | 4 +- src/terminal/ibar.c | 94 ------------- src/terminal/ibar.h | 65 --------- src/terminal/pointer.c | 94 ------------- src/terminal/pointer.h | 68 ---------- src/terminal/terminal.c | 222 +++++++++++++++++++------------ src/terminal/terminal.h | 103 ++++++++++---- src/terminal/terminal_handlers.c | 4 +- 14 files changed, 220 insertions(+), 676 deletions(-) delete mode 100644 src/terminal/blank.c delete mode 100644 src/terminal/blank.h delete mode 100644 src/terminal/cursor.c delete mode 100644 src/terminal/cursor.h delete mode 100644 src/terminal/ibar.c delete mode 100644 src/terminal/ibar.h delete mode 100644 src/terminal/pointer.c delete mode 100644 src/terminal/pointer.h diff --git a/Makefile.am b/Makefile.am index 1836cffa..562d712a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -46,7 +46,7 @@ SUBDIRS += src/common-ssh endif if ENABLE_TERMINAL -#SUBDIRS += src/terminal +SUBDIRS += src/terminal endif if ENABLE_RDP diff --git a/src/terminal/Makefile.am b/src/terminal/Makefile.am index f2cfb550..e14c12cf 100644 --- a/src/terminal/Makefile.am +++ b/src/terminal/Makefile.am @@ -26,15 +26,11 @@ ACLOCAL_AMFLAGS = -I m4 noinst_LTLIBRARIES = libguac_terminal.la noinst_HEADERS = \ - blank.h \ buffer.h \ char_mappings.h \ common.h \ - cursor.h \ display.h \ - ibar.h \ packet.h \ - pointer.h \ scrollbar.h \ terminal.h \ terminal_handlers.h \ @@ -42,15 +38,11 @@ noinst_HEADERS = \ typescript.h libguac_terminal_la_SOURCES = \ - blank.c \ buffer.c \ char_mappings.c \ common.c \ - cursor.c \ display.c \ - ibar.c \ packet.c \ - pointer.c \ scrollbar.c \ terminal.c \ terminal_handlers.c \ diff --git a/src/terminal/blank.c b/src/terminal/blank.c deleted file mode 100644 index f2165275..00000000 --- a/src/terminal/blank.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2013 Glyptodon LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "config.h" - -#include "cursor.h" - -#include -#include -#include -#include - -guac_terminal_cursor* guac_terminal_create_blank(guac_client* client) { - - guac_socket* socket = client->socket; - guac_terminal_cursor* cursor = guac_terminal_cursor_alloc(client); - - /* Set buffer to a single 1x1 transparent rectangle */ - guac_protocol_send_rect(socket, cursor->buffer, 0, 0, 1, 1); - guac_protocol_send_cfill(socket, GUAC_COMP_SRC, cursor->buffer, - 0x00, 0x00, 0x00, 0x00); - - /* Initialize cursor properties */ - cursor->width = 1; - cursor->height = 1; - cursor->hotspot_x = 0; - cursor->hotspot_y = 0; - - return cursor; - -} - diff --git a/src/terminal/blank.h b/src/terminal/blank.h deleted file mode 100644 index 0d22797b..00000000 --- a/src/terminal/blank.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2013 Glyptodon LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -#ifndef _GUAC_TERMINAL_BLANK_H -#define _GUAC_TERMINAL_BLANK_H - -#include "config.h" - -#include "cursor.h" - -#include -#include - -/** - * Creates a new blank cursor, returning the corresponding cursor object. - * - * @param client The guac_client to send the cursor to. - * @return A new cursor which must be free'd via guac_terminal_cursor_free()/ - */ -guac_terminal_cursor* guac_terminal_create_blank(guac_client* client); - -#endif diff --git a/src/terminal/cursor.c b/src/terminal/cursor.c deleted file mode 100644 index 9bd00264..00000000 --- a/src/terminal/cursor.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2013 Glyptodon LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "config.h" - -#include "cursor.h" - -#include - -#include -#include - -guac_terminal_cursor* guac_terminal_cursor_alloc(guac_client* client) { - - /* Alloc new cursor, initialize buffer */ - guac_terminal_cursor* cursor = malloc(sizeof(guac_terminal_cursor)); - cursor->buffer = guac_client_alloc_buffer(client); - - return cursor; - -} - -void guac_terminal_cursor_free(guac_client* client, guac_terminal_cursor* cursor) { - - /* Free buffer */ - guac_client_free_buffer(client, cursor->buffer); - - /* Free cursor */ - free(cursor); - -} - -void guac_terminal_set_cursor(guac_client* client, guac_terminal_cursor* cursor) { - - /* Set cursor */ - guac_protocol_send_cursor(client->socket, - cursor->hotspot_x, cursor->hotspot_y, - cursor->buffer, - 0, 0, cursor->width, cursor->height); - -} - diff --git a/src/terminal/cursor.h b/src/terminal/cursor.h deleted file mode 100644 index ffa5ca8f..00000000 --- a/src/terminal/cursor.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2013 Glyptodon LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -#ifndef _GUAC_TERMINAL_CURSOR_H -#define _GUAC_TERMINAL_CURSOR_H - -#include "config.h" - -#include -#include - -typedef struct guac_terminal_cursor { - - /** - * A buffer allocated with guac_client_alloc_buffer() that contains the - * cursor image. - */ - guac_layer* buffer; - - /** - * The width of the cursor in pixels. - */ - int width; - - /** - * The height of the cursor in pixels. - */ - int height; - - /** - * The X coordinate of the cursor hotspot. - */ - int hotspot_x; - - /** - * The Y coordinate of the cursor hotspot. - */ - int hotspot_y; - -} guac_terminal_cursor; - -/** - * Allocates a new cursor, pre-populating the cursor with a newly-allocated - * buffer. - */ -guac_terminal_cursor* guac_terminal_cursor_alloc(guac_client* client); - -/** - * Frees the buffer associated with this cursor as well as the cursor itself. - */ -void guac_terminal_cursor_free(guac_client* client, guac_terminal_cursor* cursor); - -/** - * Set the remote cursor. - */ -void guac_terminal_set_cursor(guac_client* client, guac_terminal_cursor* cursor); - -#endif diff --git a/src/terminal/display.c b/src/terminal/display.c index 5a3b40f5..ebb69f73 100644 --- a/src/terminal/display.c +++ b/src/terminal/display.c @@ -75,7 +75,7 @@ static void __guac_terminal_display_clear_select(guac_terminal_display* display) guac_protocol_send_cfill(socket, GUAC_COMP_SRC, select_layer, 0x00, 0x00, 0x00, 0x00); - guac_protocol_send_sync(socket, display->client->last_sent_timestamp); + guac_client_end_frame(display->client); guac_socket_flush(socket); /* Text is no longer selected */ @@ -935,7 +935,7 @@ void guac_terminal_display_select(guac_terminal_display* display, guac_protocol_send_cfill(socket, GUAC_COMP_SRC, select_layer, 0x00, 0x80, 0xFF, 0x60); - guac_protocol_send_sync(socket, display->client->last_sent_timestamp); + guac_client_end_frame(display->client); guac_socket_flush(socket); } diff --git a/src/terminal/ibar.c b/src/terminal/ibar.c deleted file mode 100644 index 7ba69c3b..00000000 --- a/src/terminal/ibar.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2013 Glyptodon LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "config.h" - -#include "cursor.h" - -#include -#include -#include -#include - -/* Macros for prettying up the embedded image. */ -#define X 0x00,0x00,0x00,0xFF -#define U 0x80,0x80,0x80,0xFF -#define O 0xFF,0xFF,0xFF,0xFF -#define _ 0x00,0x00,0x00,0x00 - -/* Dimensions */ -const int guac_terminal_ibar_width = 7; -const int guac_terminal_ibar_height = 16; - -/* Format */ -const cairo_format_t guac_terminal_ibar_format = CAIRO_FORMAT_ARGB32; -const int guac_terminal_ibar_stride = 28; - -/* Embedded pointer graphic */ -unsigned char guac_terminal_ibar[] = { - - X,X,X,X,X,X,X, - X,O,O,U,O,O,X, - X,X,X,O,X,X,X, - _,_,X,O,X,_,_, - _,_,X,O,X,_,_, - _,_,X,O,X,_,_, - _,_,X,O,X,_,_, - _,_,X,O,X,_,_, - _,_,X,O,X,_,_, - _,_,X,O,X,_,_, - _,_,X,O,X,_,_, - _,_,X,O,X,_,_, - _,_,X,O,X,_,_, - X,X,X,O,X,X,X, - X,O,O,U,O,O,X, - X,X,X,X,X,X,X - -}; - -guac_terminal_cursor* guac_terminal_create_ibar(guac_client* client) { - - guac_socket* socket = client->socket; - guac_terminal_cursor* cursor = guac_terminal_cursor_alloc(client); - - /* Draw to buffer */ - cairo_surface_t* graphic = cairo_image_surface_create_for_data( - guac_terminal_ibar, - guac_terminal_ibar_format, - guac_terminal_ibar_width, - guac_terminal_ibar_height, - guac_terminal_ibar_stride); - - guac_client_stream_png(client, socket, GUAC_COMP_SRC, cursor->buffer, - 0, 0, graphic); - cairo_surface_destroy(graphic); - - /* Initialize cursor properties */ - cursor->width = guac_terminal_ibar_width; - cursor->height = guac_terminal_ibar_height; - cursor->hotspot_x = guac_terminal_ibar_width / 2; - cursor->hotspot_y = guac_terminal_ibar_height / 2; - - return cursor; - -} - diff --git a/src/terminal/ibar.h b/src/terminal/ibar.h deleted file mode 100644 index bbbc6578..00000000 --- a/src/terminal/ibar.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2013 Glyptodon LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -#ifndef _GUAC_TERMINAL_IBAR_H -#define _GUAC_TERMINAL_IBAR_H - -#include "config.h" - -#include -#include - -/** - * Width of the embedded mouse cursor graphic. - */ -extern const int guac_terminal_ibar_width; - -/** - * Height of the embedded mouse cursor graphic. - */ -extern const int guac_terminal_ibar_height; - -/** - * Number of bytes in each row of the embedded mouse cursor graphic. - */ -extern const int guac_terminal_ibar_stride; - -/** - * The Cairo grapic format of the mouse cursor graphic. - */ -extern const cairo_format_t guac_terminal_ibar_format; - -/** - * Embedded mouse cursor graphic. - */ -extern unsigned char guac_terminal_ibar[]; - -/** - * Creates a new I-bar cursor, returning the corresponding cursor object. - * - * @param client The guac_client to send the cursor to. - * @return A new cursor which must be free'd via guac_terminal_cursor_free()/ - */ -guac_terminal_cursor* guac_terminal_create_ibar(guac_client* client); - -#endif diff --git a/src/terminal/pointer.c b/src/terminal/pointer.c deleted file mode 100644 index 72e99e3b..00000000 --- a/src/terminal/pointer.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2015 Glyptodon LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "config.h" - -#include "cursor.h" - -#include -#include -#include -#include - -/* Macros for prettying up the embedded image. */ -#define X 0x00,0x00,0x00,0xFF -#define U 0x80,0x80,0x80,0xFF -#define O 0xFF,0xFF,0xFF,0xFF -#define _ 0x00,0x00,0x00,0x00 - -/* Dimensions */ -const int guac_terminal_pointer_width = 11; -const int guac_terminal_pointer_height = 16; - -/* Format */ -const cairo_format_t guac_terminal_pointer_format = CAIRO_FORMAT_ARGB32; -const int guac_terminal_pointer_stride = 44; - -/* Embedded pointer graphic */ -unsigned char guac_terminal_pointer[] = { - - O,_,_,_,_,_,_,_,_,_,_, - O,O,_,_,_,_,_,_,_,_,_, - O,X,O,_,_,_,_,_,_,_,_, - O,X,X,O,_,_,_,_,_,_,_, - O,X,X,X,O,_,_,_,_,_,_, - O,X,X,X,X,O,_,_,_,_,_, - O,X,X,X,X,X,O,_,_,_,_, - O,X,X,X,X,X,X,O,_,_,_, - O,X,X,X,X,X,X,X,O,_,_, - O,X,X,X,X,X,X,X,X,O,_, - O,X,X,X,X,X,O,O,O,O,O, - O,X,X,O,X,X,O,_,_,_,_, - O,X,O,_,O,X,X,O,_,_,_, - O,O,_,_,O,X,X,O,_,_,_, - O,_,_,_,_,O,X,X,O,_,_, - _,_,_,_,_,O,O,O,O,_,_ - -}; - -guac_terminal_cursor* guac_terminal_create_pointer(guac_client* client) { - - guac_socket* socket = client->socket; - guac_terminal_cursor* cursor = guac_terminal_cursor_alloc(client); - - /* Draw to buffer */ - cairo_surface_t* graphic = cairo_image_surface_create_for_data( - guac_terminal_pointer, - guac_terminal_pointer_format, - guac_terminal_pointer_width, - guac_terminal_pointer_height, - guac_terminal_pointer_stride); - - guac_client_stream_png(client, socket, GUAC_COMP_SRC, cursor->buffer, - 0, 0, graphic); - cairo_surface_destroy(graphic); - - /* Initialize cursor properties */ - cursor->width = guac_terminal_pointer_width; - cursor->height = guac_terminal_pointer_height; - cursor->hotspot_x = 0; - cursor->hotspot_y = 0; - - return cursor; - -} - diff --git a/src/terminal/pointer.h b/src/terminal/pointer.h deleted file mode 100644 index aae2f3d2..00000000 --- a/src/terminal/pointer.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2015 Glyptodon LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -#ifndef GUAC_TERMINAL_POINTER_H -#define GUAC_TERMINAL_POINTER_H - -#include "config.h" - -#include -#include - -/** - * Width of the embedded mouse cursor graphic. - */ -extern const int guac_terminal_pointer_width; - -/** - * Height of the embedded mouse cursor graphic. - */ -extern const int guac_terminal_pointer_height; - -/** - * Number of bytes in each row of the embedded mouse cursor graphic. - */ -extern const int guac_terminal_pointer_stride; - -/** - * The Cairo grapic format of the mouse cursor graphic. - */ -extern const cairo_format_t guac_terminal_pointer_format; - -/** - * Embedded mouse cursor graphic. - */ -extern unsigned char guac_terminal_pointer[]; - -/** - * Creates a new pointer cursor, returning the corresponding cursor object. - * - * @param client - * The guac_client to send the cursor to. - * - * @return - * A new cursor which must be free'd via guac_terminal_cursor_free(). - */ -guac_terminal_cursor* guac_terminal_create_pointer(guac_client* client); - -#endif diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c index d87dfd5a..899f47ec 100644 --- a/src/terminal/terminal.c +++ b/src/terminal/terminal.c @@ -23,14 +23,12 @@ #include "config.h" #include "buffer.h" -#include "blank.h" #include "common.h" -#include "cursor.h" #include "display.h" -#include "ibar.h" #include "guac_clipboard.h" +#include "guac_cursor.h" +#include "guac_display.h" #include "packet.h" -#include "pointer.h" #include "scrollbar.h" #include "terminal.h" #include "terminal_handlers.h" @@ -60,7 +58,7 @@ static void __guac_terminal_set_columns(guac_terminal* terminal, int row, int start_column, int end_column, guac_terminal_char* character) { - guac_terminal_display_set_columns(terminal->display, row + terminal->scroll_offset, + guac_terminal_display_set_columns(terminal->term_display, row + terminal->scroll_offset, start_column, end_column, character); guac_terminal_buffer_set_columns(terminal->buffer, row, @@ -211,7 +209,7 @@ void guac_terminal_reset(guac_terminal* term) { static void guac_terminal_paint_background(guac_terminal* terminal, int width, int height) { - guac_terminal_display* display = terminal->display; + guac_terminal_display* display = terminal->term_display; guac_client* client = display->client; guac_socket* socket = client->socket; @@ -226,6 +224,40 @@ static void guac_terminal_paint_background(guac_terminal* terminal, } +/** + * Automatically and continuously renders frames of terminal data while the + * associated guac_client is running. + * + * @param data + * A pointer to the guac_terminal that should be continuously rendered + * while its associated guac_client is running. + * + * @return + * Always NULL. + */ +void* guac_terminal_thread(void* data) { + + guac_terminal* terminal = (guac_terminal*) data; + guac_client* client = terminal->client; + + /* Render frames only while client is running */ + while (client->state == GUAC_CLIENT_RUNNING) { + + /* Stop rendering if an error occurs */ + if (guac_terminal_render_frame(terminal)) + break; + + /* Signal end of frame */ + guac_client_end_frame(client); + guac_socket_flush(client->socket); + + } + + /* The client has stopped or an error has occurred */ + return NULL; + +} + guac_terminal* guac_terminal_create(guac_client* client, const char* font_name, int font_size, int dpi, int width, int height, const char* color_scheme) { @@ -286,6 +318,7 @@ guac_terminal* guac_terminal_create(guac_client* client, guac_terminal* term = malloc(sizeof(guac_terminal)); term->client = client; + term->display = guac_common_display_alloc(client, width, height); term->upload_path_handler = NULL; term->file_download_handler = NULL; @@ -293,13 +326,13 @@ guac_terminal* guac_terminal_create(guac_client* client, term->buffer = guac_terminal_buffer_alloc(1000, &default_char); /* Init display */ - term->display = guac_terminal_display_alloc(client, + term->term_display = guac_terminal_display_alloc(client, font_name, font_size, dpi, default_char.attributes.foreground, default_char.attributes.background); /* Fail if display init failed */ - if (term->display == NULL) { + if (term->term_display == NULL) { guac_client_log(client, GUAC_LOG_DEBUG, "Display initialization failed"); free(term); return NULL; @@ -309,8 +342,8 @@ guac_terminal* guac_terminal_create(guac_client* client, term->current_attributes = default_char.attributes; term->default_char = default_char; - term->term_width = available_width / term->display->char_width; - term->term_height = height / term->display->char_height; + term->term_width = available_width / term->term_display->char_width; + term->term_height = height / term->term_display->char_height; /* Open STDOUT pipe */ if (pipe(term->stdout_pipe_fd)) { @@ -338,15 +371,13 @@ guac_terminal* guac_terminal_create(guac_client* client, pthread_mutex_init(&(term->lock), NULL); /* Size display */ - guac_protocol_send_size(term->display->client->socket, - GUAC_DEFAULT_LAYER, width, height); guac_terminal_paint_background(term, width, height); - guac_terminal_display_resize(term->display, + guac_terminal_display_resize(term->term_display, term->term_width, term->term_height); /* Allocate scrollbar */ - term->scrollbar = guac_terminal_scrollbar_alloc(term->client, - GUAC_DEFAULT_LAYER, width, height, term->term_height); + term->scrollbar = guac_terminal_scrollbar_alloc(client, GUAC_DEFAULT_LAYER, + width, height, term->term_height); /* Associate scrollbar with this terminal */ term->scrollbar->data = term; @@ -359,30 +390,26 @@ guac_terminal* guac_terminal_create(guac_client* client, term->mod_ctrl = term->mod_shift = 0; - /* Set up mouse cursors */ - term->pointer_cursor = guac_terminal_create_pointer(client); - term->ibar_cursor = guac_terminal_create_ibar(client); - term->blank_cursor = guac_terminal_create_blank(client); - /* Initialize mouse cursor */ - term->current_cursor = term->blank_cursor; - guac_terminal_set_cursor(term->client, term->current_cursor); + term->current_cursor = GUAC_TERMINAL_CURSOR_BLANK; + guac_common_cursor_set_blank(term->display->cursor); /* Allocate clipboard */ term->clipboard = guac_common_clipboard_alloc(GUAC_TERMINAL_CLIPBOARD_MAX_LENGTH); + /* Start terminal thread */ + if (pthread_create(&(term->thread), NULL, + guac_terminal_thread, (void*) term)) { + guac_terminal_free(term); + return NULL; + } + return term; } void guac_terminal_free(guac_terminal* term) { - /* Close and flush any open pipe stream */ - guac_terminal_pipe_stream_close(term); - - /* Close and flush any active typescript */ - guac_terminal_typescript_free(term->typescript); - /* Close terminal output pipe */ close(term->stdout_pipe_fd[1]); close(term->stdout_pipe_fd[0]); @@ -391,8 +418,17 @@ void guac_terminal_free(guac_terminal* term) { close(term->stdin_pipe_fd[1]); close(term->stdin_pipe_fd[0]); + /* Wait for render thread to finish */ + pthread_join(term->thread, NULL); + + /* Close and flush any open pipe stream */ + guac_terminal_pipe_stream_close(term); + + /* Close and flush any active typescript */ + guac_terminal_typescript_free(term->typescript); + /* Free display */ - guac_terminal_display_free(term->display); + guac_terminal_display_free(term->term_display); /* Free buffer */ guac_terminal_buffer_free(term->buffer); @@ -403,10 +439,8 @@ void guac_terminal_free(guac_terminal* term) { /* Free scrollbar */ guac_terminal_scrollbar_free(term->scrollbar); - /* Free cursors */ - guac_terminal_cursor_free(term->client, term->pointer_cursor); - guac_terminal_cursor_free(term->client, term->ibar_cursor); - guac_terminal_cursor_free(term->client, term->blank_cursor); + /* Free the terminal itself */ + free(term); } @@ -565,7 +599,10 @@ int guac_terminal_printf(guac_terminal* terminal, const char* format, ...) { } -void guac_terminal_prompt(guac_terminal* terminal, const char* title, char* str, int size, bool echo) { +char* guac_terminal_prompt(guac_terminal* terminal, const char* title, + bool echo) { + + char buffer[1024]; int pos; char in_byte; @@ -573,16 +610,12 @@ void guac_terminal_prompt(guac_terminal* terminal, const char* title, char* str, /* Print title */ guac_terminal_printf(terminal, "%s", title); - /* Make room for null terminator */ - size--; - /* Read bytes until newline */ pos = 0; - while (pos < size && guac_terminal_read_stdin(terminal, &in_byte, 1) == 1) { + while (guac_terminal_read_stdin(terminal, &in_byte, 1) == 1) { /* Backspace */ if (in_byte == 0x7F) { - if (pos > 0) { guac_terminal_printf(terminal, "\b \b"); pos--; @@ -595,10 +628,11 @@ void guac_terminal_prompt(guac_terminal* terminal, const char* title, char* str, break; } - else { + /* Otherwise, store byte if there is room */ + else if (pos < sizeof(buffer) - 1) { /* Store character, update buffers */ - str[pos++] = in_byte; + buffer[pos++] = in_byte; /* Print character if echoing */ if (echo) @@ -608,10 +642,15 @@ void guac_terminal_prompt(guac_terminal* terminal, const char* title, char* str, } + /* Ignore all other input */ + } /* Terminate string */ - str[pos] = 0; + buffer[pos] = 0; + + /* Return newly-allocated string containing result */ + return strdup(buffer); } @@ -654,13 +693,13 @@ void guac_terminal_commit_cursor(guac_terminal* term) { /* Clear cursor */ guac_char = &(old_row->characters[term->visible_cursor_col]); guac_char->attributes.cursor = false; - guac_terminal_display_set_columns(term->display, term->visible_cursor_row + term->scroll_offset, + guac_terminal_display_set_columns(term->term_display, term->visible_cursor_row + term->scroll_offset, term->visible_cursor_col, term->visible_cursor_col, guac_char); /* Set cursor */ guac_char = &(new_row->characters[term->cursor_col]); guac_char->attributes.cursor = true; - guac_terminal_display_set_columns(term->display, term->cursor_row + term->scroll_offset, + guac_terminal_display_set_columns(term->term_display, term->cursor_row + term->scroll_offset, term->cursor_col, term->cursor_col, guac_char); term->visible_cursor_row = term->cursor_row; @@ -698,7 +737,7 @@ int guac_terminal_scroll_up(guac_terminal* term, if (start_row == 0 && end_row == term->term_height - 1) { /* Scroll up visibly */ - guac_terminal_display_copy_rows(term->display, start_row + amount, end_row, -amount); + guac_terminal_display_copy_rows(term->term_display, start_row + amount, end_row, -amount); /* Advance by scroll amount */ term->buffer->top += amount; @@ -821,7 +860,7 @@ void guac_terminal_scroll_display_down(guac_terminal* terminal, /* Shift screen up */ if (terminal->term_height > scroll_amount) - guac_terminal_display_copy_rows(terminal->display, + guac_terminal_display_copy_rows(terminal->term_display, scroll_amount, terminal->term_height - 1, -scroll_amount); @@ -842,8 +881,8 @@ void guac_terminal_scroll_display_down(guac_terminal* terminal, guac_terminal_buffer_get_row(terminal->buffer, row, 0); /* Clear row */ - guac_terminal_display_set_columns(terminal->display, - dest_row, 0, terminal->display->width, &(terminal->default_char)); + guac_terminal_display_set_columns(terminal->term_display, + dest_row, 0, terminal->term_display->width, &(terminal->default_char)); /* Draw row */ guac_terminal_char* current = buffer_row->characters; @@ -851,7 +890,7 @@ void guac_terminal_scroll_display_down(guac_terminal* terminal, /* Only draw if not blank */ if (guac_terminal_has_glyph(current->value)) - guac_terminal_display_set_columns(terminal->display, dest_row, column, column, current); + guac_terminal_display_set_columns(terminal->term_display, dest_row, column, column, current); current++; @@ -883,7 +922,7 @@ void guac_terminal_scroll_display_up(guac_terminal* terminal, /* Shift screen down */ if (terminal->term_height > scroll_amount) - guac_terminal_display_copy_rows(terminal->display, + guac_terminal_display_copy_rows(terminal->term_display, 0, terminal->term_height - scroll_amount - 1, scroll_amount); @@ -904,8 +943,8 @@ void guac_terminal_scroll_display_up(guac_terminal* terminal, guac_terminal_buffer_get_row(terminal->buffer, row, 0); /* Clear row */ - guac_terminal_display_set_columns(terminal->display, - dest_row, 0, terminal->display->width, &(terminal->default_char)); + guac_terminal_display_set_columns(terminal->term_display, + dest_row, 0, terminal->term_display->width, &(terminal->default_char)); /* Draw row */ guac_terminal_char* current = buffer_row->characters; @@ -913,7 +952,7 @@ void guac_terminal_scroll_display_up(guac_terminal* terminal, /* Only draw if not blank */ if (guac_terminal_has_glyph(current->value)) - guac_terminal_display_set_columns(terminal->display, dest_row, column, column, current); + guac_terminal_display_set_columns(terminal->term_display, dest_row, column, column, current); current++; @@ -942,7 +981,7 @@ void guac_terminal_select_redraw(guac_terminal* terminal) { else end_column += terminal->selection_end_width - 1; - guac_terminal_display_select(terminal->display, start_row, start_column, end_row, end_column); + guac_terminal_display_select(terminal->term_display, start_row, start_column, end_row, end_column); } @@ -1040,7 +1079,7 @@ void guac_terminal_select_end(guac_terminal* terminal, char* string) { /* Deselect */ terminal->text_selected = false; - guac_terminal_display_commit_select(terminal->display); + guac_terminal_display_commit_select(terminal->term_display); guac_terminal_buffer_row* buffer_row; @@ -1109,7 +1148,7 @@ void guac_terminal_select_end(guac_terminal* terminal, char* string) { void guac_terminal_copy_columns(guac_terminal* terminal, int row, int start_column, int end_column, int offset) { - guac_terminal_display_copy_columns(terminal->display, row + terminal->scroll_offset, + guac_terminal_display_copy_columns(terminal->term_display, row + terminal->scroll_offset, start_column, end_column, offset); guac_terminal_buffer_copy_columns(terminal->buffer, row, @@ -1130,7 +1169,7 @@ void guac_terminal_copy_columns(guac_terminal* terminal, int row, void guac_terminal_copy_rows(guac_terminal* terminal, int start_row, int end_row, int offset) { - guac_terminal_display_copy_rows(terminal->display, + guac_terminal_display_copy_rows(terminal->term_display, start_row + terminal->scroll_offset, end_row + terminal->scroll_offset, offset); guac_terminal_buffer_copy_rows(terminal->buffer, @@ -1179,7 +1218,7 @@ static void __guac_terminal_redraw_rect(guac_terminal* term, int start_row, int guac_terminal_buffer_get_row(term->buffer, row - term->scroll_offset, 0); /* Clear row */ - guac_terminal_display_set_columns(term->display, + guac_terminal_display_set_columns(term->term_display, row, start_col, end_col, &(term->default_char)); /* Copy characters */ @@ -1188,7 +1227,7 @@ static void __guac_terminal_redraw_rect(guac_terminal* term, int start_row, int /* Only redraw if not blank */ guac_terminal_char* c = &(buffer_row->characters[col]); if (guac_terminal_has_glyph(c->value)) - guac_terminal_display_set_columns(term->display, row, col, col, c); + guac_terminal_display_set_columns(term->term_display, row, col, col, c); } @@ -1217,8 +1256,8 @@ static void __guac_terminal_resize(guac_terminal* term, int width, int height) { /* If the new terminal bottom covers N rows, shift up N rows */ if (shift_amount > 0) { - guac_terminal_display_copy_rows(term->display, - shift_amount, term->display->height - 1, -shift_amount); + guac_terminal_display_copy_rows(term->term_display, + shift_amount, term->term_display->height - 1, -shift_amount); /* Update buffer top and cursor row based on shift */ term->buffer->top += shift_amount; @@ -1233,8 +1272,8 @@ static void __guac_terminal_resize(guac_terminal* term, int width, int height) { } /* Resize display */ - guac_terminal_display_flush(term->display); - guac_terminal_display_resize(term->display, width, height); + guac_terminal_display_flush(term->term_display); + guac_terminal_display_resize(term->term_display, width, height); /* Reraw any characters on right if widening */ if (width > term->term_width) @@ -1285,8 +1324,8 @@ static void __guac_terminal_resize(guac_terminal* term, int width, int height) { /* If anything remains, move screen as necessary */ if (shift_amount > 0) { - guac_terminal_display_copy_rows(term->display, - 0, term->display->height - shift_amount - 1, shift_amount); + guac_terminal_display_copy_rows(term->term_display, + 0, term->term_display->height - shift_amount - 1, shift_amount); /* Draw characters at top from scroll */ __guac_terminal_redraw_rect(term, 0, 0, shift_amount - 1, width-1); @@ -1313,9 +1352,8 @@ static void __guac_terminal_resize(guac_terminal* term, int width, int height) { int guac_terminal_resize(guac_terminal* terminal, int width, int height) { - guac_terminal_display* display = terminal->display; + guac_terminal_display* display = terminal->term_display; guac_client* client = display->client; - guac_socket* socket = client->socket; /* Acquire exclusive access to terminal */ guac_terminal_lock(terminal); @@ -1330,7 +1368,7 @@ int guac_terminal_resize(guac_terminal* terminal, int width, int height) { int columns = available_width / display->char_width; /* Resize default layer to given pixel dimensions */ - guac_protocol_send_size(socket, GUAC_DEFAULT_LAYER, width, height); + guac_common_surface_resize(terminal->display->default_surface, width, height); guac_terminal_paint_background(terminal, width, height); /* Notify scrollbar of resize */ @@ -1367,7 +1405,7 @@ void guac_terminal_flush(guac_terminal* terminal) { /* Flush display state */ guac_terminal_commit_cursor(terminal); - guac_terminal_display_flush(terminal->display); + guac_terminal_display_flush(terminal->term_display); guac_terminal_scrollbar_flush(terminal->scrollbar); } @@ -1391,9 +1429,9 @@ int guac_terminal_send_string(guac_terminal* term, const char* data) { static int __guac_terminal_send_key(guac_terminal* term, int keysym, int pressed) { /* Hide mouse cursor if not already hidden */ - if (term->current_cursor != term->blank_cursor) { - term->current_cursor = term->blank_cursor; - guac_terminal_set_cursor(term->client, term->blank_cursor); + if (term->current_cursor != GUAC_TERMINAL_CURSOR_BLANK) { + term->current_cursor = GUAC_TERMINAL_CURSOR_BLANK; + guac_common_cursor_set_blank(term->display->cursor); guac_terminal_notify(term); } @@ -1550,7 +1588,8 @@ int guac_terminal_send_key(guac_terminal* term, int keysym, int pressed) { } -static int __guac_terminal_send_mouse(guac_terminal* term, int x, int y, int mask) { +static int __guac_terminal_send_mouse(guac_terminal* term, guac_user* user, + int x, int y, int mask) { guac_client* client = term->client; guac_socket* socket = client->socket; @@ -1559,13 +1598,17 @@ static int __guac_terminal_send_mouse(guac_terminal* term, int x, int y, int mas int released_mask = term->mouse_mask & ~mask; int pressed_mask = ~term->mouse_mask & mask; + /* Store current mouse location */ + guac_common_cursor_move(term->display->cursor, user, x, y); + /* 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 != term->pointer_cursor) { - term->current_cursor = term->pointer_cursor; - guac_terminal_set_cursor(client, term->pointer_cursor); + if (term->current_cursor != GUAC_TERMINAL_CURSOR_POINTER) { + term->current_cursor = GUAC_TERMINAL_CURSOR_POINTER; + guac_common_cursor_set_pointer(term->display->cursor); + guac_terminal_notify(term); } guac_terminal_notify(term); @@ -1576,9 +1619,9 @@ static int __guac_terminal_send_mouse(guac_terminal* term, int x, int y, int mas term->mouse_mask = mask; /* Show mouse cursor if not already shown */ - if (term->current_cursor != term->ibar_cursor) { - term->current_cursor = term->ibar_cursor; - guac_terminal_set_cursor(client, term->ibar_cursor); + if (term->current_cursor != GUAC_TERMINAL_CURSOR_IBAR) { + term->current_cursor = GUAC_TERMINAL_CURSOR_IBAR; + guac_common_cursor_set_ibar(term->display->cursor); guac_terminal_notify(term); } @@ -1615,8 +1658,8 @@ static int __guac_terminal_send_mouse(guac_terminal* term, int x, int y, int mas /* Otherwise, just update */ else guac_terminal_select_update(term, - y / term->display->char_height - term->scroll_offset, - x / term->display->char_width); + y / term->term_display->char_height - term->scroll_offset, + x / term->term_display->char_width); } @@ -1624,8 +1667,8 @@ static int __guac_terminal_send_mouse(guac_terminal* term, int x, int y, int mas else if (!(pressed_mask & GUAC_CLIENT_MOUSE_LEFT) && mask & GUAC_CLIENT_MOUSE_LEFT) guac_terminal_select_start(term, - y / term->display->char_height - term->scroll_offset, - x / term->display->char_width); + y / term->term_display->char_height - term->scroll_offset, + x / term->term_display->char_width); /* Scroll up if wheel moved up */ if (released_mask & GUAC_CLIENT_MOUSE_SCROLL_UP) @@ -1639,12 +1682,13 @@ static int __guac_terminal_send_mouse(guac_terminal* term, int x, int y, int mas } -int guac_terminal_send_mouse(guac_terminal* term, int x, int y, int mask) { +int guac_terminal_send_mouse(guac_terminal* term, guac_user* user, + int x, int y, int mask) { int result; guac_terminal_lock(term); - result = __guac_terminal_send_mouse(term, x, y, mask); + result = __guac_terminal_send_mouse(term, user, x, y, mask); guac_terminal_unlock(term); return result; @@ -1861,3 +1905,11 @@ int guac_terminal_create_typescript(guac_terminal* term, const char* path, } +void guac_terminal_add_user(guac_terminal* term, guac_user* user, + guac_socket* socket) { + + /* Synchronize display state with new user */ + guac_common_display_dup(term->display, user, socket); + +} + diff --git a/src/terminal/terminal.h b/src/terminal/terminal.h index ea1ac1fe..a712fa1f 100644 --- a/src/terminal/terminal.h +++ b/src/terminal/terminal.h @@ -27,9 +27,9 @@ #include "config.h" #include "buffer.h" -#include "cursor.h" #include "display.h" #include "guac_clipboard.h" +#include "guac_display.h" #include "scrollbar.h" #include "types.h" #include "typescript.h" @@ -88,6 +88,28 @@ typedef struct guac_terminal guac_terminal; +/** + * All possible mouse cursors used by the terminal emulator. + */ +typedef enum guac_terminal_cursor_type { + + /** + * A transparent (blank) cursor. + */ + GUAC_TERMINAL_CURSOR_BLANK, + + /** + * A standard I-bar cursor for selecting text, etc. + */ + GUAC_TERMINAL_CURSOR_IBAR, + + /** + * A standard triangular mouse pointer for manipulating non-text objects. + */ + GUAC_TERMINAL_CURSOR_POINTER + +} guac_terminal_cursor_type; + /** * Handler for characters printed to the terminal. When a character is printed, * the current char handler for the terminal is called and given that @@ -112,10 +134,21 @@ typedef guac_stream* guac_terminal_file_download_handler(guac_client* client, ch struct guac_terminal { /** - * The Guacamole client this terminal emulator will use for rendering. + * The Guacamole client associated with this terminal emulator. */ guac_client* client; + /** + * The terminal render thread. + */ + pthread_t thread; + + /** + * The display associated with the Guacamole client this terminal emulator + * will use for rendering. + */ + guac_common_display* display; + /** * Called whenever the necessary terminal codes are sent to change * the path for future file uploads. @@ -260,7 +293,7 @@ struct guac_terminal { * The difference between the currently-rendered screen and the current * state of the terminal. */ - guac_terminal_display* display; + guac_terminal_display* term_display; /** * Current terminal display state. All characters present on the screen @@ -366,24 +399,9 @@ struct guac_terminal { int mouse_mask; /** - * The cached pointer cursor. + * The current mouse cursor, to avoid re-setting the cursor image. */ - guac_terminal_cursor* pointer_cursor; - - /** - * The cached I-bar cursor. - */ - guac_terminal_cursor* ibar_cursor; - - /** - * The cached invisible (blank) cursor. - */ - guac_terminal_cursor* blank_cursor; - - /** - * The current cursor, used to avoid re-setting the cursor. - */ - guac_terminal_cursor* current_cursor; + guac_terminal_cursor_type current_cursor; /** * The current contents of the clipboard. @@ -469,11 +487,29 @@ int guac_terminal_write_stdout(guac_terminal* terminal, const char* c, int size) int guac_terminal_notify(guac_terminal* terminal); /** - * Reads a single line from this terminal's STDIN. Input is retrieved in - * the same manner as guac_terminal_read_stdin() and the same restrictions - * apply. + * Reads a single line from this terminal's STDIN, storing the result in a + * newly-allocated string. Input is retrieved in the same manner as + * guac_terminal_read_stdin() and the same restrictions apply. + * + * @param terminal + * The terminal to which the provided title should be output, and from + * whose STDIN the single line of input should be read. + * + * @param title + * The human-readable title to output to the terminal just prior to reading + * from STDIN. + * + * @param echo + * Non-zero if the characters read from STDIN should be echoed back as + * terminal output, or zero if asterisks should be displayed instead. + * + * @return + * A newly-allocated string containing a single line of input read from the + * provided terminal's STDIN. This string must eventually be manually + * freed with a call to free(). */ -void guac_terminal_prompt(guac_terminal* terminal, const char* title, char* str, int size, bool echo); +char* guac_terminal_prompt(guac_terminal* terminal, const char* title, + bool echo); /** * Writes the given format string and arguments to this terminal's STDOUT in @@ -492,7 +528,8 @@ int guac_terminal_send_key(guac_terminal* term, int keysym, int pressed); * Handles the given mouse event, sending data, scrolling, pasting clipboard * data, etc. as necessary. */ -int guac_terminal_send_mouse(guac_terminal* term, int x, int y, int mask); +int guac_terminal_send_mouse(guac_terminal* term, guac_user* user, + int x, int y, int mask); /** * Handles a scroll event received from the scrollbar associated with a @@ -518,6 +555,22 @@ void guac_terminal_clipboard_reset(guac_terminal* term, const char* mimetype); */ void guac_terminal_clipboard_append(guac_terminal* term, const void* data, int length); +/** + * Signals the terminal emulator that a new user has joined the connection, and + * requests that the current display state be replicated to that user. + * + * @param term + * The terminal emulator associated with the connection being joined. + * + * @param user + * The user joining the connection. + * + * @param socket + * The guac_socket specific to the joining user and across which messages + * synchronizing the current display state should be sent. + */ +void guac_terminal_add_user(guac_terminal* term, guac_user* user, + guac_socket* socket); /* INTERNAL FUNCTIONS */ diff --git a/src/terminal/terminal_handlers.c b/src/terminal/terminal_handlers.c index ad943b00..c1d71501 100644 --- a/src/terminal/terminal_handlers.c +++ b/src/terminal/terminal_handlers.c @@ -907,7 +907,7 @@ int guac_terminal_set_directory(guac_terminal* term, unsigned char c) { term->upload_path_handler(term->client, filename); else guac_client_log(term->client, GUAC_LOG_DEBUG, - "Cannot set upload path. File is transfer not enabled."); + "Cannot set upload path. File transfer is not enabled."); length = 0; } @@ -932,7 +932,7 @@ int guac_terminal_download(guac_terminal* term, unsigned char c) { term->file_download_handler(term->client, filename); else guac_client_log(term->client, GUAC_LOG_DEBUG, - "Cannot send file. File is transfer not enabled."); + "Cannot send file. File transfer is not enabled."); length = 0; }