From 76a66424b5d27237fad7a3a58afede58f65c00b3 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 +++++ xrdp/lang.c | 10 ++++++++++ xrdp/xrdp.ini.in | 1 + xup/xup.c | 18 ++++++++++++++++++ xup/xup.h | 1 + 6 files changed, 41 insertions(+), 1 deletion(-) diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h index 43ce2db89d..dff6c5d09b 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 20240624 #endif diff --git a/docs/man/xrdp.ini.5.in b/docs/man/xrdp.ini.5.in index e44327ce59..383dba14b6 100644 --- a/docs/man/xrdp.ini.5.in +++ b/docs/man/xrdp.ini.5.in @@ -364,6 +364,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/xrdp/lang.c b/xrdp/lang.c index e36f688efd..77280e7389 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 11ecada6f8..0c4614f274 100644 --- a/xrdp/xrdp.ini.in +++ b/xrdp/xrdp.ini.in @@ -241,6 +241,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 645eaa5267..71ced6001c 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 05f747e724..37aa67dc6a 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