Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mappings for media keys #3022

Merged
merged 2 commits into from
May 24, 2024
Merged

Add mappings for media keys #3022

merged 2 commits into from
May 24, 2024

Conversation

sasha0552
Copy link
Contributor

@sasha0552 sasha0552 commented Mar 28, 2024

Fixes #1725, at least for this repository. The three media keys available on my keyboard now work (using Xvnc session type).
Related: neutrinolabs/xorgxrdp#303

TODO:

  • Initial implementation
  • Add more media keys
  • Add last two media keys
  • Refactor genkeymap to generate correct keysyms for media keys
  • Regenerate keymaps stored in repository
  • Fix overflow
  • Remove dependency on linux header
  • Fix remaining media keys
  • Remove debug code
  • Squash commits

List of rdp codes
List of xorg keycodes xmodmap -pk
List of keysyms

rdp code keycode keysym tested/works
16 173 XF86AudioPrev +
25 171 XF86AudioNext +
32 121 XF86AudioMute +
34 172 XF86AudioPlay +
36 174 XF86AudioStop +
46 122 XF86AudioLowerVolume +
48 123 XF86AudioRaiseVolume +
50 180 XF86HomePage +
101 225 XF86Search +
102 164 XF86Favorites +
103 181 XF86Reload +
104 136 Cancel +
105 167 XF86Forward +
106 166 XF86Back +
108 163 XF86Mail +
109 234 XF86AudioMedia +
110 156 XF86Launch1 +
111 157 XF86Launch2 +

@sasha0552 sasha0552 force-pushed the devel branch 8 times, most recently from e7fe4b6 to e889e80 Compare March 29, 2024 01:51
@sasha0552 sasha0552 marked this pull request as ready for review March 29, 2024 01:52
@matt335672
Copy link
Member

Hi @sasha0552

Thanks for this, particularly the references.

I'm going to run out of time to review this before I have to spend some family time next week I'm afraid. This isn't an area I'm that familiar with so it may take me a while. @jsorg71 - do you have some time to look at this?

One immediate question I have is your scancodes, particularly that for XF86Favorites. My understanding of the protocol is that this value is out of range. From https://x.org/releases/X11R7.7/doc/xproto/x11protocol.html:-

Min-keycode and max-keycode specify the smallest and largest keycode values transmitted by the server. Min-keycode is never less than 8, and max-keycode is never greater than 255. Not all keycodes in this range are required to have corresponding keys.

The same document only allows a CARD8 for the keycode in the on-wire protocol, even though the XKeyEvent allows an unsigned int.

Where are you getting these values from?

@sasha0552
Copy link
Contributor Author

sasha0552 commented Mar 29, 2024

Hi @matt335672.

I'm going to run out of time to review this before I have to spend some family time next week I'm afraid.

It's okay, there's no need to rush.

Where are you getting these values from?

I got the evdev scancodes from the /usr/share/X11/xkb/keycodes/evdev file. There are scancodes up to 708.

$ cat /usr/share/X11/xkb/keycodes/evdev
// translation from evdev scancodes to something resembling xfree86 keycodes.

default xkb_keycodes "evdev" {
...
        <I707> = 707;           // #define KEY_KBD_LCD_MENU4       699
        <I708> = 708;           // #define KEY_KBD_LCD_MENU5       700
        // End of autogenerated key codes
...
};

I believe Xorg can handle scancodes up to unsigned int. However, there just aren't that many scancodes, so I decided to use uint16 instead of uint8 for scancode value, and allow up to 1024 definitions in the keymap file.

@sasha0552
Copy link
Contributor Author

sasha0552 commented Mar 29, 2024

The same document only allows a CARD8 for the keycode in the on-wire protocol, even though the XKeyEvent allows an unsigned int.

A single keycode can have multiple meanings, I guess, but scancode is different. Scancode comes from the linux kernel.

$ xmodmap -pke
keycode   8 =
keycode   9 = Escape NoSymbol Escape
keycode  10 = 1 exclam 1 exclam
keycode  11 = 2 at 2 at
keycode  12 = 3 numbersign 3 numbersign
keycode  13 = 4 dollar 4 dollar
keycode  14 = 5 percent 5 percent
keycode  15 = 6 asciicircum 6 asciicircum
keycode  16 = 7 ampersand 7 ampersand
keycode  17 = 8 asterisk 8 asterisk
keycode  18 = 9 parenleft 9 parenleft
keycode  19 = 0 parenright 0 parenright
keycode  20 = minus underscore minus underscore
keycode  21 = equal plus equal plus
keycode  22 = BackSpace BackSpace BackSpace BackSpace
keycode  23 = Tab ISO_Left_Tab Tab ISO_Left_Tab
keycode  24 = q Q q Q
...

For example:

KeyRelease event, serial 44, synthetic NO, window 0x3000001,
    root 0x309, subw 0x0, time 951717947, (-437,-296), root:(270,13),
    state 0x10, keycode 164 (keysym 0x1008ff30, XF86Favorites), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

@sasha0552
Copy link
Contributor Author

xmodmap says:

$ xmodmap -pk
There are 7 KeySyms per KeyCode; KeyCodes range from 8 to 255.

    KeyCode     Keysym (Keysym) ...
    Value       Value   (Name)  ...

      8    
      9         0xff1b (Escape) 0x0000 (NoSymbol)       0xff1b (Escape)
...

@matt335672
Copy link
Member

@sasha0552

Again, I've not spent any significant time on this yet, but regarding the key code limit of 255, this is very much not a solved problem. Here are a couple of links:-

Also, if you have a closer look at /usr/share/X11/xkb/keycodes/evdev you'll find these interesting lines:-

maximum = 255;

and:-

        <I253> = 253;           // #define KEY_DISPLAY_OFF         245
        <I254> = 254;           // #define KEY_WWAN                246
        <I255> = 255;           // #define KEY_RFKILL              247

        // Key codes below cannot be used in X

        <I256> = 256;           // #define KEY_MICMUTE             248
        <I360> = 360;           // #define KEY_OK                  352
        <I361> = 361;           // #define KEY_SELECT              353

I think I've got a lot of mugging up to do on the existing code before I can give your PR the attention it deserves. I'll try to write it up on the wiki.

@sasha0552
Copy link
Contributor Author

sasha0552 commented Mar 31, 2024

@matt335672

I think xrdp is passing scancodes, not keycodes.

KeyRelease event, serial 44, synthetic NO, window 0x3000001,
    root 0x309, subw 0x0, time 951717947, (-437,-296), root:(270,13),
    state 0x10, keycode 164 (keysym 0x1008ff30, XF86Favorites), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

The keycode (164) in xev is the same on the local session and on the xrdp session. Meanwhile, there is no such keycode in the xrdp code. Only 372, which is not only keycode, but also is scancode.

<keycode name> = scancode;
<I372> = 372; // #define KEY_FAVORITES 364

In addition, this key is fully functional with the current code as listed in the table (I tested each key with + manually using either a key on the keyboard, or programmatically using xdotool key keysym.).

@sasha0552
Copy link
Contributor Author

sasha0552 commented Mar 31, 2024

I mean, xrdp doesn't even passing scancodes. The process looks like this:

  1. Convert the rdp code to some internal value (not necessary a real scancode or keycode)
  2. Convert the internal value to keysym and character directly using keymap file

Maybe we can eliminate the internal value and directly map the rdp codes to keysyms & chars in keymap file?

@sasha0552 sasha0552 force-pushed the devel branch 2 times, most recently from 616adc3 to c11cb69 Compare April 3, 2024 00:33
instfiles/km-00000409.ini Outdated Show resolved Hide resolved
@metalefty
Copy link
Member

I ever worked on around keyboard. I can look in to this but it takes time to remember.

@matt335672
Copy link
Member

I've had a bit of time today to do some reading up on the code, and I've got a better idea of what's going on within xrdp.

  • Within xrdp, the xrdp scancodes are mapped to a set of X11 keycodes using this hard-coded table:-
    static struct codepair g_map[] =
  • The X11 keycodes are mapped to X11 keysyms (and characters) in the keymaps.
  • The keymaps are only used by the login screen and the VNC backend. xorgxrdp does its own mapping.

I'm hoping to be able to get a proper review of this done next week.

@matt335672 matt335672 self-requested a review April 8, 2024 13:34
@matt335672
Copy link
Member

Right, I think I'm up to speed on what's going on in this area. Here's a summary of the current architecture:-

https://github.com/neutrinolabs/xrdp/wiki/Keyboard-mappings

First of all; @sasha0552 - thanks for your patience and for the changes you've made to your initial proposal. Things look a lot better now. I'm going to make a couple of other suggestions based on the above link. Please consider these and get back to me with any comments.

This patch removes unmapped keys from the keymap files, which makes the diffs easier to follow:-

diff --git a/genkeymap/genkeymap.c b/genkeymap/genkeymap.c
index bc5ddba7..51c05b11 100644
--- a/genkeymap/genkeymap.c
+++ b/genkeymap/genkeymap.c
@@ -148,6 +148,10 @@ int main(int argc, char **argv)
                 e.keycode = i;
             }
             nbytes = XLookupString(&e, text, 255, &ks, NULL);
+            if (ks == NoSymbol)
+            {
+                continue;
+            }
             text[nbytes] = 0;
             char_count = mbstowcs(wtext, text, 255);
             unicode = 0;
diff --git a/xrdp/lang.c b/xrdp/lang.c
index a998805d..edb03b68 100644
--- a/xrdp/lang.c
+++ b/xrdp/lang.c
@@ -189,6 +189,7 @@ km_read_section(int fd, const char *section_name, struct xrdp_key_info *keymap)
     values = list_create();
     values->auto_free = 1;
 
+    g_memset(keymap, '\0', sizeof(*keymap));
     if (file_read_section(fd, section_name, names, values) == 0)
     {
         for (index = names->count - 1; index >= 0; index--)

This one explicitly uses evdev rules for generating the keymaps, regardless of the X server being used:-

--- a/genkeymap/dump-keymaps.sh
+++ b/genkeymap/dump-keymaps.sh
@@ -6,6 +6,11 @@ then
   exit 1
 fi
 
+OLD_SETTINGS=$(setxkbmap -query -verbose 4 | sed "s/^\([a-z]\+\):\s*\(.*\)$/-\1 \2/;s/^-options/-option \"\" -option/;s/,/ -option /g" | xargs -d \\n)
+
+# Use evdev rules for these mappings
+setxkbmap -rules evdev
+
 # English - US 'en-us' 0x00000409
 setxkbmap -model pc104 -layout us
 ./xrdp-genkeymap ../instfiles/km-00000409.ini
@@ -15,7 +20,6 @@ setxkbmap -model pc104 -layout dvorak
 ./xrdp-genkeymap ../instfiles/km-00010409.ini
 
 # English - US 'dvp' 0x19360409
-OLD_SETTINGS=$(setxkbmap -query -verbose 4 | sed "s/^\([a-z]\+\):\s*\(.*\)$/-\1 \2/;s/^-options/-option \"\" -option/;s/,/ -option /g" | xargs -d \\n)
 setxkbmap -rules xfree86 -model pc105 -layout us -variant dvp -option "" -option compose:102 -option caps:shift -option numpad:sg -option numpad:shift3 -option keypad:hex -option keypad:atm -option kpdl:semi -option lv3:ralt_alt
 ./xrdp-genkeymap ../instfiles/km-19360409.ini
 setxkbmap ${OLD_SETTINGS}
@@ -52,5 +56,5 @@ setxkbmap -model pc104 -layout se
 setxkbmap -model pc104 -layout pt
 ./xrdp-genkeymap ../instfiles/km-00000816.ini
 
-# set back to en-us
-setxkbmap -model pc104 -layout us
+# set back to entry settings
+setxkbmap ${OLD_SETTINGS}

@matt335672
Copy link
Member

@sasha0552 - If I check out your PR, and run dump-keymaps.sh in my environment I get different keymap files. I'm just running on the console of an Ubuntu 22.04 machine.

How are you running the script on your end?

We need to understand why there's a difference, or it's difficult to have any confidence in the script itself.

I get the following from setxkbmap -layout us -model pc104 ; setxkbmap -v 10:-

Setting verbose level to 10
locale is C
Trying to load rules file ./rules/evdev...
Trying to load rules file /usr/share/X11/xkb/rules/evdev...
Success.
Applied rules from evdev:
rules:      evdev
model:      pc104
layout:     us
Trying to build keymap using the following components:
keycodes:   evdev+aliases(qwerty)
types:      complete
compat:     complete
symbols:    pc+us+inet(evdev)
geometry:   pc(pc104)

As far as neutrinolabs/xorgxrdp#303 goes, I think if we can get evdev keycode support working reliably here, we can probably do a lot of the mapping work in xrdp itself. Let's come back to that when we've bottomed this one out.

@sasha0552
Copy link
Contributor Author

sasha0552 commented Apr 8, 2024

@matt335672
I am running the script in the GitHub Codespaces using Xvfb as a server. Ubuntu 20.04.6 LTS is used.

sudo apt-get update && sudo apt-get install -y xvfb x11-xkb-utils
cd genkeymap
gcc *.c -lX11 -o xrdp-genkeymap
Xvfb &
xvfb-run ./dump-keymaps.sh
setxkbmap -v 10
...
@sasha0552 ➜ /workspaces/xrdp/genkeymap (devel) $ Xvfb &
[1] 5764
_XSERVTransmkdir: ERROR: euid != 0,directory /tmp/.X11-unix will not be created.
@sasha0552 ➜ /workspaces/xrdp/genkeymap (devel) $ xvfb-run setxkbmap -v 10
Setting verbose level to 10
locale is C
Trying to load rules file ./rules/evdev...
Trying to load rules file /usr/share/X11/xkb/rules/evdev...
Success.
Applied rules from evdev:
rules:      evdev
model:      pc105
layout:     us
Trying to build keymap using the following components:
keycodes:   evdev+aliases(qwerty)
types:      complete
compat:     complete
symbols:    pc+us+inet(evdev)
geometry:   pc(pc105)
@sasha0552 ➜ /workspaces/xrdp/genkeymap (devel) $ xvfb-run setxkbmap -layout us -model pc104
@sasha0552 ➜ /workspaces/xrdp/genkeymap (devel) $ xvfb-run setxkbmap -v 10
Setting verbose level to 10
locale is C
Trying to load rules file ./rules/evdev...
Trying to load rules file /usr/share/X11/xkb/rules/evdev...
Success.
Applied rules from evdev:
rules:      evdev
model:      pc105
layout:     us
Trying to build keymap using the following components:
keycodes:   evdev+aliases(qwerty)
types:      complete
compat:     complete
symbols:    pc+us+inet(evdev)
geometry:   pc(pc105)

@matt335672
Copy link
Member

That's useful - thanks.

I'll update the script to incorporate that. Patch on the way...

@jsorg71
Copy link
Contributor

jsorg71 commented Apr 8, 2024

I think we are using the base rules not evdev. I've seen these defined in evdev but not all in base. We can just add them in Xorg that is not a problem. The problem I've seen is mstsc does not send them. @sasha0552 when you say 'tested/works', what client is that.

@sasha0552
Copy link
Contributor Author

@jsorg71 I'm using FreeRDP (xfreerdp).

@matt335672
Copy link
Member

@jsorg71 - I'm thinking that moving to evdev-based keycodes would be a good idea in any case. They're the default on Linux and FreeBSD, and it should make a lot of use-cases simpler to support. What are your thoughts on that? You've got a lot more experience in this area than I have.

@jsorg71
Copy link
Contributor

jsorg71 commented Apr 8, 2024

We can implement this even if it's not standard but it would be nice to confirm these freerdp rdp scancodes are correct either with a MS client for some MSDN documentation.

@matt335672
Copy link
Member

@sasha0552 - here's a patch which should make things a bit more consistent:-

--- a/genkeymap/dump-keymaps.sh
+++ b/genkeymap/dump-keymaps.sh
@@ -1,9 +1,22 @@
 #!/bin/sh
 
-if ! command -v setxkbmap >/dev/null
-then
-  echo "error, setxkbmap not found"
-  exit 1
+# Run the keymap extraction in a clean X session
+if [ "$1" != _IN_XVFB_SESSION_ ]; then
+    # All commands available?
+    ok=1
+    for cmd in setxkbmap xvfb-run xauth; do
+        if ! command -v $cmd >/dev/null
+        then
+          echo "Error. $cmd not found" >&2
+          ok=
+        fi
+    done
+    if [ -z "$ok" ]; then
+        exit 1
+    fi
+
+    xvfb-run --auto-servernum $0 _IN_XVFB_SESSION_
+    exit $?
 fi
 
 OLD_SETTINGS=$(setxkbmap -query -verbose 4 | sed "s/^\([a-z]\+\):\s*\(.*\)$/-\1 \2/;s/^-options/-option \"\" -option/;s/,/ -option /g" | xargs -d \\n)

Do you get the same keymaps for it?

@jsorg71 - I can look at mstsc.exe tomorrow, UK time. I've got a Windows laptop and a USB keyboard with Audio Up/Down/Mute keys on it. That should give us a clue whether we're looking in the right area or not.

@sasha0552
Copy link
Contributor Author

@matt335672
Thanks for the patch. Yes, the keymaps are the same. Nice that now we can just do ./dump-keymaps.sh without launching xvfb or using xvfb-run separately.

@jsorg71
Copy link
Contributor

jsorg71 commented Apr 8, 2024

I did test mstsc with browser back and forward and got no message to xrdp.

X11rdp did use evdev but there was problem. Then I noticed that FreeBSD and Xvnc were using base rules. In fact the only place Xorg used evdev was on Linux console.. Then I noticed it was called evdev because that is the Linux input driver name. It was heavily tied to the evdev Linux driver.

This may not be true today and it might be worth another try especially if Xvnc and Xorg on other platforms moved to evdev.

@matt335672
Copy link
Member

I've done a bit of testing this morning with a UK laptop manufactured by Acer. It's running Windows 10 and mstsc.exe

First I applied this patch so I could see what was coming over from the RDP client:-

--- a/xrdp/xrdp_wm.c
+++ b/xrdp/xrdp_wm.c
@@ -1573,7 +1573,9 @@ xrdp_wm_key(struct xrdp_wm *self, int device_flags, int scan_code)
     int msg;
     struct xrdp_key_info *ki;
 
-    /*g_printf("count %d\n", self->key_down_list->count);*/
+    LOG_DEVEL(LOG_LEVEL_DEBUG,
+              "xrdp_wm_key: RDP scancode:0x%04x, flags: 0x%04x",
+              scan_code, device_flags);
     scan_code = scan_code % 128;
 
     if (self->popup_wnd != 0)

mstsc.exe was configured as follows:-

  • full-screen.
  • ('Local resources' tab), Windows key combinations applied 'Only when using the full screen'.

The laptop keyboard is compact, but has media keys accessed via a key marked '[Fn]':-
mediakeys

The useful keys appear to be raise volume, lower volume, play, stop, previous, next.

The '[Fn]' key is invisible to the RDP protocol and is probably handled by the hardware, or by the keyboard driver.

I got the following results from this keyboard:-

Key RDP scancode Key down flags Key up flags
Raise Volume 0x30 0x4100 0x8100
Lower Volume 0x2e 0x4100 0x8100
Play 0x22 0x4100 0x8100
Stop 0x24 0x4100 0x8100
Previous 0x10 0x4100 0x8100
Next 0x19 0x4100 0x8100

Next I plugged in a USB keyboard. This is a cheap Dell keyboard. At a previous job we used to get crates of these when we took delivery of a bunch of Optiplex machines. We didn't need them. This keyboard also has media keys. Some of these are accessed via an Fn key and some aren't. Again the Fn key is not visible at an RDP protocol level:-

mediakeys2

Useful keys on this keyboard are search, previous, play, next, mute, lower volume, raise volume.

I got the following results from this keyboard:-

Key RDP scancode Key down flags Key up flags
Search 0x65 0x4100 0x8100
Previous 0x10 0x4100 0x8100
Play 0x22 0x4100 0x8100
Next 0x19 0x4100 0x8100
Mute 0x20 0x4100 0x8100
Lower Volume 0x2e 0x4100 0x8100
Raise Volume 0x30 0x4100 0x8100

Both of these are consistent. Also, putting them together, I can match them up with @sasha0552's table above:-

Key RDP scancode (hex) RDP scancode (decimal) evdev KeySym
Previous 0x10 16 XF86AudioPrev
Next 0x19 25 XF86AudioNext
Mute 0x20 32 XF86AudioMute
Play 0x22 34 XF86AudioPlay
Stop 0x24 36 XF86AudioStop
Lower Volume 0x2e 46 XF86AudioLowerVolume
Raise Volume 0x30 48 XF86AudioRaiseVolume
Search 0x65 101 XF86Search

In conclusion there appears to be some sort of standard at work here.

@rowlap
Copy link
Contributor

rowlap commented Apr 9, 2024

There's a table of scancodes with references at
https://deskthority.net/wiki/Scancode#Media_keys

AIUI the Fn key is special and not sent to the OS by itself, only in combination with other "functional" keys.

@matt335672
Copy link
Member

I get minor differences on Ubuntu 22.04 when I run the dump script, but nothing significant.

FreeBSD 14 doesn't have xvfb-run (it's GNU-specific) but if I copy it over and hack it about, I get the same results as 22.04. So I think the dump script is now stable.

As regards evdev vs base keymaps, there are three places which need to be aware of the RDP scancode to keycode map currently:-

  1. The key processing in lang.c
  2. The genkeymap utility
  3. xorgxrdp

That's two too many. I think we should have one place where the scancode to keycode map is stored. This can be hard-coded, or externally located in a file. Both are good. Having one location addresses the issue of which mapping to use as we can easily change it.

That said, I'd be happy to merge this as-is and then work on unifying the maps.

Thoughts?

@jsorg71
Copy link
Contributor

jsorg71 commented Apr 9, 2024

I see now why I've never seen these keys work with mstsc. You need to be full screen or you need to set 'Keyboard | Apply Windows key combinations' to 'On the remote computer'. Strange that these keys are considered like Alt Tab.

@matt335672
Copy link
Member

That's possibly it.

I had a slight 'duh' moment yesterday with the laptop keyboard when it took me a couple of minutes to realise why the brightness keys weren't being passed through to xrdp! In my defence, it was before my normal morning coffee.

My current thoughts on where we go from this are:-

  1. Merge this shortly. I've got at least one comment to add for review.
  2. I'll produce a mapping module in 'common' which maps RDP scancodes to keycodes - initially just evdev.
  3. Use 2) in the genkeymap utility to change the mapping files to map RDP scancodes direct to KeySym / Unicode values. This means at runtime for login and VNC we've taken keycodes completely away.
  4. Work with @sasha0552 and use 2) in xup to pass both RDP scancodes and keycodes to xorgxrdp

If we then need to use base mappings on platforms without evdev we just need to update 2)

Thoughts/objections anyone? I know this is a complicated area However, if we're going to get these maps sorted out I need to really be on top of it as we'll potentially have a few user issues to triage when it goes live.

@matt335672
Copy link
Member

I was going to add a review comment about some of the keyboards not being auto-generated, but having looked into this there seems to be a significant issue here which I don't think we can address in this PR.

The following keyboards in the instfiles directory are not currently autogenerated:-

Code (see [MS-LCID] Language Attempted command
0x00000406 Danish 'da-DK' setxkbmap -model pc105 -layout dk
0x0000040a Spanish 'es-ES_tradnl' setxkbmap -model pc105 -layout es
0x0000040b Finnish 'fi-FI' setxkbmap -model pc105 -layout fi
0x0000040c French 'fr-FR' setxkbmap -model pc105 -layout fr
0x00000412 Korean 'ko-KR' setxkbmap -model pc105 -layout kr
0x00000414 Norwegian 'nb-NO' setxkbmap -model pc105 -layout no
0x00000416 Brazilian 'pt-BR' setxkbmap -model pc105 -layout br
0x00000807 German - Swiss 'de-CH' setxkbmap -model pc105 -layout ch
0x0000080a Spanish - Mexico 'es-MX' setxkbmap -model pc105 -layout latam
0x0000080c French - Belgian 'fr-BE' setxkbmap -model pc105 -layout be -variant oss
0x00000813 Dutch - Belgian 'nl-BE' setxkbmap -model pc105 -layout be
0x0000100c French - Swiss 'fr-CH' setxkbmap -model pc105 -layout ch -variant fr

Having tried to add these, I'm getting significant differences around some of the keys, in particular AE11, AE12, AD11 and AD12.

It's possible these files were generated on a different X server, or the users weren't bothered about these keys as they were only using the keymaps to log in - I can't tell which. However, at the moment it seems these keymap files are unmaintainable.

I'll sweep these up when I regenerate the files to map directly from RDP scancodes.

@matt335672
Copy link
Member

@sasha0552 - sorry it's taking a while to merge this, but I'm still exploring this area in general.

I've done a bit more testing with the generated keymaps, and I've found another potential snag for the future which is related to a change in the delivered XKB config.

When I re-run the dump-keymaps.sh script on a 22.04 LTS system (rather than 20.04), I get different settings for keys 79-91. I did some digging around and found this which was been applied to the XKB config in 22.04.

https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/merge_requests/229/diffs

Before that patch, Shift and NumLock had the same effect on the keypad. After the patch, Shift no longer produces the same results.

Why does this matter? There's some code in lang.c to cope with num lock being pressed:-

xrdp/xrdp/lang.c

Lines 87 to 98 in 0a0a393

/* keymap file is created with numlock off so we have to do this */
if ((index >= 79) && (index <= 91))
{
if (num_lock)
{
rv = &(keymap->keys_shift[index]);
}
else
{
rv = &(keymap->keys_noshift[index]);
}
}

In the fragment above, index contains a X11 keycode (from base) which maps as follows:-

X11 keycode RDP Scancode KeySym
79 0x47 KP7
80 0x48 KP8
81 0x49 KP9
82 0x4A KPSU
83 0x4B KP4
84 0x4C KP5
85 0x4D KP6
86 0x4E KDAD
87 0x4F KP1
88 0x50 KP2
89 0x51 KP3
90 0x52 KP0
91 0x53 KPDL

If I take (for example) the '[noshift]' and '[shift]' sections from km-00000809.ini I get this:-

[noshift]
...
Key79=65429:0
Key80=65431:0
Key81=65434:0
Key82=65453:45
Key83=65430:0
Key84=65437:0
Key85=65432:0
Key86=65451:43
Key87=65436:0
Key88=65433:0
Key89=65435:0
Key90=65438:0
Key91=65439:0

...
[shift]
...
Key79=65463:55
Key80=65464:56
Key81=65465:57
Key82=65453:45
Key83=65460:52
Key84=65461:53
Key85=65462:54
Key86=65451:43
Key87=65457:49
Key88=65458:50
Key89=65459:51
Key90=65456:48
Key91=65454:46

You can see that these are different, and the code above generates different results when NumLock is pressed.

On an Ubuntu 22.04 system, if I run ./dump_keymaps.sh, I get the same codes for the keypad keys in both sections, and as a result the NumLock keys stop working.

It seems likely that moving forward we will need to generate a separate NumLock section in the keymaps.

@tim-gromeyer
Copy link

Any progress on this? The media keys are quite important to me

@matt335672
Copy link
Member

@tim-gromeyer - I'm working through a bit of a backlog at the moment but this is on the list.

Be aware that this PR and #3039 will get media keys working for VNC-based sessions. For xorgxrdp-based sessions there's a bit more work to do. #3039 centralises the RDP scancode -> X11 keycode mappings in xrdp itself, and makes these available to xorgxrdp. We also need to modify xorgxrdp to make use of these.

@matt335672 matt335672 merged commit d32737a into neutrinolabs:devel May 24, 2024
13 checks passed
@matt335672
Copy link
Member

Thanks @sasha0552, and sorry about the delay.

I've rebased #3039, and after running it through CI checks will merge that too. That should let us get on with finishing off neutrinolabs/xorgxrdp#303 as well.

matt335672 added a commit to matt335672/xrdp that referenced this pull request Dec 23, 2024
The file itself has been generated on an Ubuntu 20.04 system to
avoid a non-working numlock. See this PR for more details:-

neutrinolabs#3022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Media keys have wrong keycode in XRDP session
6 participants