Skip to content

Commit

Permalink
Keyboard Host Clean-up / Unmount Bug Fix (#1177)
Browse files Browse the repository at this point in the history
* Small bits of clean-up to keyboard host. Should guarantee dev addr, instance, protocol type, mount/unmounts, and update loops

* Bug!
  • Loading branch information
arntsonl authored Oct 9, 2024
1 parent 30b3bdf commit 5448ff4
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 52 deletions.
19 changes: 7 additions & 12 deletions headers/addons/keyboard_host_listener.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,10 @@ class KeyboardHostListener : public USBListener {
virtual void get_report_complete(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t report_type, uint16_t len) {}
void process();
private:
GamepadState _keyboard_host_state;
bool _keyboard_host_enabled;
uint8_t getKeycodeFromModifier(uint8_t modifier);
void preprocess_report();
void process_kbd_report(uint8_t dev_addr, hid_keyboard_report_t const *report);
void process_mouse_report(uint8_t dev_addr, hid_mouse_report_t const *report);

KeyboardButtonMapping _keyboard_host_mapDpadUp;
KeyboardButtonMapping _keyboard_host_mapDpadDown;
KeyboardButtonMapping _keyboard_host_mapDpadLeft;
Expand All @@ -62,22 +59,20 @@ class KeyboardHostListener : public USBListener {
KeyboardButtonMapping _keyboard_host_mapButtonA2;
KeyboardButtonMapping _keyboard_host_mapButtonA3;
KeyboardButtonMapping _keyboard_host_mapButtonA4;

GamepadState _keyboard_host_state;
bool _keyboard_host_mounted;
uint8_t _keyboard_dev_addr;
uint8_t _keyboard_instance;

bool _mouse_host_enabled;
bool _mouse_host_mounted;
uint8_t _mouse_dev_addr;
uint8_t _mouse_instance;

uint16_t mouseLeftMapping;
uint16_t mouseMiddleMapping;
uint16_t mouseRightMapping;

int16_t mouseX = 0;
int16_t mouseY = 0;
int16_t mouseZ = 0;
bool mouseActive = false;
int16_t mouseX;
int16_t mouseY;
int16_t mouseZ;
bool mouseActive;
};

#endif // _KeyboardHost_H_
80 changes: 40 additions & 40 deletions src/addons/keyboard_host_listener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "storagemanager.h"
#include "class/hid/hid_host.h"

#define DEV_ADDR_NONE 0xFF

void KeyboardHostListener::setup() {
const KeyboardHostOptions& keyboardHostOptions = Storage::getInstance().getAddonOptions().keyboardHostOptions;
const KeyboardMapping& keyboardMapping = keyboardHostOptions.mapping;
Expand Down Expand Up @@ -50,22 +52,23 @@ void KeyboardHostListener::setup() {
mouseMiddleMapping = keyboardHostOptions.mouseMiddle;
mouseRightMapping = keyboardHostOptions.mouseRight;

_keyboard_host_enabled = false;
_keyboard_dev_addr = 0;
_keyboard_host_mounted = false;
_keyboard_dev_addr = DEV_ADDR_NONE;
_keyboard_instance = 0;

_mouse_host_enabled = false;
_mouse_dev_addr = 0;
_mouse_host_mounted = false;
_mouse_dev_addr = DEV_ADDR_NONE;
_mouse_instance = 0;

mouseX = 0;
mouseY = 0;
mouseZ = 0;
mouseActive = false;
}

void KeyboardHostListener::process() {
Gamepad *gamepad = Storage::getInstance().GetGamepad();
if (_keyboard_host_enabled || _mouse_host_enabled) {
if (_keyboard_host_mounted == true || _mouse_host_mounted == true) {
gamepad->state.dpad |= _keyboard_host_state.dpad;
gamepad->state.buttons |= _keyboard_host_state.buttons;
gamepad->state.lx |= _keyboard_host_state.lx;
Expand All @@ -78,66 +81,60 @@ void KeyboardHostListener::process() {
}
}

gamepad->auxState.sensors.mouse.enabled = _mouse_host_enabled;
gamepad->auxState.sensors.mouse.active = mouseActive;
if (_mouse_host_enabled && mouseActive) {
gamepad->auxState.sensors.mouse.x = mouseX;
gamepad->auxState.sensors.mouse.y = mouseY;
gamepad->auxState.sensors.mouse.z = mouseZ;
if ( _mouse_host_mounted == true ) {
gamepad->auxState.sensors.mouse.active = mouseActive;
if ( mouseActive == true ) {
gamepad->auxState.sensors.mouse.active = true;
gamepad->auxState.sensors.mouse.x = mouseX;
gamepad->auxState.sensors.mouse.y = mouseY;
gamepad->auxState.sensors.mouse.z = mouseZ;
mouseActive = false;
}
}
mouseActive = false;
}

void KeyboardHostListener::mount(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) {
// Interface protocol (hid_interface_protocol_enum_t)
uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);

// tuh_hid_report_received_cb() will be invoked when report is available
if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD) {
if (_keyboard_host_mounted == false && itf_protocol == HID_ITF_PROTOCOL_KEYBOARD) {
_keyboard_host_mounted = true;
_keyboard_dev_addr = dev_addr;
_keyboard_instance = instance;
_keyboard_host_enabled = true;
} else if (itf_protocol == HID_ITF_PROTOCOL_MOUSE) {
} else if (_mouse_host_mounted == false && itf_protocol == HID_ITF_PROTOCOL_MOUSE) {
Gamepad *gamepad = Storage::getInstance().GetGamepad();
gamepad->auxState.sensors.mouse.enabled = true;
_mouse_host_mounted = true;
_mouse_dev_addr = dev_addr;
_mouse_instance = instance;
_mouse_host_enabled = true;
} else {
return;
}
}

void KeyboardHostListener::unmount(uint8_t dev_addr) {
if ( _keyboard_dev_addr == dev_addr ) {
_keyboard_host_enabled = false;
_keyboard_dev_addr = 0;
if ( _keyboard_host_mounted == true && _keyboard_dev_addr == dev_addr ) {
_keyboard_host_mounted = false;
_keyboard_dev_addr = DEV_ADDR_NONE;
_keyboard_instance = 0;
} else if ( _mouse_dev_addr == dev_addr ) {
_mouse_host_enabled = false;
_mouse_dev_addr = 0;
} else if ( _mouse_host_mounted == true && _mouse_dev_addr == dev_addr ) {
Gamepad *gamepad = Storage::getInstance().GetGamepad();
gamepad->auxState.sensors.mouse.enabled = false;
_mouse_host_mounted = false;
_mouse_dev_addr = DEV_ADDR_NONE;
_mouse_instance = 0;
}
}

void KeyboardHostListener::report_received(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len){
if (
( _keyboard_host_enabled == false || _keyboard_dev_addr != dev_addr || _keyboard_instance != instance )
&&
( _mouse_host_enabled == false || _mouse_dev_addr != dev_addr || _mouse_instance != instance )
)
return; // do nothing if we haven't mounted

// Interface protocol (hid_interface_protocol_enum_t)
uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);

preprocess_report();
// do nothing if we haven't mounted
if ( _keyboard_host_mounted == false && _mouse_host_mounted == false )
return;

// tuh_hid_report_received_cb() will be invoked when report is available
if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD) {
if ( _keyboard_host_mounted == true && _keyboard_dev_addr == dev_addr && _keyboard_instance == instance ) {
process_kbd_report(dev_addr, (hid_keyboard_report_t const*) report );
} else if (itf_protocol == HID_ITF_PROTOCOL_MOUSE) {
} else if ( _mouse_host_mounted == true && _mouse_dev_addr == dev_addr && _mouse_instance == instance) {
process_mouse_report(dev_addr, (hid_mouse_report_t const*) report );
} else {
return;
}
}

Expand Down Expand Up @@ -171,12 +168,13 @@ void KeyboardHostListener::preprocess_report()
_keyboard_host_state.ry = joystickMid;
_keyboard_host_state.lt = 0;
_keyboard_host_state.rt = 0;

}

// convert hid keycode to ascii and print via usb device CDC (ignore non-printable)
void KeyboardHostListener::process_kbd_report(uint8_t dev_addr, hid_keyboard_report_t const *report)
{
preprocess_report();

// make this 13 instead of 7 to include modifier bitfields from hid_keyboard_modifier_bm_t
for(uint8_t i=0; i<13; i++)
{
Expand Down Expand Up @@ -223,6 +221,8 @@ void KeyboardHostListener::process_kbd_report(uint8_t dev_addr, hid_keyboard_rep

void KeyboardHostListener::process_mouse_report(uint8_t dev_addr, hid_mouse_report_t const * report)
{
preprocess_report();

//------------- button state -------------//
_keyboard_host_state.buttons |=
(report->buttons & MOUSE_BUTTON_LEFT ? mouseLeftMapping : _keyboard_host_state.buttons)
Expand Down

0 comments on commit 5448ff4

Please sign in to comment.