Merge branch 'ps2d'

This commit is contained in:
Jeremy Soller
2020-04-20 14:16:30 -06:00
5 changed files with 86 additions and 51 deletions
Generated
-1
View File
@@ -892,7 +892,6 @@ version = "0.1.0"
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"orbclient 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_event 0.1.0 (git+https://gitlab.redox-os.org/redox-os/event.git)",
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
]
-1
View File
@@ -6,5 +6,4 @@ edition = "2018"
[dependencies]
bitflags = "0.7"
orbclient = "0.3.27"
redox_event = { git = "https://gitlab.redox-os.org/redox-os/event.git" }
redox_syscall = "0.1"
+64 -34
View File
@@ -2,18 +2,15 @@
#[macro_use]
extern crate bitflags;
extern crate event;
extern crate orbclient;
extern crate syscall;
use std::{env, process};
use std::cell::RefCell;
use std::fs::File;
use std::io::{Read, Write, Result};
use std::fs::{File, OpenOptions};
use std::io::{Read, Write};
use std::os::unix::fs::OpenOptionsExt;
use std::os::unix::io::AsRawFd;
use std::sync::Arc;
use event::EventQueue;
use syscall::iopl;
use crate::state::Ps2d;
@@ -41,46 +38,79 @@ fn daemon(input: File) {
None => (keymap::us::get_char)
};
let mut key_irq = File::open("irq:1").expect("ps2d: failed to open irq:1");
let mut event_file = OpenOptions::new()
.read(true)
.write(true)
.open("event:")
.expect("ps2d: failed to open event:");
let mut mouse_irq = File::open("irq:12").expect("ps2d: failed to open irq:12");
let mut key_file = OpenOptions::new()
.read(true)
.write(true)
.custom_flags(syscall::O_NONBLOCK as i32)
.open("serio:0")
.expect("ps2d: failed to open serio:0");
let ps2d = Arc::new(RefCell::new(Ps2d::new(input, keymap)));
event_file.write(&syscall::Event {
id: key_file.as_raw_fd() as usize,
flags: syscall::EVENT_READ,
data: 0
}).expect("ps2d: failed to event serio:0");
let mut event_queue = EventQueue::<()>::new().expect("ps2d: failed to create event queue");
let mut mouse_file = OpenOptions::new()
.read(true)
.write(true)
.custom_flags(syscall::O_NONBLOCK as i32)
.open("serio:1")
.expect("ps2d: failed to open serio:1");
event_file.write(&syscall::Event {
id: mouse_file.as_raw_fd() as usize,
flags: syscall::EVENT_READ,
data: 1
}).expect("ps2d: failed to event irq:12");
let mut ps2d = Ps2d::new(input, keymap);
syscall::setrens(0, 0).expect("ps2d: failed to enter null namespace");
let key_ps2d = ps2d.clone();
event_queue.add(key_irq.as_raw_fd(), move |_event| -> Result<Option<()>> {
let mut irq = [0; 8];
if key_irq.read(&mut irq)? >= irq.len() {
key_ps2d.borrow_mut().irq();
key_irq.write(&irq)?;
let mut data = [0; 256];
loop {
// There are some gotchas with ps/2 controllers that require this weird
// way of doing things. You read key and mouse data from the same
// place. There is a status register that may show you which the data
// came from, but if it is even implemented it can have a race
// condition causing keyboard data to be read as mouse data.
//
// Due to this, we have a kernel driver doing a small amount of work
// to grab bytes and sort them based on the source
let mut event = syscall::Event::default();
if event_file.read(&mut event).expect("ps2d: failed to read event file") == 0 {
break;
}
Ok(None)
}).expect("ps2d: failed to poll irq:1");
let mouse_ps2d = ps2d;
event_queue.add(mouse_irq.as_raw_fd(), move |_event| -> Result<Option<()>> {
let mut irq = [0; 8];
if mouse_irq.read(&mut irq)? >= irq.len() {
mouse_ps2d.borrow_mut().irq();
mouse_irq.write(&irq)?;
let (file, keyboard) = match event.data {
0 => (&mut key_file, true),
1 => (&mut mouse_file, false),
_ => continue,
};
loop {
let count = match file.read(&mut data) {
Ok(0) => break,
Ok(count) => count,
Err(_) => break,
};
for i in 0..count {
ps2d.handle(keyboard, data[i]);
}
}
Ok(None)
}).expect("ps2d: failed to poll irq:12");
event_queue.trigger_all(event::Event {
fd: 0,
flags: 0,
}).expect("ps2d: failed to trigger events");
event_queue.run().expect("ps2d: failed to handle events");
}
}
fn main() {
match File::open("display:input") {
match OpenOptions::new().write(true).open("display:input") {
Ok(input) => {
// Daemonize
if unsafe { syscall::clone(0).unwrap() } == 0 {
+12 -9
View File
@@ -24,6 +24,7 @@ bitflags! {
pub struct Ps2d<F: Fn(u8,bool) -> char> {
ps2: Ps2,
vmmouse: bool,
vmmouse_relative: bool,
input: File,
width: u32,
height: u32,
@@ -46,12 +47,14 @@ impl<F: Fn(u8,bool) -> char> Ps2d<F> {
let mut ps2 = Ps2::new();
let extra_packet = ps2.init();
let vmmouse = false; //vm::enable();
let vmmouse_relative = true;
let vmmouse = false; //vm::enable(vmmouse_relative);
let mut ps2d = Ps2d {
ps2: ps2,
vmmouse: vmmouse,
input: input,
ps2,
vmmouse,
vmmouse_relative,
input,
width: 0,
height: 0,
lshift: false,
@@ -63,7 +66,7 @@ impl<F: Fn(u8,bool) -> char> Ps2d<F> {
mouse_right: false,
packets: [0; 4],
packet_i: 0,
extra_packet: extra_packet,
extra_packet,
get_char: keymap
};
@@ -118,17 +121,17 @@ impl<F: Fn(u8,bool) -> char> Ps2d<F> {
}
if queue_length % 4 != 0 {
println!("queue length not a multiple of 4: {}", queue_length);
println!("ps2d: queue length not a multiple of 4: {}", queue_length);
break;
}
let (status, dx, dy, dz, _, _) = unsafe { vm::cmd(vm::ABSPOINTER_DATA, 4) };
if status & vm::RELATIVE_PACKET == vm::RELATIVE_PACKET {
if self.vmmouse_relative {
if dx != 0 || dy != 0 {
self.input.write(&MouseRelativeEvent {
dx: dx as i32,
dy: -(dy as i32),
dy: dy as i32,
}.to_event()).expect("ps2d: failed to write mouse event");
}
} else {
@@ -174,7 +177,7 @@ impl<F: Fn(u8,bool) -> char> Ps2d<F> {
let flags = MousePacketFlags::from_bits_truncate(self.packets[0]);
if ! flags.contains(ALWAYS_ON) {
println!("MOUSE MISALIGN {:X}", self.packets[0]);
println!("ps2d: mouse misalign {:X}", self.packets[0]);
self.packets = [0; 4];
self.packet_i = 0;
+10 -6
View File
@@ -14,6 +14,7 @@ pub const ABSPOINTER_COMMAND: u32 = 41;
pub const CMD_ENABLE: u32 = 0x45414552;
pub const CMD_DISABLE: u32 = 0x000000f5;
pub const CMD_REQUEST_ABSOLUTE: u32 = 0x53424152;
pub const CMD_REQUEST_RELATIVE: u32 = 0x4c455252;
const VERSION: u32 = 0x3442554a;
@@ -55,27 +56,30 @@ pub unsafe fn cmd(cmd: u32, arg: u32) -> (u32, u32, u32, u32, u32, u32) {
(a, b, c, d, si, di)
}
pub fn enable() -> bool {
println!("Enable");
pub fn enable(relative: bool) -> bool {
println!("ps2d: Enable vmmouse");
unsafe {
let _ = cmd(ABSPOINTER_COMMAND, CMD_ENABLE);
let (status, _, _, _, _, _) = cmd(ABSPOINTER_STATUS, 0);
if (status & 0x0000ffff) == 0 {
println!("No vmmouse");
println!("ps2d: No vmmouse");
return false;
}
let (version, _, _, _, _, _) = cmd(ABSPOINTER_DATA, 1);
if version != VERSION {
println!("Invalid vmmouse version: {} instead of {}", version, VERSION);
println!("ps2d: Invalid vmmouse version: {} instead of {}", version, VERSION);
let _ = cmd(ABSPOINTER_COMMAND, CMD_DISABLE);
return false;
}
cmd(ABSPOINTER_COMMAND, CMD_REQUEST_ABSOLUTE);
if relative {
cmd(ABSPOINTER_COMMAND, CMD_REQUEST_RELATIVE);
} else {
cmd(ABSPOINTER_COMMAND, CMD_REQUEST_ABSOLUTE);
}
}
return true;