1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-02-26 08:29:33 +00:00

Attempts to implement absolute mouse positioning mode.

Along with mouse direction.
This commit is contained in:
Thomas Harte 2020-01-01 12:29:33 -05:00
parent 5ce8d7c0e5
commit 90b899c00e
2 changed files with 63 additions and 32 deletions

View File

@ -8,6 +8,8 @@
#include "IntelligentKeyboard.hpp"
#include <algorithm>
#define LOG_PREFIX "[IKYB] "
#include "../../../Outputs/Log.hpp"
@ -22,6 +24,7 @@ IntelligentKeyboard::IntelligentKeyboard(Serial::Line &input, Serial::Line &outp
joysticks_.emplace_back(new Joystick);
mouse_button_state_ = 0;
mouse_button_events_ = 0;
mouse_movement_[0] = 0;
mouse_movement_[1] = 0;
}
@ -49,20 +52,34 @@ ClockingHint::Preference IntelligentKeyboard::preferred_clocking() {
void IntelligentKeyboard::run_for(HalfCycles duration) {
// Take this opportunity to check for joystick, mouse and keyboard events,
// which will have been received asynchronously.
if(mouse_mode_ == MouseMode::Relative) {
const int captured_movement[2] = { mouse_movement_[0].load(), mouse_movement_[1].load() };
const int captured_button_state = mouse_button_state_;
if(
(posted_button_state_ != captured_button_state) ||
(abs(captured_movement[0]) >= mouse_threshold_[0]) ||
(abs(captured_movement[1]) >= mouse_threshold_[1]) ) {
mouse_movement_[0] -= captured_movement[0];
mouse_movement_[1] -= captured_movement[1];
const int captured_movement[2] = { mouse_movement_[0].load(), mouse_movement_[1].load() };
switch(mouse_mode_) {
case MouseMode::Relative: {
const int captured_button_state = mouse_button_state_;
if(
(posted_button_state_ != captured_button_state) ||
(abs(captured_movement[0]) >= mouse_threshold_[0]) ||
(abs(captured_movement[1]) >= mouse_threshold_[1]) ) {
mouse_movement_[0] -= captured_movement[0];
mouse_movement_[1] -= mouse_y_multiplier_ * captured_movement[1];
post_relative_mouse_event(captured_movement[0], captured_movement[1]);
}
} else {
// TODO: absolute-mode mouse updates.
post_relative_mouse_event(captured_movement[0], captured_movement[1]);
}
} break;
case MouseMode::Absolute: {
const int scaled_movement[2] = { captured_movement[0] / mouse_scale_[0], captured_movement[1] / mouse_scale_[1] };
mouse_position_[0] += scaled_movement[0];
mouse_position_[1] += mouse_y_multiplier_ * scaled_movement[1];
mouse_movement_[0] -= scaled_movement[0] * mouse_scale_[0];
mouse_movement_[1] -= scaled_movement[1] * mouse_scale_[1];
} break;
case MouseMode::Disabled:
mouse_movement_[0] = 0;
mouse_movement_[1] = 0;
break;
}
// Forward key changes; implicit assumption here: mutexs are cheap while there's
@ -219,19 +236,22 @@ void IntelligentKeyboard::pause() {
}
void IntelligentKeyboard::disable_mouse() {
LOG("Unimplemented: disable mouse");
mouse_mode_ = MouseMode::Disabled;
}
void IntelligentKeyboard::set_relative_mouse_position_reporting() {
LOG("Unimplemented: set relative mouse position reporting");
mouse_mode_ = MouseMode::Relative;
}
void IntelligentKeyboard::set_absolute_mouse_position_reporting(uint16_t max_x, uint16_t max_y) {
LOG("Unimplemented: set absolute mouse position reporting");
mouse_mode_ = MouseMode::Absolute;
mouse_range_[0] = int(max_x);
mouse_range_[1] = int(max_y);
}
void IntelligentKeyboard::set_mouse_position(uint16_t x, uint16_t y) {
LOG("Unimplemented: set mouse position");
mouse_position_[0] = std::min(int(x), mouse_range_[0]);
mouse_position_[1] = std::min(int(y), mouse_range_[1]);
}
void IntelligentKeyboard::set_mouse_keycode_reporting(uint8_t delta_x, uint8_t delta_y) {
@ -239,19 +259,21 @@ void IntelligentKeyboard::set_mouse_keycode_reporting(uint8_t delta_x, uint8_t d
}
void IntelligentKeyboard::set_mouse_threshold(uint8_t x, uint8_t y) {
LOG("Unimplemented: set mouse threshold");
mouse_threshold_[0] = x;
mouse_threshold_[1] = y;
}
void IntelligentKeyboard::set_mouse_scale(uint8_t x, uint8_t y) {
LOG("Unimplemented: set mouse scale");
mouse_scale_[0] = x;
mouse_scale_[1] = y;
}
void IntelligentKeyboard::set_mouse_y_downward() {
LOG("Unimplemented: set mouse y downward");
mouse_y_multiplier_ = 1;
}
void IntelligentKeyboard::set_mouse_y_upward() {
LOG("Unimplemented: set mouse y upward");
mouse_y_multiplier_ = -1;
}
void IntelligentKeyboard::set_mouse_button_actions(uint8_t actions) {
@ -259,14 +281,15 @@ void IntelligentKeyboard::set_mouse_button_actions(uint8_t actions) {
}
void IntelligentKeyboard::interrogate_mouse_position() {
LOG("Unimplemented: interrogate mouse position");
const int captured_mouse_button_events_ = mouse_button_events_;
mouse_button_events_ &= ~captured_mouse_button_events_;
output_bytes({
0xf7, // Beginning of mouse response.
0x00, // 0000dcba; a = right button down since last interrogation, b = right button up since, c/d = left button.
0x00, // x motion: MSB, LSB
0x00,
0x00, // y motion: MSB, LSB
0x00
0xf7, // Beginning of mouse response.
uint8_t(captured_mouse_button_events_), // 0000dcba; a = right button down since last interrogation, b = right button up since, c/d = left button.
uint8_t(mouse_position_[0] >> 8), // x position: MSB, LSB
uint8_t(mouse_position_[0] & 0xff),
uint8_t(mouse_position_[1] >> 8), // y position: MSB, LSB
uint8_t(mouse_position_[1] & 0xff)
});
}
@ -374,11 +397,16 @@ int IntelligentKeyboard::get_number_of_buttons() {
}
void IntelligentKeyboard::set_button_pressed(int index, bool is_pressed) {
const auto mask = 1 << (index ^ 1); // The primary button is b1; the secondary is b0.
index ^= 1; // The primary button is b1; the secondary is b0.
const auto mask = 1 << index;
const auto event_mask = 1 << (index << 1);
if(is_pressed) {
mouse_button_state_ |= mask;
mouse_button_events_ |= event_mask;
} else {
mouse_button_state_ &= ~mask;
mouse_button_events_ |= event_mask << 1;
}
}

View File

@ -110,12 +110,14 @@ class IntelligentKeyboard:
void reset_all_buttons() final;
enum class MouseMode {
Relative, Absolute
Relative, Absolute, Disabled
} mouse_mode_ = MouseMode::Relative;
// Absolute positioning state.
int mouse_range_[2] = {0, 0};
int mouse_scale_[2] = {0, 0};
int mouse_range_[2] = {320, 200};
int mouse_scale_[2] = {1, 1};
int mouse_position_[2] = {0, 0};
int mouse_y_multiplier_ = 1;
// Relative positioning state.
int posted_button_state_ = 0;
@ -125,6 +127,7 @@ class IntelligentKeyboard:
// Received mouse state.
std::atomic<int> mouse_movement_[2];
std::atomic<int> mouse_button_state_;
std::atomic<int> mouse_button_events_;
// MARK: - Joystick.
void disable_joysticks();