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
use std;
use std::os::unix::io::AsRawFd;
use std::io::Write;
use xkbcommon::xkb;
use qualia::{Illusion, KeyboardConfig, KeymapSettings, env};
const DEFAULT_FORMAT: u32 = xkb::KEYMAP_FORMAT_TEXT_V1;
pub struct XkbKeymap {
pub context: xkb::Context,
pub keymap: xkb::Keymap,
}
impl XkbKeymap {
pub fn new(config: &KeyboardConfig) -> Option<Self> {
let rules = "evdev".to_owned();
let model = "evdev".to_owned();
let layout = &config.layout;
let variant = &config.variant;
let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
let k = xkb::Keymap::new_from_names(&context, &rules, &model, layout, variant, None, 0x0);
if let Some(keymap) = k {
Some(XkbKeymap {
context: context,
keymap: keymap,
})
} else {
None
}
}
}
pub struct Keymap {
settings: KeymapSettings,
_file: std::fs::File,
}
impl Keymap {
pub fn new(env: &env::Env, config: &KeyboardConfig) -> Result<Self, Illusion> {
let xkb_keymap = if let Some(xkb_keymap) = XkbKeymap::new(config) {
xkb_keymap
} else {
return Err(Illusion::General(format!("Failed to create key map")));
};
let file_name = "keymap".to_owned();
let keymap_str = xkb_keymap.keymap.get_as_string(DEFAULT_FORMAT);
let mut file = env.open_file(file_name, env::Directory::Runtime)?;
file.write_all(keymap_str.as_bytes())?;
file.write_all("\0".as_bytes())?;
Ok(Keymap {
settings: KeymapSettings {
format: DEFAULT_FORMAT,
size: keymap_str.len() + 1,
fd: file.as_raw_fd(),
},
_file: file,
})
}
pub fn get_settings(&self) -> KeymapSettings {
self.settings.clone()
}
}