c68ace12de
Phase S1 (Critical Correctness): - sem_open/sem_close: global refcounting via BTreeMap + AtomicUsize - sem_close: decrements refcount, munmaps only at zero - sem_open: reuses existing mapping, O_EXCL returns EEXIST - sem_unlink: marks entry for removal before shm_unlink - va_list parsing: reads mode_t and value from stack after oflag - All 11 sem_* functions verified in libc.so T Phase S2-S4 (Designed, documented): - eventfd() function, signalfd read path, EINTR handling - name canonicalization, cancellation safety - Full plan in local/docs/RELIBC-AGAINST-GLIBC-ASSESSMENT.md Reference: glibc 2.41 cloned to local/reference/glibc/ Boot verified: greeter ready on VT 3 with refcounted semaphores
728 lines
19 KiB
Rust
728 lines
19 KiB
Rust
use serde::Deserialize;
|
|
use std::collections::HashMap;
|
|
|
|
#[derive(Debug, Clone, Deserialize)]
|
|
pub struct KeymapEntry {
|
|
pub scancode: u8,
|
|
pub normal: char,
|
|
pub shifted: char,
|
|
#[serde(default)]
|
|
pub altgr: char,
|
|
#[serde(default)]
|
|
pub altgr_shifted: char,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize)]
|
|
pub struct ComposeEntry {
|
|
pub sequence: String,
|
|
pub result: char,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize)]
|
|
pub struct DeadKeyEntry {
|
|
pub dead_key: char,
|
|
pub base: char,
|
|
pub composed: char,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Keymap {
|
|
pub name: String,
|
|
pub entries: HashMap<u8, KeymapEntry>,
|
|
pub compose: Vec<ComposeEntry>,
|
|
pub dead_keys: Vec<DeadKeyEntry>,
|
|
}
|
|
|
|
impl Keymap {
|
|
pub fn get_char(&self, scancode: u8, shift: bool, altgr: bool) -> char {
|
|
if let Some(entry) = self.entries.get(&scancode) {
|
|
if altgr && shift && entry.altgr_shifted != '\0' {
|
|
return entry.altgr_shifted;
|
|
}
|
|
if altgr && entry.altgr != '\0' {
|
|
return entry.altgr;
|
|
}
|
|
if shift {
|
|
return entry.shifted;
|
|
}
|
|
return entry.normal;
|
|
}
|
|
'\0'
|
|
}
|
|
|
|
pub fn compose(&self, base: char, dead_key: char) -> char {
|
|
for entry in &self.dead_keys {
|
|
if entry.dead_key == dead_key && entry.base == base {
|
|
return entry.composed;
|
|
}
|
|
}
|
|
base
|
|
}
|
|
|
|
pub fn lookup_compose(&self, sequence: &str) -> Option<char> {
|
|
for entry in &self.compose {
|
|
if entry.sequence == sequence {
|
|
return Some(entry.result);
|
|
}
|
|
}
|
|
None
|
|
}
|
|
|
|
pub fn from_json(name: &str, json_str: &str) -> Result<Self, String> {
|
|
#[derive(Deserialize)]
|
|
struct KeymapFile {
|
|
#[serde(default)]
|
|
entries: Vec<KeymapEntry>,
|
|
#[serde(default)]
|
|
compose: Vec<ComposeEntry>,
|
|
#[serde(default)]
|
|
dead_keys: Vec<DeadKeyEntry>,
|
|
}
|
|
|
|
let file: KeymapFile =
|
|
serde_json::from_str(json_str).map_err(|e| format!("parse error: {}", e))?;
|
|
|
|
let mut map = HashMap::new();
|
|
for entry in file.entries {
|
|
map.insert(entry.scancode, entry);
|
|
}
|
|
|
|
Ok(Keymap {
|
|
name: name.to_string(),
|
|
entries: map,
|
|
compose: file.compose,
|
|
dead_keys: file.dead_keys,
|
|
})
|
|
}
|
|
}
|
|
|
|
pub struct BuiltinKeymaps {
|
|
pub us: Keymap,
|
|
pub gb: Keymap,
|
|
pub dvorak: Keymap,
|
|
pub azerty: Keymap,
|
|
pub bepo: Keymap,
|
|
pub it: Keymap,
|
|
}
|
|
|
|
impl BuiltinKeymaps {
|
|
pub fn new() -> Self {
|
|
BuiltinKeymaps {
|
|
us: Self::make_us(),
|
|
gb: Self::make_gb(),
|
|
dvorak: Self::make_dvorak(),
|
|
azerty: Self::make_azerty(),
|
|
bepo: Self::make_bepo(),
|
|
it: Self::make_it(),
|
|
}
|
|
}
|
|
|
|
fn common_dead_keys() -> Vec<DeadKeyEntry> {
|
|
vec![
|
|
DeadKeyEntry {
|
|
dead_key: '`',
|
|
base: 'a',
|
|
composed: 'à',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '`',
|
|
base: 'e',
|
|
composed: 'è',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '`',
|
|
base: 'i',
|
|
composed: 'ì',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '`',
|
|
base: 'o',
|
|
composed: 'ò',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '`',
|
|
base: 'u',
|
|
composed: 'ù',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '`',
|
|
base: 'A',
|
|
composed: 'À',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '`',
|
|
base: 'E',
|
|
composed: 'È',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '`',
|
|
base: 'I',
|
|
composed: 'Ì',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '`',
|
|
base: 'O',
|
|
composed: 'Ò',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '`',
|
|
base: 'U',
|
|
composed: 'Ù',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '\'',
|
|
base: 'a',
|
|
composed: 'á',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '\'',
|
|
base: 'e',
|
|
composed: 'é',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '\'',
|
|
base: 'i',
|
|
composed: 'í',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '\'',
|
|
base: 'o',
|
|
composed: 'ó',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '\'',
|
|
base: 'u',
|
|
composed: 'ú',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '\'',
|
|
base: 'A',
|
|
composed: 'Á',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '\'',
|
|
base: 'E',
|
|
composed: 'É',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '\'',
|
|
base: 'I',
|
|
composed: 'Í',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '\'',
|
|
base: 'O',
|
|
composed: 'Ó',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '\'',
|
|
base: 'U',
|
|
composed: 'Ú',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '^',
|
|
base: 'a',
|
|
composed: 'â',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '^',
|
|
base: 'e',
|
|
composed: 'ê',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '^',
|
|
base: 'i',
|
|
composed: 'î',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '^',
|
|
base: 'o',
|
|
composed: 'ô',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '^',
|
|
base: 'u',
|
|
composed: 'û',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '^',
|
|
base: 'A',
|
|
composed: 'Â',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '^',
|
|
base: 'E',
|
|
composed: 'Ê',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '^',
|
|
base: 'I',
|
|
composed: 'Î',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '^',
|
|
base: 'O',
|
|
composed: 'Ô',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '^',
|
|
base: 'U',
|
|
composed: 'Û',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '"',
|
|
base: 'a',
|
|
composed: 'ä',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '"',
|
|
base: 'e',
|
|
composed: 'ë',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '"',
|
|
base: 'i',
|
|
composed: 'ï',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '"',
|
|
base: 'o',
|
|
composed: 'ö',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '"',
|
|
base: 'u',
|
|
composed: 'ü',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '"',
|
|
base: 'A',
|
|
composed: 'Ä',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '"',
|
|
base: 'E',
|
|
composed: 'Ë',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '"',
|
|
base: 'I',
|
|
composed: 'Ï',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '"',
|
|
base: 'O',
|
|
composed: 'Ö',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '"',
|
|
base: 'U',
|
|
composed: 'Ü',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '~',
|
|
base: 'a',
|
|
composed: 'ã',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '~',
|
|
base: 'n',
|
|
composed: 'ñ',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '~',
|
|
base: 'o',
|
|
composed: 'õ',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '~',
|
|
base: 'A',
|
|
composed: 'Ã',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '~',
|
|
base: 'N',
|
|
composed: 'Ñ',
|
|
},
|
|
DeadKeyEntry {
|
|
dead_key: '~',
|
|
base: 'O',
|
|
composed: 'Õ',
|
|
},
|
|
]
|
|
}
|
|
|
|
fn make_us() -> Keymap {
|
|
let mut entries = HashMap::new();
|
|
let bindings: &[(u8, char, char)] = &[
|
|
(0x01, '\x1B', '\x1B'),
|
|
(0x02, '1', '!'),
|
|
(0x03, '2', '@'),
|
|
(0x04, '3', '#'),
|
|
(0x05, '4', '$'),
|
|
(0x06, '5', '%'),
|
|
(0x07, '6', '^'),
|
|
(0x08, '7', '&'),
|
|
(0x09, '8', '*'),
|
|
(0x0A, '9', '('),
|
|
(0x0B, '0', ')'),
|
|
(0x0C, '-', '_'),
|
|
(0x0D, '=', '+'),
|
|
(0x0E, '\x7F', '\x7F'),
|
|
(0x0F, '\t', '\t'),
|
|
(0x10, 'q', 'Q'),
|
|
(0x11, 'w', 'W'),
|
|
(0x12, 'e', 'E'),
|
|
(0x13, 'r', 'R'),
|
|
(0x14, 't', 'T'),
|
|
(0x15, 'y', 'Y'),
|
|
(0x16, 'u', 'U'),
|
|
(0x17, 'i', 'I'),
|
|
(0x18, 'o', 'O'),
|
|
(0x19, 'p', 'P'),
|
|
(0x1A, '[', '{'),
|
|
(0x1B, ']', '}'),
|
|
(0x1C, '\n', '\n'),
|
|
(0x1E, 'a', 'A'),
|
|
(0x1F, 's', 'S'),
|
|
(0x20, 'd', 'D'),
|
|
(0x21, 'f', 'F'),
|
|
(0x22, 'g', 'G'),
|
|
(0x23, 'h', 'H'),
|
|
(0x24, 'j', 'J'),
|
|
(0x25, 'k', 'K'),
|
|
(0x26, 'l', 'L'),
|
|
(0x27, ';', ':'),
|
|
(0x28, '\'', '"'),
|
|
(0x29, '`', '~'),
|
|
(0x2B, '\\', '|'),
|
|
(0x2C, 'z', 'Z'),
|
|
(0x2D, 'x', 'X'),
|
|
(0x2E, 'c', 'C'),
|
|
(0x2F, 'v', 'V'),
|
|
(0x30, 'b', 'B'),
|
|
(0x31, 'n', 'N'),
|
|
(0x32, 'm', 'M'),
|
|
(0x33, ',', '<'),
|
|
(0x34, '.', '>'),
|
|
(0x35, '/', '?'),
|
|
(0x39, ' ', ' '),
|
|
];
|
|
for &(sc, normal, shifted) in bindings {
|
|
entries.insert(
|
|
sc,
|
|
KeymapEntry {
|
|
scancode: sc,
|
|
normal,
|
|
shifted,
|
|
altgr: '\0',
|
|
altgr_shifted: '\0',
|
|
},
|
|
);
|
|
}
|
|
let dead_keys = Self::common_dead_keys();
|
|
Keymap {
|
|
name: "us".into(),
|
|
entries,
|
|
compose: Vec::new(),
|
|
dead_keys,
|
|
}
|
|
}
|
|
|
|
fn make_gb() -> Keymap {
|
|
let mut km = Self::make_us();
|
|
km.name = "gb".into();
|
|
if let Some(e) = km.entries.get_mut(&0x29) {
|
|
e.shifted = '¬';
|
|
}
|
|
if let Some(e) = km.entries.get_mut(&0x2B) {
|
|
e.normal = '#';
|
|
e.shifted = '~';
|
|
}
|
|
km
|
|
}
|
|
|
|
fn make_dvorak() -> Keymap {
|
|
let mut entries = HashMap::new();
|
|
let remap: &[(u8, char, char)] = &[
|
|
(0x01, '\x1B', '\x1B'),
|
|
(0x02, '1', '!'),
|
|
(0x03, '2', '@'),
|
|
(0x04, '3', '#'),
|
|
(0x05, '4', '$'),
|
|
(0x06, '5', '%'),
|
|
(0x07, '6', '^'),
|
|
(0x08, '7', '&'),
|
|
(0x09, '8', '*'),
|
|
(0x0A, '9', '('),
|
|
(0x0B, '0', ')'),
|
|
(0x0C, '[', '{'),
|
|
(0x0D, ']', '}'),
|
|
(0x0E, '\x7F', '\x7F'),
|
|
(0x0F, '\t', '\t'),
|
|
(0x10, '\'', '"'),
|
|
(0x11, ',', '<'),
|
|
(0x12, '.', '>'),
|
|
(0x13, 'p', 'P'),
|
|
(0x14, 'y', 'Y'),
|
|
(0x15, 'f', 'F'),
|
|
(0x16, 'g', 'G'),
|
|
(0x17, 'c', 'C'),
|
|
(0x18, 'r', 'R'),
|
|
(0x19, 'l', 'L'),
|
|
(0x1A, '/', '?'),
|
|
(0x1B, '=', '+'),
|
|
(0x1C, '\n', '\n'),
|
|
(0x1E, 'a', 'A'),
|
|
(0x1F, 'o', 'O'),
|
|
(0x20, 'e', 'E'),
|
|
(0x21, 'u', 'U'),
|
|
(0x22, 'i', 'I'),
|
|
(0x23, 'd', 'D'),
|
|
(0x24, 'h', 'H'),
|
|
(0x25, 't', 'T'),
|
|
(0x26, 'n', 'N'),
|
|
(0x27, 's', 'S'),
|
|
(0x28, '-', '_'),
|
|
(0x29, '`', '~'),
|
|
(0x2B, '\\', '|'),
|
|
(0x2C, ';', ':'),
|
|
(0x2D, 'q', 'Q'),
|
|
(0x2E, 'j', 'J'),
|
|
(0x2F, 'k', 'K'),
|
|
(0x30, 'x', 'X'),
|
|
(0x31, 'b', 'B'),
|
|
(0x32, 'm', 'M'),
|
|
(0x33, 'w', 'W'),
|
|
(0x34, 'v', 'V'),
|
|
(0x35, 'z', 'Z'),
|
|
(0x39, ' ', ' '),
|
|
];
|
|
for &(sc, normal, shifted) in remap {
|
|
entries.insert(
|
|
sc,
|
|
KeymapEntry {
|
|
scancode: sc,
|
|
normal,
|
|
shifted,
|
|
altgr: '\0',
|
|
altgr_shifted: '\0',
|
|
},
|
|
);
|
|
}
|
|
Keymap {
|
|
name: "dvorak".into(),
|
|
entries,
|
|
compose: Vec::new(),
|
|
dead_keys: Self::common_dead_keys(),
|
|
}
|
|
}
|
|
|
|
fn make_azerty() -> Keymap {
|
|
let mut entries = HashMap::new();
|
|
let bindings: &[(u8, char, char)] = &[
|
|
(0x01, '\x1B', '\x1B'),
|
|
(0x02, '&', '1'),
|
|
(0x03, 'é', '2'),
|
|
(0x04, '"', '3'),
|
|
(0x05, '\'', '4'),
|
|
(0x06, '(', '5'),
|
|
(0x07, '-', '6'),
|
|
(0x08, 'è', '7'),
|
|
(0x09, '_', '8'),
|
|
(0x0A, 'ç', '9'),
|
|
(0x0B, 'à', '0'),
|
|
(0x0C, ')', '°'),
|
|
(0x0D, '=', '+'),
|
|
(0x0E, '\x7F', '\x7F'),
|
|
(0x0F, '\t', '\t'),
|
|
(0x10, 'a', 'A'),
|
|
(0x11, 'z', 'Z'),
|
|
(0x12, 'e', 'E'),
|
|
(0x13, 'r', 'R'),
|
|
(0x14, 't', 'T'),
|
|
(0x15, 'y', 'Y'),
|
|
(0x16, 'u', 'U'),
|
|
(0x17, 'i', 'I'),
|
|
(0x18, 'o', 'O'),
|
|
(0x19, 'p', 'P'),
|
|
(0x1A, '^', '¨'),
|
|
(0x1B, '$', '£'),
|
|
(0x1C, '\n', '\n'),
|
|
(0x1E, 'q', 'Q'),
|
|
(0x1F, 's', 'S'),
|
|
(0x20, 'd', 'D'),
|
|
(0x21, 'f', 'F'),
|
|
(0x22, 'g', 'G'),
|
|
(0x23, 'h', 'H'),
|
|
(0x24, 'j', 'J'),
|
|
(0x25, 'k', 'K'),
|
|
(0x26, 'l', 'L'),
|
|
(0x27, 'm', 'M'),
|
|
(0x28, 'ù', '%'),
|
|
(0x29, '²', '~'),
|
|
(0x2B, '*', 'µ'),
|
|
(0x2C, 'w', 'W'),
|
|
(0x2D, 'x', 'X'),
|
|
(0x2E, 'c', 'C'),
|
|
(0x2F, 'v', 'V'),
|
|
(0x30, 'b', 'B'),
|
|
(0x31, 'n', 'N'),
|
|
(0x32, ',', '?'),
|
|
(0x33, ';', '.'),
|
|
(0x34, ':', '/'),
|
|
(0x35, '!', '§'),
|
|
(0x39, ' ', ' '),
|
|
];
|
|
for &(sc, normal, shifted) in bindings {
|
|
entries.insert(
|
|
sc,
|
|
KeymapEntry {
|
|
scancode: sc,
|
|
normal,
|
|
shifted,
|
|
altgr: '\0',
|
|
altgr_shifted: '\0',
|
|
},
|
|
);
|
|
}
|
|
let mut dead_keys = Self::common_dead_keys();
|
|
dead_keys.push(DeadKeyEntry {
|
|
dead_key: '^',
|
|
base: ' ',
|
|
composed: '^',
|
|
});
|
|
dead_keys.push(DeadKeyEntry {
|
|
dead_key: '¨',
|
|
base: ' ',
|
|
composed: '¨',
|
|
});
|
|
Keymap {
|
|
name: "azerty".into(),
|
|
entries,
|
|
compose: Vec::new(),
|
|
dead_keys,
|
|
}
|
|
}
|
|
|
|
fn make_bepo() -> Keymap {
|
|
let mut entries = HashMap::new();
|
|
let bindings: &[(u8, char, char)] = &[
|
|
(0x01, '\x1B', '\x1B'),
|
|
(0x02, '"', '1'),
|
|
(0x03, '«', '2'),
|
|
(0x04, '»', '3'),
|
|
(0x05, '(', '4'),
|
|
(0x06, ')', '5'),
|
|
(0x07, '@', '6'),
|
|
(0x08, '+', '7'),
|
|
(0x09, '-', '8'),
|
|
(0x0A, '/', '9'),
|
|
(0x0B, '*', '0'),
|
|
(0x0C, '=', '°'),
|
|
(0x0D, '%', '`'),
|
|
(0x0E, '\x7F', '\x7F'),
|
|
(0x0F, '\t', '\t'),
|
|
(0x10, 'b', 'B'),
|
|
(0x11, 'é', 'É'),
|
|
(0x12, 'p', 'P'),
|
|
(0x13, 'o', 'O'),
|
|
(0x14, 'è', 'È'),
|
|
(0x15, '^', '!'),
|
|
(0x16, 'v', 'V'),
|
|
(0x17, 'd', 'D'),
|
|
(0x18, 'l', 'L'),
|
|
(0x19, 'j', 'J'),
|
|
(0x1A, 'z', 'Z'),
|
|
(0x1B, 'w', 'W'),
|
|
(0x1C, '\n', '\n'),
|
|
(0x1E, 'a', 'A'),
|
|
(0x1F, 'u', 'U'),
|
|
(0x20, 'i', 'I'),
|
|
(0x21, 'e', 'E'),
|
|
(0x22, ',', ';'),
|
|
(0x23, 'c', 'C'),
|
|
(0x24, 't', 'T'),
|
|
(0x25, 's', 'S'),
|
|
(0x26, 'r', 'R'),
|
|
(0x27, 'n', 'N'),
|
|
(0x28, 'm', 'M'),
|
|
(0x29, 'ç', 'Ç'),
|
|
(0x2B, '\'', '?'),
|
|
(0x2C, 'x', 'X'),
|
|
(0x2D, 'f', 'F'),
|
|
(0x2E, 'h', 'H'),
|
|
(0x2F, 'q', 'Q'),
|
|
(0x30, 'g', 'G'),
|
|
(0x31, 'y', 'Y'),
|
|
(0x32, 'k', 'K'),
|
|
(0x33, '.', ':'),
|
|
(0x34, '/', '§'),
|
|
(0x35, 'g', 'G'),
|
|
(0x39, ' ', ' '),
|
|
];
|
|
for &(sc, normal, shifted) in bindings {
|
|
entries.insert(
|
|
sc,
|
|
KeymapEntry {
|
|
scancode: sc,
|
|
normal,
|
|
shifted,
|
|
altgr: '\0',
|
|
altgr_shifted: '\0',
|
|
},
|
|
);
|
|
}
|
|
let mut dead_keys = Self::common_dead_keys();
|
|
dead_keys.push(DeadKeyEntry {
|
|
dead_key: '^',
|
|
base: ' ',
|
|
composed: '^',
|
|
});
|
|
Keymap {
|
|
name: "bepo".into(),
|
|
entries,
|
|
compose: Vec::new(),
|
|
dead_keys,
|
|
}
|
|
}
|
|
|
|
fn make_it() -> Keymap {
|
|
let mut km = Self::make_us();
|
|
km.name = "it".into();
|
|
if let Some(e) = km.entries.get_mut(&0x29) {
|
|
e.normal = '\\';
|
|
e.shifted = '|';
|
|
}
|
|
if let Some(e) = km.entries.get_mut(&0x0C) {
|
|
e.normal = '\'';
|
|
e.shifted = '?';
|
|
}
|
|
if let Some(e) = km.entries.get_mut(&0x0D) {
|
|
e.normal = 'ì';
|
|
e.shifted = '^';
|
|
}
|
|
if let Some(e) = km.entries.get_mut(&0x1A) {
|
|
e.normal = 'è';
|
|
e.shifted = 'é';
|
|
}
|
|
if let Some(e) = km.entries.get_mut(&0x1B) {
|
|
e.normal = '+';
|
|
e.shifted = '*';
|
|
}
|
|
if let Some(e) = km.entries.get_mut(&0x27) {
|
|
e.normal = 'ò';
|
|
e.shifted = 'ç';
|
|
}
|
|
if let Some(e) = km.entries.get_mut(&0x28) {
|
|
e.normal = 'à';
|
|
e.shifted = '°';
|
|
}
|
|
if let Some(e) = km.entries.get_mut(&0x2B) {
|
|
e.normal = 'ù';
|
|
e.shifted = '§';
|
|
}
|
|
km
|
|
}
|
|
}
|