Added option to remap scancodes

This commit is contained in:
Armin Novak
2020-10-28 12:22:48 +01:00
committed by akallabeth
parent cec261c4db
commit d7bf6553c5
10 changed files with 82 additions and 9 deletions

View File

@@ -270,7 +270,8 @@ static BOOL wl_post_connect(freerdp* instance)
instance->update->BeginPaint = wl_begin_paint;
instance->update->EndPaint = wl_end_paint;
instance->update->DesktopResize = wl_resize_display;
freerdp_keyboard_init(instance->context->settings->KeyboardLayout);
freerdp_keyboard_init_ex(instance->context->settings->KeyboardLayout,
instance->context->settings->KeyboardRemappingList);
if (!(context->disp = wlf_disp_new(context)))
return FALSE;

View File

@@ -107,7 +107,8 @@ BOOL xf_keyboard_init(xfContext* xfc)
{
xf_keyboard_clear(xfc);
xfc->KeyboardLayout = xfc->context.settings->KeyboardLayout;
xfc->KeyboardLayout = freerdp_keyboard_init(xfc->KeyboardLayout);
xfc->KeyboardLayout =
freerdp_keyboard_init_ex(xfc->KeyboardLayout, xfc->context.settings->KeyboardRemappingList);
xfc->context.settings->KeyboardLayout = xfc->KeyboardLayout;
if (xfc->modifierMap)

View File

@@ -1989,6 +1989,11 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
settings->KeyboardLayout = (UINT32)val;
}
CommandLineSwitchCase(arg, "kbd-remap")
{
if (!copy_value(arg->Value, &settings->KeyboardRemappingList))
return COMMAND_LINE_ERROR_MEMORY;
}
CommandLineSwitchCase(arg, "kbd-lang")
{
LONGLONG val;

View File

@@ -206,6 +206,9 @@ static const COMMAND_LINE_ARGUMENT_A args[] = {
"List keyboard layouts" },
{ "kbd-lang-list", COMMAND_LINE_VALUE_OPTIONAL | COMMAND_LINE_PRINT, NULL, NULL, NULL, -1, NULL,
"List keyboard languages" },
{ "kbd-remap", COMMAND_LINE_VALUE_REQUIRED,
"List of <key>=<value>,... pairs to remap scancodes", NULL, NULL, -1, NULL,
"Keyboard scancode remapping" },
{ "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" },

View File

@@ -220,6 +220,8 @@ extern "C"
#endif
FREERDP_API DWORD freerdp_keyboard_init(DWORD keyboardLayoutId);
FREERDP_API DWORD freerdp_keyboard_init_ex(DWORD keyboardLayoutId,
const char* keyboardRemappingList);
FREERDP_API RDP_KEYBOARD_LAYOUT* freerdp_keyboard_get_layouts(DWORD types);
FREERDP_API void freerdp_keyboard_layouts_free(RDP_KEYBOARD_LAYOUT* layouts);
FREERDP_API const char* freerdp_keyboard_get_layout_name_from_id(DWORD keyboardLayoutId);

View File

@@ -799,6 +799,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
#define FreeRDP_BitmapCacheV2CellInfo (2502)
#define FreeRDP_ColorPointerFlag (2560)
#define FreeRDP_PointerCacheSize (2561)
#define FreeRDP_KeyboardRemappingList (2622)
#define FreeRDP_KeyboardCodePage (2623)
#define FreeRDP_KeyboardLayout (2624)
#define FreeRDP_KeyboardType (2625)
@@ -1332,9 +1333,10 @@ struct rdp_settings
/* Pointer Capabilities */
ALIGN64 BOOL ColorPointerFlag; /* 2560 */
ALIGN64 UINT32 PointerCacheSize; /* 2561 */
UINT64 padding2624[2623 - 2562]; /* 2562 */
UINT64 padding2624[2622 - 2562]; /* 2562 */
/* Input Capabilities */
ALIGN64 char* KeyboardRemappingList; /* 2622 */
ALIGN64 UINT32 KeyboardCodePage; /* 2623 */
ALIGN64 UINT32 KeyboardLayout; /* 2624 */
ALIGN64 UINT32 KeyboardType; /* 2625 */

View File

@@ -2247,6 +2247,9 @@ const char* freerdp_settings_get_string(const rdpSettings* settings, size_t id)
case FreeRDP_KerberosRealm:
return settings->KerberosRealm;
case FreeRDP_KeyboardRemappingList:
return settings->KeyboardRemappingList;
case FreeRDP_NtlmSamFile:
return settings->NtlmSamFile;
@@ -2551,6 +2554,12 @@ BOOL freerdp_settings_set_string_(rdpSettings* settings, size_t id, const char*
settings->KerberosRealm = (val ? _strdup(val) : NULL);
return (!val || settings->KerberosRealm != NULL);
case FreeRDP_KeyboardRemappingList:
if (cleanup)
free(settings->KeyboardRemappingList);
settings->KeyboardRemappingList = (val ? _strdup(val) : NULL);
return (!val || settings->KeyboardRemappingList != NULL);
case FreeRDP_NtlmSamFile:
if (cleanup)
free(settings->NtlmSamFile);

View File

@@ -324,6 +324,7 @@ static const struct settings_str_entry settings_map[] = {
{ FreeRDP_ImeFileName, 7, "FreeRDP_ImeFileName" },
{ FreeRDP_KerberosKdc, 7, "FreeRDP_KerberosKdc" },
{ FreeRDP_KerberosRealm, 7, "FreeRDP_KerberosRealm" },
{ FreeRDP_KeyboardRemappingList, 7, "FreeRDP_KeyboardRemappingList" },
{ FreeRDP_NtlmSamFile, 7, "FreeRDP_NtlmSamFile" },
{ FreeRDP_Password, 7, "FreeRDP_Password" },
{ FreeRDP_PasswordHash, 7, "FreeRDP_PasswordHash" },

View File

@@ -333,6 +333,7 @@ static const size_t string_list_indices[] = {
FreeRDP_ImeFileName,
FreeRDP_KerberosKdc,
FreeRDP_KerberosRealm,
FreeRDP_KeyboardRemappingList,
FreeRDP_NtlmSamFile,
FreeRDP_Password,
FreeRDP_PasswordHash,

View File

@@ -42,8 +42,9 @@
#endif
DWORD VIRTUAL_SCANCODE_TO_X11_KEYCODE[256][2];
DWORD X11_KEYCODE_TO_VIRTUAL_SCANCODE[256];
static DWORD VIRTUAL_SCANCODE_TO_X11_KEYCODE[256][2] = { 0 };
static DWORD X11_KEYCODE_TO_VIRTUAL_SCANCODE[256] = { 0 };
static DWORD REMAPPING_TABLE[0x10000] = { 0 };
int freerdp_detect_keyboard(DWORD* keyboardLayoutId)
{
@@ -138,13 +139,60 @@ DWORD freerdp_keyboard_init(DWORD keyboardLayoutId)
return keyboardLayoutId;
}
DWORD freerdp_keyboard_init_ex(DWORD keyboardLayoutId, const char* keyboardRemappingList)
{
DWORD rc = freerdp_keyboard_init(keyboardLayoutId);
memset(REMAPPING_TABLE, 0, sizeof(REMAPPING_TABLE));
if (keyboardRemappingList)
{
char* copy = _strdup(keyboardRemappingList);
char* context = NULL;
char* token;
if (!copy)
goto fail;
token = strtok_s(copy, ",", &context);
while (token)
{
DWORD key, value;
int rc = sscanf(token, "%" PRIu32 "=%" PRIu32, &key, &value);
if (rc != 2)
rc = sscanf(token, "%" PRIx32 "=%" PRIx32 "", &key, &value);
if (rc != 2)
rc = sscanf(token, "%" PRIu32 "=%" PRIx32, &key, &value);
if (rc != 2)
rc = sscanf(token, "%" PRIx32 "=%" PRIu32, &key, &value);
if (rc != 2)
goto fail;
if (key >= ARRAYSIZE(REMAPPING_TABLE))
goto fail;
REMAPPING_TABLE[key] = value;
token = strtok_s(NULL, ",", &context);
}
fail:
free(copy);
}
return rc;
}
DWORD freerdp_keyboard_get_rdp_scancode_from_x11_keycode(DWORD keycode)
{
DEBUG_KBD("x11 keycode: %02" PRIX32 " -> rdp code: %02" PRIX8 "%s", keycode,
RDP_SCANCODE_CODE(X11_KEYCODE_TO_VIRTUAL_SCANCODE[keycode]),
RDP_SCANCODE_EXTENDED(X11_KEYCODE_TO_VIRTUAL_SCANCODE[keycode]) ? " extended" : "");
const DWORD scancode = X11_KEYCODE_TO_VIRTUAL_SCANCODE[keycode];
const DWORD remapped = REMAPPING_TABLE[scancode];
DEBUG_KBD("x11 keycode: %02" PRIX32 " -> rdp code: [%04" PRIx16 "] %02" PRIX8 "%s", keycode,
scancode, RDP_SCANCODE_CODE(scancode),
RDP_SCANCODE_EXTENDED(scancode) ? " extended" : "");
return X11_KEYCODE_TO_VIRTUAL_SCANCODE[keycode];
if (remapped != 0)
{
DEBUG_KBD("remapped scancode: [%04" PRIx16 "] %02" PRIX8 "[%s] -> [%04" PRIx16 "] %02" PRIX8
"[%s]",
scancode, RDP_SCANCODE_CODE(scancode),
RDP_SCANCODE_EXTENDED(scancode) ? " extended" : "", remapped,
RDP_SCANCODE_CODE(remapped), RDP_SCANCODE_EXTENDED(remapped) ? " extended" : "");
return remapped;
}
return scancode;
}
DWORD freerdp_keyboard_get_x11_keycode_from_rdp_scancode(DWORD scancode, BOOL extended)