GUACAMOLE-1538: Merge corrections to libguac-terminal build and scope.

This commit is contained in:
Mike Jumper 2022-02-28 16:56:04 -08:00 committed by GitHub
commit d8073f9b17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
67 changed files with 1202 additions and 921 deletions

View File

@ -56,5 +56,5 @@ tests/test_*
!tests/test_*.[ch]
# Generated docs
doc/doxygen-output
doc/*/doxygen-output

2
.gitignore vendored
View File

@ -44,7 +44,7 @@ configure
stamp-h1
# Generated docs
doc/doxygen-output
doc/*/doxygen-output
# IDE metadata
nbproject/

View File

@ -89,14 +89,15 @@ if ENABLE_GUACLOG
SUBDIRS += src/guaclog
endif
EXTRA_DIST = \
.dockerignore \
CONTRIBUTING \
Dockerfile \
LICENSE \
NOTICE \
bin/guacctl \
doc/Doxyfile.in \
src/guacd-docker \
EXTRA_DIST = \
.dockerignore \
CONTRIBUTING \
Dockerfile \
LICENSE \
NOTICE \
bin/guacctl \
doc/libguac/Doxyfile.in \
doc/libguac-terminal/Doxyfile.in \
src/guacd-docker \
util/generate-test-runner.pl

View File

@ -194,7 +194,7 @@ AC_SUBST([LIBGUAC_CLIENT_RDP_LTLIB], '$(top_builddir)/src/protocols/rdp/libgua
AC_SUBST([LIBGUAC_CLIENT_RDP_INCLUDE], '-I$(top_srcdir)/src/protocols/rdp')
# Terminal emulator
AC_SUBST([TERMINAL_LTLIB], '$(top_builddir)/src/terminal/libguac_terminal.la')
AC_SUBST([TERMINAL_LTLIB], '$(top_builddir)/src/terminal/libguac-terminal.la')
AC_SUBST([TERMINAL_INCLUDE], '-I$(top_srcdir)/src/terminal $(PANGO_CFLAGS) $(PANGOCAIRO_CFLAGS) $(COMMON_INCLUDE)')
# Init directory
@ -1167,7 +1167,8 @@ AM_CONDITIONAL([ENABLE_GUACLOG], [test "x${enable_guaclog}" = "xyes"])
#
AC_CONFIG_FILES([Makefile
doc/Doxyfile
doc/libguac/Doxyfile
doc/libguac-terminal/Doxyfile
src/common/Makefile
src/common/tests/Makefile
src/common-ssh/Makefile

View File

@ -0,0 +1,58 @@
#
# 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.
#
#
# Project name / version
#
PROJECT_NAME = libguac-terminal
PROJECT_NUMBER = @PACKAGE_VERSION@
#
# Warn about undocumented parameters and return values, but do not fill output
# with verbose progress info.
#
QUIET = YES
WARN_NO_PARAMDOC = YES
#
# Output format
#
ALPHABETICAL_INDEX = YES
GENERATE_HTML = YES
GENERATE_LATEX = NO
OPTIMIZE_OUTPUT_FOR_C = YES
OUTPUT_DIRECTORY = doxygen-output
RECURSIVE = YES
SHOW_INCLUDE_FILES = NO
#
# Input format
#
CASE_SENSE_NAMES = YES
FILE_PATTERNS = *.h
STRIP_FROM_PATH = ../../src/terminal
INPUT = ../../src/terminal/terminal/terminal.h
JAVADOC_AUTOBRIEF = YES
TAB_SIZE = 4
TYPEDEF_HIDES_STRUCT = YES

View File

@ -52,9 +52,9 @@ SHOW_INCLUDE_FILES = NO
CASE_SENSE_NAMES = YES
EXCLUDE_SYMBOLS = __* guac_palette*
FILE_PATTERNS = *.h
INPUT = ../src/libguac/guacamole
INPUT = ../../src/libguac/guacamole
JAVADOC_AUTOBRIEF = YES
STRIP_FROM_PATH = ../src/libguac
STRIP_FROM_PATH = ../../src/libguac
TAB_SIZE = 4
TYPEDEF_HIDES_STRUCT = YES

View File

@ -29,15 +29,15 @@
#include <string.h>
#include <stdlib.h>
guac_common_clipboard* guac_common_clipboard_alloc(int size) {
guac_common_clipboard* guac_common_clipboard_alloc() {
guac_common_clipboard* clipboard = malloc(sizeof(guac_common_clipboard));
/* Init clipboard */
clipboard->mimetype[0] = '\0';
clipboard->buffer = malloc(size);
clipboard->buffer = malloc(GUAC_COMMON_CLIPBOARD_MAX_LENGTH);
clipboard->available = GUAC_COMMON_CLIPBOARD_MAX_LENGTH;
clipboard->length = 0;
clipboard->available = size;
pthread_mutex_init(&(clipboard->lock), NULL);

View File

@ -31,6 +31,11 @@
*/
#define GUAC_COMMON_CLIPBOARD_BLOCK_SIZE 4096
/**
* The maximum number of bytes to allow within the clipboard.
*/
#define GUAC_COMMON_CLIPBOARD_MAX_LENGTH 262144
/**
* Generic clipboard structure.
*/
@ -66,12 +71,9 @@ typedef struct guac_common_clipboard {
} guac_common_clipboard;
/**
* Creates a new clipboard having the given initial size.
*
* @param size The maximum number of bytes to allow within the clipboard.
* @return A newly-allocated clipboard.
* Creates a new clipboard.
*/
guac_common_clipboard* guac_common_clipboard_alloc(int size);
guac_common_clipboard* guac_common_clipboard_alloc();
/**
* Frees the given clipboard.

View File

@ -53,8 +53,9 @@ int guac_kubernetes_argv_callback(guac_user* user, const char* mimetype,
}
/* Update Kubernetes terminal size */
guac_kubernetes_resize(client, terminal->term_height,
terminal->term_width);
guac_kubernetes_resize(client,
guac_terminal_get_rows(terminal),
guac_terminal_get_columns(terminal));
return 0;
@ -67,20 +68,20 @@ void* guac_kubernetes_send_current_argv(guac_user* user, void* data) {
/* Send current color scheme */
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_KUBERNETES_ARGV_COLOR_SCHEME, terminal->color_scheme);
GUAC_KUBERNETES_ARGV_COLOR_SCHEME,
guac_terminal_get_color_scheme(terminal));
/* Send current font name */
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_KUBERNETES_ARGV_FONT_NAME, terminal->font_name);
GUAC_KUBERNETES_ARGV_FONT_NAME,
guac_terminal_get_font_name(terminal));
/* Send current font size */
char font_size[64];
sprintf(font_size, "%i", terminal->font_size);
sprintf(font_size, "%i", guac_terminal_get_font_size(terminal));
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_KUBERNETES_ARGV_FONT_SIZE, font_size);
return NULL;
}

View File

@ -19,7 +19,6 @@
#include "argv.h"
#include "client.h"
#include "common/clipboard.h"
#include "kubernetes.h"
#include "settings.h"
#include "user.h"
@ -95,9 +94,6 @@ int guac_client_init(guac_client* client) {
guac_kubernetes_client* kubernetes_client = calloc(1, sizeof(guac_kubernetes_client));
client->data = kubernetes_client;
/* Init clipboard */
kubernetes_client->clipboard = guac_common_clipboard_alloc(GUAC_KUBERNETES_CLIPBOARD_MAX_LENGTH);
/* Set handlers */
client->join_handler = guac_kubernetes_user_join_handler;
client->free_handler = guac_kubernetes_client_free_handler;
@ -133,7 +129,6 @@ int guac_kubernetes_client_free_handler(guac_client* client) {
if (kubernetes_client->settings != NULL)
guac_kubernetes_settings_free(kubernetes_client->settings);
guac_common_clipboard_free(kubernetes_client->clipboard);
free(kubernetes_client);
return 0;

View File

@ -22,11 +22,6 @@
#include <guacamole/client.h>
/**
* The maximum number of bytes to allow within the clipboard.
*/
#define GUAC_KUBERNETES_CLIPBOARD_MAX_LENGTH 262144
/**
* Static reference to the guac_client associated with the active Kubernetes
* connection. While libwebsockets provides some means of storing and

View File

@ -18,8 +18,8 @@
*/
#include "clipboard.h"
#include "common/clipboard.h"
#include "kubernetes.h"
#include "terminal/terminal.h"
#include <guacamole/client.h>
#include <guacamole/stream.h>
@ -33,7 +33,7 @@ int guac_kubernetes_clipboard_handler(guac_user* user, guac_stream* stream,
(guac_kubernetes_client*) client->data;
/* Clear clipboard and prepare for new data */
guac_common_clipboard_reset(kubernetes_client->clipboard, mimetype);
guac_terminal_clipboard_reset(kubernetes_client->term, mimetype);
/* Set handlers for clipboard stream */
stream->blob_handler = guac_kubernetes_clipboard_blob_handler;
@ -50,7 +50,7 @@ int guac_kubernetes_clipboard_blob_handler(guac_user* user,
(guac_kubernetes_client*) client->data;
/* Append new data */
guac_common_clipboard_append(kubernetes_client->clipboard, data, length);
guac_terminal_clipboard_append(kubernetes_client->term, data, length);
return 0;
}

View File

@ -86,8 +86,9 @@ int guac_kubernetes_user_size_handler(guac_user* user, int width, int height) {
guac_terminal_resize(terminal, width, height);
/* Update Kubernetes terminal window size if connected */
guac_kubernetes_resize(client, terminal->term_height,
terminal->term_width);
guac_kubernetes_resize(client,
guac_terminal_get_rows(terminal),
guac_terminal_get_columns(terminal));
return 0;
}

View File

@ -241,7 +241,6 @@ void* guac_kubernetes_client_thread(void* data) {
/* Create terminal options with required parameters */
guac_terminal_options* options = guac_terminal_options_create(
client, kubernetes_client->clipboard,
settings->width, settings->height, settings->resolution);
/* Set optional parameters */
@ -253,7 +252,7 @@ void* guac_kubernetes_client_thread(void* data) {
options->backspace = settings->backspace;
/* Create terminal */
kubernetes_client->term = guac_terminal_create(options);
kubernetes_client->term = guac_terminal_create(client, options);
/* Free options struct now that it's been used */
free(options);
@ -414,8 +413,8 @@ void guac_kubernetes_force_redraw(guac_client* client) {
/* Get current terminal dimensions */
guac_terminal* term = kubernetes_client->term;
int rows = term->term_height;
int columns = term->term_width;
int rows = guac_terminal_get_rows(term);
int columns = guac_terminal_get_columns(term);
/* Force a redraw by increasing the terminal size by one character in
* each dimension and then resizing it back to normal (the same technique

View File

@ -102,11 +102,6 @@ typedef struct guac_kubernetes_client {
*/
pthread_t client_thread;
/**
* The current clipboard contents.
*/
guac_common_clipboard* clipboard;
/**
* The terminal which will render all output from the Kubernetes pod.
*/

View File

@ -109,8 +109,8 @@ int guac_kubernetes_user_leave_handler(guac_user* user) {
guac_kubernetes_client* kubernetes_client =
(guac_kubernetes_client*) user->client->data;
/* Update shared cursor state */
guac_common_cursor_remove_user(kubernetes_client->term->cursor, user);
/* Remove the user from the terminal */
guac_terminal_remove_user(kubernetes_client->term, user);
/* Free settings if not owner (owner settings will be freed with client) */
if (!user->owner) {

View File

@ -358,7 +358,7 @@ static UINT guac_rdp_cliprdr_format_data_request(CliprdrClientContext* cliprdr,
guac_iconv_write* remote_writer;
const char* input = clipboard->clipboard->buffer;
char* output = malloc(GUAC_RDP_CLIPBOARD_MAX_LENGTH);
char* output = malloc(GUAC_COMMON_CLIPBOARD_MAX_LENGTH);
/* Map requested clipboard format to a guac_iconv writer */
switch (format_data_request->requestedFormatId) {
@ -389,7 +389,7 @@ static UINT guac_rdp_cliprdr_format_data_request(CliprdrClientContext* cliprdr,
BYTE* start = (BYTE*) output;
guac_iconv_read* local_reader = settings->normalize_clipboard ? GUAC_READ_UTF8_NORMALIZED : GUAC_READ_UTF8;
guac_iconv(local_reader, &input, clipboard->clipboard->length,
remote_writer, &output, GUAC_RDP_CLIPBOARD_MAX_LENGTH);
remote_writer, &output, GUAC_COMMON_CLIPBOARD_MAX_LENGTH);
CLIPRDR_FORMAT_DATA_RESPONSE data_response = {
.requestedFormatData = (BYTE*) start,
@ -449,7 +449,7 @@ static UINT guac_rdp_cliprdr_format_data_response(CliprdrClientContext* cliprdr,
return CHANNEL_RC_OK;
}
char received_data[GUAC_RDP_CLIPBOARD_MAX_LENGTH];
char received_data[GUAC_COMMON_CLIPBOARD_MAX_LENGTH];
guac_iconv_read* remote_reader;
const char* input = (char*) format_data_response->requestedFormatData;
@ -595,7 +595,7 @@ guac_rdp_clipboard* guac_rdp_clipboard_alloc(guac_client* client) {
/* Allocate clipboard and underlying storage */
guac_rdp_clipboard* clipboard = calloc(1, sizeof(guac_rdp_clipboard));
clipboard->client = client;
clipboard->clipboard = guac_common_clipboard_alloc(GUAC_RDP_CLIPBOARD_MAX_LENGTH);
clipboard->clipboard = guac_common_clipboard_alloc();
clipboard->requested_format = CF_TEXT;
return clipboard;

View File

@ -62,11 +62,6 @@
*/
#define GUAC_RDP_REASONABLE_AREA (800*600)
/**
* The maximum number of bytes to allow within the clipboard.
*/
#define GUAC_RDP_CLIPBOARD_MAX_LENGTH 262144
/**
* Initial rate of audio to stream, in Hz. If the RDP server uses a different
* value, the Guacamole audio stream will simply be reset appropriately.

View File

@ -27,6 +27,7 @@
#include <guacamole/user.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -54,10 +55,12 @@ int guac_ssh_argv_callback(guac_user* user, const char* mimetype,
}
/* Update SSH pty size if connected */
int term_width = guac_terminal_get_columns(terminal);
int term_height = guac_terminal_get_rows(terminal);
if (ssh_client->term_channel != NULL) {
pthread_mutex_lock(&(ssh_client->term_channel_lock));
libssh2_channel_request_pty_size(ssh_client->term_channel,
terminal->term_width, terminal->term_height);
term_width, term_height);
pthread_mutex_unlock(&(ssh_client->term_channel_lock));
}
@ -72,15 +75,17 @@ void* guac_ssh_send_current_argv(guac_user* user, void* data) {
/* Send current color scheme */
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_SSH_ARGV_COLOR_SCHEME, terminal->color_scheme);
GUAC_SSH_ARGV_COLOR_SCHEME,
guac_terminal_get_color_scheme(terminal));
/* Send current font name */
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_SSH_ARGV_FONT_NAME, terminal->font_name);
GUAC_SSH_ARGV_FONT_NAME,
guac_terminal_get_font_name(terminal));
/* Send current font size */
char font_size[64];
sprintf(font_size, "%i", terminal->font_size);
sprintf(font_size, "%i", guac_terminal_get_font_size(terminal));
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_SSH_ARGV_FONT_SIZE, font_size);

View File

@ -21,7 +21,6 @@
#include "argv.h"
#include "client.h"
#include "common/clipboard.h"
#include "common/recording.h"
#include "common-ssh/sftp.h"
#include "ssh.h"
@ -45,9 +44,6 @@ int guac_client_init(guac_client* client) {
guac_ssh_client* ssh_client = calloc(1, sizeof(guac_ssh_client));
client->data = ssh_client;
/* Init clipboard */
ssh_client->clipboard = guac_common_clipboard_alloc(GUAC_SSH_CLIPBOARD_MAX_LENGTH);
/* Set handlers */
client->join_handler = guac_ssh_user_join_handler;
client->free_handler = guac_ssh_client_free_handler;
@ -118,7 +114,6 @@ int guac_ssh_client_free_handler(guac_client* client) {
guac_ssh_settings_free(ssh_client->settings);
/* Free client structure */
guac_common_clipboard_free(ssh_client->clipboard);
free(ssh_client);
guac_common_ssh_uninit();

View File

@ -22,11 +22,6 @@
#include <guacamole/client.h>
/**
* The maximum number of bytes to allow within the clipboard.
*/
#define GUAC_SSH_CLIPBOARD_MAX_LENGTH 262144
/**
* Handler which is invoked when the SSH client needs to be disconnected (if
* connected) and freed. This can happen if initialization fails, or all users

View File

@ -19,7 +19,6 @@
#include "config.h"
#include "clipboard.h"
#include "common/clipboard.h"
#include "ssh.h"
#include "terminal/terminal.h"
@ -33,7 +32,7 @@ int guac_ssh_clipboard_handler(guac_user* user, guac_stream* stream,
/* Clear clipboard and prepare for new data */
guac_client* client = user->client;
guac_ssh_client* ssh_client = (guac_ssh_client*) client->data;
guac_common_clipboard_reset(ssh_client->clipboard, mimetype);
guac_terminal_clipboard_reset(ssh_client->term, mimetype);
/* Set handlers for clipboard stream */
stream->blob_handler = guac_ssh_clipboard_blob_handler;
@ -48,7 +47,7 @@ int guac_ssh_clipboard_blob_handler(guac_user* user, guac_stream* stream,
/* Append new data */
guac_client* client = user->client;
guac_ssh_client* ssh_client = (guac_ssh_client*) client->data;
guac_common_clipboard_append(ssh_client->clipboard, data, length);
guac_terminal_clipboard_append(ssh_client->term, data, length);
return 0;
}

View File

@ -88,7 +88,8 @@ 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,
terminal->term_width, terminal->term_height);
guac_terminal_get_columns(terminal),
guac_terminal_get_rows(terminal));
pthread_mutex_unlock(&(ssh_client->term_channel_lock));
}

View File

@ -36,6 +36,8 @@
#include <libssh2.h>
#include <libssh2_sftp.h>
#include <guacamole/client.h>
#include <guacamole/socket.h>
#include <guacamole/timestamp.h>
#include <guacamole/wol.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
@ -98,7 +100,7 @@ static guac_common_ssh_user* guac_ssh_get_user(guac_client* client) {
guac_client_log(client, GUAC_LOG_DEBUG,
"Initial import failed: %s",
guac_common_ssh_key_error());
guac_client_log(client, GUAC_LOG_DEBUG,
"Re-attempting private key import (WITH passphrase)");
@ -148,23 +150,23 @@ static guac_common_ssh_user* guac_ssh_get_user(guac_client* client) {
* A function used to generate a terminal prompt to gather additional
* credentials from the guac_client during a connection, and using
* the specified string to generate the prompt for the user.
*
*
* @param client
* The guac_client object associated with the current connection
* where additional credentials are required.
*
*
* @param cred_name
* The prompt text to display to the screen when prompting for the
* additional credentials.
*
* @return
*
* @return
* The string of credentials gathered from the user.
*/
static char* guac_ssh_get_credential(guac_client *client, char* cred_name) {
guac_ssh_client* ssh_client = (guac_ssh_client*) client->data;
return guac_terminal_prompt(ssh_client->term, cred_name, false);
}
void* ssh_input_thread(void* data) {
@ -206,17 +208,17 @@ void* ssh_client_thread(void* data) {
if (settings->wol_send_packet) {
guac_client_log(client, GUAC_LOG_DEBUG, "Sending Wake-on-LAN packet, "
"and pausing for %d seconds.", settings->wol_wait_time);
/* Send the Wake-on-LAN request. */
if (guac_wol_wake(settings->wol_mac_addr, settings->wol_broadcast_addr,
settings->wol_udp_port))
return NULL;
/* If wait time is specified, sleep for that amount of time. */
if (settings->wol_wait_time > 0)
guac_timestamp_msleep(settings->wol_wait_time * 1000);
}
/* Init SSH base libraries */
if (guac_common_ssh_init(client)) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
@ -240,7 +242,6 @@ void* ssh_client_thread(void* data) {
/* Create terminal options with required parameters */
guac_terminal_options* options = guac_terminal_options_create(
client, ssh_client->clipboard,
settings->width, settings->height, settings->resolution);
/* Set optional parameters */
@ -252,7 +253,7 @@ void* ssh_client_thread(void* data) {
options->backspace = settings->backspace;
/* Create terminal */
ssh_client->term = guac_terminal_create(options);
ssh_client->term = guac_terminal_create(client, options);
/* Free options struct now that it's been used */
free(options);
@ -359,10 +360,12 @@ void* ssh_client_thread(void* data) {
/* Init handlers for Guacamole-specific console codes */
if (!settings->sftp_disable_upload)
ssh_client->term->upload_path_handler = guac_sftp_set_upload_path;
guac_terminal_set_upload_path_handler(ssh_client->term,
guac_sftp_set_upload_path);
if (!settings->sftp_disable_download)
ssh_client->term->file_download_handler = guac_sftp_download_file;
guac_terminal_set_file_download_handler(ssh_client->term,
guac_sftp_download_file);
guac_client_log(client, GUAC_LOG_DEBUG, "SFTP session initialized");
@ -376,10 +379,11 @@ void* ssh_client_thread(void* data) {
" Backspace may not work as expected.");
/* Request PTY */
int term_height = guac_terminal_get_rows(ssh_client->term);
int term_width = guac_terminal_get_columns(ssh_client->term);
if (libssh2_channel_request_pty_ex(ssh_client->term_channel,
settings->terminal_type, strlen(settings->terminal_type),
ssh_ttymodes, ttymodeBytes, ssh_client->term->term_width,
ssh_client->term->term_height, 0, 0)) {
ssh_ttymodes, ttymodeBytes, term_width, term_height, 0, 0)) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Unable to allocate PTY.");
return NULL;
}

View File

@ -90,11 +90,6 @@ typedef struct guac_ssh_client {
*/
pthread_mutex_t term_channel_lock;
/**
* The current clipboard contents.
*/
guac_common_clipboard* clipboard;
/**
* The terminal which will render all output from the SSH client.
*/

View File

@ -25,6 +25,7 @@
#include "input.h"
#include "user.h"
#include "pipe.h"
#include "terminal/terminal.h"
#include "sftp.h"
#include "ssh.h"
#include "settings.h"
@ -113,8 +114,8 @@ int guac_ssh_user_leave_handler(guac_user* user) {
guac_ssh_client* ssh_client = (guac_ssh_client*) user->client->data;
/* Update shared cursor state */
guac_common_cursor_remove_user(ssh_client->term->cursor, user);
/* Remove the user from the terminal */
guac_terminal_remove_user(ssh_client->term, user);
/* Free settings if not owner (owner settings will be freed with client) */
if (!user->owner) {

View File

@ -26,6 +26,7 @@
#include <guacamole/socket.h>
#include <guacamole/user.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -54,8 +55,9 @@ int guac_telnet_argv_callback(guac_user* user, const char* mimetype,
/* Update terminal window size if connected */
if (telnet_client->telnet != NULL && telnet_client->naws_enabled)
guac_telnet_send_naws(telnet_client->telnet, terminal->term_width,
terminal->term_height);
guac_telnet_send_naws(telnet_client->telnet,
guac_terminal_get_columns(terminal),
guac_terminal_get_rows(terminal));
return 0;
@ -68,15 +70,17 @@ void* guac_telnet_send_current_argv(guac_user* user, void* data) {
/* Send current color scheme */
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_TELNET_ARGV_COLOR_SCHEME, terminal->color_scheme);
GUAC_TELNET_ARGV_COLOR_SCHEME,
guac_terminal_get_color_scheme(terminal));
/* Send current font name */
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_TELNET_ARGV_FONT_NAME, terminal->font_name);
GUAC_TELNET_ARGV_FONT_NAME,
guac_terminal_get_font_name(terminal));
/* Send current font size */
char font_size[64];
sprintf(font_size, "%i", terminal->font_size);
sprintf(font_size, "%i", guac_terminal_get_font_size(terminal));
guac_user_stream_argv(user, user->socket, "text/plain",
GUAC_TELNET_ARGV_FONT_SIZE, font_size);

View File

@ -23,7 +23,6 @@
#include "common/recording.h"
#include "settings.h"
#include "telnet.h"
#include "terminal/terminal.h"
#include "user.h"
#include <langinfo.h>
@ -31,6 +30,7 @@
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <guacamole/argv.h>
#include <guacamole/client.h>
@ -44,9 +44,6 @@ int guac_client_init(guac_client* client) {
guac_telnet_client* telnet_client = calloc(1, sizeof(guac_telnet_client));
client->data = telnet_client;
/* Init clipboard */
telnet_client->clipboard = guac_common_clipboard_alloc(GUAC_TELNET_CLIPBOARD_MAX_LENGTH);
/* Init telnet client */
telnet_client->socket_fd = -1;
telnet_client->naws_enabled = 0;
@ -100,7 +97,6 @@ int guac_telnet_client_free_handler(guac_client* client) {
if (telnet_client->settings != NULL)
guac_telnet_settings_free(telnet_client->settings);
guac_common_clipboard_free(telnet_client->clipboard);
free(telnet_client);
return 0;

View File

@ -29,11 +29,6 @@
#include <libtelnet.h>
/**
* The maximum number of bytes to allow within the clipboard.
*/
#define GUAC_TELNET_CLIPBOARD_MAX_LENGTH 262144
/**
* Free handler. Required by libguac and called when the guac_client is
* disconnected and must be cleaned up.

View File

@ -19,7 +19,6 @@
#include "config.h"
#include "clipboard.h"
#include "common/clipboard.h"
#include "telnet.h"
#include "terminal/terminal.h"
@ -33,7 +32,7 @@ int guac_telnet_clipboard_handler(guac_user* user, guac_stream* stream,
/* Clear clipboard and prepare for new data */
guac_client* client = user->client;
guac_telnet_client* telnet_client = (guac_telnet_client*) client->data;
guac_common_clipboard_reset(telnet_client->clipboard, mimetype);
guac_terminal_clipboard_reset(telnet_client->term, mimetype);
/* Set handlers for clipboard stream */
stream->blob_handler = guac_telnet_clipboard_blob_handler;
@ -48,7 +47,7 @@ int guac_telnet_clipboard_blob_handler(guac_user* user, guac_stream* stream,
/* Append new data */
guac_client* client = user->client;
guac_telnet_client* telnet_client = (guac_telnet_client*) client->data;
guac_common_clipboard_append(telnet_client->clipboard, data, length);
guac_terminal_clipboard_append(telnet_client->term, data, length);
return 0;
}

View File

@ -100,7 +100,10 @@ int guac_telnet_user_key_handler(guac_user* user, int keysym, int pressed) {
if (pressed && (
keysym == 0xFF13 /* Pause */
|| keysym == 0xFF6B /* Break */
|| (term->mod_ctrl && keysym == '0') /* Ctrl + 0 */
|| (
guac_terminal_get_mod_ctrl(term)
&& keysym == '0'
) /* Ctrl + 0 */
)) {
/* Send IAC BRK */
@ -132,8 +135,9 @@ int guac_telnet_user_size_handler(guac_user* user, int width, int height) {
/* Update terminal window size if connected */
if (telnet_client->telnet != NULL && telnet_client->naws_enabled)
guac_telnet_send_naws(telnet_client->telnet, terminal->term_width,
terminal->term_height);
guac_telnet_send_naws(telnet_client->telnet,
guac_terminal_get_columns(terminal),
guac_terminal_get_rows(terminal));
return 0;
}

View File

@ -26,6 +26,7 @@
#include <guacamole/client.h>
#include <guacamole/protocol.h>
#include <guacamole/timestamp.h>
#include <guacamole/wol.h>
#include <libtelnet.h>
@ -302,7 +303,9 @@ static void __guac_telnet_event_handler(telnet_t* telnet, telnet_event_t* event,
case TELNET_EV_DO:
if (event->neg.telopt == TELNET_TELOPT_NAWS) {
telnet_client->naws_enabled = 1;
guac_telnet_send_naws(telnet, telnet_client->term->term_width, telnet_client->term->term_height);
guac_telnet_send_naws(telnet,
guac_terminal_get_columns(telnet_client->term),
guac_terminal_get_rows(telnet_client->term));
}
break;
@ -557,17 +560,17 @@ void* guac_telnet_client_thread(void* data) {
pthread_t input_thread;
char buffer[8192];
int wait_result;
/* If Wake-on-LAN is enabled, attempt to wake. */
if (settings->wol_send_packet) {
guac_client_log(client, GUAC_LOG_DEBUG, "Sending Wake-on-LAN packet, "
"and pausing for %d seconds.", settings->wol_wait_time);
/* Send the Wake-on-LAN request. */
if (guac_wol_wake(settings->wol_mac_addr, settings->wol_broadcast_addr,
settings->wol_udp_port))
return NULL;
/* If wait time is specified, sleep for that amount of time. */
if (settings->wol_wait_time > 0)
guac_timestamp_msleep(settings->wol_wait_time * 1000);
@ -587,7 +590,6 @@ void* guac_telnet_client_thread(void* data) {
/* Create terminal options with required parameters */
guac_terminal_options* options = guac_terminal_options_create(
client, telnet_client->clipboard,
settings->width, settings->height, settings->resolution);
/* Set optional parameters */
@ -599,7 +601,7 @@ void* guac_telnet_client_thread(void* data) {
options->backspace = settings->backspace;
/* Create terminal */
telnet_client->term = guac_terminal_create(options);
telnet_client->term = guac_terminal_create(client, options);
/* Free options struct now that it's been used */
free(options);

View File

@ -21,7 +21,6 @@
#define GUAC_TELNET_H
#include "config.h"
#include "common/clipboard.h"
#include "common/recording.h"
#include "settings.h"
#include "terminal/terminal.h"
@ -67,11 +66,6 @@ typedef struct guac_telnet_client {
*/
int echo_enabled;
/**
* The current clipboard contents.
*/
guac_common_clipboard* clipboard;
/**
* The terminal which will render all output from the telnet client.
*/

View File

@ -108,8 +108,8 @@ int guac_telnet_user_leave_handler(guac_user* user) {
guac_telnet_client* telnet_client =
(guac_telnet_client*) user->client->data;
/* Update shared cursor state */
guac_common_cursor_remove_user(telnet_client->term->cursor, user);
/* Remove the user from the terminal */
guac_terminal_remove_user(telnet_client->term, user);
/* Free settings if not owner (owner settings will be freed with client) */
if (!user->owner) {

View File

@ -55,7 +55,7 @@ int guac_client_init(guac_client* client) {
#endif
/* Init clipboard */
vnc_client->clipboard = guac_common_clipboard_alloc(GUAC_VNC_CLIPBOARD_MAX_LENGTH);
vnc_client->clipboard = guac_common_clipboard_alloc();
/* Set handlers */
client->join_handler = guac_vnc_user_join_handler;

View File

@ -49,11 +49,6 @@
*/
#define GUAC_VNC_CONNECT_INTERVAL 1000
/**
* The maximum number of bytes to allow within the clipboard.
*/
#define GUAC_VNC_CLIPBOARD_MAX_LENGTH 262144
/**
* Handler which frees all data associated with the guac_client.
*/

View File

@ -103,7 +103,7 @@ int guac_vnc_clipboard_end_handler(guac_user* user, guac_stream* stream) {
guac_vnc_client* vnc_client = (guac_vnc_client*) user->client->data;
rfbClient* rfb_client = vnc_client->rfb_client;
char output_data[GUAC_VNC_CLIPBOARD_MAX_LENGTH];
char output_data[GUAC_COMMON_CLIPBOARD_MAX_LENGTH];
const char* input = vnc_client->clipboard->buffer;
char* output = output_data;
@ -129,7 +129,7 @@ void guac_vnc_cut_text(rfbClient* client, const char* text, int textlen) {
if (vnc_client->settings->disable_copy)
return;
char received_data[GUAC_VNC_CLIPBOARD_MAX_LENGTH];
char received_data[GUAC_COMMON_CLIPBOARD_MAX_LENGTH];
const char* input = text;
char* output = received_data;

View File

@ -23,16 +23,16 @@
# to you by the ASF under the Apache License, Version 2.0, as described above.
#
AUTOMAKE_OPTIONS = foreign
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4
lib_LTLIBRARIES = libguac_terminal.la
lib_LTLIBRARIES = libguac-terminal.la
libguac_terminalincdir = $(includedir)/guacamole/terminal
libguac_terminalinc_HEADERS = \
noinst_HEADERS = \
terminal/buffer.h \
terminal/char_mappings.h \
terminal/char-mappings.h \
terminal/common.h \
terminal/color-scheme.h \
terminal/display.h \
@ -40,15 +40,18 @@ libguac_terminalinc_HEADERS = \
terminal/palette.h \
terminal/scrollbar.h \
terminal/select.h \
terminal/terminal.h \
terminal/terminal_handlers.h \
terminal/terminal-priv.h \
terminal/terminal-handlers.h \
terminal/types.h \
terminal/typescript.h \
terminal/xparsecolor.h
libguac_terminalinc_HEADERS = \
terminal/terminal.h
libguac_terminal_la_SOURCES = \
buffer.c \
char_mappings.c \
char-mappings.c \
color-scheme.c \
common.c \
display.c \
@ -57,7 +60,7 @@ libguac_terminal_la_SOURCES = \
scrollbar.c \
select.c \
terminal.c \
terminal_handlers.c \
terminal-handlers.c \
terminal-stdin-stream.c \
typescript.c \
xparsecolor.c
@ -70,6 +73,7 @@ libguac_terminal_la_CFLAGS = \
@PANGOCAIRO_CFLAGS@
libguac_terminal_la_LIBADD = \
@COMMON_LTLIB@ \
@LIBGUAC_LTLIB@
libguac_terminal_la_LDFLAGS = \

View File

@ -17,7 +17,6 @@
* under the License.
*/
#include "config.h"
#include "terminal/buffer.h"
#include "terminal/common.h"

View File

@ -17,7 +17,6 @@
* under the License.
*/
#include "config.h"
const int vt100_map[] = {
' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',

View File

@ -17,7 +17,6 @@
* under the License.
*/
#include "config.h"
#include "terminal/color-scheme.h"
#include "terminal/palette.h"

View File

@ -17,7 +17,6 @@
* under the License.
*/
#include "config.h"
#include "terminal/types.h"
#include <stdbool.h>

View File

@ -17,12 +17,13 @@
* under the License.
*/
#include "config.h"
#include "common/surface.h"
#include "terminal/common.h"
#include "terminal/display.h"
#include "terminal/palette.h"
#include "terminal/terminal.h"
#include "terminal/terminal-priv.h"
#include "terminal/types.h"
#include <math.h>

View File

@ -17,7 +17,6 @@
* under the License.
*/
#include "config.h"
#include "terminal/palette.h"
#include <ctype.h>

View File

@ -17,7 +17,6 @@
* under the License.
*/
#include "config.h"
#include "terminal/palette.h"
const guac_terminal_color GUAC_TERMINAL_INITIAL_PALETTE[256] = {

View File

@ -17,7 +17,6 @@
* under the License.
*/
#include "config.h"
#include "terminal/scrollbar.h"
#include <guacamole/client.h>

View File

@ -17,13 +17,13 @@
* under the License.
*/
#include "config.h"
#include "common/clipboard.h"
#include "terminal/buffer.h"
#include "terminal/display.h"
#include "terminal/select.h"
#include "terminal/terminal.h"
#include "terminal/terminal-priv.h"
#include "terminal/types.h"
#include <guacamole/client.h>

View File

@ -19,10 +19,11 @@
#include "config.h"
#include "terminal/char_mappings.h"
#include "terminal/char-mappings.h"
#include "terminal/palette.h"
#include "terminal/terminal.h"
#include "terminal/terminal_handlers.h"
#include "terminal/terminal-handlers.h"
#include "terminal/terminal-priv.h"
#include "terminal/types.h"
#include "terminal/xparsecolor.h"
@ -1226,7 +1227,7 @@ int guac_terminal_set_scrollback(guac_terminal* term, unsigned char c) {
/* Update scrollbar bounds */
guac_terminal_scrollbar_set_bounds(term->scrollbar,
-guac_terminal_available_scroll(term), 0);
-guac_terminal_get_available_scroll(term), 0);
/* Return to echo mode */
term->char_handler = guac_terminal_echo;

View File

@ -17,9 +17,9 @@
* under the License.
*/
#include "config.h"
#include "terminal/common.h"
#include "terminal/terminal.h"
#include "terminal/terminal-priv.h"
#include <guacamole/protocol.h>
#include <guacamole/socket.h>

View File

@ -17,7 +17,6 @@
* under the License.
*/
#include "config.h"
#include "common/clipboard.h"
#include "common/cursor.h"
@ -28,7 +27,8 @@
#include "terminal/palette.h"
#include "terminal/select.h"
#include "terminal/terminal.h"
#include "terminal/terminal_handlers.h"
#include "terminal/terminal-handlers.h"
#include "terminal/terminal-priv.h"
#include "terminal/types.h"
#include "terminal/typescript.h"
@ -185,10 +185,18 @@ static int guac_terminal_effective_buffer_length(guac_terminal* term) {
}
int guac_terminal_available_scroll(guac_terminal* term) {
int guac_terminal_get_available_scroll(guac_terminal* term) {
return guac_terminal_effective_buffer_length(term) - term->term_height;
}
int guac_terminal_get_rows(guac_terminal* term) {
return term->term_height;
}
int guac_terminal_get_columns(guac_terminal* term) {
return term->term_width;
}
void guac_terminal_reset(guac_terminal* term) {
int row;
@ -306,15 +314,12 @@ void* guac_terminal_thread(void* data) {
}
guac_terminal_options* guac_terminal_options_create(guac_client* client,
guac_common_clipboard* clipboard, int width, int height, int dpi) {
guac_terminal_options* guac_terminal_options_create(
int width, int height, int dpi) {
guac_terminal_options* options = malloc(sizeof(guac_terminal_options));
/* Set all required parameters */
options->client = client;
options->clipboard = clipboard;
options->width = width;
options->height = height;
options->dpi = dpi;
@ -330,7 +335,8 @@ guac_terminal_options* guac_terminal_options_create(guac_client* client,
return options;
}
guac_terminal* guac_terminal_create(guac_terminal_options* options) {
guac_terminal* guac_terminal_create(guac_client* client,
guac_terminal_options* options) {
/* The width and height may need to be changed from what's requested */
int width = options->width;
@ -352,7 +358,7 @@ guac_terminal* guac_terminal_create(guac_terminal_options* options) {
guac_terminal_color (*default_palette)[256] = (guac_terminal_color(*)[256])
malloc(sizeof(guac_terminal_color[256]));
guac_terminal_parse_color_scheme(options->client, options->color_scheme,
guac_terminal_parse_color_scheme(client, options->color_scheme,
&default_char.attributes.foreground,
&default_char.attributes.background,
default_palette);
@ -364,7 +370,7 @@ guac_terminal* guac_terminal_create(guac_terminal_options* options) {
guac_terminal* term = malloc(sizeof(guac_terminal));
term->started = false;
term->client = options->client;
term->client = client;
term->upload_path_handler = NULL;
term->file_download_handler = NULL;
@ -397,7 +403,7 @@ guac_terminal* guac_terminal_create(guac_terminal_options* options) {
&default_char);
/* Init display */
term->display = guac_terminal_display_alloc(options->client,
term->display = guac_terminal_display_alloc(client,
options->font_name, options->font_size, options->dpi,
&default_char.attributes.foreground,
&default_char.attributes.background,
@ -405,18 +411,18 @@ guac_terminal* guac_terminal_create(guac_terminal_options* options) {
/* Fail if display init failed */
if (term->display == NULL) {
guac_client_log(options->client, GUAC_LOG_DEBUG, "Display initialization failed");
guac_client_log(client, GUAC_LOG_DEBUG, "Display initialization failed");
free(term);
return NULL;
}
/* Init common cursor */
term->cursor = guac_common_cursor_alloc(options->client);
term->cursor = guac_common_cursor_alloc(client);
/* Init terminal state */
term->current_attributes = default_char.attributes;
term->default_char = default_char;
term->clipboard = options->clipboard;
term->clipboard = guac_common_clipboard_alloc();
term->disable_copy = options->disable_copy;
/* Calculate character size */
@ -546,6 +552,9 @@ void guac_terminal_free(guac_terminal* term) {
free((char*) term->color_scheme);
free((char*) term->font_name);
/* Free clipboard */
guac_common_clipboard_free(term->clipboard);
/* Free the terminal itself */
free(term);
@ -887,7 +896,7 @@ int guac_terminal_scroll_up(guac_terminal* term,
/* Reset scrollbar bounds */
guac_terminal_scrollbar_set_bounds(term->scrollbar,
-guac_terminal_available_scroll(term), 0);
-guac_terminal_get_available_scroll(term), 0);
/* Update cursor location if within region */
if (term->visible_cursor_row >= start_row &&
@ -1097,7 +1106,7 @@ void guac_terminal_scroll_display_up(guac_terminal* terminal,
int row, column;
/* Limit scroll amount by size of scrollback buffer */
int available_scroll = guac_terminal_available_scroll(terminal);
int available_scroll = guac_terminal_get_available_scroll(terminal);
if (terminal->scroll_offset + scroll_amount > available_scroll)
scroll_amount = available_scroll - terminal->scroll_offset;
@ -1298,7 +1307,7 @@ static void __guac_terminal_resize(guac_terminal* term, int width, int height) {
if (height > term->term_height) {
/* If undisplayed rows exist in the buffer, shift them into view */
int available_scroll = guac_terminal_available_scroll(term);
int available_scroll = guac_terminal_get_available_scroll(term);
if (available_scroll > 0) {
/* If the new terminal bottom reveals N rows, shift down N rows */
@ -1423,7 +1432,7 @@ int guac_terminal_resize(guac_terminal* terminal, int width, int height) {
/* Notify scrollbar of resize */
guac_terminal_scrollbar_parent_resized(terminal->scrollbar, width, height, rows);
guac_terminal_scrollbar_set_bounds(terminal->scrollbar,
-guac_terminal_available_scroll(terminal), 0);
-guac_terminal_get_available_scroll(terminal), 0);
/* Release terminal */
@ -2017,6 +2026,10 @@ void guac_terminal_apply_color_scheme(guac_terminal* terminal,
}
const char* guac_terminal_get_color_scheme(guac_terminal* terminal) {
return terminal->color_scheme;
}
void guac_terminal_apply_font(guac_terminal* terminal, const char* font_name,
int font_size, int dpi) {
@ -2055,3 +2068,40 @@ void guac_terminal_apply_font(guac_terminal* terminal, const char* font_name,
}
void guac_terminal_set_upload_path_handler(guac_terminal* terminal,
guac_terminal_upload_path_handler* upload_path_handler) {
terminal->upload_path_handler = upload_path_handler;
}
void guac_terminal_set_file_download_handler(guac_terminal* terminal,
guac_terminal_file_download_handler* file_download_handler) {
terminal->file_download_handler = file_download_handler;
}
const char* guac_terminal_get_font_name(guac_terminal* terminal) {
return terminal->font_name;
}
int guac_terminal_get_font_size(guac_terminal* terminal) {
return terminal->font_size;
}
int guac_terminal_get_mod_ctrl(guac_terminal* terminal) {
return terminal->mod_ctrl;
}
void guac_terminal_clipboard_reset(guac_terminal* terminal,
const char* mimetype) {
guac_common_clipboard_reset(terminal->clipboard, mimetype);
}
void guac_terminal_clipboard_append(guac_terminal* terminal,
const char* data, int length) {
guac_common_clipboard_append(terminal->clipboard, data, length);
}
void guac_terminal_remove_user(guac_terminal* terminal, guac_user* user) {
/* Remove the user from the terminal cursor */
guac_common_cursor_remove_user(terminal->cursor, user);
}

View File

@ -21,7 +21,13 @@
#ifndef _GUAC_TERMINAL_BUFFER_H
#define _GUAC_TERMINAL_BUFFER_H
#include "config.h"
/**
* Data structures and functions related to the terminal buffer.
*
* @file buffer.h
*/
#include "types.h"

View File

@ -21,7 +21,12 @@
#ifndef _GUAC_TERMINAL_CHAR_MAPPINGS_H
#define _GUAC_TERMINAL_CHAR_MAPPINGS_H
#include "config.h"
/**
* Graphics character mapping definitions.
*
* @file char-mappings.h
*/
/**
* VT100 graphics mapping. Each entry is the corresponding Unicode codepoint

View File

@ -20,9 +20,14 @@
#ifndef GUAC_TERMINAL_COLOR_SCHEME_H
#define GUAC_TERMINAL_COLOR_SCHEME_H
#include "config.h"
/**
* Definitions and functions related to color scheme handling.
*
* @file color-scheme.h
*/
#include "terminal/palette.h"
#include "palette.h"
#include <guacamole/client.h>

View File

@ -21,7 +21,12 @@
#ifndef _GUAC_TERMINAL_COMMON_H
#define _GUAC_TERMINAL_COMMON_H
#include "config.h"
/**
* Miscellaneous terminal function definitions.
*
* @file common.h
*/
#include "types.h"
#include <stdbool.h>

View File

@ -21,7 +21,12 @@
#ifndef _GUAC_TERMINAL_DISPLAY_H
#define _GUAC_TERMINAL_DISPLAY_H
#include "config.h"
/**
* Structures and function definitions related to the graphical display.
*
* @file display.h
*/
#include "common/surface.h"
#include "palette.h"

View File

@ -20,8 +20,13 @@
#ifndef GUAC_TERMINAL_NAMED_COLORS_H
#define GUAC_TERMINAL_NAMED_COLORS_H
#include "config.h"
#include "terminal/palette.h"
/**
* Function definitions for operating on individual terminal colors.
*
* @file named-colors.h
*/
#include "palette.h"
/**
* Searches for the color having the given name, storing that color within the

View File

@ -20,7 +20,12 @@
#ifndef GUAC_TERMINAL_PALETTE_H
#define GUAC_TERMINAL_PALETTE_H
#include "config.h"
/**
* Constants, structures, and function definitions related to the terminal color pallate.
*
* @file palette.h
*/
#include <stdint.h>

View File

@ -20,7 +20,12 @@
#ifndef GUAC_TERMINAL_SCROLLBAR_H
#define GUAC_TERMINAL_SCROLLBAR_H
#include "config.h"
/**
* Constants, structures, and function definitions related to the terminal scrollbar.
*
* @file scrollbar.h
*/
#include <guacamole/client.h>
#include <guacamole/layer.h>

View File

@ -21,7 +21,12 @@
#ifndef GUAC_TERMINAL_SELECT_H
#define GUAC_TERMINAL_SELECT_H
#include "config.h"
/**
* Function definitions related to selecting text withing a terminal.
*
* @file select.h
*/
#include "terminal.h"
#include <stdbool.h>

View File

@ -21,8 +21,15 @@
#ifndef _GUAC_TERMINAL_HANDLERS
#define _GUAC_TERMINAL_HANDLERS
/**
* Function definitions for terminal event handlers.
*
* @file terminal-handlers.h
*/
#include "config.h"
#include "display.h"
#include "terminal.h"
/**

View File

@ -0,0 +1,640 @@
/*
* 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_TERMINAL_PRIV_H
#define GUAC_TERMINAL_PRIV_H
#include "common/clipboard.h"
#include "common/cursor.h"
#include "buffer.h"
#include "display.h"
#include "scrollbar.h"
#include "terminal.h"
#include "typescript.h"
struct guac_terminal {
/**
* The Guacamole client associated with this terminal emulator.
*/
guac_client* client;
/**
* Whether user input should be handled and this terminal should render
* frames. Initially, this will be false, user input will be ignored, and
* rendering of frames will be withheld until guac_terminal_start() has
* been invoked. The data within frames will still be rendered, and text
* data received will still be handled, however actual frame boundaries
* will not be sent.
*/
bool started;
/**
* The terminal render thread.
*/
pthread_t thread;
/**
* Called whenever the necessary terminal codes are sent to change
* the path for future file uploads.
*/
guac_terminal_upload_path_handler* upload_path_handler;
/**
* Called whenever the necessary terminal codes are sent to initiate
* a download of a given remote file.
*/
guac_terminal_file_download_handler* file_download_handler;
/**
* Lock which restricts simultaneous access to this terminal via the root
* guac_terminal_* functions.
*/
pthread_mutex_t lock;
/**
* The mutex associated with the modified condition and flag, locked
* whenever a thread is waiting on the modified condition, the modified
* condition is being signalled, or the modified flag is being changed.
*/
pthread_mutex_t modified_lock;
/**
* Flag set whenever an operation has affected the terminal in a way that
* will require a frame flush. When this flag is set, the modified_cond
* condition will be signalled. The modified_lock will always be
* acquired before this flag is altered.
*/
int modified;
/**
* Condition which is signalled when the modified flag has been set
*/
pthread_cond_t modified_cond;
/**
* Pipe which will be the source of user input. When a terminal code
* generates synthesized user input, that data will be written to
* this pipe.
*/
int stdin_pipe_fd[2];
/**
* The currently-open pipe stream from which all terminal input should be
* read, if any. If no pipe stream is open, terminal input will be received
* through keyboard, clipboard, and mouse events, and this value will be
* NULL.
*/
guac_stream* input_stream;
/**
* The currently-open pipe stream to which all terminal output should be
* written, if any. If no pipe stream is open, terminal output will be
* written to the terminal display, and this value will be NULL.
*/
guac_stream* pipe_stream;
/**
* Bitwise OR of all flags which apply to the currently-open pipe stream.
* If no pipe stream is open, this value has no meaning, and its contents
* are undefined.
*
* @see GUAC_TERMINAL_PIPE_INTERPRET_OUTPUT
* @see GUAC_TERMINAL_PIPE_AUTOFLUSH
*/
int pipe_stream_flags;
/**
* Buffer of data pending write to the pipe_stream. Data within this buffer
* will be flushed to the pipe_stream when either (1) the buffer is full
* and another character needs to be written or (2) the pipe_stream is
* closed.
*/
char pipe_buffer[6048];
/**
* The number of bytes currently stored within the pipe_buffer.
*/
int pipe_buffer_length;
/**
* The currently-active typescript recording all terminal output, or NULL
* if no typescript is being used for the terminal session.
*/
guac_terminal_typescript* typescript;
/**
* Terminal-wide mouse cursor, synchronized across all users.
*/
guac_common_cursor* cursor;
/**
* Graphical representation of the current scroll state.
*/
guac_terminal_scrollbar* scrollbar;
/**
* The relative offset of the display. A positive value indicates that
* many rows have been scrolled into view, zero indicates that no
* scrolling has occurred. Negative values are illegal.
*/
int scroll_offset;
/**
* The maximum number of rows to allow within the terminal buffer. Note
* that while this value is traditionally referred to as the scrollback
* size, it actually encompasses both the display and the off-screen
* region. The terminal will ensure enough buffer space is allocated for
* the on-screen rows, even if this exceeds the defined maximum, however
* additional rows for off-screen data will only be available if the
* display is smaller than this value.
*/
int max_scrollback;
/**
* The number of rows that the user has requested be avalable within the
* terminal buffer. This value may be adjusted by the user while the
* terminal is running through console codes, and will adjust the number
* of rows available within the terminal buffer, subject to the maximum
* defined at terminal creation and stored within max_scrollback.
*/
int requested_scrollback;
/**
* The width of the space available to all components of the terminal, in
* pixels. This may include space which will not actually be used for
* character rendering.
*/
int outer_width;
/**
* The height of the space available to all components of the terminal, in
* pixels. This may include space which will not actually be used for
* character rendering.
*/
int outer_height;
/**
* The width of the terminal, in pixels.
*/
int width;
/**
* The height of the terminal, in pixels.
*/
int height;
/**
* The width of the terminal, in characters.
*/
int term_width;
/**
* The height of the terminal, in characters.
*/
int term_height;
/**
* The index of the first row in the scrolling region.
*/
int scroll_start;
/**
* The index of the last row in the scrolling region.
*/
int scroll_end;
/**
* The current row location of the cursor. Note that while most terminal
* operations will clip the cursor location within the bounds of the
* terminal, this is not guaranteed.
*/
int cursor_row;
/**
* The current column location of the cursor. Note that while most
* terminal operations will clip the cursor location within the bounds
* of the terminal, this is not guaranteed. There are times when the
* cursor is legitimately outside the terminal bounds (such as when the
* end of a line is reached, but it is not yet necessary to scroll up).
*/
int cursor_col;
/**
* The desired visibility state of the cursor.
*/
bool cursor_visible;
/**
* The row of the rendered cursor.
* Will be set to -1 if the cursor is not visible.
*/
int visible_cursor_row;
/**
* The column of the rendered cursor.
* Will be set to -1 if the cursor is not visible.
*/
int visible_cursor_col;
/**
* The row of the saved cursor (ESC 7).
*/
int saved_cursor_row;
/**
* The column of the saved cursor (ESC 7).
*/
int saved_cursor_col;
/**
* The attributes which will be applied to future characters.
*/
guac_terminal_attributes current_attributes;
/**
* The character whose attributes dictate the default attributes
* of all characters. When new screen space is allocated, this
* character fills the gaps.
*/
guac_terminal_char default_char;
/**
* Handler which will receive all printed characters, updating the terminal
* accordingly.
*/
guac_terminal_char_handler* char_handler;
/**
* The difference between the currently-rendered screen and the current
* state of the terminal, and the contextual information necessary to
* interpret and render those differences.
*/
guac_terminal_display* display;
/**
* Current terminal display state. All characters present on the screen
* are within this buffer. This has nothing to do with the display, which
* facilitates transfer of a set of changes to the remote display.
*/
guac_terminal_buffer* buffer;
/**
* Automatically place a tabstop every N characters. If zero, then no
* tabstops exist automatically.
*/
int tab_interval;
/**
* Array of all tabs set. Each entry is the column number of a tab + 1,
* or 0 if that tab cell is unset.
*/
int custom_tabs[GUAC_TERMINAL_MAX_TABS];
/**
* Array of arrays of mapped characters, where the character N is located at the N-32
* position within the array. Each element in a contained array is the corresponding Unicode
* codepoint. If NULL, a direct mapping from Unicode is used. The entries of the main array
* correspond to the character set in use (G0, G1, etc.)
*/
const int* char_mapping[2];
/**
* The active character set. For example, 0 for G0, 1 for G1, etc.
*/
int active_char_set;
/**
* Whether text is currently selected.
*/
bool text_selected;
/**
* Whether the selection is finished, and will no longer be modified. A
* committed selection remains highlighted for reference, but the
* highlight will be removed if characters within the selected region are
* modified.
*/
bool selection_committed;
/**
* The row that the selection starts at.
*/
int selection_start_row;
/**
* The column that the selection starts at.
*/
int selection_start_column;
/**
* The width of the character at selection start.
*/
int selection_start_width;
/**
* The row that the selection ends at.
*/
int selection_end_row;
/**
* The column that the selection ends at.
*/
int selection_end_column;
/**
* The width of the character at selection end.
*/
int selection_end_width;
/**
* Whether the cursor (arrow) keys should send cursor sequences
* or application sequences (DECCKM).
*/
bool application_cursor_keys;
/**
* Whether a CR should automatically follow a LF, VT, or FF.
*/
bool automatic_carriage_return;
/**
* Whether insert mode is enabled (DECIM).
*/
bool insert_mode;
/**
* Whether the alt key is currently being held down.
*/
int mod_alt;
/**
* Whether the control key is currently being held down.
*/
int mod_ctrl;
/**
* Whether the shift key is currently being held down.
*/
int mod_shift;
/**
* The current mouse button state.
*/
int mouse_mask;
/**
* The current mouse cursor, to avoid re-setting the cursor image.
*/
guac_terminal_cursor_type current_cursor;
/**
* The current contents of the clipboard. This clipboard instance is
* maintained externally (will not be freed when this terminal is freed)
* and will be updated both internally by the terminal and externally
* through received clipboard instructions.
*/
guac_common_clipboard* clipboard;
/**
* The name of the font to use when rendering glyphs, as requested at
* creation time or via guac_terminal_apply_font().
*/
const char* font_name;
/**
* The size of each glyph, in points, as requested at creation time or via
* guac_terminal_apply_font().
*/
int font_size;
/**
* The name of the color scheme to use, as requested at creation time or
* via guac_terminal_apply_color_scheme(). This string must be in the
* format accepted by guac_terminal_parse_color_scheme().
*/
const char* color_scheme;
/**
* ASCII character to send when backspace is pressed.
*/
char backspace;
/**
* Whether copying from the terminal clipboard should be blocked. If set,
* the contents of the terminal can still be copied, but will be usable
* only within the terminal itself. The clipboard contents will not be
* automatically streamed to the client.
*/
bool disable_copy;
};
/**
* Handles a scroll event received from the scrollbar associated with a
* terminal.
*
* @param scrollbar
* The scrollbar that has been scrolled.
*
* @param value
* The new value that should be stored within the scrollbar, and
* represented within the terminal display.
*/
void guac_terminal_scroll_handler(guac_terminal_scrollbar* scrollbar, int value);
/**
* Sets the given range of columns within the given row to the given
* character.
*/
void guac_terminal_set_columns(guac_terminal* terminal, int row,
int start_column, int end_column, guac_terminal_char* character);
/**
* Acquires exclusive access to the terminal. Note that enforcing this
* exclusive access requires that ALL users of the terminal call this
* function before making further calls to the terminal.
*/
void guac_terminal_lock(guac_terminal* terminal);
/**
* Releases exclusive access to the terminal.
*/
void guac_terminal_unlock(guac_terminal* terminal);
/**
* Resets the state of the given terminal, as if it were just allocated.
*/
void guac_terminal_reset(guac_terminal* term);
/**
* Sets the character at the given row and column to the specified value.
*/
int guac_terminal_set(guac_terminal* term, int row, int col, int codepoint);
/**
* Clears the given region within a single row.
*/
int guac_terminal_clear_columns(guac_terminal* term,
int row, int start_col, int end_col);
/**
* Clears the given region from right-to-left, top-to-bottom, replacing
* all characters with the current background color and attributes.
*/
int guac_terminal_clear_range(guac_terminal* term,
int start_row, int start_col,
int end_row, int end_col);
/**
* Scrolls the terminal's current scroll region up by one row.
*/
int guac_terminal_scroll_up(guac_terminal* term,
int start_row, int end_row, int amount);
/**
* Scrolls the terminal's current scroll region down by one row.
*/
int guac_terminal_scroll_down(guac_terminal* term,
int start_row, int end_row, int amount);
/**
* Commits the current cursor location, updating the visible cursor
* on the screen.
*/
void guac_terminal_commit_cursor(guac_terminal* term);
/**
* Scroll down the display by the given amount, replacing the new space with
* data from the buffer. If not enough data is available, the maximum
* amount will be scrolled.
*/
void guac_terminal_scroll_display_down(guac_terminal* terminal, int amount);
/**
* Scroll up the display by the given amount, replacing the new space with data
* from either the buffer or the terminal buffer. If not enough data is
* available, the maximum amount will be scrolled.
*/
void guac_terminal_scroll_display_up(guac_terminal* terminal, int amount);
/**
* Opens a new pipe stream, redirecting all output from the given terminal to
* that pipe stream. If a pipe stream is already open, that pipe stream will
* be flushed and closed prior to opening the new pipe stream.
*
* @param term
* The terminal which should redirect output to a new pipe stream having
* the given name.
*
* @param name
* The name of the pipe stream to open.
*
* @param flags
* A bitwise OR of all integer flags which should apply to the new pipe
* stream.
*
* @see GUAC_TERMINAL_PIPE_INTERPRET_OUTPUT
* @see GUAC_TERMINAL_PIPE_AUTOFLUSH
*/
void guac_terminal_pipe_stream_open(guac_terminal* term, const char* name,
int flags);
/**
* Writes a single byte of data to the pipe stream currently open and
* associated with the given terminal. The pipe stream must already have been
* opened via guac_terminal_pipe_stream_open(). If no pipe stream is currently
* open, this function has no effect. Data written through this function may
* be buffered.
*
* @param term
* The terminal whose currently-open pipe stream should be written to.
*
* @param c
* The byte of data to write to the pipe stream.
*/
void guac_terminal_pipe_stream_write(guac_terminal* term, char c);
/**
* Flushes any data currently buffered for the currently-open pipe stream
* associated with the given terminal. The pipe stream must already have been
* opened via guac_terminal_pipe_stream_open(). If no pipe stream is currently
* open or no data is in the buffer, this function has no effect.
*
* @param term
* The terminal whose pipe stream buffer should be flushed.
*/
void guac_terminal_pipe_stream_flush(guac_terminal* term);
/**
* Closes the currently-open pipe stream associated with the given terminal,
* redirecting all output back to the terminal display. Any data currently
* buffered for output to the pipe stream will be flushed prior to closure. The
* pipe stream must already have been opened via
* guac_terminal_pipe_stream_open(). If no pipe stream is currently open, this
* function has no effect.
*
* @param term
* The terminal whose currently-open pipe stream should be closed.
*/
void guac_terminal_pipe_stream_close(guac_terminal* term);
/**
* Sets a tabstop in the given column.
*/
void guac_terminal_set_tab(guac_terminal* term, int column);
/**
* Removes the tabstop at the given column.
*/
void guac_terminal_unset_tab(guac_terminal* term, int column);
/**
* Removes all tabstops.
*/
void guac_terminal_clear_tabs(guac_terminal* term);
/**
* Given a column within the given terminal, returns the location of the
* next tabstop (or the rightmost character, if no more tabstops exist).
*/
int guac_terminal_next_tab(guac_terminal* term, int column);
/**
* Copies the given range of columns to a new location, offset from
* the original by the given number of columns.
*/
void guac_terminal_copy_columns(guac_terminal* terminal, int row,
int start_column, int end_column, int offset);
/**
* Copies the given range of rows to a new location, offset from the
* original by the given number of rows.
*/
void guac_terminal_copy_rows(guac_terminal* terminal,
int start_row, int end_row, int offset);
/**
* Flushes all pending operations within the given guac_terminal.
*/
void guac_terminal_flush(guac_terminal* terminal);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,13 @@
#ifndef _GUAC_TERMINAL_TYPES_H
#define _GUAC_TERMINAL_TYPES_H
#include "config.h"
/**
* Structures and function definitions related to individual characters
* within the terminal.
*
* @file types.h
*/
#include "palette.h"
#include <stdbool.h>

View File

@ -21,7 +21,13 @@
#ifndef GUAC_TERMINAL_TYPESCRIPT_H
#define GUAC_TERMINAL_TYPESCRIPT_H
#include "config.h"
/**
* Constants, structures, and function definitions related to terminal
* typescripts.
*
* @file typescript.h
*/
#include <guacamole/timestamp.h>

View File

@ -20,9 +20,14 @@
#ifndef GUAC_TERMINAL_XPARSECOLOR_H
#define GUAC_TERMINAL_XPARSECOLOR_H
#include "config.h"
/**
* Function definitions related to handling X11 color specs.
*
* @file xparsecolor.h
*/
#include "terminal/palette.h"
#include "palette.h"
/**
* Parses an X11 color spec, as defined by Xlib's XParseColor(), storing the

View File

@ -17,7 +17,6 @@
* under the License.
*/
#include "config.h"
#include "common/io.h"
#include "terminal/typescript.h"

View File

@ -17,7 +17,6 @@
* under the License.
*/
#include "config.h"
#include "terminal/named-colors.h"
#include "terminal/palette.h"