mirror of https://github.com/FreeRDP/FreeRDP
[client,x11] add thread reading from named pipe
the named pipe input is converted to unicode and sent as keyboard input
This commit is contained in:
parent
a01f3ec5ab
commit
2d85aa43fa
|
@ -64,6 +64,8 @@
|
|||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/select.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/constants.h>
|
||||
|
@ -1210,6 +1212,93 @@ static BOOL xf_pre_connect(freerdp* instance)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL xf_inject_keypress(rdpContext* context, const char* buffer, size_t size)
|
||||
{
|
||||
WCHAR wbuffer[64] = { 0 };
|
||||
const SSIZE_T len = ConvertUtf8NToWChar(buffer, size, wbuffer, ARRAYSIZE(wbuffer));
|
||||
if (len < 0)
|
||||
return FALSE;
|
||||
|
||||
rdpInput* input = context->input;
|
||||
WINPR_ASSERT(input);
|
||||
|
||||
for (SSIZE_T x = 0; x < len; x++)
|
||||
{
|
||||
const WCHAR code = wbuffer[x];
|
||||
freerdp_input_send_unicode_keyboard_event(input, 0, code);
|
||||
Sleep(5);
|
||||
freerdp_input_send_unicode_keyboard_event(input, KBD_FLAGS_RELEASE, code);
|
||||
Sleep(5);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL xf_process_pipe(rdpContext* context, const char* pipe)
|
||||
{
|
||||
int fd = open(pipe, O_NONBLOCK | O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "pipe '%s' open returned %s [%d]", pipe, strerror(errno), errno);
|
||||
return FALSE;
|
||||
}
|
||||
while (!freerdp_shall_disconnect_context(context))
|
||||
{
|
||||
char buffer[64] = { 0 };
|
||||
ssize_t rd = read(fd, buffer, sizeof(buffer) - 1);
|
||||
if (rd == 0)
|
||||
{
|
||||
if ((errno == EAGAIN) || (errno == 0))
|
||||
{
|
||||
Sleep(100);
|
||||
continue;
|
||||
}
|
||||
|
||||
// EOF, abort reading.
|
||||
WLog_ERR(TAG, "pipe '%s' read returned %s [%d]", pipe, strerror(errno), errno);
|
||||
break;
|
||||
}
|
||||
else if (rd < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "pipe '%s' read returned %s [%d]", pipe, strerror(errno), errno);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!xf_inject_keypress(context, buffer, rd))
|
||||
break;
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static DWORD WINAPI xf_handle_pipe(void* arg)
|
||||
{
|
||||
xfContext* xfc = arg;
|
||||
WINPR_ASSERT(xfc);
|
||||
|
||||
rdpContext* context = &xfc->common.context;
|
||||
WINPR_ASSERT(context);
|
||||
|
||||
rdpSettings* settings = context->settings;
|
||||
WINPR_ASSERT(settings);
|
||||
|
||||
const char* pipe = freerdp_settings_get_string(settings, FreeRDP_KeyboardPipeName);
|
||||
WINPR_ASSERT(pipe);
|
||||
|
||||
const int rc = mkfifo(pipe, S_IWUSR | S_IRUSR);
|
||||
if (rc != 0)
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to create named pipe '%s': %s [%d]", pipe, strerror(errno), errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
xf_process_pipe(context, pipe);
|
||||
|
||||
unlink(pipe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback given to freerdp_connect() to perform post-connection operations.
|
||||
* It will be called only if the connection was initialized properly, and will continue the
|
||||
|
@ -1297,9 +1386,14 @@ static BOOL xf_post_connect(freerdp* instance)
|
|||
return FALSE;
|
||||
|
||||
if (!(xfc->xfDisp = xf_disp_new(xfc)))
|
||||
{
|
||||
xf_clipboard_free(xfc->clipboard);
|
||||
return FALSE;
|
||||
|
||||
const char* pipe = freerdp_settings_get_string(settings, FreeRDP_KeyboardPipeName);
|
||||
if (pipe)
|
||||
{
|
||||
xfc->pipethread = CreateThread(NULL, 0, xf_handle_pipe, xfc, 0, NULL);
|
||||
if (!xfc->pipethread)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
EventArgsInit(&e, "xfreerdp");
|
||||
|
@ -1325,6 +1419,12 @@ static void xf_post_disconnect(freerdp* instance)
|
|||
xf_OnChannelDisconnectedEventHandler);
|
||||
gdi_free(instance);
|
||||
|
||||
if (xfc->pipethread)
|
||||
{
|
||||
WaitForSingleObject(xfc->pipethread, INFINITE);
|
||||
CloseHandle(xfc->pipethread);
|
||||
xfc->pipethread = NULL;
|
||||
}
|
||||
if (xfc->clipboard)
|
||||
{
|
||||
xf_clipboard_free(xfc->clipboard);
|
||||
|
|
|
@ -294,6 +294,7 @@ struct xf_context
|
|||
#endif
|
||||
BOOL xi_rawevent;
|
||||
BOOL xi_event;
|
||||
HANDLE pipethread;
|
||||
};
|
||||
|
||||
BOOL xf_create_window(xfContext* xfc);
|
||||
|
|
|
@ -2175,7 +2175,9 @@ static int parse_kbd_options(rdpSettings* settings, const COMMAND_LINE_ARGUMENT_
|
|||
}
|
||||
else if (option_starts_with("pipe:", val))
|
||||
{
|
||||
if (!freerdp_settings_set_string(settings, FreeRDP_KeyboardPipeName, &val[5]))
|
||||
if (!freerdp_settings_set_bool(settings, FreeRDP_UnicodeInput, TRUE))
|
||||
rc = COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
|
||||
else if (!freerdp_settings_set_string(settings, FreeRDP_KeyboardPipeName, &val[5]))
|
||||
rc = COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
|
||||
}
|
||||
#if defined(WITH_FREERDP_DEPRECATED_COMMANDLINE)
|
||||
|
@ -2192,6 +2194,7 @@ static int parse_kbd_options(rdpSettings* settings, const COMMAND_LINE_ARGUMENT_
|
|||
break;
|
||||
}
|
||||
}
|
||||
free(ptr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue