Merge branch 'ps2d'
This commit is contained in:
Generated
-1
@@ -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)",
|
||||
]
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user