| 1 | //! XKB keymap. |
| 2 | |
| 3 | use std::ffi::c_char; |
| 4 | use std::ops::Deref; |
| 5 | use std::ptr::{self, NonNull}; |
| 6 | |
| 7 | #[cfg (x11_platform)] |
| 8 | use x11_dl::xlib_xcb::xcb_connection_t; |
| 9 | #[cfg (wayland_platform)] |
| 10 | use {memmap2::MmapOptions, std::os::unix::io::OwnedFd}; |
| 11 | |
| 12 | use xkb::XKB_MOD_INVALID; |
| 13 | use xkbcommon_dl::{ |
| 14 | self as xkb, xkb_keycode_t, xkb_keymap, xkb_keymap_compile_flags, xkb_keysym_t, |
| 15 | xkb_layout_index_t, xkb_mod_index_t, |
| 16 | }; |
| 17 | |
| 18 | use crate::keyboard::{Key, KeyCode, KeyLocation, NamedKey, NativeKey, NativeKeyCode, PhysicalKey}; |
| 19 | #[cfg (x11_platform)] |
| 20 | use crate::platform_impl::common::xkb::XKBXH; |
| 21 | use crate::platform_impl::common::xkb::{XkbContext, XKBH}; |
| 22 | |
| 23 | /// Map the raw X11-style keycode to the `KeyCode` enum. |
| 24 | /// |
| 25 | /// X11-style keycodes are offset by 8 from the keycodes the Linux kernel uses. |
| 26 | pub fn raw_keycode_to_physicalkey(keycode: u32) -> PhysicalKey { |
| 27 | scancode_to_physicalkey(scancode:keycode.saturating_sub(8)) |
| 28 | } |
| 29 | |
| 30 | /// Map the linux scancode to Keycode. |
| 31 | /// |
| 32 | /// Both X11 and Wayland use keys with `+ 8` offset to linux scancode. |
| 33 | pub fn scancode_to_physicalkey(scancode: u32) -> PhysicalKey { |
| 34 | // The keycode values are taken from linux/include/uapi/linux/input-event-codes.h, as |
| 35 | // libxkbcommon's documentation seems to suggest that the keycode values we're interested in |
| 36 | // are defined by the Linux kernel. If Winit programs end up being run on other Unix-likes, |
| 37 | // I can only hope they agree on what the keycodes mean. |
| 38 | // |
| 39 | // Some of the keycodes are likely superfluous for our purposes, and some are ones which are |
| 40 | // difficult to test the correctness of, or discover the purpose of. Because of this, they've |
| 41 | // either been commented out here, or not included at all. |
| 42 | PhysicalKey::Code(match scancode { |
| 43 | 0 => return PhysicalKey::Unidentified(NativeKeyCode::Xkb(0)), |
| 44 | 1 => KeyCode::Escape, |
| 45 | 2 => KeyCode::Digit1, |
| 46 | 3 => KeyCode::Digit2, |
| 47 | 4 => KeyCode::Digit3, |
| 48 | 5 => KeyCode::Digit4, |
| 49 | 6 => KeyCode::Digit5, |
| 50 | 7 => KeyCode::Digit6, |
| 51 | 8 => KeyCode::Digit7, |
| 52 | 9 => KeyCode::Digit8, |
| 53 | 10 => KeyCode::Digit9, |
| 54 | 11 => KeyCode::Digit0, |
| 55 | 12 => KeyCode::Minus, |
| 56 | 13 => KeyCode::Equal, |
| 57 | 14 => KeyCode::Backspace, |
| 58 | 15 => KeyCode::Tab, |
| 59 | 16 => KeyCode::KeyQ, |
| 60 | 17 => KeyCode::KeyW, |
| 61 | 18 => KeyCode::KeyE, |
| 62 | 19 => KeyCode::KeyR, |
| 63 | 20 => KeyCode::KeyT, |
| 64 | 21 => KeyCode::KeyY, |
| 65 | 22 => KeyCode::KeyU, |
| 66 | 23 => KeyCode::KeyI, |
| 67 | 24 => KeyCode::KeyO, |
| 68 | 25 => KeyCode::KeyP, |
| 69 | 26 => KeyCode::BracketLeft, |
| 70 | 27 => KeyCode::BracketRight, |
| 71 | 28 => KeyCode::Enter, |
| 72 | 29 => KeyCode::ControlLeft, |
| 73 | 30 => KeyCode::KeyA, |
| 74 | 31 => KeyCode::KeyS, |
| 75 | 32 => KeyCode::KeyD, |
| 76 | 33 => KeyCode::KeyF, |
| 77 | 34 => KeyCode::KeyG, |
| 78 | 35 => KeyCode::KeyH, |
| 79 | 36 => KeyCode::KeyJ, |
| 80 | 37 => KeyCode::KeyK, |
| 81 | 38 => KeyCode::KeyL, |
| 82 | 39 => KeyCode::Semicolon, |
| 83 | 40 => KeyCode::Quote, |
| 84 | 41 => KeyCode::Backquote, |
| 85 | 42 => KeyCode::ShiftLeft, |
| 86 | 43 => KeyCode::Backslash, |
| 87 | 44 => KeyCode::KeyZ, |
| 88 | 45 => KeyCode::KeyX, |
| 89 | 46 => KeyCode::KeyC, |
| 90 | 47 => KeyCode::KeyV, |
| 91 | 48 => KeyCode::KeyB, |
| 92 | 49 => KeyCode::KeyN, |
| 93 | 50 => KeyCode::KeyM, |
| 94 | 51 => KeyCode::Comma, |
| 95 | 52 => KeyCode::Period, |
| 96 | 53 => KeyCode::Slash, |
| 97 | 54 => KeyCode::ShiftRight, |
| 98 | 55 => KeyCode::NumpadMultiply, |
| 99 | 56 => KeyCode::AltLeft, |
| 100 | 57 => KeyCode::Space, |
| 101 | 58 => KeyCode::CapsLock, |
| 102 | 59 => KeyCode::F1, |
| 103 | 60 => KeyCode::F2, |
| 104 | 61 => KeyCode::F3, |
| 105 | 62 => KeyCode::F4, |
| 106 | 63 => KeyCode::F5, |
| 107 | 64 => KeyCode::F6, |
| 108 | 65 => KeyCode::F7, |
| 109 | 66 => KeyCode::F8, |
| 110 | 67 => KeyCode::F9, |
| 111 | 68 => KeyCode::F10, |
| 112 | 69 => KeyCode::NumLock, |
| 113 | 70 => KeyCode::ScrollLock, |
| 114 | 71 => KeyCode::Numpad7, |
| 115 | 72 => KeyCode::Numpad8, |
| 116 | 73 => KeyCode::Numpad9, |
| 117 | 74 => KeyCode::NumpadSubtract, |
| 118 | 75 => KeyCode::Numpad4, |
| 119 | 76 => KeyCode::Numpad5, |
| 120 | 77 => KeyCode::Numpad6, |
| 121 | 78 => KeyCode::NumpadAdd, |
| 122 | 79 => KeyCode::Numpad1, |
| 123 | 80 => KeyCode::Numpad2, |
| 124 | 81 => KeyCode::Numpad3, |
| 125 | 82 => KeyCode::Numpad0, |
| 126 | 83 => KeyCode::NumpadDecimal, |
| 127 | 85 => KeyCode::Lang5, |
| 128 | 86 => KeyCode::IntlBackslash, |
| 129 | 87 => KeyCode::F11, |
| 130 | 88 => KeyCode::F12, |
| 131 | 89 => KeyCode::IntlRo, |
| 132 | 90 => KeyCode::Lang3, |
| 133 | 91 => KeyCode::Lang4, |
| 134 | 92 => KeyCode::Convert, |
| 135 | 93 => KeyCode::KanaMode, |
| 136 | 94 => KeyCode::NonConvert, |
| 137 | // 95 => KeyCode::KPJPCOMMA, |
| 138 | 96 => KeyCode::NumpadEnter, |
| 139 | 97 => KeyCode::ControlRight, |
| 140 | 98 => KeyCode::NumpadDivide, |
| 141 | 99 => KeyCode::PrintScreen, |
| 142 | 100 => KeyCode::AltRight, |
| 143 | // 101 => KeyCode::LINEFEED, |
| 144 | 102 => KeyCode::Home, |
| 145 | 103 => KeyCode::ArrowUp, |
| 146 | 104 => KeyCode::PageUp, |
| 147 | 105 => KeyCode::ArrowLeft, |
| 148 | 106 => KeyCode::ArrowRight, |
| 149 | 107 => KeyCode::End, |
| 150 | 108 => KeyCode::ArrowDown, |
| 151 | 109 => KeyCode::PageDown, |
| 152 | 110 => KeyCode::Insert, |
| 153 | 111 => KeyCode::Delete, |
| 154 | // 112 => KeyCode::MACRO, |
| 155 | 113 => KeyCode::AudioVolumeMute, |
| 156 | 114 => KeyCode::AudioVolumeDown, |
| 157 | 115 => KeyCode::AudioVolumeUp, |
| 158 | // 116 => KeyCode::POWER, |
| 159 | 117 => KeyCode::NumpadEqual, |
| 160 | // 118 => KeyCode::KPPLUSMINUS, |
| 161 | 119 => KeyCode::Pause, |
| 162 | // 120 => KeyCode::SCALE, |
| 163 | 121 => KeyCode::NumpadComma, |
| 164 | 122 => KeyCode::Lang1, |
| 165 | 123 => KeyCode::Lang2, |
| 166 | 124 => KeyCode::IntlYen, |
| 167 | 125 => KeyCode::SuperLeft, |
| 168 | 126 => KeyCode::SuperRight, |
| 169 | 127 => KeyCode::ContextMenu, |
| 170 | // 128 => KeyCode::STOP, |
| 171 | // 129 => KeyCode::AGAIN, |
| 172 | // 130 => KeyCode::PROPS, |
| 173 | // 131 => KeyCode::UNDO, |
| 174 | // 132 => KeyCode::FRONT, |
| 175 | // 133 => KeyCode::COPY, |
| 176 | // 134 => KeyCode::OPEN, |
| 177 | // 135 => KeyCode::PASTE, |
| 178 | // 136 => KeyCode::FIND, |
| 179 | // 137 => KeyCode::CUT, |
| 180 | // 138 => KeyCode::HELP, |
| 181 | // 139 => KeyCode::MENU, |
| 182 | // 140 => KeyCode::CALC, |
| 183 | // 141 => KeyCode::SETUP, |
| 184 | // 142 => KeyCode::SLEEP, |
| 185 | // 143 => KeyCode::WAKEUP, |
| 186 | // 144 => KeyCode::FILE, |
| 187 | // 145 => KeyCode::SENDFILE, |
| 188 | // 146 => KeyCode::DELETEFILE, |
| 189 | // 147 => KeyCode::XFER, |
| 190 | // 148 => KeyCode::PROG1, |
| 191 | // 149 => KeyCode::PROG2, |
| 192 | // 150 => KeyCode::WWW, |
| 193 | // 151 => KeyCode::MSDOS, |
| 194 | // 152 => KeyCode::COFFEE, |
| 195 | // 153 => KeyCode::ROTATE_DISPLAY, |
| 196 | // 154 => KeyCode::CYCLEWINDOWS, |
| 197 | // 155 => KeyCode::MAIL, |
| 198 | // 156 => KeyCode::BOOKMARKS, |
| 199 | // 157 => KeyCode::COMPUTER, |
| 200 | // 158 => KeyCode::BACK, |
| 201 | // 159 => KeyCode::FORWARD, |
| 202 | // 160 => KeyCode::CLOSECD, |
| 203 | // 161 => KeyCode::EJECTCD, |
| 204 | // 162 => KeyCode::EJECTCLOSECD, |
| 205 | 163 => KeyCode::MediaTrackNext, |
| 206 | 164 => KeyCode::MediaPlayPause, |
| 207 | 165 => KeyCode::MediaTrackPrevious, |
| 208 | 166 => KeyCode::MediaStop, |
| 209 | // 167 => KeyCode::RECORD, |
| 210 | // 168 => KeyCode::REWIND, |
| 211 | // 169 => KeyCode::PHONE, |
| 212 | // 170 => KeyCode::ISO, |
| 213 | // 171 => KeyCode::CONFIG, |
| 214 | // 172 => KeyCode::HOMEPAGE, |
| 215 | // 173 => KeyCode::REFRESH, |
| 216 | // 174 => KeyCode::EXIT, |
| 217 | // 175 => KeyCode::MOVE, |
| 218 | // 176 => KeyCode::EDIT, |
| 219 | // 177 => KeyCode::SCROLLUP, |
| 220 | // 178 => KeyCode::SCROLLDOWN, |
| 221 | // 179 => KeyCode::KPLEFTPAREN, |
| 222 | // 180 => KeyCode::KPRIGHTPAREN, |
| 223 | // 181 => KeyCode::NEW, |
| 224 | // 182 => KeyCode::REDO, |
| 225 | 183 => KeyCode::F13, |
| 226 | 184 => KeyCode::F14, |
| 227 | 185 => KeyCode::F15, |
| 228 | 186 => KeyCode::F16, |
| 229 | 187 => KeyCode::F17, |
| 230 | 188 => KeyCode::F18, |
| 231 | 189 => KeyCode::F19, |
| 232 | 190 => KeyCode::F20, |
| 233 | 191 => KeyCode::F21, |
| 234 | 192 => KeyCode::F22, |
| 235 | 193 => KeyCode::F23, |
| 236 | 194 => KeyCode::F24, |
| 237 | // 200 => KeyCode::PLAYCD, |
| 238 | // 201 => KeyCode::PAUSECD, |
| 239 | // 202 => KeyCode::PROG3, |
| 240 | // 203 => KeyCode::PROG4, |
| 241 | // 204 => KeyCode::DASHBOARD, |
| 242 | // 205 => KeyCode::SUSPEND, |
| 243 | // 206 => KeyCode::CLOSE, |
| 244 | // 207 => KeyCode::PLAY, |
| 245 | // 208 => KeyCode::FASTFORWARD, |
| 246 | // 209 => KeyCode::BASSBOOST, |
| 247 | // 210 => KeyCode::PRINT, |
| 248 | // 211 => KeyCode::HP, |
| 249 | // 212 => KeyCode::CAMERA, |
| 250 | // 213 => KeyCode::SOUND, |
| 251 | // 214 => KeyCode::QUESTION, |
| 252 | // 215 => KeyCode::EMAIL, |
| 253 | // 216 => KeyCode::CHAT, |
| 254 | // 217 => KeyCode::SEARCH, |
| 255 | // 218 => KeyCode::CONNECT, |
| 256 | // 219 => KeyCode::FINANCE, |
| 257 | // 220 => KeyCode::SPORT, |
| 258 | // 221 => KeyCode::SHOP, |
| 259 | // 222 => KeyCode::ALTERASE, |
| 260 | // 223 => KeyCode::CANCEL, |
| 261 | // 224 => KeyCode::BRIGHTNESSDOW, |
| 262 | // 225 => KeyCode::BRIGHTNESSU, |
| 263 | // 226 => KeyCode::MEDIA, |
| 264 | // 227 => KeyCode::SWITCHVIDEOMODE, |
| 265 | // 228 => KeyCode::KBDILLUMTOGGLE, |
| 266 | // 229 => KeyCode::KBDILLUMDOWN, |
| 267 | // 230 => KeyCode::KBDILLUMUP, |
| 268 | // 231 => KeyCode::SEND, |
| 269 | // 232 => KeyCode::REPLY, |
| 270 | // 233 => KeyCode::FORWARDMAIL, |
| 271 | // 234 => KeyCode::SAVE, |
| 272 | // 235 => KeyCode::DOCUMENTS, |
| 273 | // 236 => KeyCode::BATTERY, |
| 274 | // 237 => KeyCode::BLUETOOTH, |
| 275 | // 238 => KeyCode::WLAN, |
| 276 | // 239 => KeyCode::UWB, |
| 277 | 240 => return PhysicalKey::Unidentified(NativeKeyCode::Unidentified), |
| 278 | // 241 => KeyCode::VIDEO_NEXT, |
| 279 | // 242 => KeyCode::VIDEO_PREV, |
| 280 | // 243 => KeyCode::BRIGHTNESS_CYCLE, |
| 281 | // 244 => KeyCode::BRIGHTNESS_AUTO, |
| 282 | // 245 => KeyCode::DISPLAY_OFF, |
| 283 | // 246 => KeyCode::WWAN, |
| 284 | // 247 => KeyCode::RFKILL, |
| 285 | // 248 => KeyCode::KEY_MICMUTE, |
| 286 | _ => return PhysicalKey::Unidentified(NativeKeyCode::Xkb(scancode)), |
| 287 | }) |
| 288 | } |
| 289 | |
| 290 | pub fn physicalkey_to_scancode(key: PhysicalKey) -> Option<u32> { |
| 291 | let code = match key { |
| 292 | PhysicalKey::Code(code) => code, |
| 293 | PhysicalKey::Unidentified(code) => { |
| 294 | return match code { |
| 295 | NativeKeyCode::Unidentified => Some(240), |
| 296 | NativeKeyCode::Xkb(raw) => Some(raw), |
| 297 | _ => None, |
| 298 | }; |
| 299 | }, |
| 300 | }; |
| 301 | |
| 302 | match code { |
| 303 | KeyCode::Escape => Some(1), |
| 304 | KeyCode::Digit1 => Some(2), |
| 305 | KeyCode::Digit2 => Some(3), |
| 306 | KeyCode::Digit3 => Some(4), |
| 307 | KeyCode::Digit4 => Some(5), |
| 308 | KeyCode::Digit5 => Some(6), |
| 309 | KeyCode::Digit6 => Some(7), |
| 310 | KeyCode::Digit7 => Some(8), |
| 311 | KeyCode::Digit8 => Some(9), |
| 312 | KeyCode::Digit9 => Some(10), |
| 313 | KeyCode::Digit0 => Some(11), |
| 314 | KeyCode::Minus => Some(12), |
| 315 | KeyCode::Equal => Some(13), |
| 316 | KeyCode::Backspace => Some(14), |
| 317 | KeyCode::Tab => Some(15), |
| 318 | KeyCode::KeyQ => Some(16), |
| 319 | KeyCode::KeyW => Some(17), |
| 320 | KeyCode::KeyE => Some(18), |
| 321 | KeyCode::KeyR => Some(19), |
| 322 | KeyCode::KeyT => Some(20), |
| 323 | KeyCode::KeyY => Some(21), |
| 324 | KeyCode::KeyU => Some(22), |
| 325 | KeyCode::KeyI => Some(23), |
| 326 | KeyCode::KeyO => Some(24), |
| 327 | KeyCode::KeyP => Some(25), |
| 328 | KeyCode::BracketLeft => Some(26), |
| 329 | KeyCode::BracketRight => Some(27), |
| 330 | KeyCode::Enter => Some(28), |
| 331 | KeyCode::ControlLeft => Some(29), |
| 332 | KeyCode::KeyA => Some(30), |
| 333 | KeyCode::KeyS => Some(31), |
| 334 | KeyCode::KeyD => Some(32), |
| 335 | KeyCode::KeyF => Some(33), |
| 336 | KeyCode::KeyG => Some(34), |
| 337 | KeyCode::KeyH => Some(35), |
| 338 | KeyCode::KeyJ => Some(36), |
| 339 | KeyCode::KeyK => Some(37), |
| 340 | KeyCode::KeyL => Some(38), |
| 341 | KeyCode::Semicolon => Some(39), |
| 342 | KeyCode::Quote => Some(40), |
| 343 | KeyCode::Backquote => Some(41), |
| 344 | KeyCode::ShiftLeft => Some(42), |
| 345 | KeyCode::Backslash => Some(43), |
| 346 | KeyCode::KeyZ => Some(44), |
| 347 | KeyCode::KeyX => Some(45), |
| 348 | KeyCode::KeyC => Some(46), |
| 349 | KeyCode::KeyV => Some(47), |
| 350 | KeyCode::KeyB => Some(48), |
| 351 | KeyCode::KeyN => Some(49), |
| 352 | KeyCode::KeyM => Some(50), |
| 353 | KeyCode::Comma => Some(51), |
| 354 | KeyCode::Period => Some(52), |
| 355 | KeyCode::Slash => Some(53), |
| 356 | KeyCode::ShiftRight => Some(54), |
| 357 | KeyCode::NumpadMultiply => Some(55), |
| 358 | KeyCode::AltLeft => Some(56), |
| 359 | KeyCode::Space => Some(57), |
| 360 | KeyCode::CapsLock => Some(58), |
| 361 | KeyCode::F1 => Some(59), |
| 362 | KeyCode::F2 => Some(60), |
| 363 | KeyCode::F3 => Some(61), |
| 364 | KeyCode::F4 => Some(62), |
| 365 | KeyCode::F5 => Some(63), |
| 366 | KeyCode::F6 => Some(64), |
| 367 | KeyCode::F7 => Some(65), |
| 368 | KeyCode::F8 => Some(66), |
| 369 | KeyCode::F9 => Some(67), |
| 370 | KeyCode::F10 => Some(68), |
| 371 | KeyCode::NumLock => Some(69), |
| 372 | KeyCode::ScrollLock => Some(70), |
| 373 | KeyCode::Numpad7 => Some(71), |
| 374 | KeyCode::Numpad8 => Some(72), |
| 375 | KeyCode::Numpad9 => Some(73), |
| 376 | KeyCode::NumpadSubtract => Some(74), |
| 377 | KeyCode::Numpad4 => Some(75), |
| 378 | KeyCode::Numpad5 => Some(76), |
| 379 | KeyCode::Numpad6 => Some(77), |
| 380 | KeyCode::NumpadAdd => Some(78), |
| 381 | KeyCode::Numpad1 => Some(79), |
| 382 | KeyCode::Numpad2 => Some(80), |
| 383 | KeyCode::Numpad3 => Some(81), |
| 384 | KeyCode::Numpad0 => Some(82), |
| 385 | KeyCode::NumpadDecimal => Some(83), |
| 386 | KeyCode::Lang5 => Some(85), |
| 387 | KeyCode::IntlBackslash => Some(86), |
| 388 | KeyCode::F11 => Some(87), |
| 389 | KeyCode::F12 => Some(88), |
| 390 | KeyCode::IntlRo => Some(89), |
| 391 | KeyCode::Lang3 => Some(90), |
| 392 | KeyCode::Lang4 => Some(91), |
| 393 | KeyCode::Convert => Some(92), |
| 394 | KeyCode::KanaMode => Some(93), |
| 395 | KeyCode::NonConvert => Some(94), |
| 396 | KeyCode::NumpadEnter => Some(96), |
| 397 | KeyCode::ControlRight => Some(97), |
| 398 | KeyCode::NumpadDivide => Some(98), |
| 399 | KeyCode::PrintScreen => Some(99), |
| 400 | KeyCode::AltRight => Some(100), |
| 401 | KeyCode::Home => Some(102), |
| 402 | KeyCode::ArrowUp => Some(103), |
| 403 | KeyCode::PageUp => Some(104), |
| 404 | KeyCode::ArrowLeft => Some(105), |
| 405 | KeyCode::ArrowRight => Some(106), |
| 406 | KeyCode::End => Some(107), |
| 407 | KeyCode::ArrowDown => Some(108), |
| 408 | KeyCode::PageDown => Some(109), |
| 409 | KeyCode::Insert => Some(110), |
| 410 | KeyCode::Delete => Some(111), |
| 411 | KeyCode::AudioVolumeMute => Some(113), |
| 412 | KeyCode::AudioVolumeDown => Some(114), |
| 413 | KeyCode::AudioVolumeUp => Some(115), |
| 414 | KeyCode::NumpadEqual => Some(117), |
| 415 | KeyCode::Pause => Some(119), |
| 416 | KeyCode::NumpadComma => Some(121), |
| 417 | KeyCode::Lang1 => Some(122), |
| 418 | KeyCode::Lang2 => Some(123), |
| 419 | KeyCode::IntlYen => Some(124), |
| 420 | KeyCode::SuperLeft => Some(125), |
| 421 | KeyCode::SuperRight => Some(126), |
| 422 | KeyCode::ContextMenu => Some(127), |
| 423 | KeyCode::MediaTrackNext => Some(163), |
| 424 | KeyCode::MediaPlayPause => Some(164), |
| 425 | KeyCode::MediaTrackPrevious => Some(165), |
| 426 | KeyCode::MediaStop => Some(166), |
| 427 | KeyCode::F13 => Some(183), |
| 428 | KeyCode::F14 => Some(184), |
| 429 | KeyCode::F15 => Some(185), |
| 430 | KeyCode::F16 => Some(186), |
| 431 | KeyCode::F17 => Some(187), |
| 432 | KeyCode::F18 => Some(188), |
| 433 | KeyCode::F19 => Some(189), |
| 434 | KeyCode::F20 => Some(190), |
| 435 | KeyCode::F21 => Some(191), |
| 436 | KeyCode::F22 => Some(192), |
| 437 | KeyCode::F23 => Some(193), |
| 438 | KeyCode::F24 => Some(194), |
| 439 | _ => None, |
| 440 | } |
| 441 | } |
| 442 | |
| 443 | pub fn keysym_to_key(keysym: u32) -> Key { |
| 444 | use xkbcommon_dl::keysyms; |
| 445 | Key::Named(match keysym { |
| 446 | // TTY function keys |
| 447 | keysyms::BackSpace => NamedKey::Backspace, |
| 448 | keysyms::Tab => NamedKey::Tab, |
| 449 | // keysyms::Linefeed => NamedKey::Linefeed, |
| 450 | keysyms::Clear => NamedKey::Clear, |
| 451 | keysyms::Return => NamedKey::Enter, |
| 452 | keysyms::Pause => NamedKey::Pause, |
| 453 | keysyms::Scroll_Lock => NamedKey::ScrollLock, |
| 454 | keysyms::Sys_Req => NamedKey::PrintScreen, |
| 455 | keysyms::Escape => NamedKey::Escape, |
| 456 | keysyms::Delete => NamedKey::Delete, |
| 457 | |
| 458 | // IME keys |
| 459 | keysyms::Multi_key => NamedKey::Compose, |
| 460 | keysyms::Codeinput => NamedKey::CodeInput, |
| 461 | keysyms::SingleCandidate => NamedKey::SingleCandidate, |
| 462 | keysyms::MultipleCandidate => NamedKey::AllCandidates, |
| 463 | keysyms::PreviousCandidate => NamedKey::PreviousCandidate, |
| 464 | |
| 465 | // Japanese keys |
| 466 | keysyms::Kanji => NamedKey::KanjiMode, |
| 467 | keysyms::Muhenkan => NamedKey::NonConvert, |
| 468 | keysyms::Henkan_Mode => NamedKey::Convert, |
| 469 | keysyms::Romaji => NamedKey::Romaji, |
| 470 | keysyms::Hiragana => NamedKey::Hiragana, |
| 471 | keysyms::Hiragana_Katakana => NamedKey::HiraganaKatakana, |
| 472 | keysyms::Zenkaku => NamedKey::Zenkaku, |
| 473 | keysyms::Hankaku => NamedKey::Hankaku, |
| 474 | keysyms::Zenkaku_Hankaku => NamedKey::ZenkakuHankaku, |
| 475 | // keysyms::Touroku => NamedKey::Touroku, |
| 476 | // keysyms::Massyo => NamedKey::Massyo, |
| 477 | keysyms::Kana_Lock => NamedKey::KanaMode, |
| 478 | keysyms::Kana_Shift => NamedKey::KanaMode, |
| 479 | keysyms::Eisu_Shift => NamedKey::Alphanumeric, |
| 480 | keysyms::Eisu_toggle => NamedKey::Alphanumeric, |
| 481 | // NOTE: The next three items are aliases for values we've already mapped. |
| 482 | // keysyms::Kanji_Bangou => NamedKey::CodeInput, |
| 483 | // keysyms::Zen_Koho => NamedKey::AllCandidates, |
| 484 | // keysyms::Mae_Koho => NamedKey::PreviousCandidate, |
| 485 | |
| 486 | // Cursor control & motion |
| 487 | keysyms::Home => NamedKey::Home, |
| 488 | keysyms::Left => NamedKey::ArrowLeft, |
| 489 | keysyms::Up => NamedKey::ArrowUp, |
| 490 | keysyms::Right => NamedKey::ArrowRight, |
| 491 | keysyms::Down => NamedKey::ArrowDown, |
| 492 | // keysyms::Prior => NamedKey::PageUp, |
| 493 | keysyms::Page_Up => NamedKey::PageUp, |
| 494 | // keysyms::Next => NamedKey::PageDown, |
| 495 | keysyms::Page_Down => NamedKey::PageDown, |
| 496 | keysyms::End => NamedKey::End, |
| 497 | // keysyms::Begin => NamedKey::Begin, |
| 498 | |
| 499 | // Misc. functions |
| 500 | keysyms::Select => NamedKey::Select, |
| 501 | keysyms::Print => NamedKey::PrintScreen, |
| 502 | keysyms::Execute => NamedKey::Execute, |
| 503 | keysyms::Insert => NamedKey::Insert, |
| 504 | keysyms::Undo => NamedKey::Undo, |
| 505 | keysyms::Redo => NamedKey::Redo, |
| 506 | keysyms::Menu => NamedKey::ContextMenu, |
| 507 | keysyms::Find => NamedKey::Find, |
| 508 | keysyms::Cancel => NamedKey::Cancel, |
| 509 | keysyms::Help => NamedKey::Help, |
| 510 | keysyms::Break => NamedKey::Pause, |
| 511 | keysyms::Mode_switch => NamedKey::ModeChange, |
| 512 | // keysyms::script_switch => NamedKey::ModeChange, |
| 513 | keysyms::Num_Lock => NamedKey::NumLock, |
| 514 | |
| 515 | // Keypad keys |
| 516 | // keysyms::KP_Space => return Key::Character(" "), |
| 517 | keysyms::KP_Tab => NamedKey::Tab, |
| 518 | keysyms::KP_Enter => NamedKey::Enter, |
| 519 | keysyms::KP_F1 => NamedKey::F1, |
| 520 | keysyms::KP_F2 => NamedKey::F2, |
| 521 | keysyms::KP_F3 => NamedKey::F3, |
| 522 | keysyms::KP_F4 => NamedKey::F4, |
| 523 | keysyms::KP_Home => NamedKey::Home, |
| 524 | keysyms::KP_Left => NamedKey::ArrowLeft, |
| 525 | keysyms::KP_Up => NamedKey::ArrowUp, |
| 526 | keysyms::KP_Right => NamedKey::ArrowRight, |
| 527 | keysyms::KP_Down => NamedKey::ArrowDown, |
| 528 | // keysyms::KP_Prior => NamedKey::PageUp, |
| 529 | keysyms::KP_Page_Up => NamedKey::PageUp, |
| 530 | // keysyms::KP_Next => NamedKey::PageDown, |
| 531 | keysyms::KP_Page_Down => NamedKey::PageDown, |
| 532 | keysyms::KP_End => NamedKey::End, |
| 533 | // This is the key labeled "5" on the numpad when NumLock is off. |
| 534 | // keysyms::KP_Begin => NamedKey::Begin, |
| 535 | keysyms::KP_Insert => NamedKey::Insert, |
| 536 | keysyms::KP_Delete => NamedKey::Delete, |
| 537 | // keysyms::KP_Equal => NamedKey::Equal, |
| 538 | // keysyms::KP_Multiply => NamedKey::Multiply, |
| 539 | // keysyms::KP_Add => NamedKey::Add, |
| 540 | // keysyms::KP_Separator => NamedKey::Separator, |
| 541 | // keysyms::KP_Subtract => NamedKey::Subtract, |
| 542 | // keysyms::KP_Decimal => NamedKey::Decimal, |
| 543 | // keysyms::KP_Divide => NamedKey::Divide, |
| 544 | |
| 545 | // keysyms::KP_0 => return Key::Character("0"), |
| 546 | // keysyms::KP_1 => return Key::Character("1"), |
| 547 | // keysyms::KP_2 => return Key::Character("2"), |
| 548 | // keysyms::KP_3 => return Key::Character("3"), |
| 549 | // keysyms::KP_4 => return Key::Character("4"), |
| 550 | // keysyms::KP_5 => return Key::Character("5"), |
| 551 | // keysyms::KP_6 => return Key::Character("6"), |
| 552 | // keysyms::KP_7 => return Key::Character("7"), |
| 553 | // keysyms::KP_8 => return Key::Character("8"), |
| 554 | // keysyms::KP_9 => return Key::Character("9"), |
| 555 | |
| 556 | // Function keys |
| 557 | keysyms::F1 => NamedKey::F1, |
| 558 | keysyms::F2 => NamedKey::F2, |
| 559 | keysyms::F3 => NamedKey::F3, |
| 560 | keysyms::F4 => NamedKey::F4, |
| 561 | keysyms::F5 => NamedKey::F5, |
| 562 | keysyms::F6 => NamedKey::F6, |
| 563 | keysyms::F7 => NamedKey::F7, |
| 564 | keysyms::F8 => NamedKey::F8, |
| 565 | keysyms::F9 => NamedKey::F9, |
| 566 | keysyms::F10 => NamedKey::F10, |
| 567 | keysyms::F11 => NamedKey::F11, |
| 568 | keysyms::F12 => NamedKey::F12, |
| 569 | keysyms::F13 => NamedKey::F13, |
| 570 | keysyms::F14 => NamedKey::F14, |
| 571 | keysyms::F15 => NamedKey::F15, |
| 572 | keysyms::F16 => NamedKey::F16, |
| 573 | keysyms::F17 => NamedKey::F17, |
| 574 | keysyms::F18 => NamedKey::F18, |
| 575 | keysyms::F19 => NamedKey::F19, |
| 576 | keysyms::F20 => NamedKey::F20, |
| 577 | keysyms::F21 => NamedKey::F21, |
| 578 | keysyms::F22 => NamedKey::F22, |
| 579 | keysyms::F23 => NamedKey::F23, |
| 580 | keysyms::F24 => NamedKey::F24, |
| 581 | keysyms::F25 => NamedKey::F25, |
| 582 | keysyms::F26 => NamedKey::F26, |
| 583 | keysyms::F27 => NamedKey::F27, |
| 584 | keysyms::F28 => NamedKey::F28, |
| 585 | keysyms::F29 => NamedKey::F29, |
| 586 | keysyms::F30 => NamedKey::F30, |
| 587 | keysyms::F31 => NamedKey::F31, |
| 588 | keysyms::F32 => NamedKey::F32, |
| 589 | keysyms::F33 => NamedKey::F33, |
| 590 | keysyms::F34 => NamedKey::F34, |
| 591 | keysyms::F35 => NamedKey::F35, |
| 592 | |
| 593 | // Modifiers |
| 594 | keysyms::Shift_L => NamedKey::Shift, |
| 595 | keysyms::Shift_R => NamedKey::Shift, |
| 596 | keysyms::Control_L => NamedKey::Control, |
| 597 | keysyms::Control_R => NamedKey::Control, |
| 598 | keysyms::Caps_Lock => NamedKey::CapsLock, |
| 599 | // keysyms::Shift_Lock => NamedKey::ShiftLock, |
| 600 | |
| 601 | // keysyms::Meta_L => NamedKey::Meta, |
| 602 | // keysyms::Meta_R => NamedKey::Meta, |
| 603 | keysyms::Alt_L => NamedKey::Alt, |
| 604 | keysyms::Alt_R => NamedKey::Alt, |
| 605 | keysyms::Super_L => NamedKey::Super, |
| 606 | keysyms::Super_R => NamedKey::Super, |
| 607 | keysyms::Hyper_L => NamedKey::Hyper, |
| 608 | keysyms::Hyper_R => NamedKey::Hyper, |
| 609 | |
| 610 | // XKB function and modifier keys |
| 611 | // keysyms::ISO_Lock => NamedKey::IsoLock, |
| 612 | // keysyms::ISO_Level2_Latch => NamedKey::IsoLevel2Latch, |
| 613 | keysyms::ISO_Level3_Shift => NamedKey::AltGraph, |
| 614 | keysyms::ISO_Level3_Latch => NamedKey::AltGraph, |
| 615 | keysyms::ISO_Level3_Lock => NamedKey::AltGraph, |
| 616 | // keysyms::ISO_Level5_Shift => NamedKey::IsoLevel5Shift, |
| 617 | // keysyms::ISO_Level5_Latch => NamedKey::IsoLevel5Latch, |
| 618 | // keysyms::ISO_Level5_Lock => NamedKey::IsoLevel5Lock, |
| 619 | // keysyms::ISO_Group_Shift => NamedKey::IsoGroupShift, |
| 620 | // keysyms::ISO_Group_Latch => NamedKey::IsoGroupLatch, |
| 621 | // keysyms::ISO_Group_Lock => NamedKey::IsoGroupLock, |
| 622 | keysyms::ISO_Next_Group => NamedKey::GroupNext, |
| 623 | // keysyms::ISO_Next_Group_Lock => NamedKey::GroupNextLock, |
| 624 | keysyms::ISO_Prev_Group => NamedKey::GroupPrevious, |
| 625 | // keysyms::ISO_Prev_Group_Lock => NamedKey::GroupPreviousLock, |
| 626 | keysyms::ISO_First_Group => NamedKey::GroupFirst, |
| 627 | // keysyms::ISO_First_Group_Lock => NamedKey::GroupFirstLock, |
| 628 | keysyms::ISO_Last_Group => NamedKey::GroupLast, |
| 629 | // keysyms::ISO_Last_Group_Lock => NamedKey::GroupLastLock, |
| 630 | keysyms::ISO_Left_Tab => NamedKey::Tab, |
| 631 | // keysyms::ISO_Move_Line_Up => NamedKey::IsoMoveLineUp, |
| 632 | // keysyms::ISO_Move_Line_Down => NamedKey::IsoMoveLineDown, |
| 633 | // keysyms::ISO_Partial_Line_Up => NamedKey::IsoPartialLineUp, |
| 634 | // keysyms::ISO_Partial_Line_Down => NamedKey::IsoPartialLineDown, |
| 635 | // keysyms::ISO_Partial_Space_Left => NamedKey::IsoPartialSpaceLeft, |
| 636 | // keysyms::ISO_Partial_Space_Right => NamedKey::IsoPartialSpaceRight, |
| 637 | // keysyms::ISO_Set_Margin_Left => NamedKey::IsoSetMarginLeft, |
| 638 | // keysyms::ISO_Set_Margin_Right => NamedKey::IsoSetMarginRight, |
| 639 | // keysyms::ISO_Release_Margin_Left => NamedKey::IsoReleaseMarginLeft, |
| 640 | // keysyms::ISO_Release_Margin_Right => NamedKey::IsoReleaseMarginRight, |
| 641 | // keysyms::ISO_Release_Both_Margins => NamedKey::IsoReleaseBothMargins, |
| 642 | // keysyms::ISO_Fast_Cursor_Left => NamedKey::IsoFastCursorLeft, |
| 643 | // keysyms::ISO_Fast_Cursor_Right => NamedKey::IsoFastCursorRight, |
| 644 | // keysyms::ISO_Fast_Cursor_Up => NamedKey::IsoFastCursorUp, |
| 645 | // keysyms::ISO_Fast_Cursor_Down => NamedKey::IsoFastCursorDown, |
| 646 | // keysyms::ISO_Continuous_Underline => NamedKey::IsoContinuousUnderline, |
| 647 | // keysyms::ISO_Discontinuous_Underline => NamedKey::IsoDiscontinuousUnderline, |
| 648 | // keysyms::ISO_Emphasize => NamedKey::IsoEmphasize, |
| 649 | // keysyms::ISO_Center_Object => NamedKey::IsoCenterObject, |
| 650 | keysyms::ISO_Enter => NamedKey::Enter, |
| 651 | |
| 652 | // dead_grave..dead_currency |
| 653 | |
| 654 | // dead_lowline..dead_longsolidusoverlay |
| 655 | |
| 656 | // dead_a..dead_capital_schwa |
| 657 | |
| 658 | // dead_greek |
| 659 | |
| 660 | // First_Virtual_Screen..Terminate_Server |
| 661 | |
| 662 | // AccessX_Enable..AudibleBell_Enable |
| 663 | |
| 664 | // Pointer_Left..Pointer_Drag5 |
| 665 | |
| 666 | // Pointer_EnableKeys..Pointer_DfltBtnPrev |
| 667 | |
| 668 | // ch..C_H |
| 669 | |
| 670 | // 3270 terminal keys |
| 671 | // keysyms::3270_Duplicate => NamedKey::Duplicate, |
| 672 | // keysyms::3270_FieldMark => NamedKey::FieldMark, |
| 673 | // keysyms::3270_Right2 => NamedKey::Right2, |
| 674 | // keysyms::3270_Left2 => NamedKey::Left2, |
| 675 | // keysyms::3270_BackTab => NamedKey::BackTab, |
| 676 | keysyms::_3270_EraseEOF => NamedKey::EraseEof, |
| 677 | // keysyms::3270_EraseInput => NamedKey::EraseInput, |
| 678 | // keysyms::3270_Reset => NamedKey::Reset, |
| 679 | // keysyms::3270_Quit => NamedKey::Quit, |
| 680 | // keysyms::3270_PA1 => NamedKey::Pa1, |
| 681 | // keysyms::3270_PA2 => NamedKey::Pa2, |
| 682 | // keysyms::3270_PA3 => NamedKey::Pa3, |
| 683 | // keysyms::3270_Test => NamedKey::Test, |
| 684 | keysyms::_3270_Attn => NamedKey::Attn, |
| 685 | // keysyms::3270_CursorBlink => NamedKey::CursorBlink, |
| 686 | // keysyms::3270_AltCursor => NamedKey::AltCursor, |
| 687 | // keysyms::3270_KeyClick => NamedKey::KeyClick, |
| 688 | // keysyms::3270_Jump => NamedKey::Jump, |
| 689 | // keysyms::3270_Ident => NamedKey::Ident, |
| 690 | // keysyms::3270_Rule => NamedKey::Rule, |
| 691 | // keysyms::3270_Copy => NamedKey::Copy, |
| 692 | keysyms::_3270_Play => NamedKey::Play, |
| 693 | // keysyms::3270_Setup => NamedKey::Setup, |
| 694 | // keysyms::3270_Record => NamedKey::Record, |
| 695 | // keysyms::3270_ChangeScreen => NamedKey::ChangeScreen, |
| 696 | // keysyms::3270_DeleteWord => NamedKey::DeleteWord, |
| 697 | keysyms::_3270_ExSelect => NamedKey::ExSel, |
| 698 | keysyms::_3270_CursorSelect => NamedKey::CrSel, |
| 699 | keysyms::_3270_PrintScreen => NamedKey::PrintScreen, |
| 700 | keysyms::_3270_Enter => NamedKey::Enter, |
| 701 | |
| 702 | keysyms::space => NamedKey::Space, |
| 703 | // exclam..Sinh_kunddaliya |
| 704 | |
| 705 | // XFree86 |
| 706 | // keysyms::XF86_ModeLock => NamedKey::ModeLock, |
| 707 | |
| 708 | // XFree86 - Backlight controls |
| 709 | keysyms::XF86_MonBrightnessUp => NamedKey::BrightnessUp, |
| 710 | keysyms::XF86_MonBrightnessDown => NamedKey::BrightnessDown, |
| 711 | // keysyms::XF86_KbdLightOnOff => NamedKey::LightOnOff, |
| 712 | // keysyms::XF86_KbdBrightnessUp => NamedKey::KeyboardBrightnessUp, |
| 713 | // keysyms::XF86_KbdBrightnessDown => NamedKey::KeyboardBrightnessDown, |
| 714 | |
| 715 | // XFree86 - "Internet" |
| 716 | keysyms::XF86_Standby => NamedKey::Standby, |
| 717 | keysyms::XF86_AudioLowerVolume => NamedKey::AudioVolumeDown, |
| 718 | keysyms::XF86_AudioRaiseVolume => NamedKey::AudioVolumeUp, |
| 719 | keysyms::XF86_AudioPlay => NamedKey::MediaPlay, |
| 720 | keysyms::XF86_AudioStop => NamedKey::MediaStop, |
| 721 | keysyms::XF86_AudioPrev => NamedKey::MediaTrackPrevious, |
| 722 | keysyms::XF86_AudioNext => NamedKey::MediaTrackNext, |
| 723 | keysyms::XF86_HomePage => NamedKey::BrowserHome, |
| 724 | keysyms::XF86_Mail => NamedKey::LaunchMail, |
| 725 | // keysyms::XF86_Start => NamedKey::Start, |
| 726 | keysyms::XF86_Search => NamedKey::BrowserSearch, |
| 727 | keysyms::XF86_AudioRecord => NamedKey::MediaRecord, |
| 728 | |
| 729 | // XFree86 - PDA |
| 730 | keysyms::XF86_Calculator => NamedKey::LaunchApplication2, |
| 731 | // keysyms::XF86_Memo => NamedKey::Memo, |
| 732 | // keysyms::XF86_ToDoList => NamedKey::ToDoList, |
| 733 | keysyms::XF86_Calendar => NamedKey::LaunchCalendar, |
| 734 | keysyms::XF86_PowerDown => NamedKey::Power, |
| 735 | // keysyms::XF86_ContrastAdjust => NamedKey::AdjustContrast, |
| 736 | // keysyms::XF86_RockerUp => NamedKey::RockerUp, |
| 737 | // keysyms::XF86_RockerDown => NamedKey::RockerDown, |
| 738 | // keysyms::XF86_RockerEnter => NamedKey::RockerEnter, |
| 739 | |
| 740 | // XFree86 - More "Internet" |
| 741 | keysyms::XF86_Back => NamedKey::BrowserBack, |
| 742 | keysyms::XF86_Forward => NamedKey::BrowserForward, |
| 743 | // keysyms::XF86_Stop => NamedKey::Stop, |
| 744 | keysyms::XF86_Refresh => NamedKey::BrowserRefresh, |
| 745 | keysyms::XF86_PowerOff => NamedKey::Power, |
| 746 | keysyms::XF86_WakeUp => NamedKey::WakeUp, |
| 747 | keysyms::XF86_Eject => NamedKey::Eject, |
| 748 | keysyms::XF86_ScreenSaver => NamedKey::LaunchScreenSaver, |
| 749 | keysyms::XF86_WWW => NamedKey::LaunchWebBrowser, |
| 750 | keysyms::XF86_Sleep => NamedKey::Standby, |
| 751 | keysyms::XF86_Favorites => NamedKey::BrowserFavorites, |
| 752 | keysyms::XF86_AudioPause => NamedKey::MediaPause, |
| 753 | // keysyms::XF86_AudioMedia => NamedKey::AudioMedia, |
| 754 | keysyms::XF86_MyComputer => NamedKey::LaunchApplication1, |
| 755 | // keysyms::XF86_VendorHome => NamedKey::VendorHome, |
| 756 | // keysyms::XF86_LightBulb => NamedKey::LightBulb, |
| 757 | // keysyms::XF86_Shop => NamedKey::BrowserShop, |
| 758 | // keysyms::XF86_History => NamedKey::BrowserHistory, |
| 759 | // keysyms::XF86_OpenURL => NamedKey::OpenUrl, |
| 760 | // keysyms::XF86_AddFavorite => NamedKey::AddFavorite, |
| 761 | // keysyms::XF86_HotLinks => NamedKey::HotLinks, |
| 762 | // keysyms::XF86_BrightnessAdjust => NamedKey::BrightnessAdjust, |
| 763 | // keysyms::XF86_Finance => NamedKey::BrowserFinance, |
| 764 | // keysyms::XF86_Community => NamedKey::BrowserCommunity, |
| 765 | keysyms::XF86_AudioRewind => NamedKey::MediaRewind, |
| 766 | // keysyms::XF86_BackForward => Key::???, |
| 767 | // XF86_Launch0..XF86_LaunchF |
| 768 | |
| 769 | // XF86_ApplicationLeft..XF86_CD |
| 770 | keysyms::XF86_Calculater => NamedKey::LaunchApplication2, // Nice typo, libxkbcommon :) |
| 771 | // XF86_Clear |
| 772 | keysyms::XF86_Close => NamedKey::Close, |
| 773 | keysyms::XF86_Copy => NamedKey::Copy, |
| 774 | keysyms::XF86_Cut => NamedKey::Cut, |
| 775 | // XF86_Display..XF86_Documents |
| 776 | keysyms::XF86_Excel => NamedKey::LaunchSpreadsheet, |
| 777 | // XF86_Explorer..XF86iTouch |
| 778 | keysyms::XF86_LogOff => NamedKey::LogOff, |
| 779 | // XF86_Market..XF86_MenuPB |
| 780 | keysyms::XF86_MySites => NamedKey::BrowserFavorites, |
| 781 | keysyms::XF86_New => NamedKey::New, |
| 782 | // XF86_News..XF86_OfficeHome |
| 783 | keysyms::XF86_Open => NamedKey::Open, |
| 784 | // XF86_Option |
| 785 | keysyms::XF86_Paste => NamedKey::Paste, |
| 786 | keysyms::XF86_Phone => NamedKey::LaunchPhone, |
| 787 | // XF86_Q |
| 788 | keysyms::XF86_Reply => NamedKey::MailReply, |
| 789 | keysyms::XF86_Reload => NamedKey::BrowserRefresh, |
| 790 | // XF86_RotateWindows..XF86_RotationKB |
| 791 | keysyms::XF86_Save => NamedKey::Save, |
| 792 | // XF86_ScrollUp..XF86_ScrollClick |
| 793 | keysyms::XF86_Send => NamedKey::MailSend, |
| 794 | keysyms::XF86_Spell => NamedKey::SpellCheck, |
| 795 | keysyms::XF86_SplitScreen => NamedKey::SplitScreenToggle, |
| 796 | // XF86_Support..XF86_User2KB |
| 797 | keysyms::XF86_Video => NamedKey::LaunchMediaPlayer, |
| 798 | // XF86_WheelButton |
| 799 | keysyms::XF86_Word => NamedKey::LaunchWordProcessor, |
| 800 | // XF86_Xfer |
| 801 | keysyms::XF86_ZoomIn => NamedKey::ZoomIn, |
| 802 | keysyms::XF86_ZoomOut => NamedKey::ZoomOut, |
| 803 | |
| 804 | // XF86_Away..XF86_Messenger |
| 805 | keysyms::XF86_WebCam => NamedKey::LaunchWebCam, |
| 806 | keysyms::XF86_MailForward => NamedKey::MailForward, |
| 807 | // XF86_Pictures |
| 808 | keysyms::XF86_Music => NamedKey::LaunchMusicPlayer, |
| 809 | |
| 810 | // XF86_Battery..XF86_UWB |
| 811 | keysyms::XF86_AudioForward => NamedKey::MediaFastForward, |
| 812 | // XF86_AudioRepeat |
| 813 | keysyms::XF86_AudioRandomPlay => NamedKey::RandomToggle, |
| 814 | keysyms::XF86_Subtitle => NamedKey::Subtitle, |
| 815 | keysyms::XF86_AudioCycleTrack => NamedKey::MediaAudioTrack, |
| 816 | // XF86_CycleAngle..XF86_Blue |
| 817 | keysyms::XF86_Suspend => NamedKey::Standby, |
| 818 | keysyms::XF86_Hibernate => NamedKey::Hibernate, |
| 819 | // XF86_TouchpadToggle..XF86_TouchpadOff |
| 820 | keysyms::XF86_AudioMute => NamedKey::AudioVolumeMute, |
| 821 | |
| 822 | // XF86_Switch_VT_1..XF86_Switch_VT_12 |
| 823 | |
| 824 | // XF86_Ungrab..XF86_ClearGrab |
| 825 | keysyms::XF86_Next_VMode => NamedKey::VideoModeNext, |
| 826 | // keysyms::XF86_Prev_VMode => NamedKey::VideoModePrevious, |
| 827 | // XF86_LogWindowTree..XF86_LogGrabInfo |
| 828 | |
| 829 | // SunFA_Grave..SunFA_Cedilla |
| 830 | |
| 831 | // keysyms::SunF36 => NamedKey::F36 | NamedKey::F11, |
| 832 | // keysyms::SunF37 => NamedKey::F37 | NamedKey::F12, |
| 833 | |
| 834 | // keysyms::SunSys_Req => NamedKey::PrintScreen, |
| 835 | // The next couple of xkb (until SunStop) are already handled. |
| 836 | // SunPrint_Screen..SunPageDown |
| 837 | |
| 838 | // SunUndo..SunFront |
| 839 | keysyms::SUN_Copy => NamedKey::Copy, |
| 840 | keysyms::SUN_Open => NamedKey::Open, |
| 841 | keysyms::SUN_Paste => NamedKey::Paste, |
| 842 | keysyms::SUN_Cut => NamedKey::Cut, |
| 843 | |
| 844 | // SunPowerSwitch |
| 845 | keysyms::SUN_AudioLowerVolume => NamedKey::AudioVolumeDown, |
| 846 | keysyms::SUN_AudioMute => NamedKey::AudioVolumeMute, |
| 847 | keysyms::SUN_AudioRaiseVolume => NamedKey::AudioVolumeUp, |
| 848 | // SUN_VideoDegauss |
| 849 | keysyms::SUN_VideoLowerBrightness => NamedKey::BrightnessDown, |
| 850 | keysyms::SUN_VideoRaiseBrightness => NamedKey::BrightnessUp, |
| 851 | // SunPowerSwitchShift |
| 852 | 0 => return Key::Unidentified(NativeKey::Unidentified), |
| 853 | _ => return Key::Unidentified(NativeKey::Xkb(keysym)), |
| 854 | }) |
| 855 | } |
| 856 | |
| 857 | pub fn keysym_location(keysym: u32) -> KeyLocation { |
| 858 | use xkbcommon_dl::keysyms; |
| 859 | match keysym { |
| 860 | keysyms::Shift_L |
| 861 | | keysyms::Control_L |
| 862 | | keysyms::Meta_L |
| 863 | | keysyms::Alt_L |
| 864 | | keysyms::Super_L |
| 865 | | keysyms::Hyper_L => KeyLocation::Left, |
| 866 | keysyms::Shift_R |
| 867 | | keysyms::Control_R |
| 868 | | keysyms::Meta_R |
| 869 | | keysyms::Alt_R |
| 870 | | keysyms::Super_R |
| 871 | | keysyms::Hyper_R => KeyLocation::Right, |
| 872 | keysyms::KP_0 |
| 873 | | keysyms::KP_1 |
| 874 | | keysyms::KP_2 |
| 875 | | keysyms::KP_3 |
| 876 | | keysyms::KP_4 |
| 877 | | keysyms::KP_5 |
| 878 | | keysyms::KP_6 |
| 879 | | keysyms::KP_7 |
| 880 | | keysyms::KP_8 |
| 881 | | keysyms::KP_9 |
| 882 | | keysyms::KP_Space |
| 883 | | keysyms::KP_Tab |
| 884 | | keysyms::KP_Enter |
| 885 | | keysyms::KP_F1 |
| 886 | | keysyms::KP_F2 |
| 887 | | keysyms::KP_F3 |
| 888 | | keysyms::KP_F4 |
| 889 | | keysyms::KP_Home |
| 890 | | keysyms::KP_Left |
| 891 | | keysyms::KP_Up |
| 892 | | keysyms::KP_Right |
| 893 | | keysyms::KP_Down |
| 894 | | keysyms::KP_Page_Up |
| 895 | | keysyms::KP_Page_Down |
| 896 | | keysyms::KP_End |
| 897 | | keysyms::KP_Begin |
| 898 | | keysyms::KP_Insert |
| 899 | | keysyms::KP_Delete |
| 900 | | keysyms::KP_Equal |
| 901 | | keysyms::KP_Multiply |
| 902 | | keysyms::KP_Add |
| 903 | | keysyms::KP_Separator |
| 904 | | keysyms::KP_Subtract |
| 905 | | keysyms::KP_Decimal |
| 906 | | keysyms::KP_Divide => KeyLocation::Numpad, |
| 907 | _ => KeyLocation::Standard, |
| 908 | } |
| 909 | } |
| 910 | |
| 911 | #[derive (Debug)] |
| 912 | pub struct XkbKeymap { |
| 913 | keymap: NonNull<xkb_keymap>, |
| 914 | _mods_indices: ModsIndices, |
| 915 | pub _core_keyboard_id: i32, |
| 916 | } |
| 917 | |
| 918 | impl XkbKeymap { |
| 919 | #[cfg (wayland_platform)] |
| 920 | pub fn from_fd(context: &XkbContext, fd: OwnedFd, size: usize) -> Option<Self> { |
| 921 | let map = unsafe { MmapOptions::new().len(size).map_copy_read_only(&fd).ok()? }; |
| 922 | |
| 923 | let keymap = unsafe { |
| 924 | let keymap = (XKBH.xkb_keymap_new_from_string)( |
| 925 | (*context).as_ptr(), |
| 926 | map.as_ptr() as *const _, |
| 927 | xkb::xkb_keymap_format::XKB_KEYMAP_FORMAT_TEXT_V1, |
| 928 | xkb_keymap_compile_flags::XKB_KEYMAP_COMPILE_NO_FLAGS, |
| 929 | ); |
| 930 | NonNull::new(keymap)? |
| 931 | }; |
| 932 | |
| 933 | Some(Self::new_inner(keymap, 0)) |
| 934 | } |
| 935 | |
| 936 | #[cfg (x11_platform)] |
| 937 | pub fn from_x11_keymap( |
| 938 | context: &XkbContext, |
| 939 | xcb: *mut xcb_connection_t, |
| 940 | core_keyboard_id: i32, |
| 941 | ) -> Option<Self> { |
| 942 | let keymap = unsafe { |
| 943 | (XKBXH.xkb_x11_keymap_new_from_device)( |
| 944 | context.as_ptr(), |
| 945 | xcb, |
| 946 | core_keyboard_id, |
| 947 | xkb_keymap_compile_flags::XKB_KEYMAP_COMPILE_NO_FLAGS, |
| 948 | ) |
| 949 | }; |
| 950 | let keymap = NonNull::new(keymap)?; |
| 951 | Some(Self::new_inner(keymap, core_keyboard_id)) |
| 952 | } |
| 953 | |
| 954 | fn new_inner(keymap: NonNull<xkb_keymap>, _core_keyboard_id: i32) -> Self { |
| 955 | let mods_indices = ModsIndices { |
| 956 | shift: mod_index_for_name(keymap, xkb::XKB_MOD_NAME_SHIFT), |
| 957 | caps: mod_index_for_name(keymap, xkb::XKB_MOD_NAME_CAPS), |
| 958 | ctrl: mod_index_for_name(keymap, xkb::XKB_MOD_NAME_CTRL), |
| 959 | alt: mod_index_for_name(keymap, xkb::XKB_MOD_NAME_ALT), |
| 960 | num: mod_index_for_name(keymap, xkb::XKB_MOD_NAME_NUM), |
| 961 | mod3: mod_index_for_name(keymap, b"Mod3 \0" ), |
| 962 | logo: mod_index_for_name(keymap, xkb::XKB_MOD_NAME_LOGO), |
| 963 | mod5: mod_index_for_name(keymap, b"Mod5 \0" ), |
| 964 | }; |
| 965 | |
| 966 | Self { keymap, _mods_indices: mods_indices, _core_keyboard_id } |
| 967 | } |
| 968 | |
| 969 | #[cfg (x11_platform)] |
| 970 | pub fn mods_indices(&self) -> ModsIndices { |
| 971 | self._mods_indices |
| 972 | } |
| 973 | |
| 974 | pub fn first_keysym_by_level( |
| 975 | &mut self, |
| 976 | layout: xkb_layout_index_t, |
| 977 | keycode: xkb_keycode_t, |
| 978 | ) -> xkb_keysym_t { |
| 979 | unsafe { |
| 980 | let mut keysyms = ptr::null(); |
| 981 | let count = (XKBH.xkb_keymap_key_get_syms_by_level)( |
| 982 | self.keymap.as_ptr(), |
| 983 | keycode, |
| 984 | layout, |
| 985 | // NOTE: The level should be zero to ignore modifiers. |
| 986 | 0, |
| 987 | &mut keysyms, |
| 988 | ); |
| 989 | |
| 990 | if count == 1 { |
| 991 | *keysyms |
| 992 | } else { |
| 993 | 0 |
| 994 | } |
| 995 | } |
| 996 | } |
| 997 | |
| 998 | /// Check whether the given key repeats. |
| 999 | pub fn key_repeats(&mut self, keycode: xkb_keycode_t) -> bool { |
| 1000 | unsafe { (XKBH.xkb_keymap_key_repeats)(self.keymap.as_ptr(), keycode) == 1 } |
| 1001 | } |
| 1002 | } |
| 1003 | |
| 1004 | impl Drop for XkbKeymap { |
| 1005 | fn drop(&mut self) { |
| 1006 | unsafe { |
| 1007 | (XKBH.xkb_keymap_unref)(self.keymap.as_ptr()); |
| 1008 | }; |
| 1009 | } |
| 1010 | } |
| 1011 | |
| 1012 | impl Deref for XkbKeymap { |
| 1013 | type Target = NonNull<xkb_keymap>; |
| 1014 | |
| 1015 | fn deref(&self) -> &Self::Target { |
| 1016 | &self.keymap |
| 1017 | } |
| 1018 | } |
| 1019 | |
| 1020 | /// Modifier index in the keymap. |
| 1021 | #[cfg_attr (not(x11_platform), allow(dead_code))] |
| 1022 | #[derive (Default, Debug, Clone, Copy)] |
| 1023 | pub struct ModsIndices { |
| 1024 | pub shift: Option<xkb_mod_index_t>, |
| 1025 | pub caps: Option<xkb_mod_index_t>, |
| 1026 | pub ctrl: Option<xkb_mod_index_t>, |
| 1027 | pub alt: Option<xkb_mod_index_t>, |
| 1028 | pub num: Option<xkb_mod_index_t>, |
| 1029 | pub mod3: Option<xkb_mod_index_t>, |
| 1030 | pub logo: Option<xkb_mod_index_t>, |
| 1031 | pub mod5: Option<xkb_mod_index_t>, |
| 1032 | } |
| 1033 | |
| 1034 | fn mod_index_for_name(keymap: NonNull<xkb_keymap>, name: &[u8]) -> Option<xkb_mod_index_t> { |
| 1035 | unsafe { |
| 1036 | let mod_index: u32 = |
| 1037 | (XKBH.xkb_keymap_mod_get_index)(keymap.as_ptr(), name.as_ptr() as *const c_char); |
| 1038 | if mod_index == XKB_MOD_INVALID { |
| 1039 | None |
| 1040 | } else { |
| 1041 | Some(mod_index) |
| 1042 | } |
| 1043 | } |
| 1044 | } |
| 1045 | |