Fix most lints

This commit is contained in:
Jakub Hlusička 2026-01-06 22:52:41 +01:00
parent eadc04539c
commit 03ea48deb7
13 changed files with 265 additions and 169 deletions

View file

@ -1,7 +1,7 @@
use std::env;
use std::fs::{File, OpenOptions}; use std::fs::{File, OpenOptions};
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::path::{Path, PathBuf}; use std::path::Path;
use std::env;
use const_gen::*; use const_gen::*;
use json::JsonValue; use json::JsonValue;
@ -9,10 +9,16 @@ use slint_build::{CompilerConfiguration, EmbedResourcesKind};
use xz2::read::XzEncoder; use xz2::read::XzEncoder;
fn main() { fn main() {
if let Ok(repo) = gix::discover(env::var_os("CARGO_MANIFEST_DIR").unwrap().into_string().unwrap()) { if let Ok(repo) = gix::discover(
env::var_os("CARGO_MANIFEST_DIR")
.unwrap()
.into_string()
.unwrap(),
) {
let commit_hash = repo.head_commit().unwrap().short_id().unwrap(); let commit_hash = repo.head_commit().unwrap().short_id().unwrap();
println!("cargo:rustc-env=GIT_COMMIT_HASH={}", commit_hash); println!("cargo:rustc-env=GIT_COMMIT_HASH={}", commit_hash);
println!("cargo:rustc-env=GIT_COMMIT={}", println!(
"cargo:rustc-env=GIT_COMMIT={}",
repo.find_tag(repo.head_id().unwrap()) repo.find_tag(repo.head_id().unwrap())
.ok() .ok()
.map(|tag| format!("{} ({})", tag.decode().unwrap().name, commit_hash)) .map(|tag| format!("{} ({})", tag.decode().unwrap().name, commit_hash))
@ -32,7 +38,9 @@ fn main() {
// 1. Tell cargo where to find the library // 1. Tell cargo where to find the library
// let lib_path = PathBuf::from(manifest_dir).join("libs"); // let lib_path = PathBuf::from(manifest_dir).join("libs");
// println!(r#"cargo:rustc-link-search=native={}"#, lib_path.display()); // println!(r#"cargo:rustc-link-search=native={}"#, lib_path.display());
println!(r#"cargo:rustc-link-search=native=C:\Users\Limeth\workspace\c\libxkbcommon-linux\build-debug"#); println!(
r#"cargo:rustc-link-search=native=C:\Users\Limeth\workspace\c\libxkbcommon-linux\build-debug"#
);
// 2. Link the static library (strip the 'lib' prefix and '.a' extension) // 2. Link the static library (strip the 'lib' prefix and '.a' extension)
// println!("cargo:rustc-link-lib=static=xkbcommon"); // println!("cargo:rustc-link-lib=static=xkbcommon");
@ -40,7 +48,9 @@ fn main() {
// 3. Re-run if build.rs or the library changes // 3. Re-run if build.rs or the library changes
// println!(r#"cargo:rerun-if-changed=C:\Users\Limeth\workspace\c\libxkbcommon-linux\build-debug\libxkbcommon.a"#); // println!(r#"cargo:rerun-if-changed=C:\Users\Limeth\workspace\c\libxkbcommon-linux\build-debug\libxkbcommon.a"#);
println!(r#"cargo:rerun-if-changed=C:\Users\Limeth\workspace\c\libxkbcommon-linux\build-debug\libxkbcommon_redefined_syms.a"#); println!(
r#"cargo:rerun-if-changed=C:\Users\Limeth\workspace\c\libxkbcommon-linux\build-debug\libxkbcommon_redefined_syms.a"#
);
let slint_config = CompilerConfiguration::new() let slint_config = CompilerConfiguration::new()
// .with_scale_factor(4.0) // .with_scale_factor(4.0)
@ -53,13 +63,19 @@ fn main() {
fn generate_vial_config() { fn generate_vial_config() {
// Generated vial config file // Generated vial config file
let path = Path::new(&env::var_os("OUT_DIR").unwrap()).join("config_generated.rs"); let path = Path::new(&env::var_os("OUT_DIR").unwrap()).join("config_generated.rs");
let mut out_file = OpenOptions::new().create(true).write(true).truncate(true).open(path).unwrap(); let mut out_file = OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open(path)
.unwrap();
let p = Path::new("vial.json"); let p = Path::new("vial.json");
let mut content = String::new(); let mut content = String::new();
match File::open(p) { match File::open(p) {
Ok(mut file) => { Ok(mut file) => {
file.read_to_string(&mut content).expect("Cannot read vial.json"); file.read_to_string(&mut content)
.expect("Cannot read vial.json");
} }
Err(e) => println!("Cannot find vial.json {p:?}: {e}"), Err(e) => println!("Cannot find vial.json {p:?}: {e}"),
}; };
@ -90,9 +106,18 @@ fn generate_vial_config() {
if let Some(JsonValue::Array(custom_keycodes)) = vial_cfg.get("customKeycodes") { if let Some(JsonValue::Array(custom_keycodes)) = vial_cfg.get("customKeycodes") {
for (index, custom_keycode) in custom_keycodes.iter().enumerate() { for (index, custom_keycode) in custom_keycodes.iter().enumerate() {
if let JsonValue::Object(custom_keycode) = custom_keycode { if let JsonValue::Object(custom_keycode) = custom_keycode {
let name = custom_keycode.get("name").expect("A custom keycode in vial.json is missing a name.") let name = custom_keycode
.as_str().expect("A custom keycode's name must be a string."); .get("name")
writeln!(out_file, " {} = {},", name, CUSTOM_KEYCODE_FIRST + index as u16).unwrap(); .expect("A custom keycode in vial.json is missing a name.")
.as_str()
.expect("A custom keycode's name must be a string.");
writeln!(
out_file,
" {} = {},",
name,
CUSTOM_KEYCODE_FIRST + index as u16
)
.unwrap();
} }
} }
} }

View file

@ -1,5 +1,6 @@
use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut}; #![allow(unused_variables)]
use core::ffi::{c_size_t, c_void};
use core::alloc::GlobalAlloc; use core::alloc::GlobalAlloc;
use enumset::EnumSet; use enumset::EnumSet;
@ -16,10 +17,7 @@ pub unsafe extern "C" fn __xkbc_malloc(size: c_size_t) -> *mut c_void {
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_calloc( pub unsafe extern "C" fn __xkbc_calloc(number: c_size_t, size: c_size_t) -> *mut c_void {
number: c_size_t,
size: c_size_t,
) -> *mut c_void {
let total_size = number as usize * size; let total_size = number as usize * size;
unsafe { unsafe {
let ptr = __xkbc_malloc(total_size) as *mut u8; let ptr = __xkbc_malloc(total_size) as *mut u8;
@ -35,10 +33,7 @@ pub unsafe extern "C" fn __xkbc_calloc(
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_realloc( pub unsafe extern "C" fn __xkbc_realloc(ptr: *mut c_void, new_size: c_size_t) -> *mut c_void {
ptr: *mut c_void,
new_size: c_size_t,
) -> *mut c_void {
unsafe { realloc_with_caps(ptr as *mut _, new_size, EnumSet::empty()) as *mut _ } unsafe { realloc_with_caps(ptr as *mut _, new_size, EnumSet::empty()) as *mut _ }
} }
@ -59,10 +54,7 @@ pub unsafe extern "C" fn __xkbc_free(ptr: *mut c_void) {
} }
} }
unsafe fn malloc_with_caps( unsafe fn malloc_with_caps(size: usize, caps: EnumSet<crate::MemoryCapability>) -> *mut u8 {
size: usize,
caps: EnumSet<crate::MemoryCapability>,
) -> *mut u8 {
let total_size = size + 4; let total_size = size + 4;
unsafe { unsafe {

View file

@ -1,6 +1,8 @@
//! https://gcc.gnu.org/onlinedocs/gcc-15.2.0/gccint/Libgcc.html //! https://gcc.gnu.org/onlinedocs/gcc-15.2.0/gccint/Libgcc.html
use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut}; #![allow(unused_variables)]
use core::ffi::c_long;
unsafe extern "C" { unsafe extern "C" {
fn __divdi3(a: c_long, b: c_long) -> c_long; fn __divdi3(a: c_long, b: c_long) -> c_long;

View file

@ -1,4 +1,6 @@
use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut}; #![allow(unused_variables)]
use core::ffi::{c_char, c_int};
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub enum DIR {} pub enum DIR {}

View file

@ -1,4 +1,4 @@
use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut}; #![allow(unused_variables)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[allow(clippy::upper_case_acronyms)] #[allow(clippy::upper_case_acronyms)]

View file

@ -1,23 +1,21 @@
//! This would've been called `io`, but rust-analyzer refuses to see //! This would've been called `io`, but rust-analyzer refuses to see
//! the submodules of this module when it's named `io`. //! the submodules of this module when it's named `io`.
use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut}; #![allow(unused_variables)]
use core::ffi::{VaList, c_char, c_int, c_long, c_size_t, c_void};
use log::info; use log::info;
pub mod file; use crate::ffi::inout::file::{FILE, STDERR, STDOUT};
pub mod dir;
pub use file::*; pub mod dir;
pub use dir::*; pub mod file;
// File management // File management
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_fopen( pub unsafe extern "C" fn __xkbc_fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE {
filename: *const c_char,
mode: *const c_char,
) -> *mut FILE {
todo!() todo!()
} }
@ -27,11 +25,7 @@ pub unsafe extern "C" fn __xkbc_fclose(file: *mut FILE) -> c_int {
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_fseek( pub unsafe extern "C" fn __xkbc_fseek(stream: *mut FILE, offset: c_long, whence: c_int) -> c_int {
stream: *mut FILE,
offset: c_long,
whence: c_int,
) -> c_int {
todo!() todo!()
} }
@ -62,7 +56,11 @@ pub unsafe extern "C" fn __xkbc_fprintf(
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_vfprintf(stream: *mut FILE, format: *const c_char, ap: VaList) -> c_int { pub unsafe extern "C" fn __xkbc_vfprintf(
stream: *mut FILE,
format: *const c_char,
ap: VaList,
) -> 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, format, ap);
info!("{}", string); info!("{}", string);
@ -73,12 +71,21 @@ pub unsafe extern "C" fn __xkbc_vfprintf(stream: *mut FILE, format: *const c_cha
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_vasprintf(strp: *mut *mut c_char, fmt: *const c_char, ap: VaList) -> c_int { pub unsafe extern "C" fn __xkbc_vasprintf(
strp: *mut *mut c_char,
fmt: *const c_char,
ap: VaList,
) -> c_int {
todo!() todo!()
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_vsnprintf(string: *mut c_char, size: c_size_t, format: *const c_char, ap: VaList) -> c_int { pub unsafe extern "C" fn __xkbc_vsnprintf(
string: *mut c_char,
size: c_size_t,
format: *const c_char,
ap: VaList,
) -> c_int {
todo!() todo!()
} }

View file

@ -1,13 +1,16 @@
use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut}; #![allow(unused_variables)]
use alloc::__xkbc_malloc; use core::{
use inout::{FILE, STDERR, STDIN, STDOUT}; ffi::{c_char, c_int, c_long, c_longlong, c_size_t, c_void},
use log::info; ptr::null_mut,
};
use inout::file::{FILE, STDERR, STDIN, STDOUT};
pub mod alloc; pub mod alloc;
pub mod string;
pub mod inout;
pub mod gcc_runtime; pub mod gcc_runtime;
pub mod inout;
pub mod string;
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub type c_intmax_t = c_longlong; pub type c_intmax_t = c_longlong;
@ -18,7 +21,7 @@ pub unsafe extern "C" fn __xkbc_imaxabs(j: c_intmax_t) -> c_intmax_t {
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_eaccess(pathname: *const c_char, mode: c_int ) -> c_int { pub unsafe extern "C" fn __xkbc_eaccess(pathname: *const c_char, mode: c_int) -> c_int {
todo!() todo!()
} }
@ -50,7 +53,7 @@ pub unsafe extern "C" fn __xkbc_qsort(
#[repr(C)] #[repr(C)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
struct _reent { pub struct _reent {
_errno: c_int, _errno: c_int,
_stdin: *mut FILE, _stdin: *mut FILE,
_stdout: *mut FILE, _stdout: *mut FILE,
@ -84,11 +87,7 @@ pub unsafe extern "C" fn __xkbc_getenv(name: *const c_char) -> *mut c_char {
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_open( pub unsafe extern "C" fn __xkbc_open(path: *const c_char, oflag: c_int, ...) -> c_int {
path: *const c_char,
oflag: c_int,
...
) -> c_int {
todo!() todo!()
} }
@ -103,10 +102,7 @@ pub unsafe extern "C" fn __xkbc_close(fd: c_int) -> c_int {
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_fdopen( pub unsafe extern "C" fn __xkbc_fdopen(fd: c_int, mode: *const c_char) -> *mut FILE {
fd: c_int,
mode: *const c_char,
) -> *mut FILE {
todo!() todo!()
} }
@ -116,12 +112,24 @@ pub unsafe extern "C" fn __xkbc_labs(i: c_long) -> c_long {
} }
unsafe extern "C" { unsafe extern "C" {
fn __assert_func(file: *const c_char, line: c_int, function: *const c_char, failedExpression: *const c_char); fn __assert_func(
file: *const c_char,
line: c_int,
function: *const c_char,
failedExpression: *const c_char,
);
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc___assert_func(file: *const c_char, line: c_int, function: *const c_char, failed_expression: *const c_char) { pub unsafe extern "C" fn __xkbc___assert_func(
unsafe { __assert_func(file, line, function, failed_expression); } file: *const c_char,
line: c_int,
function: *const c_char,
failed_expression: *const c_char,
) {
unsafe {
__assert_func(file, line, function, failed_expression);
}
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]

View file

@ -1,4 +1,9 @@
use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut}; #![allow(unused_variables)]
use core::{
ffi::{c_char, c_int, c_long, c_size_t, c_uchar, c_void},
ptr::null_mut,
};
use super::alloc::__xkbc_malloc; use super::alloc::__xkbc_malloc;
@ -39,8 +44,14 @@ pub unsafe extern "C" fn __xkbc_memmove(
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_memcpy(dst: *mut c_void, src: *const c_void, count: c_size_t) -> *mut c_void { pub unsafe extern "C" fn __xkbc_memcpy(
unsafe { core::ptr::copy_nonoverlapping(src, dst, count); } dst: *mut c_void,
src: *const c_void,
count: c_size_t,
) -> *mut c_void {
unsafe {
core::ptr::copy_nonoverlapping(src, dst, count);
}
dst dst
} }
@ -63,11 +74,7 @@ pub unsafe extern "C" fn __xkbc_memchr(s: *const c_void, c: c_int, n: c_size_t)
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_memcmp( pub unsafe extern "C" fn __xkbc_memcmp(s1: *const c_char, s2: *const c_char, n: c_size_t) -> c_int {
mut s1: *const c_char,
mut s2: *const c_char,
n: c_size_t,
) -> c_int {
unsafe { unsafe {
for i in 0..n as isize { for i in 0..n as isize {
let s1_i = s1.offset(i); let s1_i = s1.offset(i);
@ -99,10 +106,7 @@ pub unsafe extern "C" fn __xkbc_strdup(string: *const c_char) -> *mut c_char {
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_strndup( pub unsafe extern "C" fn __xkbc_strndup(string: *const c_char, max_len: c_size_t) -> *mut c_char {
string: *const c_char,
max_len: c_size_t,
) -> *mut c_char {
strndup_inner(string, unsafe { __xkbc_strnlen(string, max_len) }) strndup_inner(string, unsafe { __xkbc_strnlen(string, max_len) })
} }
@ -134,8 +138,13 @@ pub unsafe extern "C" fn __xkbc_strlen(mut s: *const c_char) -> c_size_t {
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_strnlen(s: *const c_char, maxlen: c_size_t) -> c_size_t { pub unsafe extern "C" fn __xkbc_strnlen(s: *const c_char, maxlen: c_size_t) -> c_size_t {
let found: *const c_char = unsafe { __xkbc_memchr(s as *const c_void, b'\0' as c_int, maxlen) } as *const c_char; let found: *const c_char =
if !found.is_null() { unsafe { found.offset_from(s) as c_size_t } } else { maxlen } unsafe { __xkbc_memchr(s as *const c_void, b'\0' as c_int, maxlen) } as *const c_char;
if !found.is_null() {
unsafe { found.offset_from(s) as c_size_t }
} else {
maxlen
}
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
@ -160,18 +169,12 @@ pub unsafe extern "C" fn __xkbc_strncmp(
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_strchr( pub unsafe extern "C" fn __xkbc_strchr(cs: *const c_char, c: c_int) -> *mut c_char {
cs: *const c_char,
c: c_int,
) -> *mut c_char {
todo!() todo!()
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_strcmp( pub unsafe extern "C" fn __xkbc_strcmp(s1: *const c_char, s2: *const c_char) -> c_int {
s1: *const c_char,
s2: *const c_char,
) -> c_int {
unsafe { unsafe {
for i in 0_isize.. { for i in 0_isize.. {
let s1_i = s1.offset(i); let s1_i = s1.offset(i);
@ -188,6 +191,10 @@ pub unsafe extern "C" fn __xkbc_strcmp(
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_strtol(nptr: *const c_char, endptr: *mut *mut c_char, base: c_int) -> c_long { pub unsafe extern "C" fn __xkbc_strtol(
nptr: *const c_char,
endptr: *mut *mut c_char,
base: c_int,
) -> c_long {
todo!() todo!()
} }

View file

@ -1,4 +1,4 @@
use rmk::types::action::{KeyAction, Action}; use rmk::types::action::KeyAction;
use rmk::{a, k, layer}; use rmk::{a, k, layer};
use crate::matrix::{MATRIX_COLS, MATRIX_ROWS}; use crate::matrix::{MATRIX_COLS, MATRIX_ROWS};

View file

@ -2,13 +2,16 @@ use core::cell::RefCell;
use core::fmt::Write; use core::fmt::Write;
use critical_section::{CriticalSection, Mutex}; use critical_section::{CriticalSection, Mutex};
use esp_hal::uart::UartTx;
use esp_hal::Blocking; use esp_hal::Blocking;
use log::{LevelFilter, Log}; use esp_hal::uart::UartTx;
use log::Log;
static ALT_LOGGER_UART: Mutex<RefCell<Option<UartTx<'static, Blocking>>>> = Mutex::new(RefCell::new(None)); static ALT_LOGGER_UART: Mutex<RefCell<Option<UartTx<'static, Blocking>>>> =
Mutex::new(RefCell::new(None));
pub fn with_uart_tx<R>(f: impl FnOnce(CriticalSection<'_>, &'_ mut UartTx<'static, Blocking>) -> R) -> R { pub fn with_uart_tx<R>(
f: impl FnOnce(CriticalSection<'_>, &'_ mut UartTx<'static, Blocking>) -> R,
) -> R {
critical_section::with(|cs| { critical_section::with(|cs| {
let mut uart = ALT_LOGGER_UART.borrow(cs).borrow_mut(); let mut uart = ALT_LOGGER_UART.borrow(cs).borrow_mut();
let uart = uart.as_mut().unwrap(); let uart = uart.as_mut().unwrap();
@ -77,7 +80,13 @@ fn print_log_record(uart: &mut UartTx<'_, Blocking>, record: &log::Record) {
log::Level::Trace => CYAN, log::Level::Trace => CYAN,
}; };
let reset = RESET; let reset = RESET;
let args = format_args!("{}{:>5} - {}{}\n", color, record.level(), record.args(), reset); let args = format_args!(
"{}{:>5} - {}{}\n",
color,
record.level(),
record.args(),
reset
);
uart.write_fmt(args).unwrap(); uart.write_fmt(args).unwrap();
uart.flush().unwrap(); uart.flush().unwrap();
} }
@ -106,8 +115,11 @@ fn panic_handler(info: &core::panic::PanicInfo) -> ! {
loop {} loop {}
} }
pub fn setup_alternative_logging(alt_uart: UartTx<'static, Blocking>, level_filter: LevelFilter) #[cfg(feature = "alt-log")]
{ pub fn setup_alternative_logging(
alt_uart: UartTx<'static, Blocking>,
level_filter: log::LevelFilter,
) {
critical_section::with(|cs| { critical_section::with(|cs| {
*ALT_LOGGER_UART.borrow(cs).borrow_mut() = Some(alt_uart); *ALT_LOGGER_UART.borrow(cs).borrow_mut() = Some(alt_uart);
}); });

View file

@ -17,38 +17,29 @@ extern crate alloc;
use core::alloc::Layout; use core::alloc::Layout;
use core::cell::RefCell; use core::cell::RefCell;
use core::ffi::CStr;
use core::slice; use core::slice;
use alloc::alloc::Allocator; use alloc::boxed::Box;
use alloc::string::{String, ToString};
use alloc::boxed::{self, Box};
use alloc::vec::Vec;
use alloc::vec; use alloc::vec;
use bt_hci::controller::ExternalController;
use cfg_if::cfg_if; use cfg_if::cfg_if;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_sync::blocking_mutex::raw::{CriticalSectionRawMutex}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::channel::Channel; use embassy_sync::channel::Channel;
use embassy_sync::signal::Signal; use embassy_sync::signal::Signal;
use embassy_time::{Duration, Instant, Timer}; use embassy_time::{Duration, Instant};
use esp_alloc::{HeapRegion, MemoryCapability}; use esp_alloc::{HeapRegion, MemoryCapability};
use esp_hal::Blocking;
use esp_hal::clock::CpuClock; use esp_hal::clock::CpuClock;
use esp_hal::dma::{BurstConfig, DmaDescriptor, DmaTxBuf, ExternalBurstConfig}; use esp_hal::dma::{BurstConfig, DmaDescriptor, DmaTxBuf, ExternalBurstConfig};
use esp_hal::gpio::{Flex, Input, InputConfig, Io, Level, Output, OutputConfig, Pull}; use esp_hal::gpio::{Flex, Input, InputConfig, Level, Output, OutputConfig, Pull};
use esp_hal::handler;
use esp_hal::i2c::master::{I2c, I2cAddress}; use esp_hal::i2c::master::{I2c, I2cAddress};
use esp_hal::interrupt::software::SoftwareInterruptControl; use esp_hal::interrupt::software::SoftwareInterruptControl;
use esp_hal::lcd_cam::LcdCam; use esp_hal::lcd_cam::LcdCam;
use esp_hal::lcd_cam::lcd::dpi::Dpi; use esp_hal::lcd_cam::lcd::dpi::Dpi;
use esp_hal::mcpwm::{McPwm, PeripheralClockConfig}; use esp_hal::mcpwm::{McPwm, PeripheralClockConfig};
use esp_hal::psram::{FlashFreq, PsramConfig, PsramSize, SpiRamFreq, SpiTimingConfigCoreClock}; use esp_hal::psram::{FlashFreq, PsramConfig, PsramSize, SpiRamFreq, SpiTimingConfigCoreClock};
use esp_hal::rng::TrngSource;
use esp_hal::system::Stack; use esp_hal::system::Stack;
use esp_hal::timer::timg::TimerGroup; use esp_hal::timer::timg::TimerGroup;
use esp_hal::{Blocking, ram};
use esp_radio::Controller as RadioController;
use esp_radio::ble::controller::BleConnector;
use esp_rtos::embassy::Executor; use esp_rtos::embassy::Executor;
use esp_storage::FlashStorage; use esp_storage::FlashStorage;
use log::{LevelFilter, error, info, warn}; use log::{LevelFilter, error, info, warn};
@ -57,8 +48,7 @@ use rmk::config::{BehaviorConfig, PositionalConfig, RmkConfig, StorageConfig, Vi
use rmk::controller::{Controller, EventController}; use rmk::controller::{Controller, EventController};
use rmk::debounce::default_debouncer::DefaultDebouncer; use rmk::debounce::default_debouncer::DefaultDebouncer;
use rmk::descriptor::KeyboardReport; use rmk::descriptor::KeyboardReport;
use rmk::embassy_futures::yield_now; use rmk::event::ControllerEvent;
use rmk::event::{ControllerEvent, KeyboardEvent};
use rmk::hid::Report; use rmk::hid::Report;
use rmk::input_device::Runnable; use rmk::input_device::Runnable;
use rmk::join_all; use rmk::join_all;
@ -67,8 +57,8 @@ use rmk::storage::async_flash_wrapper;
use rmk::types::action::{Action, KeyAction}; use rmk::types::action::{Action, KeyAction};
use rmk::types::keycode::KeyCode; use rmk::types::keycode::KeyCode;
use rmk::{initialize_keymap_and_storage, run_devices, run_rmk}; use rmk::{initialize_keymap_and_storage, run_devices, run_rmk};
use slint::platform::software_renderer::Rgb565Pixel;
use slint::ComponentHandle; use slint::ComponentHandle;
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};
@ -77,17 +67,17 @@ use {esp_alloc as _, esp_backtrace as _};
use crate::matrix::IoeMatrix; use crate::matrix::IoeMatrix;
use crate::peripherals::st7701s::St7701s; use crate::peripherals::st7701s::St7701s;
use crate::ui::backend::{FramebufferPtr, SlintBackend}; use crate::ui::backend::{FramebufferPtr, SlintBackend};
use crate::vial::{VIAL_KEYBOARD_DEF, VIAL_KEYBOARD_ID, CustomKeycodes}; use crate::vial::{CustomKeycodes, VIAL_KEYBOARD_DEF, VIAL_KEYBOARD_ID};
mutually_exclusive_features::none_or_one_of!["usb-log", "alt-log", "rtt-log"]; mutually_exclusive_features::none_or_one_of!["usb-log", "alt-log", "rtt-log"];
mod ffi;
mod keymap; mod keymap;
mod logging;
mod matrix; mod matrix;
mod peripherals; mod peripherals;
mod vial;
mod ui; mod ui;
mod logging; mod vial;
mod ffi;
#[cfg(feature = "alt-log")] #[cfg(feature = "alt-log")]
mod console; mod console;
@ -149,7 +139,11 @@ async fn main(_spawner: Spawner) {
let alt_uart_rx_task = { let alt_uart_rx_task = {
use esp_hal::uart::Uart; use esp_hal::uart::Uart;
let (uart_rx, uart_tx) = Uart::new(peripherals.UART2, Default::default()).unwrap().with_tx(peripherals.GPIO12).with_rx(peripherals.GPIO5).split(); let (uart_rx, uart_tx) = Uart::new(peripherals.UART2, Default::default())
.unwrap()
.with_tx(peripherals.GPIO12)
.with_rx(peripherals.GPIO5)
.split();
logging::setup_alternative_logging(uart_tx, LOG_LEVEL_FILTER); logging::setup_alternative_logging(uart_tx, LOG_LEVEL_FILTER);
info!("Logger initialized!"); info!("Logger initialized!");
console::run_console(uart_rx.into_async()) console::run_console(uart_rx.into_async())
@ -214,6 +208,10 @@ async fn main(_spawner: Spawner) {
#[cfg(feature = "ble")] #[cfg(feature = "ble")]
let stack = { let stack = {
// Enable the TRNG source, so `Trng` can be constructed. // Enable the TRNG source, so `Trng` can be constructed.
use bt_hci::controller::ExternalController;
use esp_hal::rng::TrngSource;
use esp_radio::{Controller as RadioController, ble::controller::BleConnector};
let _trng_source = TrngSource::new(peripherals.RNG, peripherals.ADC1); let _trng_source = TrngSource::new(peripherals.RNG, peripherals.ADC1);
let mut rng = esp_hal::rng::Trng::try_new().unwrap(); let mut rng = esp_hal::rng::Trng::try_new().unwrap();
static RADIO: StaticCell<RadioController<'static>> = StaticCell::new(); static RADIO: StaticCell<RadioController<'static>> = StaticCell::new();
@ -222,7 +220,9 @@ async fn main(_spawner: Spawner) {
let connector = BleConnector::new(radio, bluetooth, Default::default()).unwrap(); let connector = BleConnector::new(radio, bluetooth, Default::default()).unwrap();
let controller: ExternalController<_, 20> = ExternalController::new(connector); let controller: ExternalController<_, 20> = ExternalController::new(connector);
let central_addr = [0x18, 0xe2, 0x21, 0x80, 0xc0, 0xc7]; let central_addr = [0x18, 0xe2, 0x21, 0x80, 0xc0, 0xc7];
let ble_stack = rmk::ble::build_ble_stack(controller, central_addr, &mut rng, &mut host_resources).await; let ble_stack =
rmk::ble::build_ble_stack(controller, central_addr, &mut rng, &mut host_resources)
.await;
info!("BLE stack for RMK built!"); info!("BLE stack for RMK built!");
@ -363,7 +363,7 @@ async fn main(_spawner: Spawner) {
let window_size = [framebuffer.height, framebuffer.width]; let window_size = [framebuffer.height, framebuffer.width];
let framebuffer_ptr = FramebufferPtr(framebuffer.as_target_pixels() as _); let framebuffer_ptr = FramebufferPtr(framebuffer.as_target_pixels() as _);
static SECOND_CORE_STACK: StaticCell<Stack<{8192 * 2}>> = StaticCell::new(); static SECOND_CORE_STACK: StaticCell<Stack<{ 8192 * 2 }>> = StaticCell::new();
let second_core_stack = SECOND_CORE_STACK.init(Stack::new()); let second_core_stack = SECOND_CORE_STACK.init(Stack::new());
esp_rtos::start_second_core( esp_rtos::start_second_core(
peripherals.CPU_CTRL, peripherals.CPU_CTRL,
@ -393,10 +393,7 @@ async fn main(_spawner: Spawner) {
info!("Second core started!"); info!("Second core started!");
let hid_report_proxy_task = async {};
let hid_report_proxy_task = { let hid_report_proxy_task = {
use xkbcommon::xkb;
static KEYBOARD_REPORT_PROXY: Channel<CriticalSectionRawMutex, Report, 16> = Channel::new(); static KEYBOARD_REPORT_PROXY: Channel<CriticalSectionRawMutex, Report, 16> = Channel::new();
{ {
@ -409,18 +406,33 @@ async fn main(_spawner: Spawner) {
MemoryCapability::External.into(), MemoryCapability::External.into(),
Layout::from_size_align(KEYMAP_STRING.len(), 32).unwrap(), Layout::from_size_align(KEYMAP_STRING.len(), 32).unwrap(),
); );
let slice = str::from_utf8_unchecked_mut(slice::from_raw_parts_mut(allocation, KEYMAP_STRING.len())); let slice = str::from_utf8_unchecked_mut(slice::from_raw_parts_mut(
allocation,
KEYMAP_STRING.len(),
));
slice.as_bytes_mut().copy_from_slice(KEYMAP_STRING.as_bytes()); slice
.as_bytes_mut()
.copy_from_slice(KEYMAP_STRING.as_bytes());
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!("Parsing XKB keymap...");
let instant_start = Instant::now(); let instant_start = Instant::now();
let keymap = xkb::Keymap::new_from_string(&context, keymap_string_buffer, xkb::KEYMAP_FORMAT_TEXT_V1, xkb::KEYMAP_COMPILE_NO_FLAGS).unwrap(); let keymap = xkb::Keymap::new_from_string(
&context,
keymap_string_buffer,
xkb::KEYMAP_FORMAT_TEXT_V1,
xkb::KEYMAP_COMPILE_NO_FLAGS,
)
.unwrap();
let duration = Instant::now().duration_since(instant_start); let duration = Instant::now().duration_since(instant_start);
info!("XKB keymap parsed successfully! Took {seconds}.{millis:03} seconds.", seconds = duration.as_secs(), millis = duration.as_millis() % 1_000); info!(
"XKB keymap parsed successfully! Took {seconds}.{millis:03} seconds.",
seconds = duration.as_secs(),
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();
@ -431,7 +443,9 @@ async fn main(_spawner: Spawner) {
if let Report::KeyboardReport(report) = &report { if let Report::KeyboardReport(report) = &report {
// TODO: Process modifiers // TODO: Process modifiers
for (keycode_old, &keycode_new) in core::iter::zip(&mut previous_state.keycodes, &report.keycodes) { for (keycode_old, &keycode_new) in
core::iter::zip(&mut previous_state.keycodes, &report.keycodes)
{
fn into_xkb_keycode(rmk_keycode: u8) -> xkb::Keycode { fn into_xkb_keycode(rmk_keycode: u8) -> xkb::Keycode {
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/hid/hid-input.c?id=refs/tags/v6.18#n27 // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/hid/hid-input.c?id=refs/tags/v6.18#n27
const UNK: u8 = 240; const UNK: u8 = 240;
@ -459,19 +473,23 @@ async fn main(_spawner: Spawner) {
// TODO: The combination of these two operations should be precomputed // TODO: The combination of these two operations should be precomputed
// in a const expr into a single look-up table. // in a const expr into a single look-up table.
xkb::Keycode::new((HID_KEYBOARD[rmk_keycode as usize] + MIN_KEYCODE) as u32) xkb::Keycode::new(
(HID_KEYBOARD[rmk_keycode as usize] + MIN_KEYCODE) as u32,
)
} }
if *keycode_old == 0 && keycode_new == 0 { if *keycode_old == 0 && keycode_new == 0 {
continue; continue;
} }
if keycode_new == 0 || ((*keycode_old != 0) && *keycode_old != keycode_new) { if keycode_new == 0 || ((*keycode_old != 0) && *keycode_old != keycode_new)
{
warn!("Release: 0x{:02x} ({})", *keycode_old, *keycode_old); warn!("Release: 0x{:02x} ({})", *keycode_old, *keycode_old);
state.update_key(into_xkb_keycode(*keycode_old), KeyDirection::Up); state.update_key(into_xkb_keycode(*keycode_old), KeyDirection::Up);
} }
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 string = state.key_get_utf8(keycode_new_xkb);
@ -536,7 +554,9 @@ impl Controller for UserController {
type Event = ControllerEvent; type Event = ControllerEvent;
async fn process_event(&mut self, event: Self::Event) { async fn process_event(&mut self, event: Self::Event) {
if let ControllerEvent::Key(keyboard_event, KeyAction::Single(Action::Key(keycode))) = event && (KeyCode::Kb0..=KeyCode::User31).contains(&keycode) { if let ControllerEvent::Key(keyboard_event, KeyAction::Single(Action::Key(keycode))) = event
&& (KeyCode::Kb0..=KeyCode::User31).contains(&keycode)
{
warn!("{keycode:?} pressed."); warn!("{keycode:?} pressed.");
if keycode as u16 == CustomKeycodes::FOCUS_LCD as u16 { if keycode as u16 == CustomKeycodes::FOCUS_LCD as u16 {
@ -560,8 +580,7 @@ async fn run_renderer_task(backend: SlintBackend) {
SIGNAL_UI_RENDER.wait().await; SIGNAL_UI_RENDER.wait().await;
} }
slint::platform::set_platform(Box::new(backend)) slint::platform::set_platform(Box::new(backend)).expect("backend already initialized");
.expect("backend already initialized");
let main = AppWindow::new().unwrap(); let main = AppWindow::new().unwrap();

View file

@ -1,9 +1,14 @@
use core::{cell::RefCell, time::Duration}; use core::{cell::RefCell, time::Duration};
use alloc::rc::Rc; use alloc::rc::Rc;
use esp_hal::{time::Instant}; use esp_hal::time::Instant;
use log::info; use log::info;
use slint::{PhysicalSize, WindowSize, platform::{Key, software_renderer::{RenderingRotation, RepaintBufferType, Rgb565Pixel, SoftwareRenderer}}}; use slint::{
PhysicalSize, WindowSize,
platform::software_renderer::{
RenderingRotation, RepaintBufferType, Rgb565Pixel, SoftwareRenderer,
},
};
use super::window_adapter::SoftwareWindowAdapter; use super::window_adapter::SoftwareWindowAdapter;
@ -19,14 +24,21 @@ pub struct SlintBackend {
} }
impl slint::platform::Platform for SlintBackend { impl slint::platform::Platform for SlintBackend {
fn create_window_adapter(&self) -> Result<Rc<dyn slint::platform::WindowAdapter>, slint::PlatformError> { fn create_window_adapter(
&self,
) -> Result<Rc<dyn slint::platform::WindowAdapter>, slint::PlatformError> {
// TODO: Custom window adapter impl needs to be implemented, so we can change `rotation` on // TODO: Custom window adapter impl needs to be implemented, so we can change `rotation` on
// `SoftwareRenderer`. // `SoftwareRenderer`.
let renderer = SoftwareRenderer::new_with_repaint_buffer_type(RepaintBufferType::ReusedBuffer /* TODO: Implement a swapchain */); let renderer = SoftwareRenderer::new_with_repaint_buffer_type(
RepaintBufferType::ReusedBuffer, /* TODO: Implement a swapchain */
);
renderer.set_rendering_rotation(RenderingRotation::Rotate270); renderer.set_rendering_rotation(RenderingRotation::Rotate270);
let window = SoftwareWindowAdapter::new(renderer); let window = SoftwareWindowAdapter::new(renderer);
// window.set_scale_factor(4.0); // window.set_scale_factor(4.0);
window.set_size(WindowSize::Physical(PhysicalSize::new(self.window_size[0], self.window_size[1]))); window.set_size(WindowSize::Physical(PhysicalSize::new(
self.window_size[0],
self.window_size[1],
)));
self.window.replace(Some(window.clone())); self.window.replace(Some(window.clone()));
Ok(window) Ok(window)
} }
@ -39,7 +51,8 @@ impl slint::platform::Platform for SlintBackend {
// Instead of `loop`ing here, we execute a single iteration and handle `loop`ing // Instead of `loop`ing here, we execute a single iteration and handle `loop`ing
// in `crate::run_renderer_task`, where we can make use of `await`. // in `crate::run_renderer_task`, where we can make use of `await`.
/* loop */ { /* loop */
{
if let Some(window) = self.window.borrow().clone() { if let Some(window) = self.window.borrow().clone() {
// TODO: Event dispatch. Here or in `run_renderer_task`? // TODO: Event dispatch. Here or in `run_renderer_task`?
// window.try_dispatch_event(todo!())?; // window.try_dispatch_event(todo!())?;

View file

@ -1,7 +1,13 @@
use core::{cell::Cell, ops::{Deref, DerefMut}}; use core::{
cell::Cell,
ops::{Deref, DerefMut},
};
use alloc::rc::{Rc, Weak}; use alloc::rc::{Rc, Weak};
use slint::{PhysicalSize, Window, WindowSize, platform::{Renderer, WindowAdapter, WindowEvent, software_renderer::SoftwareRenderer}}; use slint::{
PhysicalSize, Window, WindowSize,
platform::{Renderer, WindowAdapter, WindowEvent, software_renderer::SoftwareRenderer},
};
/// This is a minimal adapter for a Window that doesn't have any other feature than rendering /// This is a minimal adapter for a Window that doesn't have any other feature than rendering
/// using the software renderer. /// using the software renderer.
@ -33,7 +39,9 @@ impl SoftwareWindowAdapter {
/// ///
/// Return true if something was redrawn. /// Return true if something was redrawn.
pub fn draw_if_needed(&self, render_callback: impl FnOnce(&SoftwareRenderer)) -> bool { pub fn draw_if_needed(&self, render_callback: impl FnOnce(&SoftwareRenderer)) -> bool {
if self.needs_redraw.replace(false) /*|| self.renderer.rendering_metrics_collector.is_some()*/ { if self.needs_redraw.replace(false)
/*|| self.renderer.rendering_metrics_collector.is_some()*/
{
render_callback(&self.renderer); render_callback(&self.renderer);
true true
} else { } else {
@ -41,9 +49,9 @@ impl SoftwareWindowAdapter {
} }
} }
pub fn set_scale_factor(&self, scale_factor: f32) { // pub fn set_scale_factor(&self, scale_factor: f32) {
self.window.dispatch_event(WindowEvent::ScaleFactorChanged { scale_factor }); // self.window.dispatch_event(WindowEvent::ScaleFactorChanged { scale_factor });
} // }
} }
impl WindowAdapter for SoftwareWindowAdapter { impl WindowAdapter for SoftwareWindowAdapter {
@ -62,8 +70,9 @@ impl WindowAdapter for SoftwareWindowAdapter {
fn set_size(&self, size: WindowSize) { fn set_size(&self, size: WindowSize) {
let sf = self.window.scale_factor(); let sf = self.window.scale_factor();
self.size.set(size.to_physical(sf)); self.size.set(size.to_physical(sf));
self.window self.window.dispatch_event(WindowEvent::Resized {
.dispatch_event(WindowEvent::Resized { size: size.to_logical(sf) }) size: size.to_logical(sf),
})
} }
fn request_redraw(&self) { fn request_redraw(&self) {