Added unicode input for xfreerdp

This commit is contained in:
akallabeth 2021-09-10 15:46:33 +02:00 committed by akallabeth
parent 608c1baca0
commit 41aaafef77
6 changed files with 88 additions and 20 deletions

View File

@ -43,6 +43,8 @@
#include <freerdp/log.h>
#define TAG CLIENT_TAG("x11")
static void xf_keyboard_send_key(xfContext* xfc, BOOL down, const XKeyEvent* ev);
static BOOL xf_sync_kbd_state(xfContext* xfc)
{
const UINT32 syncFlags = xf_keyboard_get_toggle_keys_state(xfc);
@ -155,7 +157,7 @@ void xf_keyboard_key_press(xfContext* xfc, const XKeyEvent* event, KeySym keysym
if (xf_keyboard_handle_special_keys(xfc, keysym))
return;
xf_keyboard_send_key(xfc, TRUE, event->keycode);
xf_keyboard_send_key(xfc, TRUE, event);
}
void xf_keyboard_key_release(xfContext* xfc, const XKeyEvent* event, KeySym keysym)
@ -168,7 +170,7 @@ void xf_keyboard_key_release(xfContext* xfc, const XKeyEvent* event, KeySym keys
xfc->KeyboardState[event->keycode] = FALSE;
xf_keyboard_handle_special_keys_release(xfc, keysym);
xf_keyboard_send_key(xfc, FALSE, event->keycode);
xf_keyboard_send_key(xfc, FALSE, event);
}
void xf_keyboard_release_all_keypress(xfContext* xfc)
@ -200,19 +202,20 @@ BOOL xf_keyboard_key_pressed(xfContext* xfc, KeySym keysym)
return xfc->KeyboardState[keycode];
}
void xf_keyboard_send_key(xfContext* xfc, BOOL down, BYTE keycode)
void xf_keyboard_send_key(xfContext* xfc, BOOL down, const XKeyEvent* event)
{
DWORD rdp_scancode;
rdpInput* input;
input = xfc->context.input;
rdp_scancode = freerdp_keyboard_get_rdp_scancode_from_x11_keycode(keycode);
if (rdp_scancode == RDP_SCANCODE_UNKNOWN)
{
WLog_ERR(TAG, "Unknown key with X keycode 0x%02" PRIx8 "", keycode);
}
else if (rdp_scancode == RDP_SCANCODE_PAUSE && !xf_keyboard_key_pressed(xfc, XK_Control_L) &&
!xf_keyboard_key_pressed(xfc, XK_Control_R))
WINPR_ASSERT(xfc);
WINPR_ASSERT(event);
input = xfc->context.input;
WINPR_ASSERT(input);
rdp_scancode = freerdp_keyboard_get_rdp_scancode_from_x11_keycode(event->keycode);
if (rdp_scancode == RDP_SCANCODE_PAUSE && !xf_keyboard_key_pressed(xfc, XK_Control_L) &&
!xf_keyboard_key_pressed(xfc, XK_Control_R))
{
/* Pause without Ctrl has to be sent as a series of keycodes
* in a single input PDU. Pause only happens on "press";
@ -225,7 +228,48 @@ void xf_keyboard_send_key(xfContext* xfc, BOOL down, BYTE keycode)
}
else
{
freerdp_input_send_keyboard_event_ex(input, down, rdp_scancode);
BOOL rc;
if (freerdp_settings_get_bool(xfc->context.settings, FreeRDP_UnicodeInput))
{
wchar_t buffer[32] = { 0 };
int rc = 0;
int xwc = -1;
switch (rdp_scancode)
{
case RDP_SCANCODE_RETURN:
break;
default:
{
XIM xim = XOpenIM(xfc->display, 0, 0, 0);
XIC xic =
XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, NULL);
KeySym ignore = { 0 };
Status return_status;
XKeyEvent ev = *event;
ev.type = KeyPress;
xwc = XwcLookupString(xic, &ev, buffer, ARRAYSIZE(buffer), &ignore,
&return_status);
}
break;
}
if (xwc < 1)
{
if (rdp_scancode == RDP_SCANCODE_UNKNOWN)
WLog_ERR(TAG, "Unknown key with X keycode 0x%02" PRIx8 "", event->keycode);
else
rc = freerdp_input_send_keyboard_event_ex(input, down, rdp_scancode);
}
else
rc = freerdp_input_send_unicode_keyboard_event(input, down ? KBD_FLAGS_RELEASE : 0,
buffer[0]);
}
else if (rdp_scancode == RDP_SCANCODE_UNKNOWN)
WLog_ERR(TAG, "Unknown key with X keycode 0x%02" PRIx8 "", event->keycode);
else
rc = freerdp_input_send_keyboard_event_ex(input, down, rdp_scancode);
if ((rdp_scancode == RDP_SCANCODE_CAPSLOCK) && (down == FALSE))
{

View File

@ -50,7 +50,7 @@ void xf_keyboard_key_release(xfContext* xfc, const XKeyEvent* event, KeySym keys
void xf_keyboard_release_all_keypress(xfContext* xfc);
BOOL xf_keyboard_key_pressed(xfContext* xfc, KeySym keysym);
void xf_keyboard_send_key(xfContext* xfc, BOOL down, BYTE keycode);
int xf_keyboard_read_keyboard_state(xfContext* xfc);
BOOL xf_keyboard_get_key_state(xfContext* xfc, int state, int keysym);
UINT32 xf_keyboard_get_toggle_keys_state(xfContext* xfc);

View File

@ -1631,6 +1631,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
arg = largs;
errno = 0;
/* Disable unicode input unless requested. */
if (!freerdp_settings_set_bool(settings, FreeRDP_UnicodeInput, FALSE))
return COMMAND_LINE_ERROR_MEMORY;
do
{
BOOL enable = arg->Value ? TRUE : FALSE;
@ -2053,6 +2057,11 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
settings->KeyboardType = (UINT32)val;
}
CommandLineSwitchCase(arg, "kbd-unicode")
{
if (!freerdp_settings_set_bool(settings, FreeRDP_UnicodeInput, enable))
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
}
CommandLineSwitchCase(arg, "kbd-subtype")
{
LONGLONG val;

View File

@ -221,6 +221,9 @@ static const COMMAND_LINE_ARGUMENT_A args[] = {
{ "kbd-subtype", COMMAND_LINE_VALUE_REQUIRED, "<id>", NULL, NULL, -1, NULL,
"Keyboard subtype" },
{ "kbd-type", COMMAND_LINE_VALUE_REQUIRED, "<id>", NULL, NULL, -1, NULL, "Keyboard type" },
{ "kbd-unicode", COMMAND_LINE_VALUE_FLAG, "", NULL, NULL, -1, NULL,
"Send unicode symbols, e.g. use the local keyboard map. ATTENTION: Does not work with every "
"RDP server!" },
{ "load-balance-info", COMMAND_LINE_VALUE_REQUIRED, "<info-string>", NULL, NULL, -1, NULL,
"Load balance info" },
{ "log-filters", COMMAND_LINE_VALUE_REQUIRED, "<tag>:<level>[,<tag>:<level>[,...]]", NULL, NULL,

View File

@ -1294,14 +1294,23 @@ static BOOL rdp_read_input_capability_set(wStream* s, rdpSettings* settings)
settings->FastPathInput = FALSE;
}
if (inputFlags & TS_INPUT_FLAG_MOUSE_HWHEEL)
settings->HasHorizontalWheel = TRUE;
if (settings->HasHorizontalWheel)
{
if (inputFlags & TS_INPUT_FLAG_MOUSE_HWHEEL)
settings->HasHorizontalWheel = TRUE;
}
if (inputFlags & INPUT_FLAG_UNICODE)
settings->UnicodeInput = TRUE;
if (settings->UnicodeInput)
{
if (inputFlags & INPUT_FLAG_UNICODE)
settings->UnicodeInput = TRUE;
}
if (inputFlags & INPUT_FLAG_MOUSEX)
settings->HasExtendedMouseEvent = TRUE;
if (settings->HasExtendedMouseEvent)
{
if (inputFlags & INPUT_FLAG_MOUSEX)
settings->HasExtendedMouseEvent = TRUE;
}
}
return TRUE;

View File

@ -311,7 +311,10 @@ rdpSettings* freerdp_settings_new(DWORD flags)
if (!settings)
return NULL;
if (!freerdp_settings_set_bool(settings, FreeRDP_HiDefRemoteApp, FALSE) ||
if (!freerdp_settings_set_bool(settings, FreeRDP_UnicodeInput, TRUE) ||
!freerdp_settings_set_bool(settings, FreeRDP_HasHorizontalWheel, TRUE) ||
!freerdp_settings_set_bool(settings, FreeRDP_HasExtendedMouseEvent, TRUE) ||
!freerdp_settings_set_bool(settings, FreeRDP_HiDefRemoteApp, FALSE) ||
!freerdp_settings_set_uint32(
settings, FreeRDP_RemoteApplicationSupportMask,
RAIL_LEVEL_SUPPORTED | RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED |