feat(pointer): virtio tablet as 2nd input dev (driver per-instance VAs, abs/btn decode), input server serves 2 devices on one notif; display software cursor, bar click switches window, presses/releases to front window in its px; k-ui hit-tests (press focuses, release on same presses, field only focuses)
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
|
||||
extern crate libkos;
|
||||
|
||||
use driver_input_virtio::VirtioInputDevice;
|
||||
use input_server::server::{InputServer, MAX_DEVICES, Pair};
|
||||
use libkos::device::{self, KIND_UART_16550, KIND_VIRTIO};
|
||||
use port_input_device::InputDevice;
|
||||
use types::bounded::CapSlot;
|
||||
@@ -12,17 +14,24 @@ libkos::entry!(main);
|
||||
|
||||
fn main() {
|
||||
let ep = CapSlot::new(0).unwrap();
|
||||
// Init hands over the keyboard (virtio) or, failing that, the UART.
|
||||
let dev = device::receive_device(ep);
|
||||
match (dev.kind, dev.mmio) {
|
||||
// Init hands over the input devices, two (a keyboard, a tablet), each
|
||||
// virtio or, failing a keyboard, the UART; either may be none.
|
||||
let first = device::receive_device(ep);
|
||||
let second = device::receive_device(ep);
|
||||
let irqs = [first.irq, second.irq];
|
||||
let tablet = match (second.kind, second.mmio) {
|
||||
(KIND_VIRTIO, Some(mmio)) => VirtioInputDevice::try_new(mmio, 1),
|
||||
_ => None,
|
||||
};
|
||||
match (first.kind, first.mmio) {
|
||||
(KIND_VIRTIO, Some(mmio)) => {
|
||||
if let Some(d) = driver_input_virtio::VirtioInputDevice::try_new(mmio) {
|
||||
run(d, dev.irq, ep);
|
||||
if let Some(d) = VirtioInputDevice::try_new(mmio, 0) {
|
||||
run(Pair { first: d, second: tablet }, irqs, ep);
|
||||
}
|
||||
}
|
||||
(KIND_UART_16550, Some(mmio)) => {
|
||||
if let Some(d) = driver_input_uart::UartInputDevice::new(mmio) {
|
||||
run(d, dev.irq, ep);
|
||||
run(Pair { first: d, second: tablet }, irqs, ep);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@@ -31,12 +40,18 @@ fn main() {
|
||||
libkos::syscall::exit();
|
||||
}
|
||||
|
||||
/// Serves `device`, woken by its interrupt when it has one.
|
||||
/// Serves `device`, woken by its interrupts when it has them.
|
||||
#[inline(never)]
|
||||
fn run<D: InputDevice>(device: D, irq: Option<CapSlot>, ep: CapSlot) -> ! {
|
||||
let mut srv = match irq.filter(|irq| device::bind_irq(*irq).is_ok()) {
|
||||
Some(irq) => input_server::server::InputServer::with_irq(device, irq),
|
||||
None => input_server::server::InputServer::new(device),
|
||||
fn run<D: InputDevice>(device: D, irqs: [Option<CapSlot>; MAX_DEVICES], ep: CapSlot) -> ! {
|
||||
let mut lines = [CapSlot::const_new(0); MAX_DEVICES];
|
||||
let mut n = 0;
|
||||
for irq in irqs.into_iter().flatten() {
|
||||
lines[n] = irq;
|
||||
n += 1;
|
||||
}
|
||||
let mut srv = match n > 0 && device::bind_irqs(&lines[..n]).is_ok() {
|
||||
true => InputServer::with_irqs(device, irqs),
|
||||
false => InputServer::new(device),
|
||||
};
|
||||
server_framework::serve(&mut srv, ep)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user