From 352e52852f79c67de6ee10e69d9b8bcf2487c9ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Hlusi=C4=8Dka?= Date: Mon, 5 Jan 2026 04:16:08 +0100 Subject: [PATCH] WIP2 --- firmware2/.cargo/config.toml | 2 +- firmware2/Cargo.lock | 5 +- firmware2/Cargo.toml | 7 +- firmware2/README.md | 34 +- firmware2/build.rs | 6 +- firmware2/cross-esp32s3.txt | 39 + firmware2/keymaps/cz-small-test.xkb | 1114 +++++++++++++++++++++++ firmware2/libxkbcommon-redefine-syms.sh | 28 + firmware2/src/ffi.rs | 241 ----- firmware2/src/ffi/alloc.rs | 104 +++ firmware2/src/ffi/gcc_runtime.rs | 12 + firmware2/src/ffi/inout/dir.rs | 25 + firmware2/src/ffi/inout/file.rs | 9 + firmware2/src/ffi/inout/mod.rs | 93 ++ firmware2/src/ffi/mod.rs | 130 +++ firmware2/src/ffi/string.rs | 193 ++++ firmware2/src/main.rs | 38 +- 17 files changed, 1824 insertions(+), 256 deletions(-) create mode 100644 firmware2/cross-esp32s3.txt create mode 100644 firmware2/keymaps/cz-small-test.xkb create mode 100644 firmware2/libxkbcommon-redefine-syms.sh delete mode 100644 firmware2/src/ffi.rs create mode 100644 firmware2/src/ffi/alloc.rs create mode 100644 firmware2/src/ffi/gcc_runtime.rs create mode 100644 firmware2/src/ffi/inout/dir.rs create mode 100644 firmware2/src/ffi/inout/file.rs create mode 100644 firmware2/src/ffi/inout/mod.rs create mode 100644 firmware2/src/ffi/mod.rs create mode 100644 firmware2/src/ffi/string.rs diff --git a/firmware2/.cargo/config.toml b/firmware2/.cargo/config.toml index 17dc3bb..751334b 100644 --- a/firmware2/.cargo/config.toml +++ b/firmware2/.cargo/config.toml @@ -7,7 +7,7 @@ target = "xtensa-esp32s3-none-elf" rustflags = [ # Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.) # NOTE: May negatively impact performance of produced code - "-C", "force-frame-pointers", "-C", "link-arg=-Wl,--wrap=strncmp", + "-C", "force-frame-pointers", ] diff --git a/firmware2/Cargo.lock b/firmware2/Cargo.lock index 5d97482..b2b4527 100644 --- a/firmware2/Cargo.lock +++ b/firmware2/Cargo.lock @@ -20,6 +20,7 @@ dependencies = [ "embedded-cli", "embedded-io 0.6.1", "embuild", + "enumset", "esp-alloc", "esp-backtrace", "esp-bootloader-esp-idf", @@ -6915,9 +6916,9 @@ dependencies = [ [[package]] name = "tinyrlibc" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d07d242693682e46801cb0186c583858bce022f698401b3f04bbd729c9a87e7" +checksum = "9af8adde15cc59c61328c5d709b41b8464522a733033584d33def687b26bd009" dependencies = [ "cc", ] diff --git a/firmware2/Cargo.toml b/firmware2/Cargo.toml index a345082..aacc73a 100644 --- a/firmware2/Cargo.toml +++ b/firmware2/Cargo.toml @@ -34,8 +34,8 @@ debug = [] trace = [] # Development profiles develop = ["limit-fps", "alt-log"] -develop-usb = ["limit-fps", "usb-log", "no-usb"] -probe = ["limit-fps", "rtt-log", "no-usb"] +develop-usb = ["limit-fps", "usb-log", "no-usb", "ble"] +probe = ["limit-fps", "rtt-log", "no-usb", "ble"] [dependencies] rmk = { version = "0.8.2", default-features = false, features = [ @@ -54,7 +54,7 @@ esp-backtrace = { version = "0.18", default-features = false, features = [ ] } esp-hal = { version = "1.0", features = ["esp32s3", "unstable", "psram", "log-04"] } esp-storage = { version = "0.8.0", features = ["esp32s3"] } -esp-alloc = { version = "0.9.0" } +esp-alloc = { version = "0.9.0", features = ["nightly"] } esp-println = { version = "0.16.0", features = ["esp32s3", "log-04"] } esp-radio = { version = "0.17", features = ["esp32s3", "unstable", "ble"] } esp-rtos = { version = "0.2", features = ["esp32s3", "esp-radio", "embassy"] } @@ -79,6 +79,7 @@ panic-rtt-target = { version = "0.2.0", optional = true } embedded-cli = { version = "0.2.1", default-features = false, features = ["help", "macros"] } embedded-io = "0.6.1" mutually_exclusive_features = "0.1.0" +enumset = "1.1.10" [build-dependencies] xz2 = "0.1.7" diff --git a/firmware2/README.md b/firmware2/README.md index 2e10380..382a088 100644 --- a/firmware2/README.md +++ b/firmware2/README.md @@ -1,3 +1,33 @@ +# ACID firmware + +## Building + +### Compiling libxkbcommon + +This needs to be done on Linux or in WSL. +meson.build needs to be changed such that `pkgconfig.generate` is called with the `variables` field embedded directly, for some reason: + +```meson + variables: [ + f'xkb_root=@XKB_CONFIG_ROOT@', + f'xkb_extra_path=@XKB_CONFIG_EXTRA_PATH@', + ], +``` + +Then, the tests, fuzzes and benches need to be commented out. +Afterwards, the following command should succeed in building the static library in debug mode: + +```sh +meson setup build-debug -Denable-x11=false -Dxkb-config-root=/usr/share/X11/xkb -Dx-locale-root=/usr/share/X11/locale -Denable-wayland=false --cross-file cross-esp32s3.txt -Denable-xkbregistry=false -Denable-docs=false -Denable-tools=false --wipe --buildtype=debug +meson compile -C build-debug +``` + +Afterwards, a static library with redefined externally-linked symbols needs to be generated: + +``` +path/to/root/libxkbcommon-redefine-syms.sh build-debug/libxkbcommon{,_redefined_syms}.a +``` + # esp32s3 BLE example To run this example, you should have latest Rust in **esp** channel installed. The full instruction of installing esp Rust toolchain can be found [here](https://docs.esp-rs.org/book/installation/index.html). @@ -18,7 +48,7 @@ cargo +esp run --release If everything is good, you'll see the log as the following: ```shell -cargo run --release +cargo run --release Compiling ... ... ... @@ -62,4 +92,4 @@ cargo install --git https://github.com/bjoernQ/espsegs # Check all segments espsegs target/xtensa-esp32s3-none-elf/release/rmk-esp32s3 --chip esp32s3 -``` \ No newline at end of file +``` diff --git a/firmware2/build.rs b/firmware2/build.rs index bf46d19..b0caac6 100644 --- a/firmware2/build.rs +++ b/firmware2/build.rs @@ -35,10 +35,12 @@ fn main() { 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) - println!("cargo:rustc-link-lib=static=xkbcommon"); + // println!("cargo:rustc-link-lib=static=xkbcommon"); + println!("cargo:rustc-link-lib=static=xkbcommon_redefined_syms"); // 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"#); let slint_config = CompilerConfiguration::new() // .with_scale_factor(4.0) diff --git a/firmware2/cross-esp32s3.txt b/firmware2/cross-esp32s3.txt new file mode 100644 index 0000000..edeae7d --- /dev/null +++ b/firmware2/cross-esp32s3.txt @@ -0,0 +1,39 @@ +[binaries] +c = 'xtensa-esp32s3-elf-gcc' +cpp = 'xtensa-esp32s3-elf-g++' +ar = 'xtensa-esp32s3-elf-ar' +strip = 'xtensa-esp32s3-elf-strip' + +[build_machine] +system = 'linux' +cpu_family = 'x86_64' +cpu = 'x86_64' +endian = 'little' + +[host_machine] +system = 'bare-metal' # Crucial: prevents Meson from assuming a POSIX environment +cpu_family = 'xtensa' +cpu = 'esp32s3' +endian = 'little' + +[built-in options] +c_args = [ + '-fdebug-prefix-map=@GLOBAL_SOURCE_ROOT@=C:/Users/Limeth/workspace/c/libxkbcommon-linux', + '-ffreestanding', + '-fno-builtin', + '-mlongcalls', + '-mfix-esp32-psram-cache-issue', + # Manually define the missing inttypes.h macros + '-DPRId64="lld"', + '-DPRIu64="llu"', + '-DPRIi64="lli"', + '-DPRId32="d"', + '-DPRIu32="u"', + '-DPRIx64="llx"' + ] +c_link_args = [ + '-nostdlib', + '-static' + ] +# Ensure we only build static libraries for bare-metal +default_library = 'static' diff --git a/firmware2/keymaps/cz-small-test.xkb b/firmware2/keymaps/cz-small-test.xkb new file mode 100644 index 0000000..a261258 --- /dev/null +++ b/firmware2/keymaps/cz-small-test.xkb @@ -0,0 +1,1114 @@ +xkb_keymap { +xkb_keycodes "(unnamed)" { + minimum = 8; + maximum = 708; + = 9; + = 10; + = 11; + = 12; + = 13; + = 14; + = 15; + = 16; + = 17; + = 18; + = 19; + = 20; + = 21; + = 22; + = 23; + = 24; + = 25; + = 26; + = 27; + = 28; + = 29; + = 30; + = 31; + = 32; + = 33; + = 34; + = 35; + = 36; + = 37; + = 38; + = 39; + = 40; + = 41; + = 42; + = 43; + = 44; + = 45; + = 46; + = 47; + = 48; + = 49; + = 50; + = 51; + = 52; + = 53; + = 54; + = 55; + = 56; + = 57; + = 58; + = 59; + = 60; + = 61; + = 62; + = 63; + = 64; + = 65; + = 66; + = 67; + = 68; + = 69; + = 70; + = 71; + = 72; + = 73; + = 74; + = 75; + = 76; + = 77; + = 78; + = 79; + = 80; + = 81; + = 82; + = 83; + = 84; + = 85; + = 86; + = 87; + = 88; + = 89; + = 90; + = 91; + = 92; + = 94; + = 95; + = 96; + = 97; + = 98; + = 99; + = 100; + = 101; + = 102; + = 103; + = 104; + = 105; + = 106; + = 107; + = 108; + = 109; + = 110; + = 111; + = 112; + = 113; + = 114; + = 115; + = 116; + = 117; + = 118; + = 119; + = 120; + = 121; + = 122; + = 123; + = 124; + = 125; + = 126; + = 127; + = 128; + = 129; + = 130; + = 131; + = 132; + = 133; + = 134; + = 135; + = 136; + = 137; + = 138; + = 139; + = 140; + = 141; + = 142; + = 143; + = 144; + = 145; + = 146; + indicator 1 = "Caps Lock"; + indicator 2 = "Num Lock"; + indicator 3 = "Scroll Lock"; + indicator 4 = "Compose"; + indicator 5 = "Kana"; + indicator 6 = "Sleep"; + indicator 7 = "Suspend"; + indicator 8 = "Mute"; + indicator 9 = "Misc"; + indicator 10 = "Mail"; + indicator 11 = "Charging"; + indicator 12 = "Shift Lock"; + indicator 13 = "Group 2"; + indicator 14 = "Mouse Keys"; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; + alias = ; +}; + +xkb_types "(unnamed)" { + virtual_modifiers NumLock,Alt,LevelThree,LevelFive,Meta,Super,Hyper,ScrollLock; + + type "ONE_LEVEL" { + modifiers= none; + level_name[1]= "Any"; + }; + type "TWO_LEVEL" { + modifiers= Shift; + map[Shift]= 2; + level_name[1]= "Base"; + level_name[2]= "Shift"; + }; + type "ALPHABETIC" { + modifiers= Shift+Lock; + map[Shift]= 2; + map[Lock]= 2; + level_name[1]= "Base"; + level_name[2]= "Caps"; + }; + type "PC_ALT_LEVEL2" { + modifiers= Alt; + map[Alt]= 2; + level_name[1]= "Base"; + level_name[2]= "Alt"; + }; + type "PC_SUPER_LEVEL2" { + modifiers= Mod4; + map[Mod4]= 2; + level_name[1]= "Base"; + level_name[2]= "Super"; + }; + type "PC_CONTROL_LEVEL2" { + modifiers= Control; + map[Control]= 2; + level_name[1]= "Base"; + level_name[2]= "Control"; + }; + type "CTRL+ALT" { + modifiers= Shift+Control+Alt+LevelThree; + map[Shift]= 2; + preserve[Shift]= Shift; + map[LevelThree]= 3; + map[Shift+LevelThree]= 4; + preserve[Shift+LevelThree]= Shift; + map[Control+Alt]= 5; + level_name[1]= "Base"; + level_name[2]= "Shift"; + level_name[3]= "AltGr"; + level_name[4]= "Shift AltGr"; + level_name[5]= "Ctrl+Alt"; + }; + type "THREE_LEVEL" { + modifiers= Shift+LevelThree; + map[Shift]= 2; + map[LevelThree]= 3; + map[Shift+LevelThree]= 3; + level_name[1]= "Base"; + level_name[2]= "Shift"; + level_name[3]= "Level3"; + }; + type "FOUR_LEVEL" { + modifiers= Shift+LevelThree; + map[Shift]= 2; + map[LevelThree]= 3; + map[Shift+LevelThree]= 4; + level_name[1]= "Base"; + level_name[2]= "Shift"; + level_name[3]= "AltGr"; + level_name[4]= "Shift AltGr"; + }; + type "FOUR_LEVEL_ALPHABETIC" { + modifiers= Shift+Lock+LevelThree; + map[Shift]= 2; + map[Lock]= 2; + map[LevelThree]= 3; + map[Shift+LevelThree]= 4; + map[Lock+LevelThree]= 4; + map[Shift+Lock+LevelThree]= 3; + level_name[1]= "Base"; + level_name[2]= "Shift"; + level_name[3]= "AltGr"; + level_name[4]= "Shift AltGr"; + }; + type "FOUR_LEVEL_SEMIALPHABETIC" { + modifiers= Shift+Lock+LevelThree; + map[Shift]= 2; + map[Lock]= 2; + map[LevelThree]= 3; + map[Shift+LevelThree]= 4; + map[Lock+LevelThree]= 3; + preserve[Lock+LevelThree]= Lock; + map[Shift+Lock+LevelThree]= 4; + preserve[Shift+Lock+LevelThree]= Lock; + level_name[1]= "Base"; + level_name[2]= "Shift"; + level_name[3]= "AltGr"; + level_name[4]= "Shift AltGr"; + }; + type "FOUR_LEVEL_KEYPAD" { + modifiers= Shift+NumLock+LevelThree; + map[Shift]= 2; + map[NumLock]= 2; + map[LevelThree]= 3; + map[Shift+LevelThree]= 4; + map[NumLock+LevelThree]= 4; + map[Shift+NumLock+LevelThree]= 3; + level_name[1]= "Base"; + level_name[2]= "Shift/Numlock"; + level_name[3]= "AltGr"; + level_name[4]= "Shift/Numlock AltGr"; + }; + type "FOUR_LEVEL_MIXED_KEYPAD" { + modifiers= Shift+NumLock+LevelThree; + map[Shift]= 2; + map[NumLock]= 2; + map[LevelThree]= 3; + map[Shift+LevelThree]= 4; + map[NumLock+LevelThree]= 3; + map[Shift+NumLock+LevelThree]= 4; + level_name[1]= "Base"; + level_name[2]= "Number"; + level_name[3]= "AltGr"; + level_name[4]= "Shift AltGr"; + }; + type "FOUR_LEVEL_X" { + modifiers= Shift+Control+Alt+LevelThree; + map[LevelThree]= 2; + map[Shift+LevelThree]= 3; + map[Control+Alt]= 4; + level_name[1]= "Base"; + level_name[2]= "AltGr"; + level_name[3]= "Shift AltGr"; + level_name[4]= "Ctrl+Alt"; + }; + type "KEYPAD" { + modifiers= Shift+NumLock; + map[NumLock]= 2; + level_name[1]= "Base"; + level_name[2]= "Number"; + }; + type "SHIFT+ALT" { + modifiers= Shift+Alt; + map[Shift+Alt]= 2; + level_name[1]= "Base"; + level_name[2]= "Shift+Alt"; + }; +}; + +xkb_compatibility "(unnamed)" { + virtual_modifiers NumLock,Alt,LevelThree,LevelFive,Meta,Super,Hyper,ScrollLock; + + interpret.useModMapMods= AnyLevel; + interpret.repeat= False; + interpret ISO_Level2_Latch+Exactly(Shift) { + useModMapMods=level1; + action= LatchMods(modifiers=Shift,clearLocks,latchToLock); + }; + interpret Shift_Lock+AnyOf(Shift+Lock) { + action= LockMods(modifiers=Shift); + }; + interpret Num_Lock+AnyOf(all) { + virtualModifier= NumLock; + action= LockMods(modifiers=NumLock); + }; + interpret ISO_Level3_Shift+AnyOf(all) { + virtualModifier= LevelThree; + useModMapMods=level1; + action= SetMods(modifiers=LevelThree,clearLocks); + }; + interpret ISO_Level3_Latch+AnyOf(all) { + virtualModifier= LevelThree; + useModMapMods=level1; + action= LatchMods(modifiers=LevelThree,clearLocks,latchToLock); + }; + interpret ISO_Level3_Lock+AnyOf(all) { + virtualModifier= LevelThree; + useModMapMods=level1; + action= LockMods(modifiers=LevelThree); + }; + interpret Alt_L+AnyOf(all) { + virtualModifier= Alt; + action= SetMods(modifiers=modMapMods,clearLocks); + }; + interpret Alt_R+AnyOf(all) { + virtualModifier= Alt; + action= SetMods(modifiers=modMapMods,clearLocks); + }; + interpret Meta_L+AnyOf(all) { + virtualModifier= Meta; + action= SetMods(modifiers=modMapMods,clearLocks); + }; + interpret Meta_R+AnyOf(all) { + virtualModifier= Meta; + action= SetMods(modifiers=modMapMods,clearLocks); + }; + interpret Super_L+AnyOf(all) { + virtualModifier= Super; + action= SetMods(modifiers=modMapMods,clearLocks); + }; + interpret Super_R+AnyOf(all) { + virtualModifier= Super; + action= SetMods(modifiers=modMapMods,clearLocks); + }; + interpret Hyper_L+AnyOf(all) { + virtualModifier= Hyper; + action= SetMods(modifiers=modMapMods,clearLocks); + }; + interpret Hyper_R+AnyOf(all) { + virtualModifier= Hyper; + action= SetMods(modifiers=modMapMods,clearLocks); + }; + interpret Scroll_Lock+AnyOf(all) { + virtualModifier= ScrollLock; + action= LockMods(modifiers=modMapMods); + }; + interpret ISO_Level5_Shift+AnyOf(all) { + virtualModifier= LevelFive; + useModMapMods=level1; + action= SetMods(modifiers=LevelFive,clearLocks); + }; + interpret ISO_Level5_Latch+AnyOf(all) { + virtualModifier= LevelFive; + useModMapMods=level1; + action= LatchMods(modifiers=LevelFive,clearLocks,latchToLock); + }; + interpret ISO_Level5_Lock+AnyOf(all) { + virtualModifier= LevelFive; + useModMapMods=level1; + action= LockMods(modifiers=LevelFive); + }; + interpret Mode_switch+AnyOfOrNone(all) { + action= SetGroup(group=+1); + }; + interpret ISO_Level3_Shift+AnyOfOrNone(all) { + action= SetMods(modifiers=LevelThree,clearLocks); + }; + interpret ISO_Level3_Latch+AnyOfOrNone(all) { + action= LatchMods(modifiers=LevelThree,clearLocks,latchToLock); + }; + interpret ISO_Level3_Lock+AnyOfOrNone(all) { + action= LockMods(modifiers=LevelThree); + }; + interpret ISO_Group_Latch+AnyOfOrNone(all) { + action= LatchGroup(group=2); + }; + interpret ISO_Next_Group+AnyOfOrNone(all) { + action= LockGroup(group=+1); + }; + interpret ISO_Prev_Group+AnyOfOrNone(all) { + action= LockGroup(group=-1); + }; + interpret ISO_First_Group+AnyOfOrNone(all) { + action= LockGroup(group=1); + }; + interpret ISO_Last_Group+AnyOfOrNone(all) { + action= LockGroup(group=2); + }; + interpret KP_1+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=-1,y=+1); + }; + interpret KP_End+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=-1,y=+1); + }; + interpret KP_2+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=+0,y=+1); + }; + interpret KP_Down+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=+0,y=+1); + }; + interpret KP_3+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=+1,y=+1); + }; + interpret KP_Next+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=+1,y=+1); + }; + interpret KP_4+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=-1,y=+0); + }; + interpret KP_Left+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=-1,y=+0); + }; + interpret KP_6+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=+1,y=+0); + }; + interpret KP_Right+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=+1,y=+0); + }; + interpret KP_7+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=-1,y=-1); + }; + interpret KP_Home+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=-1,y=-1); + }; + interpret KP_8+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=+0,y=-1); + }; + interpret KP_Up+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=+0,y=-1); + }; + interpret KP_9+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=+1,y=-1); + }; + interpret KP_Prior+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=+1,y=-1); + }; + interpret KP_5+AnyOfOrNone(all) { + repeat= True; + action= PtrBtn(button=default); + }; + interpret KP_Begin+AnyOfOrNone(all) { + repeat= True; + action= PtrBtn(button=default); + }; + interpret KP_F2+AnyOfOrNone(all) { + repeat= True; + action= SetPtrDflt(affect=button,button=1); + }; + interpret KP_Divide+AnyOfOrNone(all) { + repeat= True; + action= SetPtrDflt(affect=button,button=1); + }; + interpret KP_F3+AnyOfOrNone(all) { + repeat= True; + action= SetPtrDflt(affect=button,button=2); + }; + interpret KP_Multiply+AnyOfOrNone(all) { + repeat= True; + action= SetPtrDflt(affect=button,button=2); + }; + interpret KP_F4+AnyOfOrNone(all) { + repeat= True; + action= SetPtrDflt(affect=button,button=3); + }; + interpret KP_Subtract+AnyOfOrNone(all) { + repeat= True; + action= SetPtrDflt(affect=button,button=3); + }; + interpret KP_Separator+AnyOfOrNone(all) { + repeat= True; + action= PtrBtn(button=default,count=2); + }; + interpret KP_Add+AnyOfOrNone(all) { + repeat= True; + action= PtrBtn(button=default,count=2); + }; + interpret KP_0+AnyOfOrNone(all) { + repeat= True; + action= LockPtrBtn(button=default,affect=lock); + }; + interpret KP_Insert+AnyOfOrNone(all) { + repeat= True; + action= LockPtrBtn(button=default,affect=lock); + }; + interpret KP_Decimal+AnyOfOrNone(all) { + repeat= True; + action= LockPtrBtn(button=default,affect=unlock); + }; + interpret KP_Delete+AnyOfOrNone(all) { + repeat= True; + action= LockPtrBtn(button=default,affect=unlock); + }; + interpret F25+AnyOfOrNone(all) { + repeat= True; + action= SetPtrDflt(affect=button,button=1); + }; + interpret F26+AnyOfOrNone(all) { + repeat= True; + action= SetPtrDflt(affect=button,button=2); + }; + interpret F27+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=-1,y=-1); + }; + interpret F29+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=+1,y=-1); + }; + interpret F31+AnyOfOrNone(all) { + repeat= True; + action= PtrBtn(button=default); + }; + interpret F33+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=-1,y=+1); + }; + interpret F35+AnyOfOrNone(all) { + repeat= True; + action= MovePtr(x=+1,y=+1); + }; + interpret Pointer_Button_Dflt+AnyOfOrNone(all) { + action= PtrBtn(button=default); + }; + interpret Pointer_Button1+AnyOfOrNone(all) { + action= PtrBtn(button=1); + }; + interpret Pointer_Button2+AnyOfOrNone(all) { + action= PtrBtn(button=2); + }; + interpret Pointer_Button3+AnyOfOrNone(all) { + action= PtrBtn(button=3); + }; + interpret Pointer_DblClick_Dflt+AnyOfOrNone(all) { + action= PtrBtn(button=default,count=2); + }; + interpret Pointer_DblClick1+AnyOfOrNone(all) { + action= PtrBtn(button=1,count=2); + }; + interpret Pointer_DblClick2+AnyOfOrNone(all) { + action= PtrBtn(button=2,count=2); + }; + interpret Pointer_DblClick3+AnyOfOrNone(all) { + action= PtrBtn(button=3,count=2); + }; + interpret Pointer_Drag_Dflt+AnyOfOrNone(all) { + action= LockPtrBtn(button=default,affect=both); + }; + interpret Pointer_Drag1+AnyOfOrNone(all) { + action= LockPtrBtn(button=1,affect=both); + }; + interpret Pointer_Drag2+AnyOfOrNone(all) { + action= LockPtrBtn(button=2,affect=both); + }; + interpret Pointer_Drag3+AnyOfOrNone(all) { + action= LockPtrBtn(button=3,affect=both); + }; + interpret Pointer_EnableKeys+AnyOfOrNone(all) { + action= LockControls(controls=MouseKeys); + }; + interpret Pointer_Accelerate+AnyOfOrNone(all) { + action= LockControls(controls=MouseKeysAccel); + }; + interpret Pointer_DfltBtnNext+AnyOfOrNone(all) { + action= SetPtrDflt(affect=button,button=+1); + }; + interpret Pointer_DfltBtnPrev+AnyOfOrNone(all) { + action= SetPtrDflt(affect=button,button=-1); + }; + interpret AccessX_Enable+AnyOfOrNone(all) { + action= LockControls(controls=AccessXKeys); + }; + interpret AccessX_Feedback_Enable+AnyOfOrNone(all) { + action= LockControls(controls=AccessXFeedback); + }; + interpret RepeatKeys_Enable+AnyOfOrNone(all) { + action= LockControls(controls=RepeatKeys); + }; + interpret SlowKeys_Enable+AnyOfOrNone(all) { + action= LockControls(controls=SlowKeys); + }; + interpret BounceKeys_Enable+AnyOfOrNone(all) { + action= LockControls(controls=BounceKeys); + }; + interpret StickyKeys_Enable+AnyOfOrNone(all) { + action= LockControls(controls=StickyKeys); + }; + interpret MouseKeys_Enable+AnyOfOrNone(all) { + action= LockControls(controls=MouseKeys); + }; + interpret MouseKeys_Accel_Enable+AnyOfOrNone(all) { + action= LockControls(controls=MouseKeysAccel); + }; + interpret Overlay1_Enable+AnyOfOrNone(all) { + action= LockControls(controls=none); + }; + interpret Overlay2_Enable+AnyOfOrNone(all) { + action= LockControls(controls=none); + }; + interpret AudibleBell_Enable+AnyOfOrNone(all) { + action= LockControls(controls=AudibleBell); + }; + interpret Terminate_Server+AnyOfOrNone(all) { + action= Terminate(); + }; + interpret Alt_L+AnyOfOrNone(all) { + action= SetMods(modifiers=Alt,clearLocks); + }; + interpret Alt_R+AnyOfOrNone(all) { + action= SetMods(modifiers=Alt,clearLocks); + }; + interpret Meta_L+AnyOfOrNone(all) { + action= SetMods(modifiers=Meta,clearLocks); + }; + interpret Meta_R+AnyOfOrNone(all) { + action= SetMods(modifiers=Meta,clearLocks); + }; + interpret Super_L+AnyOfOrNone(all) { + action= SetMods(modifiers=Super,clearLocks); + }; + interpret Super_R+AnyOfOrNone(all) { + action= SetMods(modifiers=Super,clearLocks); + }; + interpret Hyper_L+AnyOfOrNone(all) { + action= SetMods(modifiers=Hyper,clearLocks); + }; + interpret Hyper_R+AnyOfOrNone(all) { + action= SetMods(modifiers=Hyper,clearLocks); + }; + interpret Shift_L+AnyOfOrNone(all) { + action= SetMods(modifiers=Shift,clearLocks); + }; + interpret Shift_R+AnyOfOrNone(all) { + action= SetMods(modifiers=Shift,clearLocks); + }; + interpret XF86Switch_VT_1+AnyOfOrNone(all) { + repeat= True; + action= SwitchScreen(screen=1,!same); + }; + interpret XF86Switch_VT_2+AnyOfOrNone(all) { + repeat= True; + action= SwitchScreen(screen=2,!same); + }; + interpret XF86Switch_VT_3+AnyOfOrNone(all) { + repeat= True; + action= SwitchScreen(screen=3,!same); + }; + interpret XF86Switch_VT_4+AnyOfOrNone(all) { + repeat= True; + action= SwitchScreen(screen=4,!same); + }; + interpret XF86Switch_VT_5+AnyOfOrNone(all) { + repeat= True; + action= SwitchScreen(screen=5,!same); + }; + interpret XF86Switch_VT_6+AnyOfOrNone(all) { + repeat= True; + action= SwitchScreen(screen=6,!same); + }; + interpret XF86Switch_VT_7+AnyOfOrNone(all) { + repeat= True; + action= SwitchScreen(screen=7,!same); + }; + interpret XF86Switch_VT_8+AnyOfOrNone(all) { + repeat= True; + action= SwitchScreen(screen=8,!same); + }; + interpret XF86Switch_VT_9+AnyOfOrNone(all) { + repeat= True; + action= SwitchScreen(screen=9,!same); + }; + interpret XF86Switch_VT_10+AnyOfOrNone(all) { + repeat= True; + action= SwitchScreen(screen=10,!same); + }; + interpret XF86Switch_VT_11+AnyOfOrNone(all) { + repeat= True; + action= SwitchScreen(screen=11,!same); + }; + interpret XF86Switch_VT_12+AnyOfOrNone(all) { + repeat= True; + action= SwitchScreen(screen=12,!same); + }; + interpret XF86LogGrabInfo+AnyOfOrNone(all) { + repeat= True; + action= Private(type=0x86,data[0]=0x50,data[1]=0x72,data[2]=0x47,data[3]=0x72,data[4]=0x62,data[5]=0x73,data[6]=0x00); + }; + interpret XF86LogWindowTree+AnyOfOrNone(all) { + repeat= True; + action= Private(type=0x86,data[0]=0x50,data[1]=0x72,data[2]=0x57,data[3]=0x69,data[4]=0x6e,data[5]=0x73,data[6]=0x00); + }; + interpret XF86Next_VMode+AnyOfOrNone(all) { + repeat= True; + action= Private(type=0x86,data[0]=0x2b,data[1]=0x56,data[2]=0x4d,data[3]=0x6f,data[4]=0x64,data[5]=0x65,data[6]=0x00); + }; + interpret XF86Prev_VMode+AnyOfOrNone(all) { + repeat= True; + action= Private(type=0x86,data[0]=0x2d,data[1]=0x56,data[2]=0x4d,data[3]=0x6f,data[4]=0x64,data[5]=0x65,data[6]=0x00); + }; + interpret ISO_Level5_Shift+AnyOfOrNone(all) { + action= SetMods(modifiers=LevelFive,clearLocks); + }; + interpret ISO_Level5_Latch+AnyOfOrNone(all) { + action= LatchMods(modifiers=LevelFive,clearLocks,latchToLock); + }; + interpret ISO_Level5_Lock+AnyOfOrNone(all) { + action= LockMods(modifiers=LevelFive); + }; + interpret Caps_Lock+AnyOfOrNone(all) { + action= LockMods(modifiers=Lock); + }; + interpret Any+Exactly(Lock) { + action= LockMods(modifiers=Lock); + }; + interpret Any+AnyOf(all) { + action= SetMods(modifiers=modMapMods,clearLocks); + }; + indicator "Caps Lock" { + whichModState= locked; + modifiers= Lock; + }; + indicator "Num Lock" { + whichModState= locked; + modifiers= NumLock; + }; + indicator "Scroll Lock" { + whichModState= locked; + modifiers= ScrollLock; + }; + indicator "Shift Lock" { + whichModState= locked; + modifiers= Shift; + }; + indicator "Group 2" { + groups= 0xfe; + }; + indicator "Mouse Keys" { + controls= MouseKeys; + }; +}; + +xkb_symbols "(unnamed)" { + name[Group1]="Czech"; + + key { [ Escape ] }; + key { [ plus, 1, exclam, dead_tilde ] }; + key { [ ecaron, 2, at, dead_caron ] }; + key { [ scaron, 3, numbersign, dead_circumflex ] }; + key { [ ccaron, 4, dollar, dead_breve ] }; + key { [ rcaron, 5, percent, dead_abovering ] }; + key { [ zcaron, 6, asciicircum, dead_ogonek ] }; + key { [ yacute, 7, ampersand, dead_grave ] }; + key { [ aacute, 8, asterisk, dead_abovedot ] }; + key { [ iacute, 9, braceleft, dead_acute ] }; + key { [ eacute, 0, braceright, dead_doubleacute ] }; + key { [ equal, percent, backslash, dead_diaeresis ] }; + key { [ dead_acute, dead_caron, dead_macron, dead_cedilla ] }; + key { [ BackSpace, BackSpace ] }; + key { [ Tab, ISO_Left_Tab ] }; + key { [ q, Q, backslash, Greek_OMEGA ] }; + key { [ w, W, bar, section ] }; + key { [ e, E, EuroSign, E ] }; + key { [ r, R, paragraph, registered ] }; + key { [ t, T, tslash, Tslash ] }; + key { [ z, Z, leftarrow, yen ] }; + key { [ u, U, downarrow, uparrow ] }; + key { [ i, I, rightarrow, idotless ] }; + key { [ o, O, oslash, Oslash ] }; + key { [ p, P, thorn, THORN ] }; + key { [ uacute, slash, bracketleft, division ] }; + key { [ parenright, parenleft, bracketright, multiply ] }; + key { [ Return ] }; + key { [ Control_L ] }; + key { [ a, A, asciitilde, AE ] }; + key { [ s, S, dstroke, U1E9E ] }; + key { [ d, D, Dstroke, ETH ] }; + key { [ f, F, bracketleft, ordfeminine ] }; + key { [ g, G, bracketright, ENG ] }; + key { [ h, H, grave, Hstroke ] }; + key { [ j, J, apostrophe, dead_horn ] }; + key { [ k, K, lstroke, ampersand ] }; + key { [ l, L, Lstroke, Lstroke ] }; + key { [ uring, quotedbl, dollar, dead_doubleacute ] }; + key { [ section, exclam, apostrophe, ssharp ] }; + key { [ semicolon, dead_abovering, grave, asciitilde ] }; + key { [ Shift_L ] }; + key { [ dead_diaeresis, apostrophe, backslash, bar ] }; + key { [ y, Y, degree, less ] }; + key { [ x, X, numbersign, greater ] }; + key { [ c, C, ampersand, copyright ] }; + key { [ v, V, at, singlelowquotemark ] }; + key { [ b, B, braceleft, leftsinglequotemark ] }; + key { [ n, N, braceright, rightsinglequotemark ] }; + key { [ m, M, asciicircum, ordmasculine ] }; + key { [ comma, question, less, multiply ] }; + key { [ period, colon, greater, division ] }; + key { [ minus, underscore, asterisk, dead_abovedot ] }; + key { [ Shift_R ] }; + key { + type= "CTRL+ALT", + symbols[Group1]= [ KP_Multiply, KP_Multiply, KP_Multiply, KP_Multiply, XF86ClearGrab ] + }; + key { [ Alt_L, Meta_L ] }; + key { [ space, space, space, space ] }; + key { [ Caps_Lock ] }; + key { + type= "CTRL+ALT", + symbols[Group1]= [ F1, F1, F1, F1, XF86Switch_VT_1 ] + }; + key { + type= "CTRL+ALT", + symbols[Group1]= [ F2, F2, F2, F2, XF86Switch_VT_2 ] + }; + key { + type= "CTRL+ALT", + symbols[Group1]= [ F3, F3, F3, F3, XF86Switch_VT_3 ] + }; + key { + type= "CTRL+ALT", + symbols[Group1]= [ F4, F4, F4, F4, XF86Switch_VT_4 ] + }; + key { + type= "CTRL+ALT", + symbols[Group1]= [ F5, F5, F5, F5, XF86Switch_VT_5 ] + }; + key { + type= "CTRL+ALT", + symbols[Group1]= [ F6, F6, F6, F6, XF86Switch_VT_6 ] + }; + key { + type= "CTRL+ALT", + symbols[Group1]= [ F7, F7, F7, F7, XF86Switch_VT_7 ] + }; + key { + type= "CTRL+ALT", + symbols[Group1]= [ F8, F8, F8, F8, XF86Switch_VT_8 ] + }; + key { + type= "CTRL+ALT", + symbols[Group1]= [ F9, F9, F9, F9, XF86Switch_VT_9 ] + }; + key { + type= "CTRL+ALT", + symbols[Group1]= [ F10, F10, F10, F10, XF86Switch_VT_10 ] + }; + key { [ Num_Lock ] }; + key { [ Scroll_Lock ] }; + key { [ KP_Home, KP_7 ] }; + key { [ KP_Up, KP_8 ] }; + key { [ KP_Prior, KP_9 ] }; + key { + type= "CTRL+ALT", + symbols[Group1]= [ KP_Subtract, KP_Subtract, KP_Subtract, KP_Subtract, XF86Prev_VMode ] + }; + key { [ KP_Left, KP_4 ] }; + key { [ KP_Begin, KP_5 ] }; + key { [ KP_Right, KP_6 ] }; + key { + type= "CTRL+ALT", + symbols[Group1]= [ KP_Add, KP_Add, KP_Add, KP_Add, XF86Next_VMode ] + }; + key { [ KP_End, KP_1 ] }; + key { [ KP_Down, KP_2 ] }; + key { [ KP_Next, KP_3 ] }; + key { [ KP_Insert, KP_0 ] }; + key { [ KP_Delete, KP_Decimal ] }; + key { [ ISO_Level3_Shift ] }; + key { [ backslash, bar, slash, brokenbar ] }; + key { + type= "CTRL+ALT", + symbols[Group1]= [ F11, F11, F11, F11, XF86Switch_VT_11 ] + }; + key { + type= "CTRL+ALT", + symbols[Group1]= [ F12, F12, F12, F12, XF86Switch_VT_12 ] + }; + key { [ Katakana ] }; + key { [ Hiragana ] }; + key { [ Henkan_Mode ] }; + key { [ Hiragana_Katakana ] }; + key { [ Muhenkan ] }; + key { [ KP_Enter ] }; + key { [ Control_R ] }; + key { + type= "CTRL+ALT", + symbols[Group1]= [ KP_Divide, KP_Divide, KP_Divide, KP_Divide, XF86Ungrab ] + }; + key { + type= "PC_ALT_LEVEL2", + symbols[Group1]= [ Print, Sys_Req ] + }; + key { + type= "ONE_LEVEL", + symbols[Group1]= [ ISO_Level3_Shift ] + }; + key { [ Linefeed ] }; + key { [ Home ] }; + key { [ Up ] }; + key { [ Prior ] }; + key { [ Left ] }; + key { [ Right ] }; + key { [ End ] }; + key { [ Down ] }; + key { [ Next ] }; + key { [ Insert ] }; + key { [ Delete ] }; + key { [ XF86AudioMute ] }; + key { [ XF86AudioLowerVolume ] }; + key { [ XF86AudioRaiseVolume ] }; + key { [ XF86PowerOff ] }; + key { [ KP_Equal ] }; + key { [ plusminus ] }; + key { + type= "PC_CONTROL_LEVEL2", + symbols[Group1]= [ Pause, Break ] + }; + key { [ XF86LaunchA ] }; + key { [ KP_Decimal, KP_Decimal ] }; + key { [ Hangul ] }; + key { [ Hangul_Hanja ] }; + key { [ Super_L ] }; + key { [ Super_R ] }; + key { [ Menu ] }; + key { [ Cancel ] }; + key { [ Redo ] }; + key { [ SunProps ] }; + key { [ Undo ] }; + key { [ SunFront ] }; + key { [ XF86Copy ] }; + key { [ XF86Open ] }; + key { [ XF86Paste ] }; + key { [ Find ] }; + key { [ XF86Cut ] }; + key { [ Help ] }; + key { [ XF86MenuKB ] }; + key { [ XF86Calculator ] }; + key { [ XF86Sleep ] }; + key { [ XF86WakeUp ] }; + key { [ XF86Explorer ] }; + key { [ XF86Send ] }; + key { [ XF86Xfer ] }; + key { [ XF86Launch1 ] }; + key { [ XF86Launch2 ] }; + key { [ XF86WWW ] }; + key { [ XF86DOS ] }; + key { [ XF86ScreenSaver ] }; + key { [ XF86RotateWindows ] }; + key { [ XF86TaskPane ] }; + key { [ XF86Mail ] }; + key { [ XF86Favorites ] }; + key { [ XF86MyComputer ] }; + key { [ XF86Back ] }; + key { [ XF86Forward ] }; + key { [ XF86Eject ] }; + key { [ XF86Eject ] }; + key { [ XF86AudioNext ] }; + key { [ XF86AudioPlay, XF86AudioPause ] }; + key { [ XF86AudioPrev ] }; + key { [ XF86AudioStop, XF86Eject ] }; + key { [ XF86AudioRecord ] }; + key { [ XF86AudioRewind ] }; + key { [ XF86Phone ] }; + key { [ XF86Tools ] }; + key { [ XF86HomePage ] }; + key { [ XF86Reload ] }; + key { [ XF86Close ] }; + key { [ XF86ScrollUp ] }; + key { [ XF86ScrollDown ] }; + key { [ parenleft ] }; + key { [ parenright ] }; + key { [ XF86New ] }; + key { [ Redo ] }; + key { [ XF86Tools ] }; + key { [ XF86Launch5 ] }; + key { [ XF86Launch6 ] }; + key { [ XF86Launch7 ] }; + key { [ XF86Launch8 ] }; + key { [ XF86Launch9 ] }; + key { [ XF86AudioMicMute ] }; + key { [ XF86TouchpadToggle ] }; + key { [ XF86TouchpadOn ] }; + key { [ XF86TouchpadOff ] }; + key { [ ISO_Level5_Shift ] }; + key { [ NoSymbol, Alt_L ] }; + key { [ NoSymbol, Meta_L ] }; + key { [ NoSymbol, Super_L ] }; + key { [ NoSymbol, Hyper_L ] }; + modifier_map Shift { , }; + modifier_map Lock { }; + modifier_map Control { , }; + modifier_map Mod1 { , , }; + modifier_map Mod2 { }; + modifier_map Mod3 { }; + modifier_map Mod4 { , , , }; + modifier_map Mod5 { }; +}; + +}; + diff --git a/firmware2/libxkbcommon-redefine-syms.sh b/firmware2/libxkbcommon-redefine-syms.sh new file mode 100644 index 0000000..d2c0c49 --- /dev/null +++ b/firmware2/libxkbcommon-redefine-syms.sh @@ -0,0 +1,28 @@ +#!/bin/bash +INPUT_LIB=$1 +OUTPUT_LIB=$2 +PREFIX="__xkbc_" + +if [ "$#" -ne 2 ]; then + echo "Usage: $0 " + exit 1 +fi + +echo "Redefining symbols from $INPUT_LIB into $OUTPUT_LIB..." + +# We use <(...) to stream the symbol map directly into objcopy +# xtensa-esp-elf-objcopy --redefine-syms=<( +# xtensa-esp-elf-nm -u "$INPUT_LIB" | +# awk '{print $NF}' | +# sort -u | +# awk -v p="$PREFIX" '{print $1 " " p $1}' +# ) "$INPUT_LIB" "$OUTPUT_LIB" + +xtensa-esp-elf-objcopy --redefine-syms=<( + comm -23 \ + <(xtensa-esp-elf-nm -u "$INPUT_LIB" | awk '{print $NF}' | sort -u) \ + <(xtensa-esp-elf-nm --defined-only "$INPUT_LIB" | awk '{print $NF}' | sort -u) | \ + awk -v p="$PREFIX" '{print $1 " " p $1}' +) "$INPUT_LIB" "$OUTPUT_LIB" + +echo "Done! Prefixed all externally linked symbols with $PREFIX." diff --git a/firmware2/src/ffi.rs b/firmware2/src/ffi.rs deleted file mode 100644 index ec7bfd2..0000000 --- a/firmware2/src/ffi.rs +++ /dev/null @@ -1,241 +0,0 @@ -#![allow(unused)] - -use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::{null, null_mut}}; - -unsafe extern "C" { - fn malloc(size: c_size_t) -> *mut c_void; -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn strpbrk(s: *const c_char, accept: *const c_char) -> *mut c_char { - todo!() -} - -#[allow(non_camel_case_types)] -type c_intmax_t = c_longlong; - -#[unsafe(no_mangle)] -unsafe extern "C" fn imaxabs(j: c_intmax_t) -> c_intmax_t { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn eaccess(pathname: *const c_char, mode: c_int ) -> c_int { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn vasprintf(strp: *mut *mut c_char, fmt: *const c_char, ap: VaList) -> c_int { - todo!() -} - -#[allow(non_camel_case_types)] -type stat = c_void; // Not implemented - -#[unsafe(no_mangle)] -unsafe extern "C" fn stat(path: *const c_char, buf: *mut stat) -> c_int { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn __errno() -> *mut c_int { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn strerror(errnum: c_int) -> *mut c_char { - todo!() -} - -#[allow(non_camel_case_types)] -type DIR = c_void; // Not implemented - -#[allow(non_camel_case_types)] -type dirent = c_void; // Not implemented - -#[unsafe(no_mangle)] -unsafe extern "C" fn opendir(name: *const c_char) -> *mut DIR { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn readdir(dirp: *mut DIR) -> *mut dirent { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn closedir(dirp: *mut DIR) -> c_int { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn qsort( - base: *mut c_void, - num: c_size_t, - size: c_size_t, - compar: Option c_int>, -) { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn __getreent() -> *mut c_void /*struct _reent*/ { - todo!() -} - -#[allow(non_camel_case_types)] -#[allow(clippy::upper_case_acronyms)] -enum FILE {} - -#[unsafe(no_mangle)] -unsafe extern "C" fn fprintf( - stream: *mut FILE, - format: *const c_char, - ... -) -> c_int { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn vfprintf(stream: *mut FILE, format: *const c_char, ap: VaList) -> c_int { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn strtol(nptr: *const c_char, endptr: *mut *mut c_char, base: c_int) -> c_long { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn secure_getenv(name: *const c_char) -> *mut c_char { - unsafe { getenv(name) } -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn getenv(name: *const c_char) -> *mut c_char { - null_mut() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn fseek( - stream: *mut FILE, - offset: c_long, - whence: c_int, -) -> c_int { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn ftell(stream: *mut FILE) -> c_long { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn fread( - ptr: *mut c_void, - size: c_size_t, - nobj: c_size_t, - stream: *mut FILE, -) -> c_size_t { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn open( - path: *const c_char, - oflag: c_int, - ... -) -> c_int { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn fstat(fildes: c_int, buf: *mut stat) -> c_int { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn close(fd: c_int) -> c_int { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn fdopen( - fd: c_int, - mode: *const c_char, -) -> *mut FILE { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn strndup( - s: *const c_char, - n: c_size_t, -) -> *mut c_char { - let len = unsafe { strnlen(s, n) }; - let new = unsafe { malloc(len + 1) } as *mut c_char; - - if new.is_null() { - return null_mut(); - } - - unsafe { - *new.add(len) = b'\0'; - - memcpy(new as *mut c_void, s as *const c_void, len) as *mut c_char - } -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn labs(i: c_long) -> c_long { - i.abs() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn memcpy(dest: *mut c_void, src: *const c_void, n: c_size_t) -> *mut c_void { - todo!() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn strnlen(s: *const c_char, maxlen: c_size_t) -> c_size_t { - let found: *const c_char = unsafe { 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 extern "C" fn memchr(s: *const c_void, c: c_int, n: c_size_t) -> *mut c_void { - let mut s = s as *const c_uchar; - let c = c as c_uchar; - - for _ in 0..n { - unsafe { - if *s == c { - return s as *mut c_void; - } - - s = s.add(1); - } - } - - null_mut() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn __wrap_strncmp( - s1: *const c_char, - s2: *const c_char, - n: c_size_t, -) -> c_int { - unsafe { - for i in 0..n as isize { - let s1_i = s1.offset(i); - let s2_i = s2.offset(i); - - let val = *s1_i as c_int - *s2_i as c_int; - if val != 0 || *s1_i == 0 { - return val; - } - } - 0 - } -} diff --git a/firmware2/src/ffi/alloc.rs b/firmware2/src/ffi/alloc.rs new file mode 100644 index 0000000..addda21 --- /dev/null +++ b/firmware2/src/ffi/alloc.rs @@ -0,0 +1,104 @@ +use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut}; + +use core::alloc::GlobalAlloc; + +use enumset::EnumSet; +use esp_alloc::EspHeap; + +// Here we select the allocator to use for libxkbcommon. +static XKBC_ALLOCATOR: &EspHeap = &crate::PSRAM_ALLOCATOR; + +// Implementation based on esp-alloc's `compat` feature. + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_malloc(size: c_size_t) -> *mut c_void { + unsafe { malloc_with_caps(size, EnumSet::empty()) as *mut _ } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_calloc( + number: c_size_t, + size: c_size_t, +) -> *mut c_void { + let total_size = number as usize * size; + unsafe { + let ptr = __xkbc_malloc(total_size) as *mut u8; + + if !ptr.is_null() { + for i in 0..total_size as isize { + ptr.offset(i).write_volatile(0); + } + } + + ptr as *mut _ + } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_realloc( + 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(no_mangle)] +pub unsafe extern "C" fn __xkbc_free(ptr: *mut c_void) { + if ptr.is_null() { + return; + } + + unsafe { + let ptr = ptr.offset(-4); + let total_size = *(ptr as *const usize); + + XKBC_ALLOCATOR.dealloc( + ptr as *mut u8, + core::alloc::Layout::from_size_align_unchecked(total_size, 4), + ) + } +} + +unsafe fn malloc_with_caps( + size: usize, + caps: EnumSet, +) -> *mut u8 { + let total_size = size + 4; + + unsafe { + let ptr = XKBC_ALLOCATOR.alloc_caps( + caps, + core::alloc::Layout::from_size_align_unchecked(total_size, 4), + ); + + if ptr.is_null() { + return ptr; + } + + *(ptr as *mut usize) = total_size; + ptr.offset(4) + } +} + +unsafe fn realloc_with_caps( + ptr: *mut u8, + new_size: usize, + caps: enumset::EnumSet, +) -> *mut u8 { + unsafe extern "C" { + fn memcpy(d: *mut u8, s: *const u8, l: usize); + } + + unsafe { + let p = malloc_with_caps(new_size, caps); + if !p.is_null() && !ptr.is_null() { + let len = usize::min( + (ptr as *const u32).sub(1).read_volatile() as usize, + new_size, + ); + memcpy(p, ptr, len); + __xkbc_free(ptr as *mut _); + } + p + } +} diff --git a/firmware2/src/ffi/gcc_runtime.rs b/firmware2/src/ffi/gcc_runtime.rs new file mode 100644 index 0000000..1f320d6 --- /dev/null +++ b/firmware2/src/ffi/gcc_runtime.rs @@ -0,0 +1,12 @@ +//! 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}; + +unsafe extern "C" { + fn __divdi3(a: c_long, b: c_long) -> c_long; +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc___divdi3(a: c_long, b: c_long) -> c_long { + unsafe { __divdi3(a, b) } +} diff --git a/firmware2/src/ffi/inout/dir.rs b/firmware2/src/ffi/inout/dir.rs new file mode 100644 index 0000000..62b2878 --- /dev/null +++ b/firmware2/src/ffi/inout/dir.rs @@ -0,0 +1,25 @@ +use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut}; + +#[allow(non_camel_case_types)] +pub enum DIR {} + +#[allow(non_camel_case_types)] +#[repr(C)] +pub struct dirent { + // Not implemented +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_opendir(name: *const c_char) -> *mut DIR { + todo!() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_readdir(dirp: *mut DIR) -> *mut dirent { + todo!() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_closedir(dirp: *mut DIR) -> c_int { + todo!() +} diff --git a/firmware2/src/ffi/inout/file.rs b/firmware2/src/ffi/inout/file.rs new file mode 100644 index 0000000..edfb5bf --- /dev/null +++ b/firmware2/src/ffi/inout/file.rs @@ -0,0 +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(non_camel_case_types)] +#[allow(clippy::upper_case_acronyms)] +pub enum FILE {} + +pub const STDIN: *mut FILE = 0 as _; +pub const STDOUT: *mut FILE = 1 as _; +pub const STDERR: *mut FILE = 2 as _; diff --git a/firmware2/src/ffi/inout/mod.rs b/firmware2/src/ffi/inout/mod.rs new file mode 100644 index 0000000..30927ec --- /dev/null +++ b/firmware2/src/ffi/inout/mod.rs @@ -0,0 +1,93 @@ +//! This would've been called `io`, but rust-analyzer refuses to see +//! 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}; + +use log::info; + +pub mod file; +pub mod dir; + +pub use file::*; +pub use dir::*; + +// File management + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_fopen( + filename: *const c_char, + mode: *const c_char, +) -> *mut FILE { + todo!() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_fclose(file: *mut FILE) -> c_int { + todo!() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_fseek( + stream: *mut FILE, + offset: c_long, + whence: c_int, +) -> c_int { + todo!() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_ftell(stream: *mut FILE) -> c_long { + todo!() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_fread( + ptr: *mut c_void, + size: c_size_t, + nobj: c_size_t, + stream: *mut FILE, +) -> c_size_t { + todo!() +} + +// Printing + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_fprintf( + stream: *mut FILE, + format: *const c_char, + mut args: ... +) -> c_int { + unsafe { __xkbc_vfprintf(stream, format, args.as_va_list()) } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_vfprintf(stream: *mut FILE, format: *const c_char, ap: VaList) -> c_int { + if stream == STDOUT || stream == STDERR { + let string = ::alloc::format!("vfprintf({:?}, {:?}, {:?})", stream, format, ap); + info!("{}", string); + string.len() as c_int + } else { + -1 + } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_vasprintf(strp: *mut *mut c_char, fmt: *const c_char, ap: VaList) -> c_int { + todo!() +} + +#[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 { + todo!() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_snprintf( + s: *mut c_char, + n: c_size_t, + format: *const c_char, + ... +) -> c_int { + todo!() +} diff --git a/firmware2/src/ffi/mod.rs b/firmware2/src/ffi/mod.rs new file mode 100644 index 0000000..cd944fe --- /dev/null +++ b/firmware2/src/ffi/mod.rs @@ -0,0 +1,130 @@ +use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut}; + +use alloc::__xkbc_malloc; +use inout::{FILE, STDERR, STDIN, STDOUT}; +use log::info; + +pub mod alloc; +pub mod string; +pub mod inout; +pub mod gcc_runtime; + +#[allow(non_camel_case_types)] +pub type c_intmax_t = c_longlong; + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_imaxabs(j: c_intmax_t) -> c_intmax_t { + todo!() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_eaccess(pathname: *const c_char, mode: c_int ) -> c_int { + todo!() +} + +#[allow(non_camel_case_types)] +type stat = c_void; // Not implemented + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_stat(path: *const c_char, buf: *mut stat) -> c_int { + todo!() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc___errno() -> *mut c_int { + todo!() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_qsort( + base: *mut c_void, + num: c_size_t, + size: c_size_t, + compar: Option c_int>, +) { + todo!() +} + +/// An incomplete representation of Newlib's `struct _reent`. +/// https://github.com/bminor/newlib/blob/b41e3b652c4215556a62a2f47e8f8f11553fa550/newlib/libc/include/sys/reent.h#L580 +#[repr(C)] +#[allow(non_camel_case_types)] +#[derive(Clone, Copy)] +struct _reent { + _errno: c_int, + _stdin: *mut FILE, + _stdout: *mut FILE, + _stderr: *mut FILE, + // Rest unimplemented +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc___getreent() -> *mut _reent { + static mut REENT: [_reent; 2] = [_reent { + _errno: 0, + _stdin: STDIN, + _stdout: STDOUT, + _stderr: STDERR, + }; 2]; + + unsafe { + let reent = &mut REENT[esp_hal::system::Cpu::current() as usize]; + reent as *mut _reent + } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_secure_getenv(name: *const c_char) -> *mut c_char { + unsafe { __xkbc_getenv(name) } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_getenv(name: *const c_char) -> *mut c_char { + null_mut() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_open( + path: *const c_char, + oflag: c_int, + ... +) -> c_int { + todo!() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_fstat(fildes: c_int, buf: *mut stat) -> c_int { + todo!() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_close(fd: c_int) -> c_int { + todo!() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_fdopen( + fd: c_int, + mode: *const c_char, +) -> *mut FILE { + todo!() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_labs(i: c_long) -> c_long { + i.abs() +} + +unsafe extern "C" { + fn __assert_func(file: *const c_char, line: c_int, function: *const c_char, failedExpression: *const c_char); +} + +#[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) { + unsafe { __assert_func(file, line, function, failed_expression); } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_atoi(s: *const c_char) -> c_int { + todo!() +} diff --git a/firmware2/src/ffi/string.rs b/firmware2/src/ffi/string.rs new file mode 100644 index 0000000..893bb00 --- /dev/null +++ b/firmware2/src/ffi/string.rs @@ -0,0 +1,193 @@ +use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut}; + +use super::alloc::__xkbc_malloc; + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_memset( + dest_original: *mut c_void, + c: c_int, + n: c_size_t, +) -> *mut c_void { + if dest_original == null_mut() { + if n > 0 { + panic!("Attempted to memset a nullptr."); + } else { + return null_mut(); + } + } + + let mut dest = dest_original as *mut u8; + let c = c as u8; + for _ in 0..n { + unsafe { + *dest = c; + dest = dest.add(1); + } + } + + dest_original +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_memmove( + dst: *mut c_void, + src: *const c_void, + count: c_size_t, +) -> *mut c_void { + unsafe { core::ptr::copy(src, dst, count) }; + dst +} + +#[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 { + unsafe { core::ptr::copy_nonoverlapping(src, dst, count); } + dst +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_memchr(s: *const c_void, c: c_int, n: c_size_t) -> *mut c_void { + let mut s = s as *const c_uchar; + let c = c as c_uchar; + + for _ in 0..n { + unsafe { + if *s == c { + return s as *mut c_void; + } + + s = s.add(1); + } + } + + null_mut() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_memcmp( + mut s1: *const c_char, + mut s2: *const c_char, + n: c_size_t, +) -> c_int { + unsafe { + for i in 0..n as isize { + let s1_i = s1.offset(i); + let s2_i = s2.offset(i); + let val = *s1_i as c_int - *s2_i as c_int; + + if val != 0 { + return val; + } + } + + 0 + } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_strpbrk(s: *const c_char, accept: *const c_char) -> *mut c_char { + todo!() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_strerror(errnum: c_int) -> *mut c_char { + todo!() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_strdup(string: *const c_char) -> *mut c_char { + strndup_inner(string, unsafe { __xkbc_strlen(string) }) +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_strndup( + string: *const c_char, + max_len: c_size_t, +) -> *mut c_char { + strndup_inner(string, unsafe { __xkbc_strnlen(string, max_len) }) +} + +fn strndup_inner(string: *const c_char, computed_len: c_size_t) -> *mut c_char { + let new = unsafe { __xkbc_malloc(computed_len + 1) } as *mut c_char; + + if new.is_null() { + return null_mut(); + } + + unsafe { + *new.add(computed_len) = b'\0'; + + __xkbc_memcpy(new as *mut c_void, string as *const c_void, computed_len) as *mut c_char + } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_strlen(mut s: *const c_char) -> c_size_t { + let mut result = 0; + unsafe { + while *s != 0 { + s = s.offset(1); + result += 1; + } + } + result +} + +#[unsafe(no_mangle)] +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; + if !found.is_null() { unsafe { found.offset_from(s) as c_size_t } } else { maxlen } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_strncmp( + s1: *const c_char, + s2: *const c_char, + n: c_size_t, +) -> c_int { + unsafe { + for i in 0..n as isize { + let s1_i = s1.offset(i); + let s2_i = s2.offset(i); + let val = *s1_i as c_int - *s2_i as c_int; + + if val != 0 || *s1_i == 0 { + return val; + } + } + + 0 + } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_strchr( + cs: *const c_char, + c: c_int, +) -> *mut c_char { + todo!() +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_strcmp( + s1: *const c_char, + s2: *const c_char, +) -> c_int { + unsafe { + for i in 0_isize.. { + let s1_i = s1.offset(i); + let s2_i = s2.offset(i); + let val = *s1_i as c_int - *s2_i as c_int; + + if val != 0 || *s1_i == 0 { + return val; + } + } + + 0 + } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __xkbc_strtol(nptr: *const c_char, endptr: *mut *mut c_char, base: c_int) -> c_long { + todo!() +} diff --git a/firmware2/src/main.rs b/firmware2/src/main.rs index 41f4908..f6ad207 100644 --- a/firmware2/src/main.rs +++ b/firmware2/src/main.rs @@ -8,6 +8,7 @@ //! https://esp32.com/viewtopic.php?f=12&t=26793&start=20#p95677 #![no_std] #![no_main] +#![feature(allocator_api)] #![feature(macro_metavar_expr)] #![feature(c_variadic)] #![feature(c_size_t)] @@ -17,9 +18,12 @@ extern crate alloc; use core::alloc::Layout; use core::cell::RefCell; use core::ffi::CStr; +use core::slice; -use alloc::string::ToString; -use alloc::boxed::Box; +use alloc::alloc::Allocator; +use alloc::string::{String, ToString}; +use alloc::boxed::{self, Box}; +use alloc::vec::Vec; use alloc::vec; use bt_hci::controller::ExternalController; use cfg_if::cfg_if; @@ -66,7 +70,6 @@ use slint::platform::software_renderer::Rgb565Pixel; use slint::ComponentHandle; use static_cell::StaticCell; use ui::AppWindow; -use xkbcommon::xkb::{self, Keymap}; use {esp_alloc as _, esp_backtrace as _}; use crate::matrix::IoeMatrix; @@ -109,7 +112,7 @@ cfg_if! { const FRAME_DURATION_MIN: Duration = Duration::from_millis(40); // 25 FPS -static PSRAM_ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty(); +pub static PSRAM_ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty(); /// Used to signal that MCU is ready to submit the framebuffer to the LCD. static SIGNAL_LCD_SUBMIT: Signal = Signal::new(); @@ -153,6 +156,9 @@ async fn main(_spawner: Spawner) { let alt_uart_rx_task = async {}; // Use the internal DRAM as the heap. + // TODO: Can we combine the regular link section with dram2? + // esp_alloc::heap_allocator!(size: 80 * 1024); + // esp_alloc::heap_allocator!(#[unsafe(link_section = ".dram2_uninit")] size: 72 * 1024); esp_alloc::heap_allocator!(#[unsafe(link_section = ".dram2_uninit")] size: 64 * 1024); info!("Heap initialized! {:#?}", esp_alloc::HEAP.stats()); @@ -384,7 +390,10 @@ async fn main(_spawner: Spawner) { info!("Second core started!"); + let hid_report_proxy_task = async {}; + let hid_report_proxy_task = { + use xkbcommon::xkb::{self, Keymap}; static KEYBOARD_REPORT_PROXY: Channel = Channel::new(); { @@ -395,10 +404,21 @@ async fn main(_spawner: Spawner) { Timer::after_secs(1).await; info!("HID Report Proxy Task: Done waiting."); const KEYMAP_STRING: &str = include_str!("../keymaps/cz.xkb"); + let keymap_string_buffer = unsafe { + let allocation = PSRAM_ALLOCATOR.alloc_caps( + MemoryCapability::External.into(), + 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())); + + slice.as_bytes_mut().copy_from_slice(KEYMAP_STRING.as_bytes()); + + Box::from_raw_in(slice as *mut str, &PSRAM_ALLOCATOR) + }; info!("HID Report Proxy Task: test"); let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS); info!("HID Report Proxy Task: foo"); - let keymap = Keymap::new_from_string(&context, KEYMAP_STRING, xkb::KEYMAP_FORMAT_TEXT_V1, xkb::KEYMAP_COMPILE_NO_FLAGS).unwrap(); + let keymap = Keymap::new_from_string(&context, keymap_string_buffer, xkb::KEYMAP_FORMAT_TEXT_V1, xkb::KEYMAP_COMPILE_NO_FLAGS).unwrap(); info!("HID Report Proxy Task: bar"); async { @@ -472,6 +492,14 @@ impl Controller for UserController { #[embassy_executor::task] async fn run_renderer_task(backend: SlintBackend) { + // TODO: Disable rendering because it causes crashes in allocation + loop { + SIGNAL_LCD_SUBMIT.signal(()); + #[cfg(feature = "limit-fps")] + embassy_time::Timer::after(FRAME_DURATION_MIN).await; + SIGNAL_UI_RENDER.wait().await; + } + slint::platform::set_platform(Box::new(backend)) .expect("backend already initialized");