From 5448ff4fc5af029fba6badce59ffaa025927a799 Mon Sep 17 00:00:00 2001 From: Luke A Date: Wed, 9 Oct 2024 12:58:21 -0400 Subject: [PATCH] Keyboard Host Clean-up / Unmount Bug Fix (#1177) * Small bits of clean-up to keyboard host. Should guarantee dev addr, instance, protocol type, mount/unmounts, and update loops * Bug! --- headers/addons/keyboard_host_listener.h | 19 +++--- src/addons/keyboard_host_listener.cpp | 80 ++++++++++++------------- 2 files changed, 47 insertions(+), 52 deletions(-) diff --git a/headers/addons/keyboard_host_listener.h b/headers/addons/keyboard_host_listener.h index 769d9cca2..c41c6c2f7 100644 --- a/headers/addons/keyboard_host_listener.h +++ b/headers/addons/keyboard_host_listener.h @@ -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; @@ -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_ \ No newline at end of file diff --git a/src/addons/keyboard_host_listener.cpp b/src/addons/keyboard_host_listener.cpp index 4734c48a4..4974e581e 100644 --- a/src/addons/keyboard_host_listener.cpp +++ b/src/addons/keyboard_host_listener.cpp @@ -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; @@ -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; @@ -78,14 +81,16 @@ 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) { @@ -93,51 +98,43 @@ void KeyboardHostListener::mount(uint8_t dev_addr, uint8_t instance, uint8_t con 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; } } @@ -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++) { @@ -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)