From ba1d93930ac44740e8c3e8d481a762bca5c095cd Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Mon, 24 Jun 2024 15:07:54 +0100 Subject: [PATCH] Allow keycode set to be specified for the X server This commit allows a keycode_set to be specified as a module parameter in xrdp.ini. This has the following effects:- 1) xrdp loads the specified keycode set for mapping RDP scancodes to X11 keycodes. These are then passed to xorgxrdp as part of key press/ key release events. 2) The name of the XKB rules which use the specified keycode set are passed to xorgxrdp so that XKB can be configured with rules which match the chosen keycodes. The effect is to remove all keycode set dependencies from xorgxrdp. Normally evdev rules and evdev keycodes will be used but base rules and base keycodes can be used instead for applications that require them. Also, any systems which do not ship the evdev rules can be made to work with base rules. --- common/xrdp_client_info.h | 7 ++++++- docs/man/xrdp.ini.5.in | 5 +++++ librfxcodec | 2 +- xrdp/lang.c | 10 ++++++++++ xrdp/xrdp.ini.in | 1 + xup/xup.c | 18 ++++++++++++++++++ xup/xup.h | 1 + 7 files changed, 42 insertions(+), 2 deletions(-) diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h index 43ce2db8..45965bea 100644 --- a/common/xrdp_client_info.h +++ b/common/xrdp_client_info.h @@ -200,6 +200,11 @@ struct xrdp_client_info char layout[16]; char variant[16]; char options[256]; + char xkb_rules[32]; + // A few x11 keycodes are needed by the xup module + int x11_keycode_caps_lock; + int x11_keycode_num_lock; + int x11_keycode_scroll_lock; /* ==================================================================== */ /* Private to xrdp below this line */ @@ -269,6 +274,6 @@ enum xrdp_encoder_flags /* yyyymmdd of last incompatible change to xrdp_client_info */ /* also used for changes to all the xrdp installed headers */ -#define CLIENT_INFO_CURRENT_VERSION 20240514 +#define CLIENT_INFO_CURRENT_VERSION 20240805 #endif diff --git a/docs/man/xrdp.ini.5.in b/docs/man/xrdp.ini.5.in index c6802ee2..28b8fc70 100644 --- a/docs/man/xrdp.ini.5.in +++ b/docs/man/xrdp.ini.5.in @@ -390,6 +390,11 @@ use of \fBxrdp\-chansrv\fR facilities in the VNC session. The first form of this setting is recommended, replacing \fIn\fR with the X11 display number of the session. +.TP +\fBkeycode_set\fR=\fI\fR +[Xorg only] Asks for the specified keycode set to be used by the X server. +Normally "evdev" or "base". The default should be correct for your system. + .SH "EXAMPLES" This is an example \fBxrdp.ini\fR: diff --git a/librfxcodec b/librfxcodec index c6b41afa..e8208bfc 160000 --- a/librfxcodec +++ b/librfxcodec @@ -1 +1 @@ -Subproject commit c6b41afa6986d5e6df18778a342b407cae40e1b5 +Subproject commit e8208bfc0b9d122b1c393a659427fbb135e9cd75 diff --git a/xrdp/lang.c b/xrdp/lang.c index e36f688e..77280e73 100644 --- a/xrdp/lang.c +++ b/xrdp/lang.c @@ -653,4 +653,14 @@ xrdp_init_xkb_layout(struct xrdp_client_info *client_info) LOG(LOG_LEVEL_ERROR, "xrdp_init_xkb_layout: error opening %s", keyboard_cfg_file); } + + // Initialise the rules and a few keycodes for xorgxrdp + snprintf(client_info->xkb_rules, sizeof(client_info->xkb_rules), + "%s", scancode_get_xkb_rules()); + client_info->x11_keycode_caps_lock = + scancode_to_x11_keycode(SCANCODE_CAPS_KEY); + client_info->x11_keycode_num_lock = + scancode_to_x11_keycode(SCANCODE_NUMLOCK_KEY); + client_info->x11_keycode_scroll_lock = + scancode_to_x11_keycode(SCANCODE_SCROLL_KEY); } diff --git a/xrdp/xrdp.ini.in b/xrdp/xrdp.ini.in index b48c739f..53924764 100644 --- a/xrdp/xrdp.ini.in +++ b/xrdp/xrdp.ini.in @@ -248,6 +248,7 @@ username=ask password=ask port=-1 code=20 +#keycode_set=evdev [Xvnc] name=Xvnc diff --git a/xup/xup.c b/xup/xup.c index 645eaa52..71ced600 100644 --- a/xup/xup.c +++ b/xup/xup.c @@ -175,7 +175,21 @@ lib_mod_connect(struct mod *mod) // be set. // // Load the XKB layout + if (mod->keycode_set[0] != '\0') + { + if (scancode_set_keycode_set(mod->keycode_set) == 0) + { + LOG(LOG_LEVEL_INFO, "Loaded '%s' keycode set", mod->keycode_set); + } + else + { + LOG(LOG_LEVEL_WARNING, "Unable to load '%s' keycode set", + mod->keycode_set); + } + } mod->server_init_xkb_layout(mod, &(mod->client_info)); + LOG(LOG_LEVEL_INFO, "XKB rules '%s' will be used by the module", + mod->client_info.xkb_rules); make_stream(s); g_sprintf(con_port, "%s", mod->port); @@ -1869,6 +1883,10 @@ lib_mod_set_param(struct mod *mod, const char *name, const char *value) { g_strncpy(mod->port, value, 255); } + else if (g_strcasecmp(name, "keycode_set") == 0) + { + g_snprintf(mod->keycode_set, sizeof(mod->keycode_set), "%s", value); + } else if (g_strcasecmp(name, "client_info") == 0) { g_memcpy(&(mod->client_info), value, sizeof(mod->client_info)); diff --git a/xup/xup.h b/xup/xup.h index 05f747e7..37aa67dc 100644 --- a/xup/xup.h +++ b/xup/xup.h @@ -201,6 +201,7 @@ struct mod int screen_shmem_id_mapped; /* boolean */ char *screen_shmem_pixels; struct trans *trans; + char keycode_set[32]; }; #endif // XUP_H