diff --git a/ps2d/src/state.rs b/ps2d/src/state.rs index b556897645..9891cc8e7e 100644 --- a/ps2d/src/state.rs +++ b/ps2d/src/state.rs @@ -26,8 +26,6 @@ pub struct Ps2d char> { vmmouse: bool, vmmouse_relative: bool, input: File, - width: u32, - height: u32, extended: bool, lshift: bool, rshift: bool, @@ -48,16 +46,15 @@ impl char> Ps2d { 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 char> Ps2d { 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::().unwrap_or(0); - self.height = res.split("/").nth(2).unwrap_or("").parse::().unwrap_or(0); } } @@ -253,20 +236,20 @@ impl char> Ps2d { } } 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 char> Ps2d { 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 { diff --git a/ps2d/src/vm.rs b/ps2d/src/vm.rs index 3445015091..3f3ae50b50 100644 --- a/ps2d/src/vm.rs +++ b/ps2d/src/vm.rs @@ -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?