spectrusty_peripherals/
mouse.rs

1/*
2    Copyright (C) 2020-2022  Rafal Michalski
3
4    This file is part of SPECTRUSTY, a Rust library for building emulators.
5
6    For the full copyright notice, see the lib.rs file.
7*/
8//! A pointing device / mouse communication interface and emulators of mouse devices.
9use core::fmt::Debug;
10
11pub mod kempston;
12
13bitflags! {
14    /// Flags for mouse buttons.
15    /// * Bit = 1 button is pressed.
16    /// * Bit = 0 button is released.
17    #[derive(Default)]
18    pub struct MouseButtons: u8 {
19        const LEFT    = 0b0000_0001;
20        const RIGHT   = 0b0000_0010;
21        const MIDDLE  = 0b0000_0100;
22        const FOURTH  = 0b0001_0000;
23        const FIFTH   = 0b0010_0000;
24        const SIXTH   = 0b0100_0000;
25        const SEVENTH = 0b1000_0000;
26    }
27}
28
29/// This type is being used to provide input data for the mouse emulator.
30///
31/// The pointing device coordinates are measured in PAL pixels (704x576 including border).
32/// * Horizontal values increase from left to right.
33/// * Vertical values increase from top to bottom.
34#[derive(Clone, Copy, Default, Debug)]
35pub struct MouseMovement {
36    pub horizontal: i16,
37    pub vertical: i16
38}
39
40/// An interface for providing user input data for a [MouseDevice] implementation.
41pub trait MouseInterface {
42    /// Sets the state of all mouse buttons.
43    fn set_buttons(&mut self, buttons: MouseButtons);
44    /// Returns a state of all mouse buttons.
45    fn get_buttons(&self) -> MouseButtons;
46    /// Moves the mouse by the given interval.
47    fn move_mouse(&mut self, mov: MouseMovement);
48}
49
50/// A mouse device interface for the mouse [bus][crate::bus::mouse] device implementations.
51pub trait MouseDevice: Debug {
52    /// Should return a current mouse state. The `port` argument can be used to decide which
53    /// information will be returned - one of the axes or a button state.
54    fn port_read(&self, port: u16) -> u8;
55    /// Writes data to a mouse device.
56    ///
57    /// If a device does not support writes, this method should return `false`.
58    /// The default implementation does exactly just that.
59    fn port_write(&mut self, _port: u16, _data: u8) -> bool { false }
60}
61
62/// The mouse device that can be used as a placeholder type.
63#[derive(Clone, Copy, Default, Debug)]
64pub struct NullMouseDevice;
65
66impl From<(i16, i16)> for MouseMovement {
67    fn from((x, y): (i16, i16)) -> Self {
68        MouseMovement {
69            horizontal: x,
70            vertical: y
71        }
72    }
73}
74
75impl From<[i16;2]> for MouseMovement {
76    fn from([x, y]: [i16;2]) -> Self {
77        (x, y).into()
78    }
79}
80
81impl MouseInterface for NullMouseDevice {
82    fn set_buttons(&mut self, _buttons: MouseButtons) {}
83    fn get_buttons(&self) -> MouseButtons {
84        MouseButtons::empty()
85    }
86    fn move_mouse(&mut self, _mov: MouseMovement) {}
87}
88
89impl MouseDevice for NullMouseDevice {
90    fn port_read(&self, _port: u16) -> u8 {
91        u8::max_value()
92    }   
93}