bcfb36633f
- redbear-netctl: route --boot (and other manual commands) around clap so CommonArgs::parse no longer aborts with 'unexpected argument --boot' (12_netctl.service boot-time profile application was failing). - redbear-keymapd: a missing /etc/keymaps is normal on mini (built-in keymaps cover the console) — log INFO, not ERROR, on NotFound. - driver-manager: fix 'options loadeds' plural typo; log read_dir errno on PCI enumeration failure instead of an opaque IoError. - redbear-mini: ship a 05_firmware-loader.service stub so the bluetooth units' weak dep resolves (was 'unit not found' x2 per boot).
105 lines
3.2 KiB
Rust
105 lines
3.2 KiB
Rust
mod keymap;
|
|
mod scheme;
|
|
mod xkb;
|
|
|
|
use std::env;
|
|
use std::io::Write;
|
|
|
|
use redox_scheme::{RequestKind, SignalBehavior, Socket};
|
|
use redox_scheme::scheme::{register_sync_scheme, SchemeState, SchemeSync};
|
|
use scheme::KeymapScheme;
|
|
|
|
fn log_msg(level: &str, msg: &str) {
|
|
let _ = writeln!(std::io::stderr(), "[keymapd] {} {}", level, msg);
|
|
}
|
|
|
|
fn main() {
|
|
let mut scheme = KeymapScheme::new();
|
|
let mut state = SchemeState::new();
|
|
|
|
let builtins = keymap::BuiltinKeymaps::new();
|
|
scheme.load_builtin(&builtins);
|
|
|
|
let keymap_dir = match env::var("KEYMAP_DIR") {
|
|
Ok(dir) => dir,
|
|
Err(_) => "/etc/keymaps".to_string(),
|
|
};
|
|
if let Err(e) = scheme.load_from_dir(&keymap_dir) {
|
|
// A missing keymap directory is the NORMAL state on minimal images
|
|
// (mini ships no /etc/keymaps; the built-in keymaps loaded above
|
|
// cover the console). Only a present-but-unreadable dir is an error.
|
|
if e.kind() == std::io::ErrorKind::NotFound {
|
|
log_msg(
|
|
"INFO",
|
|
&format!("no keymap dir at {}; using built-in keymaps", keymap_dir),
|
|
);
|
|
} else {
|
|
log_msg(
|
|
"ERROR",
|
|
&format!("failed to load keymaps from {}: {}", keymap_dir, e),
|
|
);
|
|
}
|
|
}
|
|
|
|
if let Ok(xkb_root) = env::var("XKB_CONFIG_ROOT") {
|
|
let layout = env::var("XKB_DEFAULT_LAYOUT").unwrap_or_else(|_| "us".to_string());
|
|
let variant = env::var("XKB_DEFAULT_VARIANT").ok();
|
|
if let Err(e) = scheme.load_xkb(&xkb_root, &layout, variant.as_deref()) {
|
|
log_msg(
|
|
"ERROR",
|
|
&format!(
|
|
"failed to load XKB keymap {} from {}: {}",
|
|
layout, xkb_root, e
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
log_msg(
|
|
"INFO",
|
|
&format!("loaded {} keymap(s)", scheme.keymap_count()),
|
|
);
|
|
|
|
let socket = match Socket::create() {
|
|
Ok(s) => s,
|
|
Err(e) => {
|
|
log_msg("ERROR", &format!("failed to create scheme socket: {}", e));
|
|
std::process::exit(1);
|
|
}
|
|
};
|
|
if let Err(e) = register_sync_scheme(&socket, "keymap", &mut scheme) {
|
|
log_msg("ERROR", &format!("failed to register scheme:keymap: {}", e));
|
|
std::process::exit(1);
|
|
}
|
|
log_msg("INFO", "registered scheme:keymap");
|
|
|
|
loop {
|
|
let request = match socket.next_request(SignalBehavior::Restart) {
|
|
Ok(Some(r)) => r,
|
|
Ok(None) => {
|
|
log_msg("INFO", "scheme unmounted, exiting");
|
|
break;
|
|
}
|
|
Err(e) => {
|
|
log_msg("ERROR", &format!("scheme read error: {}", e));
|
|
break;
|
|
}
|
|
};
|
|
|
|
let req = match request.kind() {
|
|
RequestKind::Call(c) => c,
|
|
RequestKind::OnClose { id } => {
|
|
scheme.on_close(id);
|
|
state.on_close(id);
|
|
continue;
|
|
}
|
|
_ => continue,
|
|
};
|
|
|
|
let response = req.handle_sync(&mut scheme, &mut state);
|
|
if let Err(e) = socket.write_response(response, SignalBehavior::Restart) {
|
|
log_msg("ERROR", &format!("failed to write response: {}", e));
|
|
}
|
|
}
|
|
}
|