Skip to content

Commit

Permalink
ps2/mouse: Expose mouse events in /dev/mouse
Browse files Browse the repository at this point in the history
  • Loading branch information
rafalmiel committed Nov 18, 2023
1 parent f7a590e commit e9e1057
Show file tree
Hide file tree
Showing 10 changed files with 148 additions and 10 deletions.
3 changes: 3 additions & 0 deletions cykusz-rs/src/drivers/ps2/kbd/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ use crate::kernel::fs::vfs::FsError;
use syscall_defs::events::{Event, EventType};
use syscall_defs::poll::PollEventFlags;
use syscall_defs::OpenFlags;
use syscall_defs::time::Timeval;
use crate::kernel::timer::current_ns;

use super::scancode;

Expand Down Expand Up @@ -134,6 +136,7 @@ impl KbdState {
if opened {
let repeat = !released && was_pressed;
let evt = Event {
timeval: Timeval::from_nsecs(current_ns()),
typ: EventType::Key,
code: key as u16,
val: if released {
Expand Down
3 changes: 1 addition & 2 deletions cykusz-rs/src/drivers/ps2/kbd/scancode.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::kernel::kbd::keys::KeyCode;

use syscall_defs::events::keys::KeyCode;
macro_rules! init_arr (
($a: ident, $([$k: expr, $v: expr]),+) => {
$($a[$k] = $v;)*
Expand Down
103 changes: 100 additions & 3 deletions cykusz-rs/src/drivers/ps2/mouse/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ use crate::kernel::fs::inode::INode;
use crate::kernel::fs::poll::PollTable;
use crate::kernel::fs::vfs::FsError;
use crate::kernel::sync::Spin;
use crate::kernel::timer::current_ns;
use crate::kernel::utils::buffer::BufferQueue;
use alloc::string::String;
use alloc::sync::{Arc, Weak};
use bit_field::BitField;
use spin::Once;
use syscall_defs::events::{Event, EventType};
use syscall_defs::events::buttons::{ButtonCode, RelCode};
use syscall_defs::poll::PollEventFlags;
use syscall_defs::OpenFlags;
use syscall_defs::time::Timeval;

struct MouseState {
state: Spin<State>,
Expand All @@ -22,6 +27,7 @@ struct State {
packet: [u8; 4],
index: usize,
opened: bool,
btn_state: [bool; 3],
}

impl State {
Expand All @@ -30,8 +36,91 @@ impl State {
packet: [0; 4],
index: 0,
opened: false,
btn_state: [false; 3], //btn left, btn right, btn middle, btn side, btn extra
}
}

fn iter(&mut self) -> StateIter {
StateIter {
state: self,
idx: 0,
}
}
}

struct StateIter<'a> {
state: &'a mut State,
idx: usize,
}

impl<'a> StateIter<'a> {
fn btn_code(&self) -> Option<ButtonCode> {
match self.idx {
0 => Some(ButtonCode::BTN_LEFT),
1 => Some(ButtonCode::BTN_RIGHT),
2 => Some(ButtonCode::BTN_MIDDLE),
_ => None
}
}

fn get_rel_x(&self) -> i32 {
let d = self.state.packet[1] as i32;
return d - (((self.state.packet[0] as i32) << 4) & 0x100);
}

fn get_rel_y(&self) -> i32 {
let d = self.state.packet[2] as i32;
return d - (((self.state.packet[0] as i32) << 3) & 0x100);
}
}

impl<'a> Iterator for StateIter<'a> {
type Item = Event;

fn next(&mut self) -> Option<Self::Item> {
while let Some(btn_code) = self.btn_code() {
let idx = self.idx;
self.idx += 1;
if self.state.btn_state[idx] != self.state.packet[0].get_bit(idx) {
self.state.btn_state[idx] = self.state.packet[0].get_bit(idx);

return Some(Event {
timeval: Timeval::from_nsecs(current_ns()),
typ: EventType::Key,
code: btn_code as u16,
val: if self.state.btn_state[idx] { 1 } else { 0 },
})
}
}

if self.idx == 3 {
self.idx += 1;
let rel_x = self.get_rel_x();
if rel_x != 0 {
return Some(Event {
timeval: Timeval::from_nsecs(current_ns()),
typ: EventType::Rel,
code: RelCode::REL_X as u16,
val: rel_x,
})
}
}

if self.idx == 4 {
self.idx += 1;
let rel_y = self.get_rel_y();
if rel_y != 0 {
return Some(Event {
timeval: Timeval::from_nsecs(current_ns()),
typ: EventType::Rel,
code: RelCode::REL_Y as u16,
val: rel_y,
})
}
}

None
}
}

impl Device for MouseState {
Expand All @@ -50,7 +139,7 @@ impl Device for MouseState {

impl INode for MouseState {
fn read_at(&self, _offset: usize, buf: &mut [u8]) -> crate::kernel::fs::vfs::Result<usize> {
if buf.len() % 4 != 0 {
if buf.len() % core::mem::size_of::<Event>() != 0 {
Err(FsError::InvalidParam)
} else {
Ok(self.buf.read_data(buf)?)
Expand Down Expand Up @@ -99,8 +188,16 @@ impl MouseState {
state.packet[idx] = data;
state.index = (state.index + 1) % 4;

if state.opened {
self.buf.try_append_data(&state.packet);
if state.index == 0 && state.opened {
if let Some(evt) = state.iter().next() {
unsafe {
let bytes: &[u8] = core::slice::from_raw_parts(
&evt as *const Event as *const u8,
core::mem::size_of::<Event>(),
);
self.buf.try_append_data(bytes);
}
}
}

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion cykusz-rs/src/drivers/tty/keymap.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::kernel::kbd::keys::KeyCode;
use syscall_defs::events::keys::KeyCode;

pub static PLAIN_MAP: [u16; 128] = [
0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037, 0xf038, 0xf039, 0xf030,
Expand Down
2 changes: 1 addition & 1 deletion cykusz-rs/src/drivers/tty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use core::fmt::Debug;
use core::fmt::{Error, Formatter};

use input::*;
use syscall_defs::events::keys::KeyCode;
use syscall_defs::ioctl::tty;
use syscall_defs::poll::PollEventFlags;
use syscall_defs::signal::{SIGHUP, SIGINT, SIGQUIT, SIGTSTP};
Expand All @@ -14,7 +15,6 @@ use crate::kernel::device::Device;
use crate::kernel::fs::inode::INode;
use crate::kernel::fs::poll::PollTable;
use crate::kernel::fs::vfs::FsError;
use crate::kernel::kbd::keys::KeyCode;
use crate::kernel::kbd::KeyListener;
use crate::kernel::mm::VirtAddr;
use crate::kernel::sched::current_task_ref;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use alloc::vec::Vec;

use crate::kernel::kbd::keys::KeyCode;
use crate::kernel::sync::RwSpin;

pub mod keys;
use syscall_defs::events::keys::KeyCode;

pub trait KeyListener: Sync {
fn on_new_key(&self, key: keys::KeyCode, released: bool);
fn on_new_key(&self, key: KeyCode, released: bool);
}

static LISTENERS: RwSpin<Vec<&'static dyn KeyListener>> = RwSpin::new(Vec::new());
Expand Down
17 changes: 17 additions & 0 deletions syscall-defs/src/events/buttons.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#[allow(non_camel_case_types, dead_code)]
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum ButtonCode {
BTN_MOUSE = 0x100,
BTN_LEFT = 0x110,
BTN_RIGHT = 0x111,
BTN_MIDDLE = 0x112,
BTN_SIDE = 0x113,
BTN_EXTRA = 0x114,
}

#[allow(non_camel_case_types, dead_code)]
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum RelCode {
REL_X = 0x00,
REL_Y = 0x01,
}
File renamed without changes.
7 changes: 7 additions & 0 deletions syscall-defs/src/events.rs → syscall-defs/src/events/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
use crate::time::Timeval;

pub mod keys;
pub mod buttons;

#[repr(u16)]
#[derive(Debug)]
pub enum EventType {
Key = 1,
Rel = 2,
}

#[repr(C)]
#[derive(Debug)]
pub struct Event {
pub timeval: Timeval,
pub typ: EventType,
pub code: u16,
pub val: i32,
Expand Down
16 changes: 16 additions & 0 deletions syscall-defs/src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,19 @@ impl Timespec {
self.nsecs == UTIME_OMIT
}
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Timeval {
pub secs: u64,
pub usecs: u64,
}

impl Timeval {
pub fn from_nsecs(nsecs: u64) -> Timeval {
Timeval {
secs: nsecs / 1000_000_000,
usecs: (nsecs / 1000) % 1000_000,
}
}
}

0 comments on commit e9e1057

Please sign in to comment.