add evfbo (evdev + fbdev + stdout) backend
During a normal boot in the postmarketOS initramfs, the TTY is not easily accessible. The on-screen keyboard is expected to send the password to stdout instead of to a uinput device. Add the evfbo backend to support full-disk encryption.
This commit is contained in:
parent
7b38edb656
commit
c92b571c16
4 changed files with 185 additions and 0 deletions
|
|
@ -37,6 +37,10 @@ bindgen = "0.71"
|
||||||
name = "ufkbd-evfb"
|
name = "ufkbd-evfb"
|
||||||
path = "src/ufkbd_evfb.rs"
|
path = "src/ufkbd_evfb.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "ufkbd-evfbo"
|
||||||
|
path = "src/ufkbd_evfbo.rs"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "ufkbd-gnome"
|
name = "ufkbd-gnome"
|
||||||
path = "src/ufkbd_gnome.rs"
|
path = "src/ufkbd_gnome.rs"
|
||||||
|
|
|
||||||
8
src/stdio/mod.rs
Normal file
8
src/stdio/mod.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Richard Acayan. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mod output;
|
||||||
|
|
||||||
|
pub use self::output::Output;
|
||||||
92
src/stdio/output.rs
Normal file
92
src/stdio/output.rs
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Richard Acayan. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::core::Keyboard;
|
||||||
|
use crate::core::Layout;
|
||||||
|
use std::iter::FromIterator;
|
||||||
|
use xkeysym::Keysym;
|
||||||
|
|
||||||
|
pub struct Output {
|
||||||
|
back: String,
|
||||||
|
front: String,
|
||||||
|
complete: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Output {
|
||||||
|
pub fn new() -> Self
|
||||||
|
{
|
||||||
|
Self {
|
||||||
|
back: String::new(),
|
||||||
|
front: String::new(),
|
||||||
|
complete: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn complete(&self) -> bool
|
||||||
|
{
|
||||||
|
self.complete
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Keyboard for Output {
|
||||||
|
fn key_supported(&self, sym: Keysym) -> bool
|
||||||
|
{
|
||||||
|
match sym {
|
||||||
|
Keysym::Return => true,
|
||||||
|
Keysym::BackSpace => true,
|
||||||
|
Keysym::Delete => true,
|
||||||
|
Keysym::Left => true,
|
||||||
|
Keysym::Right => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn press(&mut self, sym: Keysym)
|
||||||
|
{
|
||||||
|
match sym {
|
||||||
|
Keysym::Return => {
|
||||||
|
let front = self.front.chars().rev();
|
||||||
|
let front = String::from_iter(front);
|
||||||
|
|
||||||
|
println!("{}{}", self.back, front);
|
||||||
|
|
||||||
|
self.complete = true;
|
||||||
|
},
|
||||||
|
Keysym::BackSpace => {
|
||||||
|
self.back.pop();
|
||||||
|
},
|
||||||
|
Keysym::Delete => {
|
||||||
|
self.front.pop();
|
||||||
|
},
|
||||||
|
Keysym::Left => {
|
||||||
|
if let Some(c) = self.back.pop() {
|
||||||
|
self.front.push(c);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Keysym::Right => {
|
||||||
|
if let Some(c) = self.front.pop() {
|
||||||
|
self.back.push(c);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn release(&mut self, _: Keysym)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
fn text(&mut self, text: &str)
|
||||||
|
{
|
||||||
|
for c in text.chars() {
|
||||||
|
self.back.push(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn change_layout(&mut self, _: &Layout)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
81
src/ufkbd_evfbo.rs
Normal file
81
src/ufkbd_evfbo.rs
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Richard Acayan. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mod core;
|
||||||
|
mod evdev;
|
||||||
|
mod fbdev;
|
||||||
|
mod linux;
|
||||||
|
mod stdio;
|
||||||
|
|
||||||
|
use crate::core::Button;
|
||||||
|
use crate::core::Configuration;
|
||||||
|
use crate::core::Display;
|
||||||
|
use crate::core::Graphics;
|
||||||
|
use crate::core::Layout;
|
||||||
|
use crate::evdev::Touchscreen;
|
||||||
|
use crate::fbdev::Framebuffer;
|
||||||
|
use crate::stdio::Output;
|
||||||
|
use polling::Event;
|
||||||
|
use polling::Events;
|
||||||
|
use polling::Poller;
|
||||||
|
use signal_hook::consts::signal;
|
||||||
|
use signal_hook::iterator::Signals;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
fn main()
|
||||||
|
{
|
||||||
|
let cfg = Configuration::load().unwrap();
|
||||||
|
let disp = Framebuffer::new(&cfg).unwrap();
|
||||||
|
|
||||||
|
let gfx = Graphics::new(disp, &cfg);
|
||||||
|
let gfx = Mutex::new(gfx);
|
||||||
|
let gfx = Arc::new(gfx);
|
||||||
|
|
||||||
|
let kbd = Output::new();
|
||||||
|
let layout = Layout::load(&cfg).unwrap();
|
||||||
|
let mut btn = Button::new(&cfg, layout, kbd, gfx.clone());
|
||||||
|
btn.set_text_supported(true);
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut gfx = gfx.lock().unwrap();
|
||||||
|
let (width, height) = gfx.display().size();
|
||||||
|
gfx.resize(btn.layout(), btn.mod_state(), width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut touchscreen = Touchscreen::new(btn, &cfg).unwrap();
|
||||||
|
|
||||||
|
let mut events = Events::new();
|
||||||
|
let poller = Poller::new().unwrap();
|
||||||
|
let ts_evt = Event::readable(0);
|
||||||
|
|
||||||
|
let mut sigs = Signals::new([
|
||||||
|
signal::SIGHUP,
|
||||||
|
signal::SIGINT,
|
||||||
|
signal::SIGPIPE,
|
||||||
|
signal::SIGTERM,
|
||||||
|
]).unwrap();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
poller.add(&touchscreen, ts_evt).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
while sigs.pending().next().is_none() && !touchscreen.button().keyboard().complete() {
|
||||||
|
let timer = touchscreen.button().next_time().map(|t| t - Instant::now());
|
||||||
|
|
||||||
|
events.clear();
|
||||||
|
poller.modify(&touchscreen, ts_evt).unwrap();
|
||||||
|
poller.wait(&mut events, timer).unwrap();
|
||||||
|
|
||||||
|
if !events.is_empty() {
|
||||||
|
touchscreen.handle_events();
|
||||||
|
}
|
||||||
|
|
||||||
|
touchscreen.dispatch_timers();
|
||||||
|
}
|
||||||
|
|
||||||
|
poller.delete(&touchscreen).unwrap();
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue