From 8fe5090c8e968a3ee809711482804110ec9c7e30 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Thu, 13 Jul 2017 00:35:57 +0200 Subject: [PATCH] x0vncserver: keyEvent(): use scancodes if available Use the client provided (using QEMU extendend key event) scancodes if available instead of reverse mapping the keysym. X11 unfortunately uses keyboard driver specific keycodes and provides no direct way to query this, so guess based on the keyboard mapping. Handle the two most likely keyboard drivers, the old xorgkbd and evdev. Signed-off-by: Peter Korsgaard --- unix/x0vncserver/CMakeLists.txt | 2 + unix/x0vncserver/qnum_to_xorgevdev.c | 245 +++++++++++++++++++++++++++ unix/x0vncserver/qnum_to_xorgkbd.c | 121 +++++++++++++ unix/x0vncserver/x0vncserver.cxx | 51 +++++- unix/x0vncserver/x0vncserver.man | 7 + 5 files changed, 424 insertions(+), 2 deletions(-) create mode 100644 unix/x0vncserver/qnum_to_xorgevdev.c create mode 100644 unix/x0vncserver/qnum_to_xorgkbd.c diff --git a/unix/x0vncserver/CMakeLists.txt b/unix/x0vncserver/CMakeLists.txt index 82f0d2ac..7208f312 100644 --- a/unix/x0vncserver/CMakeLists.txt +++ b/unix/x0vncserver/CMakeLists.txt @@ -10,6 +10,8 @@ add_executable(x0vncserver PollingManager.cxx PollingScheduler.cxx TimeMillis.cxx + qnum_to_xorgevdev.c + qnum_to_xorgkbd.c x0vncserver.cxx XPixelBuffer.cxx ../vncconfig/QueryConnectDialog.cxx diff --git a/unix/x0vncserver/qnum_to_xorgevdev.c b/unix/x0vncserver/qnum_to_xorgevdev.c new file mode 100644 index 00000000..357c88d1 --- /dev/null +++ b/unix/x0vncserver/qnum_to_xorgevdev.c @@ -0,0 +1,245 @@ +/* + * This file is auto-generated from keymaps.csv on 2017-08-28 13:03 + * Database checksum sha256(f8aeff0c3430077a350e3d7ba2b335b381bd929ac4b193413730a402ff3f0097) + * To re-generate, run: + * keymap-gen --lang=stdc code-map keymaps.csv qnum xorgevdev +*/ +const unsigned short code_map_qnum_to_xorgevdev[254] = { + [0x1] = 0x9, /* qnum:1 -> linux:1 (KEY_ESC) -> xorgevdev:9 */ + [0x2] = 0xa, /* qnum:2 -> linux:2 (KEY_1) -> xorgevdev:10 */ + [0x3] = 0xb, /* qnum:3 -> linux:3 (KEY_2) -> xorgevdev:11 */ + [0x4] = 0xc, /* qnum:4 -> linux:4 (KEY_3) -> xorgevdev:12 */ + [0x5] = 0xd, /* qnum:5 -> linux:5 (KEY_4) -> xorgevdev:13 */ + [0x6] = 0xe, /* qnum:6 -> linux:6 (KEY_5) -> xorgevdev:14 */ + [0x7] = 0xf, /* qnum:7 -> linux:7 (KEY_6) -> xorgevdev:15 */ + [0x8] = 0x10, /* qnum:8 -> linux:8 (KEY_7) -> xorgevdev:16 */ + [0x9] = 0x11, /* qnum:9 -> linux:9 (KEY_8) -> xorgevdev:17 */ + [0xa] = 0x12, /* qnum:10 -> linux:10 (KEY_9) -> xorgevdev:18 */ + [0xb] = 0x13, /* qnum:11 -> linux:11 (KEY_0) -> xorgevdev:19 */ + [0xc] = 0x14, /* qnum:12 -> linux:12 (KEY_MINUS) -> xorgevdev:20 */ + [0xd] = 0x15, /* qnum:13 -> linux:13 (KEY_EQUAL) -> xorgevdev:21 */ + [0xe] = 0x16, /* qnum:14 -> linux:14 (KEY_BACKSPACE) -> xorgevdev:22 */ + [0xf] = 0x17, /* qnum:15 -> linux:15 (KEY_TAB) -> xorgevdev:23 */ + [0x10] = 0x18, /* qnum:16 -> linux:16 (KEY_Q) -> xorgevdev:24 */ + [0x11] = 0x19, /* qnum:17 -> linux:17 (KEY_W) -> xorgevdev:25 */ + [0x12] = 0x1a, /* qnum:18 -> linux:18 (KEY_E) -> xorgevdev:26 */ + [0x13] = 0x1b, /* qnum:19 -> linux:19 (KEY_R) -> xorgevdev:27 */ + [0x14] = 0x1c, /* qnum:20 -> linux:20 (KEY_T) -> xorgevdev:28 */ + [0x15] = 0x1d, /* qnum:21 -> linux:21 (KEY_Y) -> xorgevdev:29 */ + [0x16] = 0x1e, /* qnum:22 -> linux:22 (KEY_U) -> xorgevdev:30 */ + [0x17] = 0x1f, /* qnum:23 -> linux:23 (KEY_I) -> xorgevdev:31 */ + [0x18] = 0x20, /* qnum:24 -> linux:24 (KEY_O) -> xorgevdev:32 */ + [0x19] = 0x21, /* qnum:25 -> linux:25 (KEY_P) -> xorgevdev:33 */ + [0x1a] = 0x22, /* qnum:26 -> linux:26 (KEY_LEFTBRACE) -> xorgevdev:34 */ + [0x1b] = 0x23, /* qnum:27 -> linux:27 (KEY_RIGHTBRACE) -> xorgevdev:35 */ + [0x1c] = 0x24, /* qnum:28 -> linux:28 (KEY_ENTER) -> xorgevdev:36 */ + [0x1d] = 0x25, /* qnum:29 -> linux:29 (KEY_LEFTCTRL) -> xorgevdev:37 */ + [0x1e] = 0x26, /* qnum:30 -> linux:30 (KEY_A) -> xorgevdev:38 */ + [0x1f] = 0x27, /* qnum:31 -> linux:31 (KEY_S) -> xorgevdev:39 */ + [0x20] = 0x28, /* qnum:32 -> linux:32 (KEY_D) -> xorgevdev:40 */ + [0x21] = 0x29, /* qnum:33 -> linux:33 (KEY_F) -> xorgevdev:41 */ + [0x22] = 0x2a, /* qnum:34 -> linux:34 (KEY_G) -> xorgevdev:42 */ + [0x23] = 0x2b, /* qnum:35 -> linux:35 (KEY_H) -> xorgevdev:43 */ + [0x24] = 0x2c, /* qnum:36 -> linux:36 (KEY_J) -> xorgevdev:44 */ + [0x25] = 0x2d, /* qnum:37 -> linux:37 (KEY_K) -> xorgevdev:45 */ + [0x26] = 0x2e, /* qnum:38 -> linux:38 (KEY_L) -> xorgevdev:46 */ + [0x27] = 0x2f, /* qnum:39 -> linux:39 (KEY_SEMICOLON) -> xorgevdev:47 */ + [0x28] = 0x30, /* qnum:40 -> linux:40 (KEY_APOSTROPHE) -> xorgevdev:48 */ + [0x29] = 0x31, /* qnum:41 -> linux:41 (KEY_GRAVE) -> xorgevdev:49 */ + [0x2a] = 0x32, /* qnum:42 -> linux:42 (KEY_LEFTSHIFT) -> xorgevdev:50 */ + [0x2b] = 0x33, /* qnum:43 -> linux:43 (KEY_BACKSLASH) -> xorgevdev:51 */ + [0x2c] = 0x34, /* qnum:44 -> linux:44 (KEY_Z) -> xorgevdev:52 */ + [0x2d] = 0x35, /* qnum:45 -> linux:45 (KEY_X) -> xorgevdev:53 */ + [0x2e] = 0x36, /* qnum:46 -> linux:46 (KEY_C) -> xorgevdev:54 */ + [0x2f] = 0x37, /* qnum:47 -> linux:47 (KEY_V) -> xorgevdev:55 */ + [0x30] = 0x38, /* qnum:48 -> linux:48 (KEY_B) -> xorgevdev:56 */ + [0x31] = 0x39, /* qnum:49 -> linux:49 (KEY_N) -> xorgevdev:57 */ + [0x32] = 0x3a, /* qnum:50 -> linux:50 (KEY_M) -> xorgevdev:58 */ + [0x33] = 0x3b, /* qnum:51 -> linux:51 (KEY_COMMA) -> xorgevdev:59 */ + [0x34] = 0x3c, /* qnum:52 -> linux:52 (KEY_DOT) -> xorgevdev:60 */ + [0x35] = 0x3d, /* qnum:53 -> linux:53 (KEY_SLASH) -> xorgevdev:61 */ + [0x36] = 0x3e, /* qnum:54 -> linux:54 (KEY_RIGHTSHIFT) -> xorgevdev:62 */ + [0x37] = 0x3f, /* qnum:55 -> linux:55 (KEY_KPASTERISK) -> xorgevdev:63 */ + [0x38] = 0x40, /* qnum:56 -> linux:56 (KEY_LEFTALT) -> xorgevdev:64 */ + [0x39] = 0x41, /* qnum:57 -> linux:57 (KEY_SPACE) -> xorgevdev:65 */ + [0x3a] = 0x42, /* qnum:58 -> linux:58 (KEY_CAPSLOCK) -> xorgevdev:66 */ + [0x3b] = 0x43, /* qnum:59 -> linux:59 (KEY_F1) -> xorgevdev:67 */ + [0x3c] = 0x44, /* qnum:60 -> linux:60 (KEY_F2) -> xorgevdev:68 */ + [0x3d] = 0x45, /* qnum:61 -> linux:61 (KEY_F3) -> xorgevdev:69 */ + [0x3e] = 0x46, /* qnum:62 -> linux:62 (KEY_F4) -> xorgevdev:70 */ + [0x3f] = 0x47, /* qnum:63 -> linux:63 (KEY_F5) -> xorgevdev:71 */ + [0x40] = 0x48, /* qnum:64 -> linux:64 (KEY_F6) -> xorgevdev:72 */ + [0x41] = 0x49, /* qnum:65 -> linux:65 (KEY_F7) -> xorgevdev:73 */ + [0x42] = 0x4a, /* qnum:66 -> linux:66 (KEY_F8) -> xorgevdev:74 */ + [0x43] = 0x4b, /* qnum:67 -> linux:67 (KEY_F9) -> xorgevdev:75 */ + [0x44] = 0x4c, /* qnum:68 -> linux:68 (KEY_F10) -> xorgevdev:76 */ + [0x45] = 0x4d, /* qnum:69 -> linux:69 (KEY_NUMLOCK) -> xorgevdev:77 */ + [0x46] = 0x4e, /* qnum:70 -> linux:70 (KEY_SCROLLLOCK) -> xorgevdev:78 */ + [0x47] = 0x4f, /* qnum:71 -> linux:71 (KEY_KP7) -> xorgevdev:79 */ + [0x48] = 0x50, /* qnum:72 -> linux:72 (KEY_KP8) -> xorgevdev:80 */ + [0x49] = 0x51, /* qnum:73 -> linux:73 (KEY_KP9) -> xorgevdev:81 */ + [0x4a] = 0x52, /* qnum:74 -> linux:74 (KEY_KPMINUS) -> xorgevdev:82 */ + [0x4b] = 0x53, /* qnum:75 -> linux:75 (KEY_KP4) -> xorgevdev:83 */ + [0x4c] = 0x54, /* qnum:76 -> linux:76 (KEY_KP5) -> xorgevdev:84 */ + [0x4d] = 0x55, /* qnum:77 -> linux:77 (KEY_KP6) -> xorgevdev:85 */ + [0x4e] = 0x56, /* qnum:78 -> linux:78 (KEY_KPPLUS) -> xorgevdev:86 */ + [0x4f] = 0x57, /* qnum:79 -> linux:79 (KEY_KP1) -> xorgevdev:87 */ + [0x50] = 0x58, /* qnum:80 -> linux:80 (KEY_KP2) -> xorgevdev:88 */ + [0x51] = 0x59, /* qnum:81 -> linux:81 (KEY_KP3) -> xorgevdev:89 */ + [0x52] = 0x5a, /* qnum:82 -> linux:82 (KEY_KP0) -> xorgevdev:90 */ + [0x53] = 0x5b, /* qnum:83 -> linux:83 (KEY_KPDOT) -> xorgevdev:91 */ + [0x54] = 0x6b, /* qnum:84 -> linux:99 (KEY_SYSRQ) -> xorgevdev:107 */ + [0x55] = 0xc2, /* qnum:85 -> linux:186 (KEY_F16) -> xorgevdev:194 */ + [0x56] = 0x5e, /* qnum:86 -> linux:86 (KEY_102ND) -> xorgevdev:94 */ + [0x57] = 0x5f, /* qnum:87 -> linux:87 (KEY_F11) -> xorgevdev:95 */ + [0x58] = 0x60, /* qnum:88 -> linux:88 (KEY_F12) -> xorgevdev:96 */ + [0x59] = 0x7d, /* qnum:89 -> linux:117 (KEY_KPEQUAL) -> xorgevdev:125 */ + [0x5a] = 0xc6, /* qnum:90 -> linux:190 (KEY_F20) -> xorgevdev:198 */ + [0x5b] = 0x6d, /* qnum:91 -> linux:101 (KEY_LINEFEED) -> xorgevdev:109 */ + [0x5c] = 0x67, /* qnum:92 -> linux:95 (KEY_KPJPCOMMA) -> xorgevdev:103 */ + [0x5d] = 0xbf, /* qnum:93 -> linux:183 (KEY_F13) -> xorgevdev:191 */ + [0x5e] = 0xc0, /* qnum:94 -> linux:184 (KEY_F14) -> xorgevdev:192 */ + [0x5f] = 0xc1, /* qnum:95 -> linux:185 (KEY_F15) -> xorgevdev:193 */ + [0x63] = 0xb1, /* qnum:99 -> linux:169 (KEY_PHONE) -> xorgevdev:177 */ + [0x64] = 0x8e, /* qnum:100 -> linux:134 (KEY_OPEN) -> xorgevdev:142 */ + [0x65] = 0x8f, /* qnum:101 -> linux:135 (KEY_PASTE) -> xorgevdev:143 */ + [0x66] = 0x95, /* qnum:102 -> linux:141 (KEY_SETUP) -> xorgevdev:149 */ + [0x67] = 0x98, /* qnum:103 -> linux:144 (KEY_FILE) -> xorgevdev:152 */ + [0x68] = 0x99, /* qnum:104 -> linux:145 (KEY_SENDFILE) -> xorgevdev:153 */ + [0x69] = 0x9a, /* qnum:105 -> linux:146 (KEY_DELETEFILE) -> xorgevdev:154 */ + [0x6a] = 0x9f, /* qnum:106 -> linux:151 (KEY_MSDOS) -> xorgevdev:159 */ + [0x6b] = 0xa1, /* qnum:107 -> linux:153 (KEY_DIRECTION) -> xorgevdev:161 */ + [0x6c] = 0xa9, /* qnum:108 -> linux:161 (KEY_EJECTCD) -> xorgevdev:169 */ + [0x6d] = 0xc9, /* qnum:109 -> linux:193 (KEY_F23) -> xorgevdev:201 */ + [0x6f] = 0xca, /* qnum:111 -> linux:194 (KEY_F24) -> xorgevdev:202 */ + [0x70] = 0xb2, /* qnum:112 -> linux:170 (KEY_ISO) -> xorgevdev:178 */ + [0x71] = 0xb6, /* qnum:113 -> linux:174 (KEY_EXIT) -> xorgevdev:182 */ + [0x72] = 0xb7, /* qnum:114 -> linux:175 (KEY_MOVE) -> xorgevdev:183 */ + [0x73] = 0x61, /* qnum:115 -> linux:89 (KEY_RO) -> xorgevdev:97 */ + [0x74] = 0xc7, /* qnum:116 -> linux:191 (KEY_F21) -> xorgevdev:199 */ + [0x75] = 0xb9, /* qnum:117 -> linux:177 (KEY_SCROLLUP) -> xorgevdev:185 */ + [0x76] = 0x5d, /* qnum:118 -> linux:85 (KEY_ZENKAKUHANKAKU) -> xorgevdev:93 */ + [0x77] = 0x63, /* qnum:119 -> linux:91 (KEY_HIRAGANA) -> xorgevdev:99 */ + [0x78] = 0x62, /* qnum:120 -> linux:90 (KEY_KATAKANA) -> xorgevdev:98 */ + [0x79] = 0x64, /* qnum:121 -> linux:92 (KEY_HENKAN) -> xorgevdev:100 */ + [0x7b] = 0x66, /* qnum:123 -> linux:94 (KEY_MUHENKAN) -> xorgevdev:102 */ + [0x7d] = 0x84, /* qnum:125 -> linux:124 (KEY_YEN) -> xorgevdev:132 */ + [0x7e] = 0x81, /* qnum:126 -> linux:121 (KEY_KPCOMMA) -> xorgevdev:129 */ + [0x81] = 0xb3, /* qnum:129 -> linux:171 (KEY_CONFIG) -> xorgevdev:179 */ + [0x82] = 0x9e, /* qnum:130 -> linux:150 (KEY_WWW) -> xorgevdev:158 */ + [0x83] = 0xc3, /* qnum:131 -> linux:187 (KEY_F17) -> xorgevdev:195 */ + [0x84] = 0xc5, /* qnum:132 -> linux:189 (KEY_F19) -> xorgevdev:197 */ + [0x85] = 0x89, /* qnum:133 -> linux:129 (KEY_AGAIN) -> xorgevdev:137 */ + [0x86] = 0x8a, /* qnum:134 -> linux:130 (KEY_PROPS) -> xorgevdev:138 */ + [0x87] = 0x8b, /* qnum:135 -> linux:131 (KEY_UNDO) -> xorgevdev:139 */ + [0x88] = 0xb8, /* qnum:136 -> linux:176 (KEY_EDIT) -> xorgevdev:184 */ + [0x89] = 0xbd, /* qnum:137 -> linux:181 (KEY_NEW) -> xorgevdev:189 */ + [0x8a] = 0xbe, /* qnum:138 -> linux:182 (KEY_REDO) -> xorgevdev:190 */ + [0x8b] = 0x80, /* qnum:139 -> linux:120 (KEY_SCALE) -> xorgevdev:128 */ + [0x8c] = 0x8c, /* qnum:140 -> linux:132 (KEY_FRONT) -> xorgevdev:140 */ + [0x8d] = 0x83, /* qnum:141 -> linux:123 (KEY_HANJA) -> xorgevdev:131 */ + [0x8e] = 0xf1, /* qnum:142 -> linux:233 (KEY_FORWARDMAIL) -> xorgevdev:241 */ + [0x8f] = 0xba, /* qnum:143 -> linux:178 (KEY_SCROLLDOWN) -> xorgevdev:186 */ + [0x90] = 0xad, /* qnum:144 -> linux:165 (KEY_PREVIOUSSONG) -> xorgevdev:173 */ + [0x92] = 0xa0, /* qnum:146 -> linux:152 (KEY_SCREENLOCK) -> xorgevdev:160 */ + [0x93] = 0x9b, /* qnum:147 -> linux:147 (KEY_XFER) -> xorgevdev:155 */ + [0x94] = 0xe6, /* qnum:148 -> linux:222 (KEY_ALTERASE) -> xorgevdev:230 */ + [0x95] = 0xcb, /* qnum:149 -> linux:195 (unnamed) -> xorgevdev:203 */ + [0x96] = 0xcc, /* qnum:150 -> linux:196 (unnamed) -> xorgevdev:204 */ + [0x97] = 0x9d, /* qnum:151 -> linux:149 (KEY_PROG2) -> xorgevdev:157 */ + [0x98] = 0xb0, /* qnum:152 -> linux:168 (KEY_REWIND) -> xorgevdev:176 */ + [0x99] = 0xab, /* qnum:153 -> linux:163 (KEY_NEXTSONG) -> xorgevdev:171 */ + [0x9a] = 0xcd, /* qnum:154 -> linux:197 (unnamed) -> xorgevdev:205 */ + [0x9b] = 0xce, /* qnum:155 -> linux:198 (unnamed) -> xorgevdev:206 */ + [0x9c] = 0x68, /* qnum:156 -> linux:96 (KEY_KPENTER) -> xorgevdev:104 */ + [0x9d] = 0x69, /* qnum:157 -> linux:97 (KEY_RIGHTCTRL) -> xorgevdev:105 */ + [0x9e] = 0x93, /* qnum:158 -> linux:139 (KEY_MENU) -> xorgevdev:147 */ + [0x9f] = 0x9c, /* qnum:159 -> linux:148 (KEY_PROG1) -> xorgevdev:156 */ + [0xa0] = 0x79, /* qnum:160 -> linux:113 (KEY_MUTE) -> xorgevdev:121 */ + [0xa1] = 0x94, /* qnum:161 -> linux:140 (KEY_CALC) -> xorgevdev:148 */ + [0xa2] = 0xac, /* qnum:162 -> linux:164 (KEY_PLAYPAUSE) -> xorgevdev:172 */ + [0xa3] = 0xa8, /* qnum:163 -> linux:160 (KEY_CLOSECD) -> xorgevdev:168 */ + [0xa4] = 0xae, /* qnum:164 -> linux:166 (KEY_STOPCD) -> xorgevdev:174 */ + [0xa5] = 0xd5, /* qnum:165 -> linux:205 (KEY_SUSPEND) -> xorgevdev:213 */ + [0xa6] = 0xa2, /* qnum:166 -> linux:154 (KEY_CYCLEWINDOWS) -> xorgevdev:162 */ + [0xa7] = 0xcf, /* qnum:167 -> linux:199 (unnamed) -> xorgevdev:207 */ + [0xa8] = 0xd0, /* qnum:168 -> linux:200 (KEY_PLAYCD) -> xorgevdev:208 */ + [0xa9] = 0xd1, /* qnum:169 -> linux:201 (KEY_PAUSECD) -> xorgevdev:209 */ + [0xab] = 0xd2, /* qnum:171 -> linux:202 (KEY_PROG3) -> xorgevdev:210 */ + [0xac] = 0xd3, /* qnum:172 -> linux:203 (KEY_PROG4) -> xorgevdev:211 */ + [0xad] = 0xd4, /* qnum:173 -> linux:204 (KEY_DASHBOARD) -> xorgevdev:212 */ + [0xae] = 0x7a, /* qnum:174 -> linux:114 (KEY_VOLUMEDOWN) -> xorgevdev:122 */ + [0xaf] = 0xd6, /* qnum:175 -> linux:206 (KEY_CLOSE) -> xorgevdev:214 */ + [0xb0] = 0x7b, /* qnum:176 -> linux:115 (KEY_VOLUMEUP) -> xorgevdev:123 */ + [0xb1] = 0xaf, /* qnum:177 -> linux:167 (KEY_RECORD) -> xorgevdev:175 */ + [0xb2] = 0xb4, /* qnum:178 -> linux:172 (KEY_HOMEPAGE) -> xorgevdev:180 */ + [0xb3] = 0xd7, /* qnum:179 -> linux:207 (KEY_PLAY) -> xorgevdev:215 */ + [0xb4] = 0xd8, /* qnum:180 -> linux:208 (KEY_FASTFORWARD) -> xorgevdev:216 */ + [0xb5] = 0x6a, /* qnum:181 -> linux:98 (KEY_KPSLASH) -> xorgevdev:106 */ + [0xb6] = 0xd9, /* qnum:182 -> linux:209 (KEY_BASSBOOST) -> xorgevdev:217 */ + [0xb8] = 0x6c, /* qnum:184 -> linux:100 (KEY_RIGHTALT) -> xorgevdev:108 */ + [0xb9] = 0xda, /* qnum:185 -> linux:210 (KEY_PRINT) -> xorgevdev:218 */ + [0xba] = 0xdb, /* qnum:186 -> linux:211 (KEY_HP) -> xorgevdev:219 */ + [0xbb] = 0xdc, /* qnum:187 -> linux:212 (KEY_CAMERA) -> xorgevdev:220 */ + [0xbc] = 0x91, /* qnum:188 -> linux:137 (KEY_CUT) -> xorgevdev:145 */ + [0xbd] = 0xdd, /* qnum:189 -> linux:213 (KEY_SOUND) -> xorgevdev:221 */ + [0xbe] = 0xde, /* qnum:190 -> linux:214 (KEY_QUESTION) -> xorgevdev:222 */ + [0xbf] = 0xdf, /* qnum:191 -> linux:215 (KEY_EMAIL) -> xorgevdev:223 */ + [0xc0] = 0xe0, /* qnum:192 -> linux:216 (KEY_CHAT) -> xorgevdev:224 */ + [0xc1] = 0x90, /* qnum:193 -> linux:136 (KEY_FIND) -> xorgevdev:144 */ + [0xc2] = 0xe2, /* qnum:194 -> linux:218 (KEY_CONNECT) -> xorgevdev:226 */ + [0xc3] = 0xe3, /* qnum:195 -> linux:219 (KEY_FINANCE) -> xorgevdev:227 */ + [0xc4] = 0xe4, /* qnum:196 -> linux:220 (KEY_SPORT) -> xorgevdev:228 */ + [0xc5] = 0xe5, /* qnum:197 -> linux:221 (KEY_SHOP) -> xorgevdev:229 */ + [0xc6] = 0x7f, /* qnum:198 -> linux:119 (KEY_PAUSE) -> xorgevdev:127 */ + [0xc7] = 0x6e, /* qnum:199 -> linux:102 (KEY_HOME) -> xorgevdev:110 */ + [0xc8] = 0x6f, /* qnum:200 -> linux:103 (KEY_UP) -> xorgevdev:111 */ + [0xc9] = 0x70, /* qnum:201 -> linux:104 (KEY_PAGEUP) -> xorgevdev:112 */ + [0xca] = 0xe7, /* qnum:202 -> linux:223 (KEY_CANCEL) -> xorgevdev:231 */ + [0xcb] = 0x71, /* qnum:203 -> linux:105 (KEY_LEFT) -> xorgevdev:113 */ + [0xcc] = 0xe8, /* qnum:204 -> linux:224 (KEY_BRIGHTNESSDOWN) -> xorgevdev:232 */ + [0xcd] = 0x72, /* qnum:205 -> linux:106 (KEY_RIGHT) -> xorgevdev:114 */ + [0xce] = 0x7e, /* qnum:206 -> linux:118 (KEY_KPPLUSMINUS) -> xorgevdev:126 */ + [0xcf] = 0x73, /* qnum:207 -> linux:107 (KEY_END) -> xorgevdev:115 */ + [0xd0] = 0x74, /* qnum:208 -> linux:108 (KEY_DOWN) -> xorgevdev:116 */ + [0xd1] = 0x75, /* qnum:209 -> linux:109 (KEY_PAGEDOWN) -> xorgevdev:117 */ + [0xd2] = 0x76, /* qnum:210 -> linux:110 (KEY_INSERT) -> xorgevdev:118 */ + [0xd3] = 0x77, /* qnum:211 -> linux:111 (KEY_DELETE) -> xorgevdev:119 */ + [0xd4] = 0xe9, /* qnum:212 -> linux:225 (KEY_BRIGHTNESSUP) -> xorgevdev:233 */ + [0xd5] = 0xf2, /* qnum:213 -> linux:234 (KEY_SAVE) -> xorgevdev:242 */ + [0xd6] = 0xeb, /* qnum:214 -> linux:227 (KEY_SWITCHVIDEOMODE) -> xorgevdev:235 */ + [0xd7] = 0xec, /* qnum:215 -> linux:228 (KEY_KBDILLUMTOGGLE) -> xorgevdev:236 */ + [0xd8] = 0xed, /* qnum:216 -> linux:229 (KEY_KBDILLUMDOWN) -> xorgevdev:237 */ + [0xd9] = 0xee, /* qnum:217 -> linux:230 (KEY_KBDILLUMUP) -> xorgevdev:238 */ + [0xda] = 0xef, /* qnum:218 -> linux:231 (KEY_SEND) -> xorgevdev:239 */ + [0xdb] = 0x85, /* qnum:219 -> linux:125 (KEY_LEFTMETA) -> xorgevdev:133 */ + [0xdc] = 0x86, /* qnum:220 -> linux:126 (KEY_RIGHTMETA) -> xorgevdev:134 */ + [0xdd] = 0x87, /* qnum:221 -> linux:127 (KEY_COMPOSE) -> xorgevdev:135 */ + [0xde] = 0x7c, /* qnum:222 -> linux:116 (KEY_POWER) -> xorgevdev:124 */ + [0xdf] = 0x96, /* qnum:223 -> linux:142 (KEY_SLEEP) -> xorgevdev:150 */ + [0xe3] = 0x97, /* qnum:227 -> linux:143 (KEY_WAKEUP) -> xorgevdev:151 */ + [0xe4] = 0xf0, /* qnum:228 -> linux:232 (KEY_REPLY) -> xorgevdev:240 */ + [0xe5] = 0xe1, /* qnum:229 -> linux:217 (KEY_SEARCH) -> xorgevdev:225 */ + [0xe6] = 0xa4, /* qnum:230 -> linux:156 (KEY_BOOKMARKS) -> xorgevdev:164 */ + [0xe7] = 0xb5, /* qnum:231 -> linux:173 (KEY_REFRESH) -> xorgevdev:181 */ + [0xe8] = 0x88, /* qnum:232 -> linux:128 (KEY_STOP) -> xorgevdev:136 */ + [0xe9] = 0xa7, /* qnum:233 -> linux:159 (KEY_FORWARD) -> xorgevdev:167 */ + [0xea] = 0xa6, /* qnum:234 -> linux:158 (KEY_BACK) -> xorgevdev:166 */ + [0xeb] = 0xa5, /* qnum:235 -> linux:157 (KEY_COMPUTER) -> xorgevdev:165 */ + [0xec] = 0xa3, /* qnum:236 -> linux:155 (KEY_MAIL) -> xorgevdev:163 */ + [0xed] = 0xea, /* qnum:237 -> linux:226 (KEY_MEDIA) -> xorgevdev:234 */ + [0xef] = 0x78, /* qnum:239 -> linux:112 (KEY_MACRO) -> xorgevdev:120 */ + [0xf0] = 0xf3, /* qnum:240 -> linux:235 (KEY_DOCUMENTS) -> xorgevdev:243 */ + [0xf1] = 0xf4, /* qnum:241 -> linux:236 (KEY_BATTERY) -> xorgevdev:244 */ + [0xf2] = 0xf5, /* qnum:242 -> linux:237 (KEY_BLUETOOTH) -> xorgevdev:245 */ + [0xf3] = 0xf6, /* qnum:243 -> linux:238 (KEY_WLAN) -> xorgevdev:246 */ + [0xf4] = 0xf7, /* qnum:244 -> linux:239 (KEY_UWB) -> xorgevdev:247 */ + [0xf5] = 0x92, /* qnum:245 -> linux:138 (KEY_HELP) -> xorgevdev:146 */ + [0xf6] = 0xbb, /* qnum:246 -> linux:179 (KEY_KPLEFTPAREN) -> xorgevdev:187 */ + [0xf7] = 0xc4, /* qnum:247 -> linux:188 (KEY_F18) -> xorgevdev:196 */ + [0xf8] = 0x8d, /* qnum:248 -> linux:133 (KEY_COPY) -> xorgevdev:141 */ + [0xf9] = 0xc8, /* qnum:249 -> linux:192 (KEY_F22) -> xorgevdev:200 */ + [0xfb] = 0xbc, /* qnum:251 -> linux:180 (KEY_KPRIGHTPAREN) -> xorgevdev:188 */ + [0xfd] = 0xaa, /* qnum:253 -> linux:162 (KEY_EJECTCLOSECD) -> xorgevdev:170 */ +}; +const unsigned int code_map_qnum_to_xorgevdev_len = sizeof(code_map_qnum_to_xorgevdev)/sizeof(code_map_qnum_to_xorgevdev[0]); diff --git a/unix/x0vncserver/qnum_to_xorgkbd.c b/unix/x0vncserver/qnum_to_xorgkbd.c new file mode 100644 index 00000000..57c2047a --- /dev/null +++ b/unix/x0vncserver/qnum_to_xorgkbd.c @@ -0,0 +1,121 @@ +/* + * This file is auto-generated from keymaps.csv on 2017-08-28 13:04 + * Database checksum sha256(f8aeff0c3430077a350e3d7ba2b335b381bd929ac4b193413730a402ff3f0097) + * To re-generate, run: + * keymap-gen --lang=stdc code-map keymaps.csv qnum xorgkbd +*/ +const unsigned short code_map_qnum_to_xorgkbd[254] = { + [0x1] = 0x9, /* qnum:1 -> linux:1 (KEY_ESC) -> xorgkbd:9 */ + [0x2] = 0xa, /* qnum:2 -> linux:2 (KEY_1) -> xorgkbd:10 */ + [0x3] = 0xb, /* qnum:3 -> linux:3 (KEY_2) -> xorgkbd:11 */ + [0x4] = 0xc, /* qnum:4 -> linux:4 (KEY_3) -> xorgkbd:12 */ + [0x5] = 0xd, /* qnum:5 -> linux:5 (KEY_4) -> xorgkbd:13 */ + [0x6] = 0xe, /* qnum:6 -> linux:6 (KEY_5) -> xorgkbd:14 */ + [0x7] = 0xf, /* qnum:7 -> linux:7 (KEY_6) -> xorgkbd:15 */ + [0x8] = 0x10, /* qnum:8 -> linux:8 (KEY_7) -> xorgkbd:16 */ + [0x9] = 0x11, /* qnum:9 -> linux:9 (KEY_8) -> xorgkbd:17 */ + [0xa] = 0x12, /* qnum:10 -> linux:10 (KEY_9) -> xorgkbd:18 */ + [0xb] = 0x13, /* qnum:11 -> linux:11 (KEY_0) -> xorgkbd:19 */ + [0xc] = 0x14, /* qnum:12 -> linux:12 (KEY_MINUS) -> xorgkbd:20 */ + [0xd] = 0x15, /* qnum:13 -> linux:13 (KEY_EQUAL) -> xorgkbd:21 */ + [0xe] = 0x16, /* qnum:14 -> linux:14 (KEY_BACKSPACE) -> xorgkbd:22 */ + [0xf] = 0x17, /* qnum:15 -> linux:15 (KEY_TAB) -> xorgkbd:23 */ + [0x10] = 0x18, /* qnum:16 -> linux:16 (KEY_Q) -> xorgkbd:24 */ + [0x11] = 0x19, /* qnum:17 -> linux:17 (KEY_W) -> xorgkbd:25 */ + [0x12] = 0x1a, /* qnum:18 -> linux:18 (KEY_E) -> xorgkbd:26 */ + [0x13] = 0x1b, /* qnum:19 -> linux:19 (KEY_R) -> xorgkbd:27 */ + [0x14] = 0x1c, /* qnum:20 -> linux:20 (KEY_T) -> xorgkbd:28 */ + [0x15] = 0x1d, /* qnum:21 -> linux:21 (KEY_Y) -> xorgkbd:29 */ + [0x16] = 0x1e, /* qnum:22 -> linux:22 (KEY_U) -> xorgkbd:30 */ + [0x17] = 0x1f, /* qnum:23 -> linux:23 (KEY_I) -> xorgkbd:31 */ + [0x18] = 0x20, /* qnum:24 -> linux:24 (KEY_O) -> xorgkbd:32 */ + [0x19] = 0x21, /* qnum:25 -> linux:25 (KEY_P) -> xorgkbd:33 */ + [0x1a] = 0x22, /* qnum:26 -> linux:26 (KEY_LEFTBRACE) -> xorgkbd:34 */ + [0x1b] = 0x23, /* qnum:27 -> linux:27 (KEY_RIGHTBRACE) -> xorgkbd:35 */ + [0x1c] = 0x24, /* qnum:28 -> linux:28 (KEY_ENTER) -> xorgkbd:36 */ + [0x1d] = 0x25, /* qnum:29 -> linux:29 (KEY_LEFTCTRL) -> xorgkbd:37 */ + [0x1e] = 0x26, /* qnum:30 -> linux:30 (KEY_A) -> xorgkbd:38 */ + [0x1f] = 0x27, /* qnum:31 -> linux:31 (KEY_S) -> xorgkbd:39 */ + [0x20] = 0x28, /* qnum:32 -> linux:32 (KEY_D) -> xorgkbd:40 */ + [0x21] = 0x29, /* qnum:33 -> linux:33 (KEY_F) -> xorgkbd:41 */ + [0x22] = 0x2a, /* qnum:34 -> linux:34 (KEY_G) -> xorgkbd:42 */ + [0x23] = 0x2b, /* qnum:35 -> linux:35 (KEY_H) -> xorgkbd:43 */ + [0x24] = 0x2c, /* qnum:36 -> linux:36 (KEY_J) -> xorgkbd:44 */ + [0x25] = 0x2d, /* qnum:37 -> linux:37 (KEY_K) -> xorgkbd:45 */ + [0x26] = 0x2e, /* qnum:38 -> linux:38 (KEY_L) -> xorgkbd:46 */ + [0x27] = 0x2f, /* qnum:39 -> linux:39 (KEY_SEMICOLON) -> xorgkbd:47 */ + [0x28] = 0x30, /* qnum:40 -> linux:40 (KEY_APOSTROPHE) -> xorgkbd:48 */ + [0x29] = 0x31, /* qnum:41 -> linux:41 (KEY_GRAVE) -> xorgkbd:49 */ + [0x2a] = 0x32, /* qnum:42 -> linux:42 (KEY_LEFTSHIFT) -> xorgkbd:50 */ + [0x2b] = 0x33, /* qnum:43 -> linux:43 (KEY_BACKSLASH) -> xorgkbd:51 */ + [0x2c] = 0x34, /* qnum:44 -> linux:44 (KEY_Z) -> xorgkbd:52 */ + [0x2d] = 0x35, /* qnum:45 -> linux:45 (KEY_X) -> xorgkbd:53 */ + [0x2e] = 0x36, /* qnum:46 -> linux:46 (KEY_C) -> xorgkbd:54 */ + [0x2f] = 0x37, /* qnum:47 -> linux:47 (KEY_V) -> xorgkbd:55 */ + [0x30] = 0x38, /* qnum:48 -> linux:48 (KEY_B) -> xorgkbd:56 */ + [0x31] = 0x39, /* qnum:49 -> linux:49 (KEY_N) -> xorgkbd:57 */ + [0x32] = 0x3a, /* qnum:50 -> linux:50 (KEY_M) -> xorgkbd:58 */ + [0x33] = 0x3b, /* qnum:51 -> linux:51 (KEY_COMMA) -> xorgkbd:59 */ + [0x34] = 0x3c, /* qnum:52 -> linux:52 (KEY_DOT) -> xorgkbd:60 */ + [0x35] = 0x3d, /* qnum:53 -> linux:53 (KEY_SLASH) -> xorgkbd:61 */ + [0x36] = 0x3e, /* qnum:54 -> linux:54 (KEY_RIGHTSHIFT) -> xorgkbd:62 */ + [0x37] = 0x3f, /* qnum:55 -> linux:55 (KEY_KPASTERISK) -> xorgkbd:63 */ + [0x38] = 0x40, /* qnum:56 -> linux:56 (KEY_LEFTALT) -> xorgkbd:64 */ + [0x39] = 0x41, /* qnum:57 -> linux:57 (KEY_SPACE) -> xorgkbd:65 */ + [0x3a] = 0x42, /* qnum:58 -> linux:58 (KEY_CAPSLOCK) -> xorgkbd:66 */ + [0x3b] = 0x43, /* qnum:59 -> linux:59 (KEY_F1) -> xorgkbd:67 */ + [0x3c] = 0x44, /* qnum:60 -> linux:60 (KEY_F2) -> xorgkbd:68 */ + [0x3d] = 0x45, /* qnum:61 -> linux:61 (KEY_F3) -> xorgkbd:69 */ + [0x3e] = 0x46, /* qnum:62 -> linux:62 (KEY_F4) -> xorgkbd:70 */ + [0x3f] = 0x47, /* qnum:63 -> linux:63 (KEY_F5) -> xorgkbd:71 */ + [0x40] = 0x48, /* qnum:64 -> linux:64 (KEY_F6) -> xorgkbd:72 */ + [0x41] = 0x49, /* qnum:65 -> linux:65 (KEY_F7) -> xorgkbd:73 */ + [0x42] = 0x4a, /* qnum:66 -> linux:66 (KEY_F8) -> xorgkbd:74 */ + [0x43] = 0x4b, /* qnum:67 -> linux:67 (KEY_F9) -> xorgkbd:75 */ + [0x44] = 0x4c, /* qnum:68 -> linux:68 (KEY_F10) -> xorgkbd:76 */ + [0x45] = 0x4d, /* qnum:69 -> linux:69 (KEY_NUMLOCK) -> xorgkbd:77 */ + [0x46] = 0x4e, /* qnum:70 -> linux:70 (KEY_SCROLLLOCK) -> xorgkbd:78 */ + [0x47] = 0x4f, /* qnum:71 -> linux:71 (KEY_KP7) -> xorgkbd:79 */ + [0x48] = 0x50, /* qnum:72 -> linux:72 (KEY_KP8) -> xorgkbd:80 */ + [0x49] = 0x51, /* qnum:73 -> linux:73 (KEY_KP9) -> xorgkbd:81 */ + [0x4a] = 0x52, /* qnum:74 -> linux:74 (KEY_KPMINUS) -> xorgkbd:82 */ + [0x4b] = 0x53, /* qnum:75 -> linux:75 (KEY_KP4) -> xorgkbd:83 */ + [0x4c] = 0x54, /* qnum:76 -> linux:76 (KEY_KP5) -> xorgkbd:84 */ + [0x4d] = 0x55, /* qnum:77 -> linux:77 (KEY_KP6) -> xorgkbd:85 */ + [0x4e] = 0x56, /* qnum:78 -> linux:78 (KEY_KPPLUS) -> xorgkbd:86 */ + [0x4f] = 0x57, /* qnum:79 -> linux:79 (KEY_KP1) -> xorgkbd:87 */ + [0x50] = 0x58, /* qnum:80 -> linux:80 (KEY_KP2) -> xorgkbd:88 */ + [0x51] = 0x59, /* qnum:81 -> linux:81 (KEY_KP3) -> xorgkbd:89 */ + [0x52] = 0x5a, /* qnum:82 -> linux:82 (KEY_KP0) -> xorgkbd:90 */ + [0x53] = 0x5b, /* qnum:83 -> linux:83 (KEY_KPDOT) -> xorgkbd:91 */ + [0x54] = 0x6f, /* qnum:84 -> linux:99 (KEY_SYSRQ) -> xorgkbd:111 */ + [0x55] = 0x79, /* qnum:85 -> linux:186 (KEY_F16) -> xorgkbd:121 */ + [0x56] = 0x5e, /* qnum:86 -> linux:86 (KEY_102ND) -> xorgkbd:94 */ + [0x57] = 0x5f, /* qnum:87 -> linux:87 (KEY_F11) -> xorgkbd:95 */ + [0x58] = 0x60, /* qnum:88 -> linux:88 (KEY_F12) -> xorgkbd:96 */ + [0x59] = 0x7e, /* qnum:89 -> linux:117 (KEY_KPEQUAL) -> xorgkbd:126 */ + [0x5d] = 0x76, /* qnum:93 -> linux:183 (KEY_F13) -> xorgkbd:118 */ + [0x5e] = 0x77, /* qnum:94 -> linux:184 (KEY_F14) -> xorgkbd:119 */ + [0x5f] = 0x78, /* qnum:95 -> linux:185 (KEY_F15) -> xorgkbd:120 */ + [0x7d] = 0x85, /* qnum:125 -> linux:124 (KEY_YEN) -> xorgkbd:133 */ + [0x83] = 0x7a, /* qnum:131 -> linux:187 (KEY_F17) -> xorgkbd:122 */ + [0x9c] = 0x6c, /* qnum:156 -> linux:96 (KEY_KPENTER) -> xorgkbd:108 */ + [0x9d] = 0x6d, /* qnum:157 -> linux:97 (KEY_RIGHTCTRL) -> xorgkbd:109 */ + [0xb5] = 0x70, /* qnum:181 -> linux:98 (KEY_KPSLASH) -> xorgkbd:112 */ + [0xb8] = 0x71, /* qnum:184 -> linux:100 (KEY_RIGHTALT) -> xorgkbd:113 */ + [0xc6] = 0x6e, /* qnum:198 -> linux:119 (KEY_PAUSE) -> xorgkbd:110 */ + [0xc7] = 0x61, /* qnum:199 -> linux:102 (KEY_HOME) -> xorgkbd:97 */ + [0xc8] = 0x62, /* qnum:200 -> linux:103 (KEY_UP) -> xorgkbd:98 */ + [0xc9] = 0x63, /* qnum:201 -> linux:104 (KEY_PAGEUP) -> xorgkbd:99 */ + [0xcb] = 0x64, /* qnum:203 -> linux:105 (KEY_LEFT) -> xorgkbd:100 */ + [0xcd] = 0x66, /* qnum:205 -> linux:106 (KEY_RIGHT) -> xorgkbd:102 */ + [0xcf] = 0x67, /* qnum:207 -> linux:107 (KEY_END) -> xorgkbd:103 */ + [0xd0] = 0x68, /* qnum:208 -> linux:108 (KEY_DOWN) -> xorgkbd:104 */ + [0xd1] = 0x69, /* qnum:209 -> linux:109 (KEY_PAGEDOWN) -> xorgkbd:105 */ + [0xd2] = 0x6a, /* qnum:210 -> linux:110 (KEY_INSERT) -> xorgkbd:106 */ + [0xd3] = 0x6b, /* qnum:211 -> linux:111 (KEY_DELETE) -> xorgkbd:107 */ + [0xdb] = 0x73, /* qnum:219 -> linux:125 (KEY_LEFTMETA) -> xorgkbd:115 */ + [0xdc] = 0x74, /* qnum:220 -> linux:126 (KEY_RIGHTMETA) -> xorgkbd:116 */ + [0xdd] = 0x75, /* qnum:221 -> linux:127 (KEY_COMPOSE) -> xorgkbd:117 */ +}; +const unsigned int code_map_qnum_to_xorgkbd_len = sizeof(code_map_qnum_to_xorgkbd)/sizeof(code_map_qnum_to_xorgkbd[0]); diff --git a/unix/x0vncserver/x0vncserver.cxx b/unix/x0vncserver/x0vncserver.cxx index 7fb197aa..1ca73781 100644 --- a/unix/x0vncserver/x0vncserver.cxx +++ b/unix/x0vncserver/x0vncserver.cxx @@ -52,6 +52,12 @@ #include #include +extern const unsigned short code_map_qnum_to_xorgevdev[]; +extern const unsigned int code_map_qnum_to_xorgevdev_len; + +extern const unsigned short code_map_qnum_to_xorgkbd[]; +extern const unsigned int code_map_qnum_to_xorgkbd_len; + // XXX Lynx/OS 2.3: protos for select(), bzero() #ifdef Lynx #include @@ -87,6 +93,10 @@ IntParameter queryConnectTimeout("QueryConnectTimeout", "rejecting the connection", 10); StringParameter hostsFile("HostsFile", "File with IP access control rules", ""); +BoolParameter rawKeyboard("RawKeyboard", + "Send keyboard events straight through and " + "avoid mapping them to the current keyboard " + "layout", false); // // Allow the main loop terminate itself gracefully on receiving a signal. @@ -150,7 +160,8 @@ public: XDesktop(Display* dpy_, Geometry *geometry_) : dpy(dpy_), geometry(geometry_), pb(0), server(0), oldButtonMask(0), haveXtest(false), haveDamage(false), - maxButtons(0), running(false), ledMasks(), ledState(0) + maxButtons(0), running(false), ledMasks(), ledState(0), + codeMap(0), codeMapLen(0) { int major, minor; @@ -183,6 +194,32 @@ public: ledState |= 1u << i; } + // X11 unfortunately uses keyboard driver specific keycodes and provides no + // direct way to query this, so guess based on the keyboard mapping + XkbDescPtr desc = XkbGetKeyboard(dpy, XkbAllComponentsMask, XkbUseCoreKbd); + if (desc && desc->names) { + char *keycodes = XGetAtomName(dpy, desc->names->keycodes); + + if (keycodes) { + if (strncmp("evdev", keycodes, strlen("evdev")) == 0) { + codeMap = code_map_qnum_to_xorgevdev; + codeMapLen = code_map_qnum_to_xorgevdev_len; + vlog.info("Using evdev codemap\n"); + } else if (strncmp("xfree86", keycodes, strlen("xfree86")) == 0) { + codeMap = code_map_qnum_to_xorgkbd; + codeMapLen = code_map_qnum_to_xorgkbd_len; + vlog.info("Using xorgkbd codemap\n"); + } else { + vlog.info("Unknown keycode '%s', no codemap\n", keycodes); + } + XFree(keycodes); + } else { + vlog.debug("Unable to get keycode map\n"); + } + + XkbFreeKeyboard(desc, XkbAllComponentsMask, True); + } + #ifdef HAVE_XTEST int xtestEventBase; int xtestErrorBase; @@ -297,8 +334,16 @@ public: virtual void keyEvent(rdr::U32 keysym, rdr::U32 xtcode, bool down) { #ifdef HAVE_XTEST + int keycode = 0; if (!haveXtest) return; - int keycode = XKeysymToKeycode(dpy, keysym); + + // Use scan code if provided and mapping exists + if (codeMap && rawKeyboard && xtcode < codeMapLen) + keycode = codeMap[xtcode]; + + if (!keycode) + keycode = XKeysymToKeycode(dpy, keysym); + if (keycode) XTestFakeKeyEvent(dpy, keycode, down, CurrentTime); #endif @@ -368,6 +413,8 @@ protected: int xkbEventBase; int ledMasks[N_LEDS]; unsigned ledState; + const unsigned short *codeMap; + unsigned codeMapLen; }; diff --git a/unix/x0vncserver/x0vncserver.man b/unix/x0vncserver/x0vncserver.man index 095f6db3..804a70fc 100644 --- a/unix/x0vncserver/x0vncserver.man +++ b/unix/x0vncserver/x0vncserver.man @@ -168,6 +168,13 @@ two hex values, prefixed by \fB0x\fP, and separated by \fB->\fP (`dash' and `greater than' characters). . .TP +.B RawKeyboard +Send keyboard events straight through and avoid mapping them to the current +keyboard layout. This effectively makes the keyboard behave according to the +layout configured on the server instead of the layout configured on the +client. Default is off. +. +.TP .B Protocol3.3 Always use RFB protocol version 3.3 for backwards compatibility with badly-behaved clients. Default is off. -- 2.39.5