GUACAMOLE-478: Add optional clipboard line ending normalization for RDP.
This commit is contained in:
parent
7472310a03
commit
09bd4af77e
@ -352,10 +352,11 @@ static UINT guac_rdp_cliprdr_format_data_request(CliprdrClientContext* cliprdr,
|
|||||||
|
|
||||||
guac_client* client = clipboard->client;
|
guac_client* client = clipboard->client;
|
||||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||||
|
guac_rdp_settings* settings = rdp_client->settings;
|
||||||
|
|
||||||
guac_client_log(client, GUAC_LOG_TRACE, "CLIPRDR: Received format data request.");
|
guac_client_log(client, GUAC_LOG_TRACE, "CLIPRDR: Received format data request.");
|
||||||
|
|
||||||
guac_iconv_write* writer;
|
guac_iconv_write* remote_writer;
|
||||||
const char* input = clipboard->clipboard->buffer;
|
const char* input = clipboard->clipboard->buffer;
|
||||||
char* output = malloc(GUAC_RDP_CLIPBOARD_MAX_LENGTH);
|
char* output = malloc(GUAC_RDP_CLIPBOARD_MAX_LENGTH);
|
||||||
|
|
||||||
@ -363,11 +364,11 @@ static UINT guac_rdp_cliprdr_format_data_request(CliprdrClientContext* cliprdr,
|
|||||||
switch (format_data_request->requestedFormatId) {
|
switch (format_data_request->requestedFormatId) {
|
||||||
|
|
||||||
case CF_TEXT:
|
case CF_TEXT:
|
||||||
writer = GUAC_WRITE_CP1252;
|
remote_writer = settings->clipboard_crlf ? GUAC_WRITE_CP1252_CRLF : GUAC_WRITE_CP1252;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CF_UNICODETEXT:
|
case CF_UNICODETEXT:
|
||||||
writer = GUAC_WRITE_UTF16;
|
remote_writer = settings->clipboard_crlf ? GUAC_WRITE_UTF16_CRLF : GUAC_WRITE_UTF16;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Warn if clipboard data cannot be sent as intended due to a violation
|
/* Warn if clipboard data cannot be sent as intended due to a violation
|
||||||
@ -386,8 +387,9 @@ static UINT guac_rdp_cliprdr_format_data_request(CliprdrClientContext* cliprdr,
|
|||||||
/* Send received clipboard data to the RDP server in the format
|
/* Send received clipboard data to the RDP server in the format
|
||||||
* requested */
|
* requested */
|
||||||
BYTE* start = (BYTE*) output;
|
BYTE* start = (BYTE*) output;
|
||||||
guac_iconv(GUAC_READ_UTF8, &input, clipboard->clipboard->length,
|
guac_iconv_read* local_reader = settings->normalize_clipboard ? GUAC_READ_UTF8_NORMALIZED : GUAC_READ_UTF8;
|
||||||
writer, &output, GUAC_RDP_CLIPBOARD_MAX_LENGTH);
|
guac_iconv(local_reader, &input, clipboard->clipboard->length,
|
||||||
|
remote_writer, &output, GUAC_RDP_CLIPBOARD_MAX_LENGTH);
|
||||||
|
|
||||||
CLIPRDR_FORMAT_DATA_RESPONSE data_response = {
|
CLIPRDR_FORMAT_DATA_RESPONSE data_response = {
|
||||||
.requestedFormatData = (BYTE*) start,
|
.requestedFormatData = (BYTE*) start,
|
||||||
@ -449,7 +451,7 @@ static UINT guac_rdp_cliprdr_format_data_response(CliprdrClientContext* cliprdr,
|
|||||||
|
|
||||||
char received_data[GUAC_RDP_CLIPBOARD_MAX_LENGTH];
|
char received_data[GUAC_RDP_CLIPBOARD_MAX_LENGTH];
|
||||||
|
|
||||||
guac_iconv_read* reader;
|
guac_iconv_read* remote_reader;
|
||||||
const char* input = (char*) format_data_response->requestedFormatData;
|
const char* input = (char*) format_data_response->requestedFormatData;
|
||||||
char* output = received_data;
|
char* output = received_data;
|
||||||
|
|
||||||
@ -458,12 +460,12 @@ static UINT guac_rdp_cliprdr_format_data_response(CliprdrClientContext* cliprdr,
|
|||||||
|
|
||||||
/* Non-Unicode (Windows CP-1252) */
|
/* Non-Unicode (Windows CP-1252) */
|
||||||
case CF_TEXT:
|
case CF_TEXT:
|
||||||
reader = GUAC_READ_CP1252;
|
remote_reader = settings->normalize_clipboard ? GUAC_READ_CP1252_NORMALIZED : GUAC_READ_CP1252;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Unicode (UTF-16) */
|
/* Unicode (UTF-16) */
|
||||||
case CF_UNICODETEXT:
|
case CF_UNICODETEXT:
|
||||||
reader = GUAC_READ_UTF16;
|
remote_reader = settings->normalize_clipboard ? GUAC_READ_UTF16_NORMALIZED : GUAC_READ_UTF16;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* If the format ID stored within the guac_rdp_clipboard structure is actually
|
/* If the format ID stored within the guac_rdp_clipboard structure is actually
|
||||||
@ -481,7 +483,7 @@ static UINT guac_rdp_cliprdr_format_data_response(CliprdrClientContext* cliprdr,
|
|||||||
|
|
||||||
/* Convert, store, and forward the clipboard data received from RDP
|
/* Convert, store, and forward the clipboard data received from RDP
|
||||||
* server */
|
* server */
|
||||||
if (guac_iconv(reader, &input, format_data_response->dataLen,
|
if (guac_iconv(remote_reader, &input, format_data_response->dataLen,
|
||||||
GUAC_WRITE_UTF8, &output, sizeof(received_data))) {
|
GUAC_WRITE_UTF8, &output, sizeof(received_data))) {
|
||||||
int length = strnlen(received_data, sizeof(received_data));
|
int length = strnlen(received_data, sizeof(received_data));
|
||||||
guac_common_clipboard_reset(clipboard->clipboard, "text/plain");
|
guac_common_clipboard_reset(clipboard->clipboard, "text/plain");
|
||||||
|
@ -130,6 +130,7 @@ const char* GUAC_RDP_CLIENT_ARGS[] = {
|
|||||||
"wol-wait-time",
|
"wol-wait-time",
|
||||||
|
|
||||||
"force-lossless",
|
"force-lossless",
|
||||||
|
"normalize-clipboard",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -647,6 +648,16 @@ enum RDP_ARGS_IDX {
|
|||||||
*/
|
*/
|
||||||
IDX_FORCE_LOSSLESS,
|
IDX_FORCE_LOSSLESS,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls whether the text content of the clipboard should be
|
||||||
|
* automatically normalized to use a particular line ending format. Valid
|
||||||
|
* values are "preserve", to preserve line endings verbatim, "windows" to
|
||||||
|
* transform all line endings to Windows-style CRLF sequences, or "unix" to
|
||||||
|
* transform all line endings to Unix-style newline characters ('\n'). By
|
||||||
|
* default, line endings within the clipboard are preserved.
|
||||||
|
*/
|
||||||
|
IDX_NORMALIZE_CLIPBOARD,
|
||||||
|
|
||||||
RDP_ARGS_COUNT
|
RDP_ARGS_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1167,7 +1178,36 @@ guac_rdp_settings* guac_rdp_parse_args(guac_user* user,
|
|||||||
settings->disable_paste =
|
settings->disable_paste =
|
||||||
guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,
|
guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,
|
||||||
IDX_DISABLE_PASTE, 0);
|
IDX_DISABLE_PASTE, 0);
|
||||||
|
|
||||||
|
/* Normalize clipboard line endings to Unix format */
|
||||||
|
if (strcmp(argv[IDX_NORMALIZE_CLIPBOARD], "unix") == 0) {
|
||||||
|
guac_user_log(user, GUAC_LOG_INFO, "Clipboard line ending normalization: Unix (LF)");
|
||||||
|
settings->normalize_clipboard = 1;
|
||||||
|
settings->clipboard_crlf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Normalize clipboard line endings to Windows format */
|
||||||
|
else if (strcmp(argv[IDX_NORMALIZE_CLIPBOARD], "windows") == 0) {
|
||||||
|
guac_user_log(user, GUAC_LOG_INFO, "Clipboard line ending normalization: Windows (CRLF)");
|
||||||
|
settings->normalize_clipboard = 1;
|
||||||
|
settings->clipboard_crlf = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Preserve clipboard line ending format */
|
||||||
|
else if (strcmp(argv[IDX_NORMALIZE_CLIPBOARD], "preserve") == 0) {
|
||||||
|
guac_user_log(user, GUAC_LOG_INFO, "Clipboard line ending normalization: Preserve (none)");
|
||||||
|
settings->normalize_clipboard = 0;
|
||||||
|
settings->clipboard_crlf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If nothing given, default to preserving line endings */
|
||||||
|
else {
|
||||||
|
guac_user_log(user, GUAC_LOG_INFO, "No clipboard line-ending normalization specified. Defaulting to preserving the format of all line endings.");
|
||||||
|
settings->normalize_clipboard = 0;
|
||||||
|
settings->clipboard_crlf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Parse Wake-on-LAN (WoL) settings */
|
/* Parse Wake-on-LAN (WoL) settings */
|
||||||
settings->wol_send_packet =
|
settings->wol_send_packet =
|
||||||
guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,
|
guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,
|
||||||
|
@ -323,6 +323,19 @@ typedef struct guac_rdp_settings {
|
|||||||
*/
|
*/
|
||||||
int disable_paste;
|
int disable_paste;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether line endings within the clipboard should be automatically
|
||||||
|
* normalized to Unix-style newline characters.
|
||||||
|
*/
|
||||||
|
int normalize_clipboard;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether Unix-style newline characters within the clipboard should be
|
||||||
|
* automatically translated to CRLF sequences before transmission to the
|
||||||
|
* RDP server.
|
||||||
|
*/
|
||||||
|
int clipboard_crlf;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the desktop wallpaper should be visible. If unset, the desktop
|
* Whether the desktop wallpaper should be visible. If unset, the desktop
|
||||||
* wallpaper will be hidden, reducing the amount of bandwidth required.
|
* wallpaper will be hidden, reducing the amount of bandwidth required.
|
||||||
|
Loading…
Reference in New Issue
Block a user