Command-line option to choose an X selection.

I personally find it more convenient to have pasted data written to
the X11 PRIMARY selection, so that I can paste it with a fast middle-
button click, than to write to CLIPBOARD which typically needs a key
sequence or menu action.

This commit adds a command-line option to let me express that
preference: now I can say "/clipboard:use-selection:PRIMARY" on the
command line, which not only enables clipboard transfer but also says
which X selection I want it to talk to. The previous options
"+clipboard" and "-clipboard" are also still supported.
This commit is contained in:
Simon Tatham 2020-03-18 20:59:12 +00:00 committed by akallabeth
parent c90479c7f5
commit 1dc8198803
5 changed files with 49 additions and 5 deletions

View File

@ -1668,6 +1668,7 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
int i, n = 0;
rdpChannels* channels;
xfClipboard* clipboard;
const char* selectionAtom;
if (!(clipboard = (xfClipboard*)calloc(1, sizeof(xfClipboard))))
{
@ -1682,11 +1683,14 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
clipboard->system = ClipboardCreate();
clipboard->requestedFormatId = -1;
clipboard->root_window = DefaultRootWindow(xfc->display);
clipboard->clipboard_atom = XInternAtom(xfc->display, "CLIPBOARD", FALSE);
selectionAtom = "CLIPBOARD";
if (xfc->context.settings->XSelectionAtom)
selectionAtom = xfc->context.settings->XSelectionAtom;
clipboard->clipboard_atom = XInternAtom(xfc->display, selectionAtom, FALSE);
if (clipboard->clipboard_atom == None)
{
WLog_ERR(TAG, "unable to get CLIPBOARD atom");
WLog_ERR(TAG, "unable to get %s atom", selectionAtom);
goto error;
}

View File

@ -2340,7 +2340,36 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
}
CommandLineSwitchCase(arg, "clipboard")
{
settings->RedirectClipboard = enable;
if (arg->Value == BoolValueTrue || arg->Value == BoolValueFalse)
{
settings->RedirectClipboard = (arg->Value == BoolValueTrue);
}
else
{
int rc = 0;
char** p;
size_t count, x;
p = CommandLineParseCommaSeparatedValues(arg->Value, &count);
for (x = 0; (x < count) && (rc == 0); x++)
{
const char usesel[14] = "use-selection:";
const char* cur = p[x];
if (_strnicmp(usesel, cur, sizeof(usesel)) == 0)
{
const char* val = &cur[sizeof(usesel)];
if (!copy_value(val, &settings->XSelectionAtom))
rc = COMMAND_LINE_ERROR_MEMORY;
settings->RedirectClipboard = TRUE;
}
else
rc = COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
}
free(p);
if (rc)
return rc;
}
}
CommandLineSwitchCase(arg, "shell")
{

View File

@ -102,8 +102,12 @@ static const COMMAND_LINE_ARGUMENT_A args[] = {
"Client Build Number sent to server (influences smartcard behaviour, see [MS-RDPESC])" },
{ "client-hostname", COMMAND_LINE_VALUE_REQUIRED, "<name>", NULL, NULL, -1, NULL,
"Client Hostname to send to server" },
{ "clipboard", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL,
"Redirect clipboard" },
{ "clipboard", COMMAND_LINE_VALUE_BOOL | COMMAND_LINE_VALUE_OPTIONAL, "[use-selection:<atom>]",
BoolValueTrue, NULL, -1, NULL,
"Redirect clipboard. "
" * use-selection:<atom> ... (X11) Specify which X selection to access. Default is "
"CLIPBOARD."
" PRIMARY is the X-style middle-click selection." },
{ "codec-cache", COMMAND_LINE_VALUE_REQUIRED, "[rfx|nsc|jpeg]", NULL, NULL, -1, NULL,
"Bitmap codec cache" },
{ "compression", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, "z", "compression" },

View File

@ -1559,6 +1559,7 @@ struct rdp_settings
default value - currently UNUSED! */
ALIGN64 char* ActionScript;
ALIGN64 DWORD Floatbar;
ALIGN64 char* XSelectionAtom;
};
typedef struct rdp_settings rdpSettings;

View File

@ -594,6 +594,7 @@ rdpSettings* freerdp_settings_new(DWORD flags)
settings_load_hkey_local_machine(settings);
settings->ActionScript = _strdup("~/.config/freerdp/action.sh");
settings->XSelectionAtom = NULL;
settings->SmartcardLogon = FALSE;
settings->TlsSecLevel = 1;
settings->OrderSupport = calloc(1, 32);
@ -640,6 +641,8 @@ static void freerdp_settings_free_internal(rdpSettings* settings)
/* Extensions */
free(settings->ActionScript);
settings->ActionScript = NULL;
free(settings->XSelectionAtom);
settings->XSelectionAtom = NULL;
/* Free all strings, set other pointers NULL */
freerdp_settings_free_keys(settings, TRUE);
@ -967,6 +970,8 @@ static BOOL freerdp_settings_int_buffer_copy(rdpSettings* _settings, const rdpSe
if (settings->ActionScript)
_settings->ActionScript = _strdup(settings->ActionScript);
if (settings->XSelectionAtom)
_settings->XSelectionAtom = _strdup(settings->XSelectionAtom);
rc = TRUE;
out_fail:
return rc;
@ -1008,6 +1013,7 @@ BOOL freerdp_settings_copy(rdpSettings* _settings, const rdpSettings* settings)
_settings->StaticChannelArray = NULL;
_settings->DynamicChannelArray = NULL;
_settings->ActionScript = NULL;
_settings->XSelectionAtom = NULL;
if (!rc)
goto out_fail;