Merge branch 'fix_absolute_mouse_events' into 'master'
Switch to absolute mouse events by default when running in a VM See merge request redox-os/drivers!126
This commit is contained in:
+20
-41
@@ -26,8 +26,6 @@ pub struct Ps2d<F: Fn(u8,bool) -> char> {
|
||||
vmmouse: bool,
|
||||
vmmouse_relative: bool,
|
||||
input: File,
|
||||
width: u32,
|
||||
height: u32,
|
||||
extended: bool,
|
||||
lshift: bool,
|
||||
rshift: bool,
|
||||
@@ -48,16 +46,15 @@ impl<F: Fn(u8,bool) -> char> Ps2d<F> {
|
||||
let mut ps2 = Ps2::new();
|
||||
let extra_packet = ps2.init().expect("ps2d: failed to initialize");
|
||||
|
||||
let vmmouse_relative = true;
|
||||
// FIXME add an option for orbital to disable this when an app captures the mouse.
|
||||
let vmmouse_relative = false;
|
||||
let vmmouse = vm::enable(vmmouse_relative);
|
||||
|
||||
let mut ps2d = Ps2d {
|
||||
Ps2d {
|
||||
ps2,
|
||||
vmmouse,
|
||||
vmmouse_relative,
|
||||
input,
|
||||
width: 0,
|
||||
height: 0,
|
||||
extended: false,
|
||||
lshift: false,
|
||||
rshift: false,
|
||||
@@ -70,20 +67,6 @@ impl<F: Fn(u8,bool) -> char> Ps2d<F> {
|
||||
packet_i: 0,
|
||||
extra_packet,
|
||||
get_char: keymap
|
||||
};
|
||||
|
||||
ps2d.resize();
|
||||
|
||||
ps2d
|
||||
}
|
||||
|
||||
pub fn resize(&mut self) {
|
||||
let mut buf: [u8; 4096] = [0; 4096];
|
||||
if let Ok(count) = syscall::fpath(self.input.as_raw_fd() as usize, &mut buf) {
|
||||
let path = unsafe { str::from_utf8_unchecked(&buf[..count]) };
|
||||
let res = path.split(":").nth(1).unwrap_or("");
|
||||
self.width = res.split("/").nth(1).unwrap_or("").parse::<u32>().unwrap_or(0);
|
||||
self.height = res.split("/").nth(2).unwrap_or("").parse::<u32>().unwrap_or(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,20 +236,20 @@ impl<F: Fn(u8,bool) -> char> Ps2d<F> {
|
||||
}
|
||||
} else if self.vmmouse {
|
||||
for _i in 0..256 {
|
||||
let (status, _, _, _, _, _) = unsafe { vm::cmd(vm::ABSPOINTER_STATUS, 0) };
|
||||
//TODO if ((status & VMMOUSE_ERROR) == VMMOUSE_ERROR)
|
||||
let (status, _, _, _, _, _) = unsafe { vm::cmd(vm::ABSPOINTER_STATUS, 0) };
|
||||
//TODO if ((status & VMMOUSE_ERROR) == VMMOUSE_ERROR)
|
||||
|
||||
let queue_length = status & 0xffff;
|
||||
if queue_length == 0 {
|
||||
break;
|
||||
let queue_length = status & 0xffff;
|
||||
if queue_length == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
if queue_length % 4 != 0 {
|
||||
eprintln!("ps2d: queue length not a multiple of 4: {}", queue_length);
|
||||
break;
|
||||
}
|
||||
if queue_length % 4 != 0 {
|
||||
eprintln!("ps2d: queue length not a multiple of 4: {}", queue_length);
|
||||
break;
|
||||
}
|
||||
|
||||
let (status, dx, dy, dz, _, _) = unsafe { vm::cmd(vm::ABSPOINTER_DATA, 4) };
|
||||
let (status, dx, dy, dz, _, _) = unsafe { vm::cmd(vm::ABSPOINTER_DATA, 4) };
|
||||
|
||||
if self.vmmouse_relative {
|
||||
if dx != 0 || dy != 0 {
|
||||
@@ -275,21 +258,17 @@ impl<F: Fn(u8,bool) -> char> Ps2d<F> {
|
||||
dy: dy as i32,
|
||||
}.to_event()).expect("ps2d: failed to write mouse event");
|
||||
}
|
||||
} else {
|
||||
// TODO: Improve efficiency
|
||||
self.resize();
|
||||
|
||||
let x = dx as i32 * self.width as i32 / 0xFFFF;
|
||||
let y = dy as i32 * self.height as i32 / 0xFFFF;
|
||||
} else {
|
||||
let x = dx as i32;
|
||||
let y = dy as i32;
|
||||
if x != self.mouse_x || y != self.mouse_y {
|
||||
self.mouse_x = x;
|
||||
self.mouse_y = y;
|
||||
self.input.write(&MouseEvent {
|
||||
x: x,
|
||||
y: y,
|
||||
}.to_event()).expect("ps2d: failed to write mouse event");
|
||||
self.input
|
||||
.write(&MouseEvent { x, y }.to_event())
|
||||
.expect("ps2d: failed to write mouse event");
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
if dz != 0 {
|
||||
self.input.write(&ScrollEvent {
|
||||
|
||||
+20
-39
@@ -4,7 +4,7 @@
|
||||
// As well as the Linux implementation here:
|
||||
// http://elixir.free-electrons.com/linux/v4.1/source/drivers/input/mouse/vmmouse.c
|
||||
|
||||
use core::arch::global_asm;
|
||||
use core::arch::asm;
|
||||
|
||||
const MAGIC: u32 = 0x564D5868;
|
||||
const PORT: u16 = 0x5658;
|
||||
@@ -27,49 +27,30 @@ pub const LEFT_BUTTON: u32 = 0x20;
|
||||
pub const RIGHT_BUTTON: u32 = 0x10;
|
||||
pub const MIDDLE_BUTTON: u32 = 0x08;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
global_asm!("
|
||||
.globl cmd_inner
|
||||
cmd_inner:
|
||||
mov r8, rdi
|
||||
|
||||
// 2nd argument `cmd` as per sysv64.
|
||||
mov ecx, esi
|
||||
// 3rd argument `arg` as per sysv64.
|
||||
mov ebx, edx
|
||||
|
||||
mov eax, {MAGIC}
|
||||
mov dx, {PORT}
|
||||
|
||||
in eax, dx
|
||||
|
||||
xchg rdi, r8
|
||||
|
||||
mov DWORD PTR [rdi + 0x00], eax
|
||||
mov DWORD PTR [rdi + 0x04], ebx
|
||||
mov DWORD PTR [rdi + 0x08], ecx
|
||||
mov DWORD PTR [rdi + 0x0C], edx
|
||||
mov DWORD PTR [rdi + 0x10], esi
|
||||
mov DWORD PTR [rdi + 0x14], r8d
|
||||
|
||||
ret
|
||||
",
|
||||
MAGIC = const MAGIC,
|
||||
PORT = const PORT,
|
||||
);
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub unsafe fn cmd(cmd: u32, arg: u32) -> (u32, u32, u32, u32, u32, u32) {
|
||||
extern "sysv64" {
|
||||
fn cmd_inner(array_ptr: *mut u32, cmd: u32, arg: u32);
|
||||
}
|
||||
let a: u32;
|
||||
let b: u32;
|
||||
let c: u32;
|
||||
let d: u32;
|
||||
let si: u32;
|
||||
let di: u32;
|
||||
|
||||
let mut array = [0_u32; 6];
|
||||
// ebx can't be used as input or output constraint in rust as LLVM reserves it.
|
||||
// Use xchg to pass it through r9 instead while restoring the original value in
|
||||
// rbx when leaving the inline asm block.
|
||||
asm!(
|
||||
"xchg r9, rbx; in eax, dx; xchg r9, rbx",
|
||||
inout("eax") MAGIC => a,
|
||||
inout("r9") arg => b,
|
||||
inout("ecx") cmd => c,
|
||||
inout("edx") PORT as u32 => d,
|
||||
out("esi") si,
|
||||
out("edi") di,
|
||||
);
|
||||
|
||||
cmd_inner(array.as_mut_ptr(), cmd, arg);
|
||||
(a, b, c, d, si, di)
|
||||
|
||||
let [a, b, c, d, e, f] = array;
|
||||
(a, b, c, d, e, f)
|
||||
}
|
||||
|
||||
//TODO: is it possible to enable this on non-x86_64?
|
||||
|
||||
Reference in New Issue
Block a user