diff --git a/client/common/cmdline.c b/client/common/cmdline.c index b1e6b0466..a6fa301de 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -1753,6 +1753,32 @@ static PARSE_ON_OFF_RESULT parse_on_off_option(const char* value) return PARSE_FAIL; } +typedef enum +{ + CLIP_DIR_PARSE_ALL, + CLIP_DIR_PARSE_OFF, + CLIP_DIR_PARSE_LOCAL, + CLIP_DIR_PARSE_REMOTE, + CLIP_DIR_PARSE_FAIL +} PARSE_CLIP_DIR_RESULT; + +static PARSE_CLIP_DIR_RESULT parse_clip_direciton_to_option(const char* value) +{ + WINPR_ASSERT(value); + const char* sep = strchr(value, ':'); + if (!sep) + return CLIP_DIR_PARSE_FAIL; + if (option_equals("all", &sep[1])) + return CLIP_DIR_PARSE_ALL; + if (option_equals("off", &sep[1])) + return CLIP_DIR_PARSE_OFF; + if (option_equals("local", &sep[1])) + return CLIP_DIR_PARSE_LOCAL; + if (option_equals("remote", &sep[1])) + return CLIP_DIR_PARSE_REMOTE; + return CLIP_DIR_PARSE_FAIL; +} + static int parse_tls_ciphers(rdpSettings* settings, const char* Value) { const char* ciphers = NULL; @@ -3353,6 +3379,69 @@ static int freerdp_client_settings_parse_command_line_arguments_int(rdpSettings* rc = COMMAND_LINE_ERROR_MEMORY; settings->RedirectClipboard = TRUE; } + else if (option_starts_with("direction-to", cur)) + { + const UINT32 mask = + freerdp_settings_get_uint32(settings, FreeRDP_ClipboardFeatureMask) & + ~(CLIPRDR_FLAG_LOCAL_TO_REMOTE | CLIPRDR_FLAG_REMOTE_TO_LOCAL); + const PARSE_CLIP_DIR_RESULT bval = parse_clip_direciton_to_option(cur); + UINT32 flags = 0; + switch (bval) + { + case CLIP_DIR_PARSE_ALL: + flags |= + CLIPRDR_FLAG_LOCAL_TO_REMOTE | CLIPRDR_FLAG_REMOTE_TO_LOCAL; + break; + case CLIP_DIR_PARSE_LOCAL: + flags |= CLIPRDR_FLAG_REMOTE_TO_LOCAL; + break; + case CLIP_DIR_PARSE_REMOTE: + flags |= CLIPRDR_FLAG_LOCAL_TO_REMOTE; + break; + case CLIP_DIR_PARSE_OFF: + break; + case CLIP_DIR_PARSE_FAIL: + default: + rc = COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + break; + } + + if (!freerdp_settings_set_uint32(settings, FreeRDP_ClipboardFeatureMask, + mask | flags)) + rc = COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + } + else if (option_starts_with("files-to", cur)) + { + const UINT32 mask = + freerdp_settings_get_uint32(settings, FreeRDP_ClipboardFeatureMask) & + ~(CLIPRDR_FLAG_LOCAL_TO_REMOTE_FILES | + CLIPRDR_FLAG_REMOTE_TO_LOCAL_FILES); + const PARSE_CLIP_DIR_RESULT bval = parse_clip_direciton_to_option(cur); + UINT32 flags = 0; + switch (bval) + { + case CLIP_DIR_PARSE_ALL: + flags |= CLIPRDR_FLAG_LOCAL_TO_REMOTE_FILES | + CLIPRDR_FLAG_REMOTE_TO_LOCAL_FILES; + break; + case CLIP_DIR_PARSE_LOCAL: + flags |= CLIPRDR_FLAG_REMOTE_TO_LOCAL_FILES; + break; + case CLIP_DIR_PARSE_REMOTE: + flags |= CLIPRDR_FLAG_LOCAL_TO_REMOTE_FILES; + break; + case CLIP_DIR_PARSE_OFF: + break; + case CLIP_DIR_PARSE_FAIL: + default: + rc = COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + break; + } + + if (!freerdp_settings_set_uint32(settings, FreeRDP_ClipboardFeatureMask, + mask | flags)) + rc = COMMAND_LINE_ERROR_UNEXPECTED_VALUE; + } else rc = COMMAND_LINE_ERROR_UNEXPECTED_VALUE; } diff --git a/client/common/cmdline.h b/client/common/cmdline.h index 7a7a67362..4d2301ce8 100644 --- a/client/common/cmdline.h +++ b/client/common/cmdline.h @@ -116,7 +116,9 @@ static const COMMAND_LINE_ARGUMENT_A global_cmd_args[] = { "Client Build Number sent to server (influences smartcard behaviour, see [MS-RDPESC])" }, { "client-hostname", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Client Hostname to send to server" }, - { "clipboard", COMMAND_LINE_VALUE_BOOL | COMMAND_LINE_VALUE_OPTIONAL, "[use-selection:]", + { "clipboard", COMMAND_LINE_VALUE_BOOL | COMMAND_LINE_VALUE_OPTIONAL, + "[[use-selection:],[direction-to:[all|local|remote|off]],[files-to[:all|local|remote|" + "off]]],", BoolValueTrue, NULL, -1, NULL, "Redirect clipboard. " " * use-selection: ... (X11) Specify which X selection to access. Default is "