core: layout: handle extra "loc " keys
This commit is contained in:
parent
d9956baffa
commit
67f6538a8b
1 changed files with 53 additions and 34 deletions
|
|
@ -25,7 +25,7 @@ unsafe extern "C" fn start_elem(data: *mut c_void,
|
||||||
c_name: *const expat::XML_Char,
|
c_name: *const expat::XML_Char,
|
||||||
c_attrs: *mut *const expat::XML_Char)
|
c_attrs: *mut *const expat::XML_Char)
|
||||||
{
|
{
|
||||||
let layout = &mut *(data as *mut LayoutFile);
|
let layout = &mut *(data as *mut LayoutLoader);
|
||||||
let name = CStr::from_ptr(c_name)
|
let name = CStr::from_ptr(c_name)
|
||||||
.to_str().expect("layout: XML element name must be UTF-8");
|
.to_str().expect("layout: XML element name must be UTF-8");
|
||||||
|
|
||||||
|
|
@ -45,7 +45,7 @@ unsafe extern "C" fn start_elem(data: *mut c_void,
|
||||||
|
|
||||||
unsafe extern "C" fn end_elem(data: *mut c_void, c_name: *const expat::XML_Char)
|
unsafe extern "C" fn end_elem(data: *mut c_void, c_name: *const expat::XML_Char)
|
||||||
{
|
{
|
||||||
let layout = &mut *(data as *mut LayoutFile);
|
let layout = &mut *(data as *mut LayoutLoader);
|
||||||
let name = CStr::from_ptr(c_name)
|
let name = CStr::from_ptr(c_name)
|
||||||
.to_str().expect("layout: XML element name must be UTF-8");
|
.to_str().expect("layout: XML element name must be UTF-8");
|
||||||
|
|
||||||
|
|
@ -448,6 +448,7 @@ const KEYSYMS: [(&str, Keysym, &str); 24] = [
|
||||||
("\\?", Keysym::question, "?"),
|
("\\?", Keysym::question, "?"),
|
||||||
("\\@", Keysym::at, "@"),
|
("\\@", Keysym::at, "@"),
|
||||||
("\\\\", Keysym::backslash, "\\"),
|
("\\\\", Keysym::backslash, "\\"),
|
||||||
|
("alt", Keysym::Alt_L, "Alt"),
|
||||||
("backspace", Keysym::BackSpace, "⌫"),
|
("backspace", Keysym::BackSpace, "⌫"),
|
||||||
("ctrl", Keysym::Control_L, "Ctrl"),
|
("ctrl", Keysym::Control_L, "Ctrl"),
|
||||||
("delete", Keysym::Delete, "⌦"),
|
("delete", Keysym::Delete, "⌦"),
|
||||||
|
|
@ -458,8 +459,7 @@ const KEYSYMS: [(&str, Keysym, &str); 24] = [
|
||||||
("f12_placeholder", Keysym::F12, "F12"),
|
("f12_placeholder", Keysym::F12, "F12"),
|
||||||
("fn", Keysym::XF86_Fn, "Fn"),
|
("fn", Keysym::XF86_Fn, "Fn"),
|
||||||
("left", Keysym::Left, "←"),
|
("left", Keysym::Left, "←"),
|
||||||
("loc alt", Keysym::Alt_L, "Alt"),
|
("meta", Keysym::Meta_L, "Meta"),
|
||||||
("loc meta", Keysym::Meta_L, "Meta"),
|
|
||||||
("right", Keysym::Right, "→"),
|
("right", Keysym::Right, "→"),
|
||||||
("shift", Keysym::Shift_L, "⇧"),
|
("shift", Keysym::Shift_L, "⇧"),
|
||||||
("space", Keysym::space, " "),
|
("space", Keysym::space, " "),
|
||||||
|
|
@ -476,13 +476,28 @@ struct LayoutFile {
|
||||||
has_bottom_row: bool,
|
has_bottom_row: bool,
|
||||||
width: f64,
|
width: f64,
|
||||||
height: f64,
|
height: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LayoutLoader<'a> {
|
||||||
|
file: LayoutFile,
|
||||||
|
extra_keys: &'a Vec<String>,
|
||||||
row_width: f64,
|
row_width: f64,
|
||||||
in_row: u32,
|
in_row: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayoutFile {
|
impl<'a> LayoutLoader<'a> {
|
||||||
fn get_keysym_by_name(name: &str) -> KeyValue
|
fn get_keysym_by_name(extra_keys: &Vec<String>, name: &str) -> KeyValue
|
||||||
{
|
{
|
||||||
|
let name = if name.starts_with("loc ") {
|
||||||
|
if extra_keys.binary_search_by_key(&&name[4..], |k| k).is_ok() {
|
||||||
|
&name[4..]
|
||||||
|
} else {
|
||||||
|
return KeyValue::from(Keysym::NoSymbol, "")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
name
|
||||||
|
};
|
||||||
|
|
||||||
if let Ok(idx) = KEYSYMS.binary_search_by_key(&name, |&(k, _, _)| k) {
|
if let Ok(idx) = KEYSYMS.binary_search_by_key(&name, |&(k, _, _)| k) {
|
||||||
return KeyValue::from(KEYSYMS[idx].1, KEYSYMS[idx].2);
|
return KeyValue::from(KEYSYMS[idx].1, KEYSYMS[idx].2);
|
||||||
}
|
}
|
||||||
|
|
@ -513,25 +528,25 @@ impl LayoutFile {
|
||||||
self.row_width = x2;
|
self.row_width = x2;
|
||||||
|
|
||||||
let key = Key::new(
|
let key = Key::new(
|
||||||
x1, self.height, x2, self.height + 1.0,
|
x1, self.file.height, x2, self.file.height + 1.0,
|
||||||
Self::get_keysym_by_name(attrs.get("key0").unwrap_or(&"")),
|
Self::get_keysym_by_name(&self.extra_keys, attrs.get("key0").unwrap_or(&"")),
|
||||||
Self::get_keysym_by_name(attrs.get("key1").unwrap_or(&"")),
|
Self::get_keysym_by_name(&self.extra_keys, attrs.get("key1").unwrap_or(&"")),
|
||||||
Self::get_keysym_by_name(attrs.get("key2").unwrap_or(&"")),
|
Self::get_keysym_by_name(&self.extra_keys, attrs.get("key2").unwrap_or(&"")),
|
||||||
Self::get_keysym_by_name(attrs.get("key3").unwrap_or(&"")),
|
Self::get_keysym_by_name(&self.extra_keys, attrs.get("key3").unwrap_or(&"")),
|
||||||
Self::get_keysym_by_name(attrs.get("key4").unwrap_or(&"")),
|
Self::get_keysym_by_name(&self.extra_keys, attrs.get("key4").unwrap_or(&"")),
|
||||||
Self::get_keysym_by_name(attrs.get("key5").unwrap_or(&"")),
|
Self::get_keysym_by_name(&self.extra_keys, attrs.get("key5").unwrap_or(&"")),
|
||||||
Self::get_keysym_by_name(attrs.get("key6").unwrap_or(&"")),
|
Self::get_keysym_by_name(&self.extra_keys, attrs.get("key6").unwrap_or(&"")),
|
||||||
Self::get_keysym_by_name(attrs.get("key7").unwrap_or(&"")),
|
Self::get_keysym_by_name(&self.extra_keys, attrs.get("key7").unwrap_or(&"")),
|
||||||
Self::get_keysym_by_name(attrs.get("key8").unwrap_or(&""))
|
Self::get_keysym_by_name(&self.extra_keys, attrs.get("key8").unwrap_or(&""))
|
||||||
);
|
);
|
||||||
|
|
||||||
let idx = self.rows.len() - 1;
|
let idx = self.file.rows.len() - 1;
|
||||||
self.rows[idx].push(key);
|
self.file.rows[idx].push(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_row(&mut self)
|
fn start_row(&mut self)
|
||||||
{
|
{
|
||||||
self.rows.push(Vec::new());
|
self.file.rows.push(Vec::new());
|
||||||
self.in_row += 1;
|
self.in_row += 1;
|
||||||
self.row_width = 0.0;
|
self.row_width = 0.0;
|
||||||
}
|
}
|
||||||
|
|
@ -539,7 +554,7 @@ impl LayoutFile {
|
||||||
fn start_keyboard(&mut self, attrs: &HashMap<&str, &str>)
|
fn start_keyboard(&mut self, attrs: &HashMap<&str, &str>)
|
||||||
{
|
{
|
||||||
if *attrs.get("bottom_row").unwrap_or(&"") == "false" {
|
if *attrs.get("bottom_row").unwrap_or(&"") == "false" {
|
||||||
self.has_bottom_row = false;
|
self.file.has_bottom_row = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -558,11 +573,11 @@ impl LayoutFile {
|
||||||
{
|
{
|
||||||
self.in_row -= 1;
|
self.in_row -= 1;
|
||||||
|
|
||||||
if self.row_width > self.width {
|
if self.row_width > self.file.width {
|
||||||
self.width = self.row_width;
|
self.file.width = self.row_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.height += 1.0;
|
self.file.height += 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end_elem(&mut self, name: &str)
|
fn end_elem(&mut self, name: &str)
|
||||||
|
|
@ -572,13 +587,16 @@ impl LayoutFile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load<P: AsRef<Path>>(path: P) -> Result<Self, Error>
|
fn load<P: AsRef<Path>>(path: P, extra_keys: &'a Vec<String>) -> Result<LayoutFile, Error>
|
||||||
{
|
{
|
||||||
let mut layout = LayoutFile {
|
let mut layout = LayoutLoader {
|
||||||
|
file: LayoutFile {
|
||||||
rows: Vec::new(),
|
rows: Vec::new(),
|
||||||
has_bottom_row: true,
|
has_bottom_row: true,
|
||||||
width: 0.0,
|
width: 0.0,
|
||||||
height: 0.0,
|
height: 0.0,
|
||||||
|
},
|
||||||
|
extra_keys,
|
||||||
row_width: 0.0,
|
row_width: 0.0,
|
||||||
in_row: 0,
|
in_row: 0,
|
||||||
};
|
};
|
||||||
|
|
@ -605,7 +623,7 @@ impl LayoutFile {
|
||||||
expat::XML_ParserFree(parser);
|
expat::XML_ParserFree(parser);
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(layout)
|
Ok(layout.file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -694,19 +712,20 @@ impl Layout {
|
||||||
|
|
||||||
pub fn load(cfg: &Configuration) -> Result<Self, Error>
|
pub fn load(cfg: &Configuration) -> Result<Self, Error>
|
||||||
{
|
{
|
||||||
|
let extra_keys = cfg.extra_keys();
|
||||||
let dir = Path::new("/usr/share/unfettered-keyboard/layouts");
|
let dir = Path::new("/usr/share/unfettered-keyboard/layouts");
|
||||||
|
|
||||||
let path = dir.join(cfg.layout());
|
let path = dir.join(cfg.layout());
|
||||||
let main_layout = LayoutFile::load(path)?;
|
let main_layout = LayoutLoader::load(path, extra_keys)?;
|
||||||
|
|
||||||
let path = dir.join("numeric.xml");
|
let path = dir.join("numeric.xml");
|
||||||
let numeric = LayoutFile::load(path)?;
|
let numeric = LayoutLoader::load(path, extra_keys)?;
|
||||||
|
|
||||||
let path = dir.join("greekmath.xml");
|
let path = dir.join("greekmath.xml");
|
||||||
let greekmath = LayoutFile::load(path)?;
|
let greekmath = LayoutLoader::load(path, extra_keys)?;
|
||||||
|
|
||||||
let path = dir.join("bottom_row.xml");
|
let path = dir.join("bottom_row.xml");
|
||||||
let bottom_row = LayoutFile::load(path)?;
|
let bottom_row = LayoutLoader::load(path, extra_keys)?;
|
||||||
|
|
||||||
let mut layout = Layout {
|
let mut layout = Layout {
|
||||||
main_layout,
|
main_layout,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue