-
-
Notifications
You must be signed in to change notification settings - Fork 150
Description
Now there are a few modes for working with the trackball
I only use scroll mode, but there is also a high-precision mode, etc.
I searched through the source code and pool requests, and I liked the idea of an abstract PointingProcessor from PMW3360 and PMW3389 input devices
It seemed to me a good idea to make such modes options of the contact Pointing device, and not a specific implementation, since the algorithms are most likely universal for all devices, at least software implementations
I made one for myself
struct ScrollConfig {
delta_per_tick: u8,
}
impl Default for ScrollConfig {
fn default() -> Self {
Self { delta_per_tick: 25 }
}
}
struct MotionAccumulator {
acc_x: i32,
acc_y: i32,
}
impl MotionAccumulator {
const fn new() -> Self {
Self { acc_x: 0, acc_y: 0 }
}
fn process(&mut self, dx: i16, dy: i16, divisor: u8) -> (i16, i16) {
self.acc_x += dx as i32;
self.acc_y += dy as i32;
let out_x = (self.acc_x / divisor as i32) as i16;
let out_y = (self.acc_y / divisor as i32) as i16;
self.acc_x -= out_x as i32 * divisor as i32;
self.acc_y -= out_y as i32 * divisor as i32;
(out_x, out_y)
}
fn reset(&mut self) {
self.acc_x = 0;
self.acc_y = 0;
}
}
enum PointingMode {
Cursor,
Scroll {
config: ScrollConfig,
accumulator: MotionAccumulator,
},
}
impl PointingMode {
fn generate_report(&mut self, x: i16, y: i16) -> MouseReport {
match self {
Self::Cursor => MouseReport {
buttons: 0,
x: x.clamp(i8::MIN as i16, i8::MAX as i16) as i8,
y: y.clamp(i8::MIN as i16, i8::MAX as i16) as i8,
wheel: 0,
pan: 0,
},
Self::Scroll { config, accumulator } => {
let (pan, wheel) = accumulator.process(x, y, config.delta_per_tick);
MouseReport {
buttons: 0,
x: 0,
y: 0,
wheel: wheel.clamp(i8::MIN as i16, i8::MAX as i16) as i8,
pan: pan.clamp(i8::MIN as i16, i8::MAX as i16) as i8,
}
}
}
}
}But I haven't figured out how to push values from configs here, so I've hardcoded them at the initialization stage so far.
Next I found ScrollWheelProcessor in Add config for input devices
so far, I don't understand how this will work, with the current settings
in the presence of processor_chain, the current code will be ignored, for example in Pmw3610Processor::process? Since it also processes the delta arrival event and moves the cursor.
or you will also have to add scroll_mode: bool to Pmw3610Processor so that the main and auxiliary processors do not work together. But then there will be a strong connectivity of components, which doesn't look very good.
In general, I have some doubts about how this will work, which I decided to share with you.