key_names/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
//! Platform-aware keyboard key name handling for Rust applications.
#![warn(missing_docs)]
pub use keycode::*;
mod common;
#[cfg(target_os = "linux")]
mod linux;
#[cfg(target_os = "macos")]
mod macos;
#[cfg(target_arch = "wasm32")]
pub mod web;
#[cfg(windows)]
mod windows;
#[cfg(target_os = "linux")]
use linux as os;
#[cfg(target_os = "macos")]
use macos as os;
#[cfg(target_arch = "wasm32")]
use web as os;
#[cfg(windows)]
use windows as os;
/// OS's conventional modifiers order, represented as an ASCII string containing
/// the characters `csam` for `CTRL`, `SHIFT`, `ALT`, and `META`/`LOGO`
/// respectively in some order.
pub const MODIFIERS_ORDER: &str = os::MODIFIERS_ORDER;
/// OS's conventional name for the <key>Ctrl</key> modifier.
pub const CTRL_STR: &str = "Ctrl";
/// OS's conventional name for the <key>Shift</key> modifier.
pub const SHIFT_STR: &str = "Shift";
/// OS's conventional name for the <key>Alt</key> modifier.
pub const ALT_STR: &str = os::ALT_STR;
/// OS's conventional name for the logo modifier.
pub const LOGO_STR: &str = os::LOGO_STR;
/// Returns a string representing modifiers using the OS's conventional names
/// and ordering. For example, on Windows this function might produce "Ctrl +
/// Shift + Alt + Win + " while on macOS it might produce "Ctrl + Option + Shift
/// + Cmd + ".
pub fn mods_prefix_string(shift: bool, ctrl: bool, alt: bool, logo: bool) -> String {
let mut ret = String::new();
for ch in MODIFIERS_ORDER.chars() {
match ch {
's' if shift => {
ret += SHIFT_STR;
ret += " + ";
}
'c' if ctrl => {
ret += CTRL_STR;
ret += " + ";
}
'a' if alt => {
ret += ALT_STR;
ret += " + ";
}
'm' if logo => {
ret += LOGO_STR;
ret += " + ";
}
_ => (),
}
}
ret
}
/// Converts the OS-specific scancode to an OS-independent key mapping code.
pub fn sc_to_key(sc: u16) -> Option<KeyMappingCode> {
let key_mapping = os::SC_TO_KEY_MAPPING(sc);
KeyMap::try_from(key_mapping).ok()?.code
}
/// Converts the OS-independent key mapping code back into an OS-specific
/// scancode. This is not guaranteed to produce the original scancode.
pub fn key_to_sc(key: KeyMappingCode) -> Option<u16> {
let key_map = KeyMap::try_from(KeyMapping::Code(Some(key))).ok()?;
let sc = os::KEY_MAP_TO_SC(key_map);
Some(sc).filter(|&sc| sc != os::SC_INVALID)
}
/// Uses the operarting system's API to return a name for the scancode.
pub fn scancode_name(sc: u16) -> String {
os::scancode_name(sc)
}
/// Uses the operating system's API to return a name for the key.
pub fn key_name(key: KeyMappingCode) -> String {
match key_to_sc(key) {
Some(sc) => scancode_name(sc),
None => format!("{:?}", key),
}
}
/// Converts the key mapping code to a virtual keycode
#[cfg(feature = "winit")]
pub fn key_to_winit_vkey(key: KeyMappingCode) -> Option<winit::event::VirtualKeyCode> {
let key_map = KeyMap::try_from(KeyMapping::Code(Some(key))).ok()?;
os::key_map_to_winit_vkey(key_map)
}