Compose file loading
This commit is contained in:
parent
56f8b52cf9
commit
1f21d29bd2
11
firmware2/Cargo.lock
generated
11
firmware2/Cargo.lock
generated
|
|
@ -37,6 +37,7 @@ dependencies = [
|
||||||
"mutually_exclusive_features",
|
"mutually_exclusive_features",
|
||||||
"panic-rtt-target",
|
"panic-rtt-target",
|
||||||
"paste",
|
"paste",
|
||||||
|
"printf-compat",
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"rmk",
|
"rmk",
|
||||||
"rtt-target",
|
"rtt-target",
|
||||||
|
|
@ -5581,6 +5582,16 @@ dependencies = [
|
||||||
"elliptic-curve",
|
"elliptic-curve",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "printf-compat"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ccd7bb33c3c13016f1315e4e4c6ad1d0021ce575b1e254868f4330eab99e1b6"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.10.0",
|
||||||
|
"itertools 0.14.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-crate"
|
name = "proc-macro-crate"
|
||||||
version = "3.4.0"
|
version = "3.4.0"
|
||||||
|
|
|
||||||
|
|
@ -74,12 +74,13 @@ cfg-if = "1.0.4"
|
||||||
xkbcommon = { path = "../../../rust/xkbcommon-rs-ffi", default-features = false, features = ["tinyrlibc"] }
|
xkbcommon = { path = "../../../rust/xkbcommon-rs-ffi", default-features = false, features = ["tinyrlibc"] }
|
||||||
rtt-target = { version = "0.6.2", features = ["log"], optional = true }
|
rtt-target = { version = "0.6.2", features = ["log"], optional = true }
|
||||||
panic-rtt-target = { version = "0.2.0", optional = true }
|
panic-rtt-target = { version = "0.2.0", optional = true }
|
||||||
|
enumset = "1.1.10"
|
||||||
|
printf-compat = { version = "0.2.1", default-features = false }
|
||||||
|
|
||||||
# Crates for serial UART CLI
|
# Crates for serial UART CLI
|
||||||
embedded-cli = { version = "0.2.1", default-features = false, features = ["help", "macros"] }
|
embedded-cli = { version = "0.2.1", default-features = false, features = ["help", "macros"] }
|
||||||
embedded-io = "0.6.1"
|
embedded-io = "0.6.1"
|
||||||
mutually_exclusive_features = "0.1.0"
|
mutually_exclusive_features = "0.1.0"
|
||||||
enumset = "1.1.10"
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
xz2 = "0.1.7"
|
xz2 = "0.1.7"
|
||||||
|
|
|
||||||
5125
firmware2/compose/cs_CZ Compose.txt
Normal file
5125
firmware2/compose/cs_CZ Compose.txt
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -3,11 +3,19 @@
|
||||||
|
|
||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
|
|
||||||
use core::ffi::{VaList, c_char, c_int, c_long, c_size_t, c_void};
|
use core::{
|
||||||
|
ffi::{CStr, VaList, c_char, c_int, c_long, c_size_t, c_void},
|
||||||
|
ptr::null_mut,
|
||||||
|
};
|
||||||
|
|
||||||
use log::info;
|
use alloc::string::String;
|
||||||
|
use log::{info, warn};
|
||||||
|
use printf_compat::output::fmt_write;
|
||||||
|
|
||||||
use crate::ffi::inout::file::{FILE, STDERR, STDOUT};
|
use crate::ffi::{
|
||||||
|
inout::file::{FILE, STDERR, STDOUT},
|
||||||
|
string::__xkbc_memcpy,
|
||||||
|
};
|
||||||
|
|
||||||
pub mod dir;
|
pub mod dir;
|
||||||
pub mod file;
|
pub mod file;
|
||||||
|
|
@ -16,7 +24,11 @@ pub mod file;
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn __xkbc_fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE {
|
pub unsafe extern "C" fn __xkbc_fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE {
|
||||||
todo!()
|
warn!(
|
||||||
|
"The xkbcommon library is attempting to open a file at path: {:?}",
|
||||||
|
unsafe { CStr::from_ptr(filename) }
|
||||||
|
);
|
||||||
|
null_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
|
|
@ -62,7 +74,12 @@ pub unsafe extern "C" fn __xkbc_vfprintf(
|
||||||
ap: VaList,
|
ap: VaList,
|
||||||
) -> c_int {
|
) -> c_int {
|
||||||
if stream == STDOUT || stream == STDERR {
|
if stream == STDOUT || stream == STDERR {
|
||||||
let string = ::alloc::format!("vfprintf({:?}, {:?}, {:?})", stream, format, ap);
|
let string = ::alloc::format!(
|
||||||
|
"vfprintf({:?}, {:?}, {:?})",
|
||||||
|
stream,
|
||||||
|
unsafe { CStr::from_ptr(format) },
|
||||||
|
ap
|
||||||
|
);
|
||||||
info!("{}", string);
|
info!("{}", string);
|
||||||
string.len() as c_int
|
string.len() as c_int
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -79,22 +96,50 @@ pub unsafe extern "C" fn __xkbc_vasprintf(
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME/TODO: This shouldn't be necessary. We need to rename the symbol in libxkbcommon.a(src_compose_state.c.o).
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn __xkbc_vsnprintf(
|
pub unsafe extern "C" fn snprintf(
|
||||||
string: *mut c_char,
|
string: *mut c_char,
|
||||||
size: c_size_t,
|
size: c_size_t,
|
||||||
format: *const c_char,
|
format: *const c_char,
|
||||||
ap: VaList,
|
mut args: ...
|
||||||
) -> c_int {
|
) -> c_int {
|
||||||
todo!()
|
unsafe { __xkbc_vsnprintf(string, size, format, args.as_va_list()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn __xkbc_snprintf(
|
pub unsafe extern "C" fn __xkbc_snprintf(
|
||||||
s: *mut c_char,
|
string: *mut c_char,
|
||||||
n: c_size_t,
|
size: c_size_t,
|
||||||
format: *const c_char,
|
format: *const c_char,
|
||||||
...
|
mut args: ...
|
||||||
) -> c_int {
|
) -> c_int {
|
||||||
todo!()
|
unsafe { __xkbc_vsnprintf(string, size, format, args.as_va_list()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
pub unsafe extern "C" fn __xkbc_vsnprintf(
|
||||||
|
string: *mut c_char,
|
||||||
|
// Length in bytes **including the terminating null byte**.
|
||||||
|
size: c_size_t,
|
||||||
|
format: *const c_char,
|
||||||
|
ap: VaList,
|
||||||
|
) -> c_int {
|
||||||
|
if size == 0 {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut rust_buffer = String::new();
|
||||||
|
unsafe {
|
||||||
|
printf_compat::format(format, ap, fmt_write(&mut rust_buffer));
|
||||||
|
let string_length = core::cmp::min(rust_buffer.len(), size - 1);
|
||||||
|
// __xkbc_strncpy would be preferrable, if it was available
|
||||||
|
__xkbc_memcpy(
|
||||||
|
string as *mut _,
|
||||||
|
rust_buffer.as_ptr() as *mut _,
|
||||||
|
string_length,
|
||||||
|
);
|
||||||
|
*string.add(string_length) = 0; // Add terminating null byte.
|
||||||
|
string_length as c_int
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ use slint::ComponentHandle;
|
||||||
use slint::platform::software_renderer::Rgb565Pixel;
|
use slint::platform::software_renderer::Rgb565Pixel;
|
||||||
use static_cell::StaticCell;
|
use static_cell::StaticCell;
|
||||||
use ui::AppWindow;
|
use ui::AppWindow;
|
||||||
use xkbcommon::xkb::{self, KeyDirection};
|
use xkbcommon::xkb::{self, KeyDirection, ModIndex};
|
||||||
use {esp_alloc as _, esp_backtrace as _};
|
use {esp_alloc as _, esp_backtrace as _};
|
||||||
|
|
||||||
use crate::matrix::IoeMatrix;
|
use crate::matrix::IoeMatrix;
|
||||||
|
|
@ -418,7 +418,7 @@ async fn main(_spawner: Spawner) {
|
||||||
Box::from_raw_in(slice as *mut str, &PSRAM_ALLOCATOR)
|
Box::from_raw_in(slice as *mut str, &PSRAM_ALLOCATOR)
|
||||||
};
|
};
|
||||||
let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
|
let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
|
||||||
info!("Parsing XKB keymap...");
|
info!("Loading XKB keymap...");
|
||||||
let instant_start = Instant::now();
|
let instant_start = Instant::now();
|
||||||
let keymap = xkb::Keymap::new_from_string(
|
let keymap = xkb::Keymap::new_from_string(
|
||||||
&context,
|
&context,
|
||||||
|
|
@ -429,18 +429,40 @@ async fn main(_spawner: Spawner) {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let duration = Instant::now().duration_since(instant_start);
|
let duration = Instant::now().duration_since(instant_start);
|
||||||
info!(
|
info!(
|
||||||
"XKB keymap parsed successfully! Took {seconds}.{millis:03} seconds.",
|
"XKB keymap loaded successfully! Took {seconds}.{millis:03} seconds.",
|
||||||
|
seconds = duration.as_secs(),
|
||||||
|
millis = duration.as_millis() % 1_000
|
||||||
|
);
|
||||||
|
info!("Loading XKB compose map...");
|
||||||
|
let instant_start = Instant::now();
|
||||||
|
const COMPOSE_MAP_STRING: &str = include_str!("../compose/cs_CZ Compose.txt");
|
||||||
|
const COMPOSE_MAP_LOCALE: &str = "cs_CZ.UTF-8";
|
||||||
|
let compose_table = xkb::compose::Table::new_from_buffer(
|
||||||
|
&context,
|
||||||
|
COMPOSE_MAP_STRING,
|
||||||
|
COMPOSE_MAP_LOCALE,
|
||||||
|
xkb::compose::FORMAT_TEXT_V1,
|
||||||
|
xkb::compose::COMPILE_NO_FLAGS,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let duration = Instant::now().duration_since(instant_start);
|
||||||
|
info!(
|
||||||
|
"XKB compose map loaded successfully! Took {seconds}.{millis:03} seconds.",
|
||||||
seconds = duration.as_secs(),
|
seconds = duration.as_secs(),
|
||||||
millis = duration.as_millis() % 1_000
|
millis = duration.as_millis() % 1_000
|
||||||
);
|
);
|
||||||
let mut state = xkb::State::new(&keymap);
|
let mut state = xkb::State::new(&keymap);
|
||||||
let mut previous_state = KeyboardReport::default();
|
let mut previous_state = KeyboardReport::default();
|
||||||
|
let mut compose_state =
|
||||||
|
xkb::compose::State::new(&compose_table, xkb::compose::STATE_NO_FLAGS);
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
loop {
|
loop {
|
||||||
let report = KEYBOARD_REPORT_PROXY.receive().await;
|
let report = KEYBOARD_REPORT_PROXY.receive().await;
|
||||||
|
|
||||||
if let Report::KeyboardReport(report) = &report {
|
if let Report::KeyboardReport(report) = &report {
|
||||||
|
warn!("MODIFIERS = {:02x}", report.modifier);
|
||||||
|
const RMK_ALT: u8 = 0xE2;
|
||||||
// TODO: Process modifiers
|
// TODO: Process modifiers
|
||||||
|
|
||||||
for (keycode_old, &keycode_new) in
|
for (keycode_old, &keycode_new) in
|
||||||
|
|
@ -491,15 +513,21 @@ async fn main(_spawner: Spawner) {
|
||||||
if *keycode_old == 0 || ((keycode_new != 0) && *keycode_old != keycode_new)
|
if *keycode_old == 0 || ((keycode_new != 0) && *keycode_old != keycode_new)
|
||||||
{
|
{
|
||||||
let keycode_new_xkb = into_xkb_keycode(keycode_new);
|
let keycode_new_xkb = into_xkb_keycode(keycode_new);
|
||||||
let string = state.key_get_utf8(keycode_new_xkb);
|
let syms = state.key_get_syms(keycode_new_xkb);
|
||||||
|
|
||||||
|
for sym in syms {
|
||||||
|
compose_state.feed(*sym);
|
||||||
|
}
|
||||||
|
|
||||||
|
let string = compose_state.utf8();
|
||||||
|
|
||||||
warn!("Pressed: 0x{:02x} ({})", keycode_new, keycode_new);
|
warn!("Pressed: 0x{:02x} ({})", keycode_new, keycode_new);
|
||||||
warn!("Print: {string}");
|
warn!("Syms: {syms:?}");
|
||||||
|
warn!("String: {string:?}");
|
||||||
|
|
||||||
state.update_key(keycode_new_xkb, KeyDirection::Down);
|
state.update_key(keycode_new_xkb, KeyDirection::Down);
|
||||||
}
|
}
|
||||||
|
|
||||||
// state.update_key(keycode, direction);
|
|
||||||
*keycode_old = keycode_new;
|
*keycode_old = keycode_new;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue