diff --git a/genkeymap/dump-keymaps.sh b/genkeymap/dump-keymaps.sh index 155cbaf0b0..6248530df3 100755 --- a/genkeymap/dump-keymaps.sh +++ b/genkeymap/dump-keymaps.sh @@ -18,7 +18,10 @@ kbgen() desc="$2" os="$3" shift 3 - setxkbmap "$@" + if ! setxkbmap "$@"; then + echo "Failed to run setxkbmap $*" >&2 + return 1 + fi ./xrdp-genkeymap \ -c "Description: $desc" \ -c "Operating system: $os" \ @@ -68,7 +71,8 @@ fi kbgen 0406 "da-DK" "$os" -model pc105 -layout dk kbgen 0407 "de-DE" "$os" -model pc104 -layout de kbgen 0409 "en-US" "$os" -model pc104 -layout us -kbgen 10409 "en-US" "$os" -model pc104 -layout dvorak +kbgen 10409 "en-US" "$os" -model pc104 -layout us -variant dvorak +kbgen 60409 "en-US" "$os" -model pc104 -layout us -variant colemak kbgen 040a "es-ES_tradnl" "$os" -model pc105 -layout es kbgen 040b "fi-FI" "$os" -model pc105 -layout 'fi' kbgen 040c "fr-FR" "$os" -model pc105 -layout fr diff --git a/genkeymap/genkeymap.c b/genkeymap/genkeymap.c index badc75aa73..9f0095dd8a 100644 --- a/genkeymap/genkeymap.c +++ b/genkeymap/genkeymap.c @@ -317,6 +317,34 @@ output_file_section(FILE *outf, } +/*****************************************************************************/ +/** + * Determine is caps-lock is supported. Some layouts (e.g. Colemak) do not + * support this key. + * + * @param dpy X display + * @reurn boolean + */ +static int +is_caps_lock_supported(Display *dpy) +{ + char dummy[4]; + KeySym ks; + XKeyPressedEvent e = + { + .type = KeyPress, + .serial = 16, + .send_event = True, + .display = dpy, + .state = 0, + .keycode = scancode_to_x11_keycode(SCANCODE_CAPS_KEY), + .same_screen = True + }; + + (void)XLookupString(&e, dummy, sizeof(dummy), &ks, NULL); + return (ks == XK_Caps_Lock || ks == XK_Eisu_toggle); +} + /*****************************************************************************/ /** * Main @@ -345,6 +373,7 @@ int main(int argc, char **argv) const char *keycode_set = NULL; struct kbd_info *kbd_info = NULL; int status = 1; + int caps_lock_supported; setlocale(LC_CTYPE, ""); if (strrchr(argv[0], '/') != NULL) @@ -418,6 +447,8 @@ int main(int argc, char **argv) goto finish; } + caps_lock_supported = is_caps_lock_supported(dpy); + fprintf(outf, "# Created by %s V" PACKAGE_VERSION "\n# Key code set: %s\n", programname, keycode_set); @@ -430,10 +461,18 @@ int main(int argc, char **argv) } fprintf(outf, "\n[General]\nversion=" KEYMAP_FILE_FORMAT_VERSION "\n"); + fprintf(outf, "caps_lock_supported=%s\n", + (caps_lock_supported) ? "true" : "false"); for (idx = 0; idx < NUM_STATES; idx++) /* Sections and states */ { - output_file_section(outf, dpy, sections[idx], states[idx]); + int mod_state = states[idx]; + if (!caps_lock_supported && ((mod_state & 2) != 0)) + { + // Skip this section as it's for caps lock + continue; + } + output_file_section(outf, dpy, sections[idx], mod_state); } status = 0; // Successful run diff --git a/instfiles/Makefile.am b/instfiles/Makefile.am index 9fd5d3d512..5c7f4279b3 100644 --- a/instfiles/Makefile.am +++ b/instfiles/Makefile.am @@ -51,6 +51,7 @@ dist_startscript_DATA = \ km-00000816.toml \ km-0000100c.toml \ km-00010409.toml \ + km-00060409.toml \ km-19360409.toml # diff --git a/instfiles/km-00000406.toml b/instfiles/km-00000406.toml index 8d52b9d25c..436c00a3ef 100644 --- a/instfiles/km-00000406.toml +++ b/instfiles/km-00000406.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwerty) # setxkbmap -rules evdev -model pc105 -layout dk # Description: da-DK -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-00000407.toml b/instfiles/km-00000407.toml index 167d6dea7c..9ad8efdc15 100644 --- a/instfiles/km-00000407.toml +++ b/instfiles/km-00000407.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwertz) # setxkbmap -rules evdev -model pc104 -layout de # Description: de-DE -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-00000409.toml b/instfiles/km-00000409.toml index 701949708b..94bcbca324 100644 --- a/instfiles/km-00000409.toml +++ b/instfiles/km-00000409.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwerty) # setxkbmap -rules evdev -model pc104 -layout us # Description: en-US -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-0000040a.toml b/instfiles/km-0000040a.toml index 3be3c3acef..c2f99036c4 100644 --- a/instfiles/km-0000040a.toml +++ b/instfiles/km-0000040a.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwerty) # setxkbmap -rules evdev -model pc105 -layout es # Description: es-ES_tradnl -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-0000040b.toml b/instfiles/km-0000040b.toml index de4cb8d72f..2719f954ea 100644 --- a/instfiles/km-0000040b.toml +++ b/instfiles/km-0000040b.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwerty) # setxkbmap -rules evdev -model pc105 -layout fi # Description: fi-FI -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-0000040c.toml b/instfiles/km-0000040c.toml index 9b0f50e8fc..4cd3c93b46 100644 --- a/instfiles/km-0000040c.toml +++ b/instfiles/km-0000040c.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(azerty) # setxkbmap -rules evdev -model pc105 -layout fr # Description: fr-FR -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-00000410.toml b/instfiles/km-00000410.toml index 4f53b9c3a6..3e9c91df02 100644 --- a/instfiles/km-00000410.toml +++ b/instfiles/km-00000410.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwerty) # setxkbmap -rules evdev -model pc104 -layout it # Description: it-IT -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-00000411.toml b/instfiles/km-00000411.toml index 3eca81beea..9d4921dff6 100644 --- a/instfiles/km-00000411.toml +++ b/instfiles/km-00000411.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwerty) # setxkbmap -rules evdev -model pc105 -layout jp -variant OADG109A # Description: ja-JP -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-00000412.toml b/instfiles/km-00000412.toml index 1a745253f4..8675569eca 100644 --- a/instfiles/km-00000412.toml +++ b/instfiles/km-00000412.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwerty) # setxkbmap -rules evdev -model pc105 -layout kr # Description: ko-KR -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-00000414.toml b/instfiles/km-00000414.toml index 7786caed40..e534dc430e 100644 --- a/instfiles/km-00000414.toml +++ b/instfiles/km-00000414.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwerty) # setxkbmap -rules evdev -model pc105 -layout no # Description: nb-NO -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-00000415.toml b/instfiles/km-00000415.toml index 390b87c41b..b8fc33eb76 100644 --- a/instfiles/km-00000415.toml +++ b/instfiles/km-00000415.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwerty) # setxkbmap -rules evdev -model pc104 -layout pl # Description: pl-PL -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-00000416.toml b/instfiles/km-00000416.toml index 29d2072f4d..c4d9622f1b 100644 --- a/instfiles/km-00000416.toml +++ b/instfiles/km-00000416.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwerty) # setxkbmap -rules evdev -model pc105 -layout br # Description: pt-BR -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-00000419.toml b/instfiles/km-00000419.toml index 6251bb75eb..89be89d1b6 100644 --- a/instfiles/km-00000419.toml +++ b/instfiles/km-00000419.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwerty) # setxkbmap -rules evdev -model pc104 -layout ru # Description: ru-RU -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-0000041d.toml b/instfiles/km-0000041d.toml index 4a3211121e..d460256c77 100644 --- a/instfiles/km-0000041d.toml +++ b/instfiles/km-0000041d.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwerty) # setxkbmap -rules evdev -model pc104 -layout se # Description: sv-SE -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-00000807.toml b/instfiles/km-00000807.toml index 34b6fee168..d6d94b5e2b 100644 --- a/instfiles/km-00000807.toml +++ b/instfiles/km-00000807.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwertz) # setxkbmap -rules evdev -model pc105 -layout ch # Description: de-CH -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-00000809.toml b/instfiles/km-00000809.toml index 97b9bf9983..7f3f1e8104 100644 --- a/instfiles/km-00000809.toml +++ b/instfiles/km-00000809.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwerty) # setxkbmap -rules evdev -model pc105 -layout gb # Description: en-GB -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-0000080a.toml b/instfiles/km-0000080a.toml index 8157ffc861..ebdf1f7fc4 100644 --- a/instfiles/km-0000080a.toml +++ b/instfiles/km-0000080a.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwerty) # setxkbmap -rules evdev -model pc105 -layout latam # Description: es-MX -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-0000080c.toml b/instfiles/km-0000080c.toml index c99f073134..ef2b4d4f01 100644 --- a/instfiles/km-0000080c.toml +++ b/instfiles/km-0000080c.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(azerty) # setxkbmap -rules evdev -model pc105 -layout be -variant oss # Description: fr-BE -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-00000813.toml b/instfiles/km-00000813.toml index 5756717b77..53001b46d7 100644 --- a/instfiles/km-00000813.toml +++ b/instfiles/km-00000813.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(azerty) # setxkbmap -rules evdev -model pc105 -layout be # Description: nl-BE -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-00000816.toml b/instfiles/km-00000816.toml index 05e6678987..b237917422 100644 --- a/instfiles/km-00000816.toml +++ b/instfiles/km-00000816.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwerty) # setxkbmap -rules evdev -model pc104 -layout pt # Description: pt-PT -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-0000100c.toml b/instfiles/km-0000100c.toml index 80b85212aa..0ad3a5f1b8 100644 --- a/instfiles/km-0000100c.toml +++ b/instfiles/km-0000100c.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwertz) # setxkbmap -rules evdev -model pc105 -layout ch -variant fr # Description: fr-CH -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-00010409.toml b/instfiles/km-00010409.toml index 654a26f065..30f8d52d69 100644 --- a/instfiles/km-00010409.toml +++ b/instfiles/km-00010409.toml @@ -1,11 +1,12 @@ # Created by xrdp-genkeymap V0.10.80 # Key code set: evdev+aliases(qwerty) -# setxkbmap -rules evdev -model pc104 -layout dvorak +# setxkbmap -rules evdev -model pc104 -layout us -variant dvorak # Description: en-US -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/instfiles/km-00060409.toml b/instfiles/km-00060409.toml new file mode 100644 index 0000000000..edef50b3dc --- /dev/null +++ b/instfiles/km-00060409.toml @@ -0,0 +1,520 @@ +# Created by xrdp-genkeymap V0.10.80 +# Key code set: evdev+aliases(qwerty) +# setxkbmap -rules evdev -model pc104 -layout us -variant colemak +# Description: en-US +# Operating system: Ubuntu 22.04.5 LTS + +[General] +version=2 +caps_lock_supported=false + +[noshift] +01="65307:U+001B" # Escape +02="49:U+0031" # 1 +03="50:U+0032" # 2 +04="51:U+0033" # 3 +05="52:U+0034" # 4 +06="53:U+0035" # 5 +07="54:U+0036" # 6 +08="55:U+0037" # 7 +09="56:U+0038" # 8 +0A="57:U+0039" # 9 +0B="48:U+0030" # 0 +0C="45:U+002D" # minus +0D="61:U+003D" # equal +0E="65288:U+0008" # BackSpace +0F="65289:U+0009" # Tab +10="113:U+0071" # q +11="119:U+0077" # w +12="102:U+0066" # f +13="112:U+0070" # p +14="103:U+0067" # g +15="106:U+006A" # j +16="108:U+006C" # l +17="117:U+0075" # u +18="121:U+0079" # y +19="59:U+003B" # semicolon +1A="91:U+005B" # bracketleft +1B="93:U+005D" # bracketright +1C="65293:U+000D" # Return +1D="65507" # Control_L +1E="97:U+0061" # a +1F="114:U+0072" # r +20="115:U+0073" # s +21="116:U+0074" # t +22="100:U+0064" # d +23="104:U+0068" # h +24="110:U+006E" # n +25="101:U+0065" # e +26="105:U+0069" # i +27="111:U+006F" # o +28="39:U+0027" # apostrophe +29="96:U+0060" # grave +2A="65505" # Shift_L +2B="92:U+005C" # backslash +2C="122:U+007A" # z +2D="120:U+0078" # x +2E="99:U+0063" # c +2F="118:U+0076" # v +30="98:U+0062" # b +31="107:U+006B" # k +32="109:U+006D" # m +33="44:U+002C" # comma +34="46:U+002E" # period +35="47:U+002F" # slash +36="65506" # Shift_R +37="65450:U+002A" # KP_Multiply +38="65513" # Alt_L +39="32:U+0020" # space +3A="65288:U+0008" # BackSpace +3B="65470" # F1 +3C="65471" # F2 +3D="65472" # F3 +3E="65473" # F4 +3F="65474" # F5 +40="65475" # F6 +41="65476" # F7 +42="65477" # F8 +43="65478" # F9 +44="65479" # F10 +45="65407" # Num_Lock +46="65300" # Scroll_Lock +47="65429" # KP_Home +48="65431" # KP_Up +49="65434" # KP_Prior +4A="65453:U+002D" # KP_Subtract +4B="65430" # KP_Left +4C="65437" # KP_Begin +4D="65432" # KP_Right +4E="65451:U+002B" # KP_Add +4F="65436" # KP_End +50="65433" # KP_Down +51="65435" # KP_Next +52="65438" # KP_Insert +53="65439" # KP_Delete +56="45:U+002D" # minus +57="65480" # F11 +58="65481" # F12 +70="65319" # Hiragana_Katakana +79="65315" # Henkan_Mode +7B="65314" # Muhenkan +7E="65454:U+002E" # KP_Decimal +E0_10="269025046" # XF86AudioPrev +E0_19="269025047" # XF86AudioNext +E0_1C="65421:U+000D" # KP_Enter +E0_1D="65508" # Control_R +E0_20="269025042" # XF86AudioMute +E0_21="269025053" # XF86Calculator +E0_22="269025044" # XF86AudioPlay +E0_24="269025045" # XF86AudioStop +E0_2E="269025041" # XF86AudioLowerVolume +E0_30="269025043" # XF86AudioRaiseVolume +E0_32="269025048" # XF86HomePage +E0_35="65455:U+002F" # KP_Divide +E0_37="65377" # Print +E0_38="65027" # ISO_Level3_Shift +E0_47="65360" # Home +E0_48="65362" # Up +E0_49="65365" # Prior +E0_4B="65361" # Left +E0_4D="65363" # Right +E0_4F="65367" # End +E0_50="65364" # Down +E0_51="65366" # Next +E0_52="65379" # Insert +E0_53="65535:U+007F" # Delete +E0_5B="65515" # Super_L +E0_5C="65516" # Super_R +E0_5D="65383" # Menu +E0_65="269025051" # XF86Search +E0_66="269025072" # XF86Favorites +E0_6B="269025075" # XF86MyComputer +E0_6C="269025049" # XF86Mail +E1_1D="65299" # Pause + +[shift] +01="65307:U+001B" # Escape +02="33:U+0021" # exclam +03="64:U+0040" # at +04="35:U+0023" # numbersign +05="36:U+0024" # dollar +06="37:U+0025" # percent +07="94:U+005E" # asciicircum +08="38:U+0026" # ampersand +09="42:U+002A" # asterisk +0A="40:U+0028" # parenleft +0B="41:U+0029" # parenright +0C="95:U+005F" # underscore +0D="43:U+002B" # plus +0E="65288:U+0008" # BackSpace +0F="65056" # ISO_Left_Tab +10="81:U+0051" # Q +11="87:U+0057" # W +12="70:U+0046" # F +13="80:U+0050" # P +14="71:U+0047" # G +15="74:U+004A" # J +16="76:U+004C" # L +17="85:U+0055" # U +18="89:U+0059" # Y +19="58:U+003A" # colon +1A="123:U+007B" # braceleft +1B="125:U+007D" # braceright +1C="65293:U+000D" # Return +1D="65507" # Control_L +1E="65:U+0041" # A +1F="82:U+0052" # R +20="83:U+0053" # S +21="84:U+0054" # T +22="68:U+0044" # D +23="72:U+0048" # H +24="78:U+004E" # N +25="69:U+0045" # E +26="73:U+0049" # I +27="79:U+004F" # O +28="34:U+0022" # quotedbl +29="126:U+007E" # asciitilde +2A="65505" # Shift_L +2B="124:U+007C" # bar +2C="90:U+005A" # Z +2D="88:U+0058" # X +2E="67:U+0043" # C +2F="86:U+0056" # V +30="66:U+0042" # B +31="75:U+004B" # K +32="77:U+004D" # M +33="60:U+003C" # less +34="62:U+003E" # greater +35="63:U+003F" # question +36="65506" # Shift_R +37="65450:U+002A" # KP_Multiply +38="65511" # Meta_L +39="32:U+0020" # space +3A="65288:U+0008" # BackSpace +3B="65470" # F1 +3C="65471" # F2 +3D="65472" # F3 +3E="65473" # F4 +3F="65474" # F5 +40="65475" # F6 +41="65476" # F7 +42="65477" # F8 +43="65478" # F9 +44="65479" # F10 +45="65407" # Num_Lock +46="65300" # Scroll_Lock +47="65429" # KP_Home +48="65431" # KP_Up +49="65434" # KP_Prior +4A="65453:U+002D" # KP_Subtract +4B="65430" # KP_Left +4C="65437" # KP_Begin +4D="65432" # KP_Right +4E="65451:U+002B" # KP_Add +4F="65436" # KP_End +50="65433" # KP_Down +51="65435" # KP_Next +52="65438" # KP_Insert +53="65439" # KP_Delete +56="95:U+005F" # underscore +57="65480" # F11 +58="65481" # F12 +70="65319" # Hiragana_Katakana +79="65315" # Henkan_Mode +7B="65314" # Muhenkan +7E="65454:U+002E" # KP_Decimal +E0_10="269025046" # XF86AudioPrev +E0_19="269025047" # XF86AudioNext +E0_1C="65421:U+000D" # KP_Enter +E0_1D="65508" # Control_R +E0_20="269025042" # XF86AudioMute +E0_21="269025053" # XF86Calculator +E0_22="269025073" # XF86AudioPause +E0_24="269025068" # XF86Eject +E0_2E="269025041" # XF86AudioLowerVolume +E0_30="269025043" # XF86AudioRaiseVolume +E0_32="269025048" # XF86HomePage +E0_35="65455:U+002F" # KP_Divide +E0_37="65377" # Print +E0_38="65027" # ISO_Level3_Shift +E0_47="65360" # Home +E0_48="65362" # Up +E0_49="65365" # Prior +E0_4B="65361" # Left +E0_4D="65363" # Right +E0_4F="65367" # End +E0_50="65364" # Down +E0_51="65366" # Next +E0_52="65379" # Insert +E0_53="65535:U+007F" # Delete +E0_5B="65515" # Super_L +E0_5C="65516" # Super_R +E0_5D="65383" # Menu +E0_65="269025051" # XF86Search +E0_66="269025072" # XF86Favorites +E0_6B="269025075" # XF86MyComputer +E0_6C="269025049" # XF86Mail +E1_1D="65299" # Pause + +[altgr] +01="65307:U+001B" # Escape +02="161:U+00A1" # exclamdown +03="186:U+00BA" # masculine +04="170:U+00AA" # ordfeminine +05="162:U+00A2" # cent +06="8364:U+20AC" # EuroSign +07="689:U+0127" # hstroke +08="240:U+00F0" # eth +09="254:U+00FE" # thorn +0A="2768:U+2018" # leftsinglequotemark +0B="2769:U+2019" # rightsinglequotemark +0C="2730:U+2013" # endash +0D="215:U+00D7" # multiply +0E="65288:U+0008" # BackSpace +0F="65289:U+0009" # Tab +10="228:U+00E4" # adiaeresis +11="229:U+00E5" # aring +12="227:U+00E3" # atilde +13="248:U+00F8" # oslash +14="65116:U+02DB" # dead_ogonek +15="496:U+0111" # dstroke +16="435:U+0142" # lstroke +17="250:U+00FA" # uacute +18="252:U+00FC" # udiaeresis +19="246:U+00F6" # odiaeresis +1A="171:U+00AB" # guillemotleft +1B="187:U+00BB" # guillemotright +1C="65293:U+000D" # Return +1D="65507" # Control_L +1E="225:U+00E1" # aacute +1F="65104:U+0060" # dead_grave +20="223:U+00DF" # ssharp +21="65105:U+00B4" # dead_acute +22="65111:U+00A8" # dead_diaeresis +23="65114:U+02C7" # dead_caron +24="241:U+00F1" # ntilde +25="233:U+00E9" # eacute +26="237:U+00ED" # iacute +27="243:U+00F3" # oacute +28="245:U+00F5" # otilde +29="65107:U+007E" # dead_tilde +2A="65505" # Shift_L +2B="126:U+007E" # asciitilde +2C="230:U+00E6" # ae +2D="65106:U+005E" # dead_circumflex +2E="231:U+00E7" # ccedilla +2F="5053:U+0153" # oe +30="65109:U+02D8" # dead_breve +31="65112:U+00B0" # dead_abovering +32="65108:U+00AF" # dead_macron +33="65115:U+00B8" # dead_cedilla +34="65110:U+02D9" # dead_abovedot +35="191:U+00BF" # questiondown +36="65506" # Shift_R +37="65450:U+002A" # KP_Multiply +38="65513" # Alt_L +39="32:U+0020" # space +3A="65288:U+0008" # BackSpace +3B="65470" # F1 +3C="65471" # F2 +3D="65472" # F3 +3E="65473" # F4 +3F="65474" # F5 +40="65475" # F6 +41="65476" # F7 +42="65477" # F8 +43="65478" # F9 +44="65479" # F10 +45="65407" # Num_Lock +46="65300" # Scroll_Lock +47="65429" # KP_Home +48="65431" # KP_Up +49="65434" # KP_Prior +4A="65453:U+002D" # KP_Subtract +4B="65430" # KP_Left +4C="65437" # KP_Begin +4D="65432" # KP_Right +4E="65451:U+002B" # KP_Add +4F="65436" # KP_End +50="65433" # KP_Down +51="65435" # KP_Next +52="65438" # KP_Insert +53="65439" # KP_Delete +56="2730:U+2013" # endash +57="65480" # F11 +58="65481" # F12 +70="65319" # Hiragana_Katakana +79="65315" # Henkan_Mode +7B="65314" # Muhenkan +7E="65454:U+002E" # KP_Decimal +E0_10="269025046" # XF86AudioPrev +E0_19="269025047" # XF86AudioNext +E0_1C="65421:U+000D" # KP_Enter +E0_1D="65508" # Control_R +E0_20="269025042" # XF86AudioMute +E0_21="269025053" # XF86Calculator +E0_22="269025044" # XF86AudioPlay +E0_24="269025045" # XF86AudioStop +E0_2E="269025041" # XF86AudioLowerVolume +E0_30="269025043" # XF86AudioRaiseVolume +E0_32="269025048" # XF86HomePage +E0_35="65455:U+002F" # KP_Divide +E0_37="65377" # Print +E0_38="65027" # ISO_Level3_Shift +E0_47="65360" # Home +E0_48="65362" # Up +E0_49="65365" # Prior +E0_4B="65361" # Left +E0_4D="65363" # Right +E0_4F="65367" # End +E0_50="65364" # Down +E0_51="65366" # Next +E0_52="65379" # Insert +E0_53="65535:U+007F" # Delete +E0_5B="65515" # Super_L +E0_5C="65516" # Super_R +E0_5D="65383" # Menu +E0_65="269025051" # XF86Search +E0_66="269025072" # XF86Favorites +E0_6B="269025075" # XF86MyComputer +E0_6C="269025049" # XF86Mail +E1_1D="65299" # Pause + +[shiftaltgr] +01="65307:U+001B" # Escape +02="185:U+00B9" # onesuperior +03="178:U+00B2" # twosuperior +04="179:U+00B3" # threesuperior +05="163:U+00A3" # sterling +06="165:U+00A5" # yen +07="673:U+0126" # Hstroke +08="208:U+00D0" # ETH +09="222:U+00DE" # THORN +0A="2770:U+201C" # leftdoublequotemark +0B="2771:U+201D" # rightdoublequotemark +0C="2729:U+2014" # emdash +0D="247:U+00F7" # division +0E="65288:U+0008" # BackSpace +0F="65056" # ISO_Left_Tab +10="196:U+00C4" # Adiaeresis +11="197:U+00C5" # Aring +12="195:U+00C3" # Atilde +13="216:U+00D8" # Oslash +14="126:U+007E" # asciitilde +15="464:U+0110" # Dstroke +16="419:U+0141" # Lstroke +17="218:U+00DA" # Uacute +18="220:U+00DC" # Udiaeresis +19="214:U+00D6" # Odiaeresis +1A="16785465:U+2039" # U2039 +1B="16785466:U+203A" # U203A +1C="65293:U+000D" # Return +1D="65507" # Control_L +1E="193:U+00C1" # Aacute +1F="126:U+007E" # asciitilde +20="16785054:U+1E9E" # U1E9E +21="65113:U+02DD" # dead_doubleacute +22="126:U+007E" # asciitilde +23="126:U+007E" # asciitilde +24="209:U+00D1" # Ntilde +25="201:U+00C9" # Eacute +26="205:U+00CD" # Iacute +27="211:U+00D3" # Oacute +28="213:U+00D5" # Otilde +29="126:U+007E" # asciitilde +2A="65505" # Shift_L +2B="126:U+007E" # asciitilde +2C="198:U+00C6" # AE +2D="126:U+007E" # asciitilde +2E="199:U+00C7" # Ccedilla +2F="5052:U+0152" # OE +30="126:U+007E" # asciitilde +31="126:U+007E" # asciitilde +32="126:U+007E" # asciitilde +33="126:U+007E" # asciitilde +34="126:U+007E" # asciitilde +35="126:U+007E" # asciitilde +36="65506" # Shift_R +37="65450:U+002A" # KP_Multiply +38="65511" # Meta_L +39="160:U+00A0" # nobreakspace +3A="65288:U+0008" # BackSpace +3B="65470" # F1 +3C="65471" # F2 +3D="65472" # F3 +3E="65473" # F4 +3F="65474" # F5 +40="65475" # F6 +41="65476" # F7 +42="65477" # F8 +43="65478" # F9 +44="65479" # F10 +45="65407" # Num_Lock +46="65300" # Scroll_Lock +47="65429" # KP_Home +48="65431" # KP_Up +49="65434" # KP_Prior +4A="65453:U+002D" # KP_Subtract +4B="65430" # KP_Left +4C="65437" # KP_Begin +4D="65432" # KP_Right +4E="65451:U+002B" # KP_Add +4F="65436" # KP_End +50="65433" # KP_Down +51="65435" # KP_Next +52="65438" # KP_Insert +53="65439" # KP_Delete +56="2729:U+2014" # emdash +57="65480" # F11 +58="65481" # F12 +70="65319" # Hiragana_Katakana +79="65315" # Henkan_Mode +7B="65314" # Muhenkan +7E="65454:U+002E" # KP_Decimal +E0_10="269025046" # XF86AudioPrev +E0_19="269025047" # XF86AudioNext +E0_1C="65421:U+000D" # KP_Enter +E0_1D="65508" # Control_R +E0_20="269025042" # XF86AudioMute +E0_21="269025053" # XF86Calculator +E0_22="269025073" # XF86AudioPause +E0_24="269025068" # XF86Eject +E0_2E="269025041" # XF86AudioLowerVolume +E0_30="269025043" # XF86AudioRaiseVolume +E0_32="269025048" # XF86HomePage +E0_35="65455:U+002F" # KP_Divide +E0_37="65377" # Print +E0_38="65027" # ISO_Level3_Shift +E0_47="65360" # Home +E0_48="65362" # Up +E0_49="65365" # Prior +E0_4B="65361" # Left +E0_4D="65363" # Right +E0_4F="65367" # End +E0_50="65364" # Down +E0_51="65366" # Next +E0_52="65379" # Insert +E0_53="65535:U+007F" # Delete +E0_5B="65515" # Super_L +E0_5C="65516" # Super_R +E0_5D="65383" # Menu +E0_65="269025051" # XF86Search +E0_66="269025072" # XF86Favorites +E0_6B="269025075" # XF86MyComputer +E0_6C="269025049" # XF86Mail +E1_1D="65299" # Pause + +[numlock] +47="65463:U+0037" # KP_7 +48="65464:U+0038" # KP_8 +49="65465:U+0039" # KP_9 +4A="65453:U+002D" # KP_Subtract +4B="65460:U+0034" # KP_4 +4C="65461:U+0035" # KP_5 +4D="65462:U+0036" # KP_6 +4E="65451:U+002B" # KP_Add +4F="65457:U+0031" # KP_1 +50="65458:U+0032" # KP_2 +51="65459:U+0033" # KP_3 +52="65456:U+0030" # KP_0 +53="65454:U+002E" # KP_Decimal diff --git a/instfiles/km-19360409.toml b/instfiles/km-19360409.toml index 679ed76356..905fac2489 100644 --- a/instfiles/km-19360409.toml +++ b/instfiles/km-19360409.toml @@ -2,10 +2,11 @@ # Key code set: evdev+aliases(qwerty) # setxkbmap -rules evdev -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 # Description: en-US -# Operating system: Ubuntu 22.04.4 LTS +# Operating system: Ubuntu 22.04.5 LTS [General] version=2 +caps_lock_supported=true [noshift] 01="65307:U+001B" # Escape diff --git a/xrdp/lang.c b/xrdp/lang.c index 77280e7389..23db4a122f 100644 --- a/xrdp/lang.c +++ b/xrdp/lang.c @@ -37,6 +37,21 @@ ((d) >= 'a' && (d) <= 'f') ? (d) - 'a' + 10 : \ (d) - 'A' + 10) +/* + * Struct representing the contents of a km file [General] section + */ +struct km_general +{ + unsigned int version; + int caps_lock_supported; +}; + +const struct km_general km_general_default = +{ + .version = 0, + .caps_lock_supported = 1 +}; + /*****************************************************************************/ struct xrdp_key_info * get_key_info_from_kbd_event(int keyboard_flags, int key_code, int *keys, @@ -53,6 +68,9 @@ get_key_info_from_kbd_event(int keyboard_flags, int key_code, int *keys, rv = 0; index = scancode_to_index(SCANCODE_FROM_KBD_EVENT(key_code, keyboard_flags)); + // Don't take caps_lock into account if the keymap doesn't support it. + caps_lock = caps_lock && keymap->caps_lock_supported; + if (index >= 0) { // scancode_to_index() guarantees to map numlock scancodes @@ -100,46 +118,6 @@ get_key_info_from_kbd_event(int keyboard_flags, int key_code, int *keys, return rv; } -/*****************************************************************************/ -int -get_keysym_from_kbd_event(int keyboard_flags, int key_code, int *keys, - int caps_lock, int num_lock, int scroll_lock, - struct xrdp_keymap *keymap) -{ - struct xrdp_key_info *ki; - - ki = get_key_info_from_kbd_event(keyboard_flags, key_code, keys, - caps_lock, num_lock, scroll_lock, - keymap); - - if (ki == 0) - { - return 0; - } - - return ki->sym; -} - -/*****************************************************************************/ -char32_t -get_char_from_kbd_event(int keyboard_flags, int key_code, int *keys, - int caps_lock, int num_lock, int scroll_lock, - struct xrdp_keymap *keymap) -{ - struct xrdp_key_info *ki; - - ki = get_key_info_from_kbd_event(keyboard_flags, key_code, keys, - caps_lock, num_lock, scroll_lock, - keymap); - - if (ki == 0) - { - return 0; - } - - return ki->chr; -} - /*****************************************************************************/ /** * Converts a table key to a scancode index value @@ -353,6 +331,101 @@ get_keymaps(int keylayout, struct xrdp_keymap *keymap) return 0; } +/*****************************************************************************/ +/** + * Parses the [General] section in a keymap file + * @param tfile TOML file in memory + * @param general result (initialised to defaults) + */ +static void +parse_km_general(toml_table_t *tfile, struct km_general *general) +{ + toml_table_t *section; + + if (tfile != NULL && (section = toml_table_in(tfile, "General")) != NULL) + { + toml_datum_t d; + if ((d = toml_int_in(section, "version")).ok) + { + general->version = d.u.i; + } + if ((d = toml_bool_in(section, "caps_lock_supported")).ok) + { + general->caps_lock_supported = d.u.b; + } + } +} + +/*****************************************************************************/ +/** + * Loads the [General] section only from a TOML file + * @param filename Name of TOML file + * @param quiet Set true to not log errors + * @param[out] km_general Contents of [General] section. Defaults are provided. + * @return 0 if the operation was successful + */ +static int +km_load_file_general(const char *filename, int quiet, + struct km_general *general) +{ + FILE *fp; + toml_table_t *tfile; + char errbuf[200]; + int rv = 1; + + *general = km_general_default; + + if ((fp = fopen(filename, "r")) == NULL) + { + if (!quiet) + { + LOG(LOG_LEVEL_ERROR, "Error loading keymap file %s (%s)", + filename, g_get_strerror()); + } + } + else + { + tfile = toml_parse_file(fp, errbuf, sizeof(errbuf)); + fclose(fp); + if (tfile == NULL) + { + if (!quiet) + { + LOG(LOG_LEVEL_ERROR, "Error in keymap file %s - %s", + filename, errbuf); + } + } + else + { + parse_km_general(tfile, general); + rv = 0; + toml_free(tfile); + } + } + + return rv; +} + +/*****************************************************************************/ +/** + * Boolean to test if a keylayout supports the caps_lock modifier key + * @param keylayout keyboardLayout from TS_UD_CS_CORE (see [MS-RDPBCGR]) + * @return True if layout supports caps lock + */ +static int +keylayout_supports_caps_lock(int keylayout) +{ + char filename[256]; + struct km_general general; + + g_snprintf(filename, sizeof(filename), + XRDP_CFG_PATH "/km-%08x.toml", keylayout); + + (void)km_load_file_general(filename, 1, &general); + + return general.caps_lock_supported; +} + /*****************************************************************************/ int km_load_file(const char *filename, struct xrdp_keymap *keymap) @@ -361,6 +434,7 @@ km_load_file(const char *filename, struct xrdp_keymap *keymap) toml_table_t *tfile; char errbuf[200]; int rv = 0; + struct km_general general = km_general_default; if ((fp = fopen(filename, "r")) == NULL) { @@ -382,16 +456,23 @@ km_load_file(const char *filename, struct xrdp_keymap *keymap) /* Clear the whole keymap */ memset(keymap, 0, sizeof(*keymap)); + /* Check to see if we should expect caps lock entries */ + parse_km_general(tfile, &general); + keymap->caps_lock_supported = general.caps_lock_supported; + /* read the keymap sections */ km_read_section(tfile, "noshift", keymap->keys_noshift); km_read_section(tfile, "shift", keymap->keys_shift); km_read_section(tfile, "altgr", keymap->keys_altgr); km_read_section(tfile, "shiftaltgr", keymap->keys_shiftaltgr); - km_read_section(tfile, "capslock", keymap->keys_capslock); - km_read_section(tfile, "capslockaltgr", keymap->keys_capslockaltgr); - km_read_section(tfile, "shiftcapslock", keymap->keys_shiftcapslock); - km_read_section(tfile, "shiftcapslockaltgr", - keymap->keys_shiftcapslockaltgr); + if (keymap->caps_lock_supported) + { + km_read_section(tfile, "capslock", keymap->keys_capslock); + km_read_section(tfile, "capslockaltgr", keymap->keys_capslockaltgr); + km_read_section(tfile, "shiftcapslock", keymap->keys_shiftcapslock); + km_read_section(tfile, "shiftcapslockaltgr", + keymap->keys_shiftcapslockaltgr); + } /* The numlock map is much smaller and offset by * SCANCODE_MIX_NUMLOCK. Read the section into a temporary @@ -657,8 +738,16 @@ xrdp_init_xkb_layout(struct xrdp_client_info *client_info) // 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); + if (keylayout_supports_caps_lock(client_info->keylayout)) + { + client_info->x11_keycode_caps_lock = + scancode_to_x11_keycode(SCANCODE_CAPS_KEY); + } + else + { + LOG(LOG_LEVEL_INFO, "xrdp_init_xkb_layout: caps lock is not supported"); + client_info->x11_keycode_caps_lock = 0; + } client_info->x11_keycode_num_lock = scancode_to_x11_keycode(SCANCODE_NUMLOCK_KEY); client_info->x11_keycode_scroll_lock = diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index c40557ebb3..072df9cc0a 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -442,14 +442,6 @@ get_key_info_from_kbd_event(int keyboard_flags, int key_code, int *keys, int caps_lock, int num_lock, int scroll_lock, struct xrdp_keymap *keymap); int -get_keysym_from_kbd_event(int keyboard_flags, int key_code, int *keys, - int caps_lock, int num_lock, int scroll_lock, - struct xrdp_keymap *keymap); -char32_t -get_char_from_kbd_event(int keyboard_flags, int key_code, int *keys, - int caps_lock, int num_lock, int scroll_lock, - struct xrdp_keymap *keymap); -int get_keymaps(int keylayout, struct xrdp_keymap *keymap); int diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c index 34ef7cab34..005d935daa 100644 --- a/xrdp/xrdp_bitmap.c +++ b/xrdp/xrdp_bitmap.c @@ -29,7 +29,10 @@ #include "log.h" #include "string_calls.h" - +// For a very few key functions, using the keysym is preferable to the +// raw scancode. Here are defines to avoid pulling an X11 dependency +// into the xrdp:- +#define XK_BackSpace 0xff08 static const unsigned int g_crc_table[256] = @@ -1150,6 +1153,13 @@ xrdp_bitmap_def_proc(struct xrdp_bitmap *self, int msg, { int scan_code = SCANCODE_FROM_KBD_EVENT(param1, param2); int num_lock = self->wm->num_lock; + /* We may need a keysym or a printable character for the key */ + struct xrdp_key_info *ki = get_key_info_from_kbd_event + (param2, param1, self->wm->keys, + self->wm->caps_lock, + self->wm->num_lock, self->wm->scroll_lock, + &(self->wm->keymap)); + /* left or up arrow */ if ((scan_code == SCANCODE_LEFT_ARROW_KEY) || (scan_code == SCANCODE_UP_ARROW_KEY) || @@ -1174,8 +1184,9 @@ xrdp_bitmap_def_proc(struct xrdp_bitmap *self, int msg, xrdp_bitmap_invalidate(self, 0); } } - /* backspace */ - else if (scan_code == SCANCODE_BACKSPACE_KEY) + /* backspace. Test keysym rather than scan code, so keys + * other than SCANCODE_BACKSPACE_KEY can generate backspace */ + else if (ki != NULL && ki->sym == XK_BackSpace) { n = utf8_char_count(self->caption1); @@ -1229,10 +1240,7 @@ xrdp_bitmap_def_proc(struct xrdp_bitmap *self, int msg, } else { - char32_t c = get_char_from_kbd_event - (param2, param1, self->wm->keys, self->wm->caps_lock, - self->wm->num_lock, self->wm->scroll_lock, - &(self->wm->keymap)); + char32_t c = (ki == NULL) ? 0 : ki->chr; // Add a printing character to the string. If successful, // bump the edit position and re-display the string if (c >= ' ' && diff --git a/xrdp/xrdp_keyboard.ini b/xrdp/xrdp_keyboard.ini index b7aa34969d..70d3a235ff 100644 --- a/xrdp/xrdp_keyboard.ini +++ b/xrdp/xrdp_keyboard.ini @@ -58,6 +58,7 @@ layouts_map=default_layouts_map [default_rdp_layouts] rdp_layout_us=0x00000409 +rdp_layout_us_colemak=0x00060409 rdp_layout_us_dvorak=0x00010409 rdp_layout_us_dvp=0x19360409 rdp_layout_dk=0x00000406 @@ -86,6 +87,7 @@ rdp_layout_pt=0x00000816 ; = [default_layouts_map] rdp_layout_us=us +rdp_layout_us_colemak=us(colemak) rdp_layout_us_dvorak=us(dvorak) rdp_layout_us_dvp=us(dvp) rdp_layout_dk=dk @@ -125,6 +127,7 @@ layouts_map=default_layouts_map [rdp_layouts_map_mac] rdp_layout_us=us +rdp_layout_us_colemak=us(colemak) rdp_layout_us_dvorak=us(dvorak) rdp_layout_us_dvp=us(dvp) rdp_layout_dk=dk diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index c5c80975ef..d972e02fd3 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -462,6 +462,9 @@ struct xrdp_key_info struct xrdp_keymap { + // Are the caps lock maps populated? + int caps_lock_supported; + // These arrays are indexed by a return from scancode_to_index() struct xrdp_key_info keys_noshift[SCANCODE_MAX_INDEX + 1]; struct xrdp_key_info keys_shift[SCANCODE_MAX_INDEX + 1];