diff --git a/src/input/common.cpp b/src/input/common.cpp index 2cb00413bda..261b486fb90 100644 --- a/src/input/common.cpp +++ b/src/input/common.cpp @@ -2,10 +2,10 @@ * @file src/input/common.cpp * @brief Definitions for common input. */ -#include "common.h" -#include "init.h" +#include "src/input/common.h" +#include "src/input/gamepad.h" +#include "src/input/init.h" -#include "gamepad.h" #include "src/thread_pool.h" #include diff --git a/src/input/common.h b/src/input/common.h index 86988f5004b..4d4895f6630 100644 --- a/src/input/common.h +++ b/src/input/common.h @@ -16,7 +16,7 @@ extern "C" { #include "src/platform/common.h" #include "src/thread_pool.h" -#include "gamepad.h" +#include "src/input/gamepad.h" namespace input { diff --git a/src/input/gamepad.cpp b/src/input/gamepad.cpp index 00929368e8e..875fd5eaa78 100644 --- a/src/input/gamepad.cpp +++ b/src/input/gamepad.cpp @@ -2,11 +2,11 @@ * @file src/input/gamepad.cpp * @brief Definitions for common gamepad input. */ -#include "gamepad.h" -#include "common.h" -#include "init.h" -#include "platform_input.h" -#include "processor.h" +#include "src/input/gamepad.h" +#include "src/input/common.h" +#include "src/input/init.h" +#include "src/input/platform_input.h" +#include "src/input/processor.h" #include "src/globals.h" #include "src/thread_pool.h" diff --git a/src/input/gamepad.h b/src/input/gamepad.h index e00c8607920..1a6afacb698 100644 --- a/src/input/gamepad.h +++ b/src/input/gamepad.h @@ -18,7 +18,7 @@ extern "C" { #include "src/platform/common.h" #include "src/thread_pool.h" -#include "init.h" +#include "src/input/init.h" namespace input::gamepad { static std::bitset gamepadMask = {}; diff --git a/src/input/keyboard.cpp b/src/input/keyboard.cpp index 7993a432c59..26c223735cc 100644 --- a/src/input/keyboard.cpp +++ b/src/input/keyboard.cpp @@ -2,11 +2,10 @@ * @file src/input/keyboard.cpp * @brief Definitions for common keyboard input. */ -#include "keyboard.h" -#include "init.h" - -#include "platform_input.h" -#include "processor.h" +#include "src/input/keyboard.h" +#include "src/input/init.h" +#include "src/input/platform_input.h" +#include "src/input/processor.h" namespace input::keyboard { @@ -23,176 +22,178 @@ namespace input::keyboard { static task_pool_util::TaskPool::task_id_t key_press_repeat_id {}; static std::unordered_map key_press {}; - key_press_id_t - make_kpid(uint16_t vk, uint8_t flags) { - return (key_press_id_t) vk << 8 | flags; - } + namespace { + key_press_id_t + make_kpid(uint16_t vk, uint8_t flags) { + return (key_press_id_t) vk << 8 | flags; + } - uint16_t - vk_from_kpid(key_press_id_t kpid) { - return kpid >> 8; - } + uint16_t + vk_from_kpid(key_press_id_t kpid) { + return kpid >> 8; + } - uint8_t - flags_from_kpid(key_press_id_t kpid) { - return kpid & 0xFF; - } + uint8_t + flags_from_kpid(key_press_id_t kpid) { + return kpid & 0xFF; + } - void - print(PNV_KEYBOARD_PACKET packet) { - BOOST_LOG(debug) - << "--begin keyboard packet--"sv << std::endl - << "keyAction ["sv << util::hex(packet->header.magic).to_string_view() << ']' << std::endl - << "keyCode ["sv << util::hex(packet->keyCode).to_string_view() << ']' << std::endl - << "modifiers ["sv << util::hex(packet->modifiers).to_string_view() << ']' << std::endl - << "flags ["sv << util::hex(packet->flags).to_string_view() << ']' << std::endl - << "--end keyboard packet--"sv; - } + /** + * @brief Apply shortcut based on VKEY. + * @param keyCode The VKEY code. + * @return 0 if no shortcut applied, > 0 if shortcut applied. + */ + int + apply_shortcut(short keyCode) { + constexpr auto VK_F1 = 0x70; + constexpr auto VK_F13 = 0x7C; - void - print(PNV_UNICODE_PACKET packet) { - std::string text(packet->text, util::endian::big(packet->header.size) - sizeof(packet->header.magic)); - BOOST_LOG(debug) - << "--begin unicode packet--"sv << std::endl - << "text ["sv << text << ']' << std::endl - << "--end unicode packet--"sv; - } + BOOST_LOG(debug) << "Apply Shortcut: 0x"sv << util::hex((std::uint8_t) keyCode).to_string_view(); - /** - * @brief Apply shortcut based on VKEY. - * @param keyCode The VKEY code. - * @return 0 if no shortcut applied, > 0 if shortcut applied. - */ - inline int - apply_shortcut(short keyCode) { - constexpr auto VK_F1 = 0x70; - constexpr auto VK_F13 = 0x7C; - - BOOST_LOG(debug) << "Apply Shortcut: 0x"sv << util::hex((std::uint8_t) keyCode).to_string_view(); - - if (keyCode >= VK_F1 && keyCode <= VK_F13) { - mail::man->event(mail::switch_display)->raise(keyCode - VK_F1); - return 1; - } - - switch (keyCode) { - case 0x4E /* VKEY_N */: - display_cursor = !display_cursor; + if (keyCode >= VK_F1 && keyCode <= VK_F13) { + mail::man->event(mail::switch_display)->raise(keyCode - VK_F1); return 1; + } + + switch (keyCode) { + case 0x4E /* VKEY_N */: + display_cursor = !display_cursor; + return 1; + } + + return 0; } - return 0; - } + short + map_keycode(short keycode) { + auto it = config::input.keybindings.find(keycode); + if (it != std::end(config::input.keybindings)) { + return it->second; + } - short - map_keycode(short keycode) { - auto it = config::input.keybindings.find(keycode); - if (it != std::end(config::input.keybindings)) { - return it->second; + return keycode; } - return keycode; - } + /** + * @brief Update flags for keyboard shortcut combos + */ + void + update_shortcutFlags(int *flags, short keyCode, bool release) { + switch (keyCode) { + case VKEY_SHIFT: + case VKEY_LSHIFT: + case VKEY_RSHIFT: + if (release) { + *flags &= ~input_t::SHIFT; + } + else { + *flags |= input_t::SHIFT; + } + break; + case VKEY_CONTROL: + case VKEY_LCONTROL: + case VKEY_RCONTROL: + if (release) { + *flags &= ~input_t::CTRL; + } + else { + *flags |= input_t::CTRL; + } + break; + case VKEY_MENU: + case VKEY_LMENU: + case VKEY_RMENU: + if (release) { + *flags &= ~input_t::ALT; + } + else { + *flags |= input_t::ALT; + } + break; + } + } + + bool + is_modifier(uint16_t keyCode) { + switch (keyCode) { + case VKEY_SHIFT: + case VKEY_LSHIFT: + case VKEY_RSHIFT: + case VKEY_CONTROL: + case VKEY_LCONTROL: + case VKEY_RCONTROL: + case VKEY_MENU: + case VKEY_LMENU: + case VKEY_RMENU: + return true; + default: + return false; + } + } - /** - * @brief Update flags for keyboard shortcut combos - */ - inline void - update_shortcutFlags(int *flags, short keyCode, bool release) { - switch (keyCode) { - case VKEY_SHIFT: - case VKEY_LSHIFT: - case VKEY_RSHIFT: - if (release) { - *flags &= ~input_t::SHIFT; + void + send_key_and_modifiers(uint16_t key_code, bool release, uint8_t flags, uint8_t synthetic_modifiers) { + if (!release) { + // Press any synthetic modifiers required for this key + if (synthetic_modifiers & MODIFIER_SHIFT) { + platf::keyboard_update(PlatformInput::getInstance(), VKEY_SHIFT, false, flags); } - else { - *flags |= input_t::SHIFT; + if (synthetic_modifiers & MODIFIER_CTRL) { + platf::keyboard_update(PlatformInput::getInstance(), VKEY_CONTROL, false, flags); } - break; - case VKEY_CONTROL: - case VKEY_LCONTROL: - case VKEY_RCONTROL: - if (release) { - *flags &= ~input_t::CTRL; + if (synthetic_modifiers & MODIFIER_ALT) { + platf::keyboard_update(PlatformInput::getInstance(), VKEY_MENU, false, flags); } - else { - *flags |= input_t::CTRL; + } + + platf::keyboard_update(PlatformInput::getInstance(), map_keycode(key_code), release, flags); + + if (!release) { + // Raise any synthetic modifier keys we pressed + if (synthetic_modifiers & MODIFIER_SHIFT) { + platf::keyboard_update(PlatformInput::getInstance(), VKEY_SHIFT, true, flags); } - break; - case VKEY_MENU: - case VKEY_LMENU: - case VKEY_RMENU: - if (release) { - *flags &= ~input_t::ALT; + if (synthetic_modifiers & MODIFIER_CTRL) { + platf::keyboard_update(PlatformInput::getInstance(), VKEY_CONTROL, true, flags); } - else { - *flags |= input_t::ALT; + if (synthetic_modifiers & MODIFIER_ALT) { + platf::keyboard_update(PlatformInput::getInstance(), VKEY_MENU, true, flags); } - break; - } - } - - bool - is_modifier(uint16_t keyCode) { - switch (keyCode) { - case VKEY_SHIFT: - case VKEY_LSHIFT: - case VKEY_RSHIFT: - case VKEY_CONTROL: - case VKEY_LCONTROL: - case VKEY_RCONTROL: - case VKEY_MENU: - case VKEY_LMENU: - case VKEY_RMENU: - return true; - default: - return false; + } } - } - void - send_key_and_modifiers(uint16_t key_code, bool release, uint8_t flags, uint8_t synthetic_modifiers) { - if (!release) { - // Press any synthetic modifiers required for this key - if (synthetic_modifiers & MODIFIER_SHIFT) { - platf::keyboard_update(PlatformInput::getInstance(), VKEY_SHIFT, false, flags); - } - if (synthetic_modifiers & MODIFIER_CTRL) { - platf::keyboard_update(PlatformInput::getInstance(), VKEY_CONTROL, false, flags); - } - if (synthetic_modifiers & MODIFIER_ALT) { - platf::keyboard_update(PlatformInput::getInstance(), VKEY_MENU, false, flags); + void + repeat_key(uint16_t key_code, uint8_t flags, uint8_t synthetic_modifiers) { + // If key no longer pressed, stop repeating + if (!key_press[make_kpid(key_code, flags)]) { + key_press_repeat_id = nullptr; + return; } - } - platf::keyboard_update(PlatformInput::getInstance(), map_keycode(key_code), release, flags); + send_key_and_modifiers(key_code, false, flags, synthetic_modifiers); - if (!release) { - // Raise any synthetic modifier keys we pressed - if (synthetic_modifiers & MODIFIER_SHIFT) { - platf::keyboard_update(PlatformInput::getInstance(), VKEY_SHIFT, true, flags); - } - if (synthetic_modifiers & MODIFIER_CTRL) { - platf::keyboard_update(PlatformInput::getInstance(), VKEY_CONTROL, true, flags); - } - if (synthetic_modifiers & MODIFIER_ALT) { - platf::keyboard_update(PlatformInput::getInstance(), VKEY_MENU, true, flags); - } + key_press_repeat_id = task_pool.pushDelayed(repeat_key, config::input.key_repeat_period, key_code, flags, synthetic_modifiers).task_id; } - } + } // namespace void - repeat_key(uint16_t key_code, uint8_t flags, uint8_t synthetic_modifiers) { - // If key no longer pressed, stop repeating - if (!key_press[make_kpid(key_code, flags)]) { - key_press_repeat_id = nullptr; - return; - } - - send_key_and_modifiers(key_code, false, flags, synthetic_modifiers); + print(PNV_KEYBOARD_PACKET packet) { + BOOST_LOG(debug) + << "--begin keyboard packet--"sv << std::endl + << "keyAction ["sv << util::hex(packet->header.magic).to_string_view() << ']' << std::endl + << "keyCode ["sv << util::hex(packet->keyCode).to_string_view() << ']' << std::endl + << "modifiers ["sv << util::hex(packet->modifiers).to_string_view() << ']' << std::endl + << "flags ["sv << util::hex(packet->flags).to_string_view() << ']' << std::endl + << "--end keyboard packet--"sv; + } - key_press_repeat_id = task_pool.pushDelayed(repeat_key, config::input.key_repeat_period, key_code, flags, synthetic_modifiers).task_id; + void + print(PNV_UNICODE_PACKET packet) { + std::string text(packet->text, util::endian::big(packet->header.size) - sizeof(packet->header.magic)); + BOOST_LOG(debug) + << "--begin unicode packet--"sv << std::endl + << "text ["sv << text << ']' << std::endl + << "--end unicode packet--"sv; } void diff --git a/src/input/keyboard.h b/src/input/keyboard.h index 10263b589b0..a79dd54ba05 100644 --- a/src/input/keyboard.h +++ b/src/input/keyboard.h @@ -12,28 +12,52 @@ extern "C" { #include -#include "common.h" +#include "src/input/common.h" #include "src/platform/common.h" #include "src/thread_safe.h" namespace input::keyboard { typedef uint32_t key_press_id_t; + /** + * @brief Prints a keyboard event packet. + * @param packet The keyboard event packet. + */ void print(PNV_KEYBOARD_PACKET packet); + /** + * @brief Prints a unicode text packet. + * @param packet The unicode text packet. + */ void print(PNV_UNICODE_PACKET packet); + /** + * @brief Called to pass a keyboard event to the platform backend. + * @param input The input context pointer. + * @param packet The keyboard event packet. + */ void passthrough(std::shared_ptr &input, PNV_KEYBOARD_PACKET packet); + /** + * @brief Called to pass a unicode text message to the platform backend. + * @param packet The unicode text packet. + */ void passthrough(PNV_UNICODE_PACKET packet); + /** + * @brief Resets the overall state of a keyboard in the platform backend. + * @param platf_input The input context reference. + */ void reset(platf::input_t &platf_input); + /** + * @brief Cancel pending key presses in the platform backend task pool. + */ void cancel(); } // namespace input::keyboard diff --git a/src/input/mouse.cpp b/src/input/mouse.cpp index bde7067361b..5ce9d429356 100644 --- a/src/input/mouse.cpp +++ b/src/input/mouse.cpp @@ -4,10 +4,10 @@ */ #include "mouse.h" -#include "init.h" -#include "platform_input.h" -#include "processor.h" -#include "touch.h" +#include "src/input/init.h" +#include "src/input/platform_input.h" +#include "src/input/processor.h" +#include "src/input/touch.h" namespace input::mouse { diff --git a/src/input/mouse.h b/src/input/mouse.h index 8e531c934e6..500dbd37528 100644 --- a/src/input/mouse.h +++ b/src/input/mouse.h @@ -12,7 +12,7 @@ extern "C" { #include -#include "common.h" +#include "src/input/common.h" #include "src/platform/common.h" #include "src/thread_safe.h" @@ -22,27 +22,62 @@ namespace input::mouse { #define WHEEL_DELTA 120 #endif + /** + * @brief Prints a relative mouse movement event (x, y) packet. + * @param packet The move packet. + */ void print(PNV_REL_MOUSE_MOVE_PACKET packet); + /** + * @brief Prints an absolute mouse movement event (x, y) packet. + * @param packet The move packet. + */ void print(PNV_ABS_MOUSE_MOVE_PACKET packet); + /** + * @brief Prints a mouse button event packet. + * @param packet The button packet. + */ void print(PNV_MOUSE_BUTTON_PACKET packet); + /** + * @brief Prints a vertical mouse scroll event packet. + * @param packet The scroll packet. + */ void print(PNV_SCROLL_PACKET packet); + /** + * @brief Prints a horizontal mouse scroll event packet. + * @param packet The scroll packet. + */ void print(PSS_HSCROLL_PACKET packet); + /** + * @brief Called to pass a relative mouse movement event (dx, dy) to the platform backend. + * @param input The input context pointer. + * @param packet The move event packet. + */ void passthrough(const std::shared_ptr &input, PNV_REL_MOUSE_MOVE_PACKET packet); + /** + * @brief Called to pass an absolute mouse movement event (x, y) to the platform backend. + * @param input The input context pointer. + * @param packet The move event packet. + */ void passthrough(std::shared_ptr &input, PNV_ABS_MOUSE_MOVE_PACKET packet); + /** + * @brief Called to pass a button event message to the platform backend. + * @param input The input context pointer. + * @param packet The button event packet. + */ void passthrough(std::shared_ptr &input, PNV_MOUSE_BUTTON_PACKET packet); @@ -98,6 +133,10 @@ namespace input::mouse { batch_result_e batch(PSS_HSCROLL_PACKET dest, PSS_HSCROLL_PACKET src); + /** + * @brief Resets the overall state of a mouse in the platform backend. + * @param platf_input The input context reference. + */ void reset(platf::input_t &platf_input); @@ -108,6 +147,9 @@ namespace input::mouse { void force_frame_move(platf::input_t &platf_input); + /** + * @brief Cancel pending mouse events in the platform backend task pool. + */ void cancel(const std::shared_ptr &input); } // namespace input::mouse diff --git a/src/input/pen.cpp b/src/input/pen.cpp index ca4efc4375d..e5b15fbe51b 100644 --- a/src/input/pen.cpp +++ b/src/input/pen.cpp @@ -22,11 +22,11 @@ extern "C" { #include "src/thread_pool.h" #include "src/utility.h" -#include "common.h" -#include "init.h" -#include "pen.h" -#include "processor.h" -#include "touch.h" +#include "src/input/common.h" +#include "src/input/init.h" +#include "src/input/pen.h" +#include "src/input/processor.h" +#include "src/input/touch.h" #include using namespace std::literals; diff --git a/src/input/pen.h b/src/input/pen.h index 7506a5b04a9..5bc9928d4d2 100644 --- a/src/input/pen.h +++ b/src/input/pen.h @@ -12,7 +12,7 @@ extern "C" { #include -#include "common.h" +#include "src/input/common.h" #include "src/platform/common.h" #include "src/thread_safe.h" diff --git a/src/input/platform_input.cpp b/src/input/platform_input.cpp index da4923bb174..5a679817706 100644 --- a/src/input/platform_input.cpp +++ b/src/input/platform_input.cpp @@ -2,7 +2,7 @@ * @file src/input/platform_input.cpp * @brief Definitions for common platform input. */ -#include "platform_input.h" +#include "src/input/platform_input.h" platf::input_t PlatformInput::_instance; diff --git a/src/input/platform_input.h b/src/input/platform_input.h index 00c11be237a..317d43769ff 100644 --- a/src/input/platform_input.h +++ b/src/input/platform_input.h @@ -1,11 +1,20 @@ /** * @file src/input/platform_input.h - * @brief Declarations for common platform input. + * @brief Declarations for common platform input singleton. */ #pragma once #include "src/platform/common.h" +/** + * Singleton class to hold a reference to the platform input. + * + * We used to have a single global instance of the platform input, declared in the input namespace, + * but this caused issues with static initialization, while using it from many namespaces, + * so we moved it to it's own singleton class. + * + * @todo Improve the whole input layer so we can easily initialize via a factory, DI, whatever and remove this. + */ class PlatformInput { public: static platf::input_t _instance; diff --git a/src/input/processor.cpp b/src/input/processor.cpp index 829268e46f6..72475487f59 100644 --- a/src/input/processor.cpp +++ b/src/input/processor.cpp @@ -19,14 +19,14 @@ extern "C" { #include #include -#include "common.h" -#include "gamepad.h" -#include "init.h" -#include "keyboard.h" -#include "mouse.h" -#include "pen.h" -#include "processor.h" -#include "touch.h" +#include "src/input/common.h" +#include "src/input/gamepad.h" +#include "src/input/init.h" +#include "src/input/keyboard.h" +#include "src/input/mouse.h" +#include "src/input/pen.h" +#include "src/input/processor.h" +#include "src/input/touch.h" #include "src/config.h" #include "src/globals.h" @@ -41,6 +41,147 @@ using namespace std::literals; namespace input { + namespace { + /** + * @brief Batch two input messages. + * @param dest The original packet to batch into. + * @param src A later packet to attempt to batch. + * @return The status of the batching operation. + */ + batch_result_e + batch(PNV_INPUT_HEADER dest, PNV_INPUT_HEADER src) { + // We can only batch if the packet types are the same + if (dest->magic != src->magic) { + return batch_result_e::terminate_batch; + } + + // We can only batch certain message types + switch (util::endian::little(dest->magic)) { + case MOUSE_MOVE_REL_MAGIC_GEN5: + return mouse::batch((PNV_REL_MOUSE_MOVE_PACKET) dest, (PNV_REL_MOUSE_MOVE_PACKET) src); + case MOUSE_MOVE_ABS_MAGIC: + return mouse::batch((PNV_ABS_MOUSE_MOVE_PACKET) dest, (PNV_ABS_MOUSE_MOVE_PACKET) src); + case SCROLL_MAGIC_GEN5: + return mouse::batch((PNV_SCROLL_PACKET) dest, (PNV_SCROLL_PACKET) src); + case SS_HSCROLL_MAGIC: + return mouse::batch((PSS_HSCROLL_PACKET) dest, (PSS_HSCROLL_PACKET) src); + case MULTI_CONTROLLER_MAGIC_GEN5: + return gamepad::batch((PNV_MULTI_CONTROLLER_PACKET) dest, (PNV_MULTI_CONTROLLER_PACKET) src); + case SS_TOUCH_MAGIC: + return touch::batch((PSS_TOUCH_PACKET) dest, (PSS_TOUCH_PACKET) src); + case SS_PEN_MAGIC: + return pen::batch((PSS_PEN_PACKET) dest, (PSS_PEN_PACKET) src); + case SS_CONTROLLER_TOUCH_MAGIC: + return gamepad::batch((PSS_CONTROLLER_TOUCH_PACKET) dest, (PSS_CONTROLLER_TOUCH_PACKET) src); + case SS_CONTROLLER_MOTION_MAGIC: + return gamepad::batch((PSS_CONTROLLER_MOTION_PACKET) dest, (PSS_CONTROLLER_MOTION_PACKET) src); + default: + // Not a batchable message type + return batch_result_e::terminate_batch; + } + } + + /** + * @brief Called on a thread pool thread to process an input message. + * @param input The input context pointer. + */ + void + passthrough_next_message(std::shared_ptr input) { + // 'entry' backs the 'payload' pointer, so they must remain in scope together + std::vector entry; + PNV_INPUT_HEADER payload; + + // Lock the input queue while batching, but release it before sending + // the input to the OS. This avoids potentially lengthy lock contention + // in the control stream thread while input is being processed by the OS. + { + std::lock_guard lg(input->input_queue_lock); + + // If all entries have already been processed, nothing to do + if (input->input_queue.empty()) { + return; + } + + // Pop off the first entry, which we will send + entry = input->input_queue.front(); + payload = (PNV_INPUT_HEADER) entry.data(); + input->input_queue.pop_front(); + + // Try to batch with remaining items on the queue + auto i = input->input_queue.begin(); + while (i != input->input_queue.end()) { + auto batchable_entry = *i; + auto batchable_payload = (PNV_INPUT_HEADER) batchable_entry.data(); + + auto batch_result = batch(payload, batchable_payload); + if (batch_result == batch_result_e::terminate_batch) { + // Stop batching + break; + } + else if (batch_result == batch_result_e::batched) { + // Erase this entry since it was batched + i = input->input_queue.erase(i); + } + else { + // We couldn't batch this entry, but try to batch later entries. + i++; + } + } + } + + // Print the final input packet + input::print((void *) payload); + + // Send the batched input to the OS + switch (util::endian::little(payload->magic)) { + case MOUSE_MOVE_REL_MAGIC_GEN5: + mouse::passthrough(input, (PNV_REL_MOUSE_MOVE_PACKET) payload); + break; + case MOUSE_MOVE_ABS_MAGIC: + mouse::passthrough(input, (PNV_ABS_MOUSE_MOVE_PACKET) payload); + break; + case MOUSE_BUTTON_DOWN_EVENT_MAGIC_GEN5: + case MOUSE_BUTTON_UP_EVENT_MAGIC_GEN5: + mouse::passthrough(input, (PNV_MOUSE_BUTTON_PACKET) payload); + break; + case SCROLL_MAGIC_GEN5: + mouse::passthrough(input, (PNV_SCROLL_PACKET) payload); + break; + case SS_HSCROLL_MAGIC: + mouse::passthrough(input, (PSS_HSCROLL_PACKET) payload); + break; + case KEY_DOWN_EVENT_MAGIC: + case KEY_UP_EVENT_MAGIC: + keyboard::passthrough(input, (PNV_KEYBOARD_PACKET) payload); + break; + case UTF8_TEXT_EVENT_MAGIC: + keyboard::passthrough((PNV_UNICODE_PACKET) payload); + break; + case MULTI_CONTROLLER_MAGIC_GEN5: + gamepad::passthrough(input, (PNV_MULTI_CONTROLLER_PACKET) payload); + break; + case SS_TOUCH_MAGIC: + touch::passthrough(input, (PSS_TOUCH_PACKET) payload); + break; + case SS_PEN_MAGIC: + pen::passthrough(input, (PSS_PEN_PACKET) payload); + break; + case SS_CONTROLLER_ARRIVAL_MAGIC: + gamepad::passthrough(input, (PSS_CONTROLLER_ARRIVAL_PACKET) payload); + break; + case SS_CONTROLLER_TOUCH_MAGIC: + gamepad::passthrough(input, (PSS_CONTROLLER_TOUCH_PACKET) payload); + break; + case SS_CONTROLLER_MOTION_MAGIC: + gamepad::passthrough(input, (PSS_CONTROLLER_MOTION_PACKET) payload); + break; + case SS_CONTROLLER_BATTERY_MAGIC: + gamepad::passthrough(input, (PSS_CONTROLLER_BATTERY_PACKET) payload); + break; + } + } + } // namespace + void print(void *payload) { const auto header = static_cast(payload); @@ -93,145 +234,6 @@ namespace input { } } - /** - * @brief Batch two input messages. - * @param dest The original packet to batch into. - * @param src A later packet to attempt to batch. - * @return The status of the batching operation. - */ - batch_result_e - batch(PNV_INPUT_HEADER dest, PNV_INPUT_HEADER src) { - // We can only batch if the packet types are the same - if (dest->magic != src->magic) { - return batch_result_e::terminate_batch; - } - - // We can only batch certain message types - switch (util::endian::little(dest->magic)) { - case MOUSE_MOVE_REL_MAGIC_GEN5: - return mouse::batch((PNV_REL_MOUSE_MOVE_PACKET) dest, (PNV_REL_MOUSE_MOVE_PACKET) src); - case MOUSE_MOVE_ABS_MAGIC: - return mouse::batch((PNV_ABS_MOUSE_MOVE_PACKET) dest, (PNV_ABS_MOUSE_MOVE_PACKET) src); - case SCROLL_MAGIC_GEN5: - return mouse::batch((PNV_SCROLL_PACKET) dest, (PNV_SCROLL_PACKET) src); - case SS_HSCROLL_MAGIC: - return mouse::batch((PSS_HSCROLL_PACKET) dest, (PSS_HSCROLL_PACKET) src); - case MULTI_CONTROLLER_MAGIC_GEN5: - return gamepad::batch((PNV_MULTI_CONTROLLER_PACKET) dest, (PNV_MULTI_CONTROLLER_PACKET) src); - case SS_TOUCH_MAGIC: - return touch::batch((PSS_TOUCH_PACKET) dest, (PSS_TOUCH_PACKET) src); - case SS_PEN_MAGIC: - return pen::batch((PSS_PEN_PACKET) dest, (PSS_PEN_PACKET) src); - case SS_CONTROLLER_TOUCH_MAGIC: - return gamepad::batch((PSS_CONTROLLER_TOUCH_PACKET) dest, (PSS_CONTROLLER_TOUCH_PACKET) src); - case SS_CONTROLLER_MOTION_MAGIC: - return gamepad::batch((PSS_CONTROLLER_MOTION_PACKET) dest, (PSS_CONTROLLER_MOTION_PACKET) src); - default: - // Not a batchable message type - return batch_result_e::terminate_batch; - } - } - - /** - * @brief Called on a thread pool thread to process an input message. - * @param input The input context pointer. - */ - void - passthrough_next_message(std::shared_ptr input) { - // 'entry' backs the 'payload' pointer, so they must remain in scope together - std::vector entry; - PNV_INPUT_HEADER payload; - - // Lock the input queue while batching, but release it before sending - // the input to the OS. This avoids potentially lengthy lock contention - // in the control stream thread while input is being processed by the OS. - { - std::lock_guard lg(input->input_queue_lock); - - // If all entries have already been processed, nothing to do - if (input->input_queue.empty()) { - return; - } - - // Pop off the first entry, which we will send - entry = input->input_queue.front(); - payload = (PNV_INPUT_HEADER) entry.data(); - input->input_queue.pop_front(); - - // Try to batch with remaining items on the queue - auto i = input->input_queue.begin(); - while (i != input->input_queue.end()) { - auto batchable_entry = *i; - auto batchable_payload = (PNV_INPUT_HEADER) batchable_entry.data(); - - auto batch_result = batch(payload, batchable_payload); - if (batch_result == batch_result_e::terminate_batch) { - // Stop batching - break; - } - else if (batch_result == batch_result_e::batched) { - // Erase this entry since it was batched - i = input->input_queue.erase(i); - } - else { - // We couldn't batch this entry, but try to batch later entries. - i++; - } - } - } - - // Print the final input packet - input::print((void *) payload); - - // Send the batched input to the OS - switch (util::endian::little(payload->magic)) { - case MOUSE_MOVE_REL_MAGIC_GEN5: - mouse::passthrough(input, (PNV_REL_MOUSE_MOVE_PACKET) payload); - break; - case MOUSE_MOVE_ABS_MAGIC: - mouse::passthrough(input, (PNV_ABS_MOUSE_MOVE_PACKET) payload); - break; - case MOUSE_BUTTON_DOWN_EVENT_MAGIC_GEN5: - case MOUSE_BUTTON_UP_EVENT_MAGIC_GEN5: - mouse::passthrough(input, (PNV_MOUSE_BUTTON_PACKET) payload); - break; - case SCROLL_MAGIC_GEN5: - mouse::passthrough(input, (PNV_SCROLL_PACKET) payload); - break; - case SS_HSCROLL_MAGIC: - mouse::passthrough(input, (PSS_HSCROLL_PACKET) payload); - break; - case KEY_DOWN_EVENT_MAGIC: - case KEY_UP_EVENT_MAGIC: - keyboard::passthrough(input, (PNV_KEYBOARD_PACKET) payload); - break; - case UTF8_TEXT_EVENT_MAGIC: - keyboard::passthrough((PNV_UNICODE_PACKET) payload); - break; - case MULTI_CONTROLLER_MAGIC_GEN5: - gamepad::passthrough(input, (PNV_MULTI_CONTROLLER_PACKET) payload); - break; - case SS_TOUCH_MAGIC: - touch::passthrough(input, (PSS_TOUCH_PACKET) payload); - break; - case SS_PEN_MAGIC: - pen::passthrough(input, (PSS_PEN_PACKET) payload); - break; - case SS_CONTROLLER_ARRIVAL_MAGIC: - gamepad::passthrough(input, (PSS_CONTROLLER_ARRIVAL_PACKET) payload); - break; - case SS_CONTROLLER_TOUCH_MAGIC: - gamepad::passthrough(input, (PSS_CONTROLLER_TOUCH_PACKET) payload); - break; - case SS_CONTROLLER_MOTION_MAGIC: - gamepad::passthrough(input, (PSS_CONTROLLER_MOTION_PACKET) payload); - break; - case SS_CONTROLLER_BATTERY_MAGIC: - gamepad::passthrough(input, (PSS_CONTROLLER_BATTERY_PACKET) payload); - break; - } - } - void passthrough(std::shared_ptr &input, std::vector &&input_data) { { diff --git a/src/input/processor.h b/src/input/processor.h index 84d288ab658..a13d0cfc7a7 100644 --- a/src/input/processor.h +++ b/src/input/processor.h @@ -6,15 +6,24 @@ #include -#include "common.h" -#include "init.h" +#include "src/input/common.h" +#include "src/input/init.h" #include "src/platform/common.h" #include "src/thread_safe.h" namespace input { + /** + * @brief Retrieves the packet from the payload input and prints its contents. + * @param payload The payload context pointer. + */ void - print(void *input); + print(void *payload); + + /** + * @brief Resets all inputs overall state in the platform backend. + * @param input The input context pointer. + */ void reset(std::shared_ptr &input); diff --git a/src/input/touch.cpp b/src/input/touch.cpp index 0d006200f70..a399319ffc1 100644 --- a/src/input/touch.cpp +++ b/src/input/touch.cpp @@ -2,9 +2,9 @@ * @file src/input/touch.cpp * @brief Definitions for common touch input. */ -#include "touch.h" -#include "init.h" -#include "processor.h" +#include "src/input/touch.h" +#include "src/input/init.h" +#include "src/input/processor.h" namespace input::touch { void diff --git a/src/input/touch.h b/src/input/touch.h index 0a8d13e9ab1..3d3c5375ce6 100644 --- a/src/input/touch.h +++ b/src/input/touch.h @@ -12,7 +12,7 @@ extern "C" { #include -#include "common.h" +#include "src/input/common.h" #include "src/platform/common.h" #include "src/thread_pool.h" diff --git a/src/server/confighttp.cpp b/src/server/confighttp.cpp index 155ccd2160a..c1fcfc63550 100644 --- a/src/server/confighttp.cpp +++ b/src/server/confighttp.cpp @@ -6,8 +6,6 @@ */ #define BOOST_BIND_GLOBAL_PLACEHOLDERS -#include "src/process.h" - #include #include @@ -25,17 +23,18 @@ #include #include -#include "confighttp.h" -#include "crypto.h" -#include "httpcommon.h" -#include "network.h" -#include "nvhttp.h" -#include "rtsp.h" #include "src/config.h" #include "src/file_handler.h" #include "src/globals.h" #include "src/logging.h" #include "src/platform/common.h" +#include "src/process.h" +#include "src/server/confighttp.h" +#include "src/server/crypto.h" +#include "src/server/httpcommon.h" +#include "src/server/network.h" +#include "src/server/nvhttp.h" +#include "src/server/rtsp.h" #include "src/utility.h" #include "src/uuid.h" #include "version.h" diff --git a/src/server/crypto.cpp b/src/server/crypto.cpp index 267eb106092..8c0dc538e69 100644 --- a/src/server/crypto.cpp +++ b/src/server/crypto.cpp @@ -2,9 +2,10 @@ * @file src/server/crypto.cpp * @brief Definitions for cryptography functions. */ -#include "crypto.h" #include +#include "src/server/crypto.h" + namespace crypto { using asn1_string_t = util::safe_ptr; diff --git a/src/server/httpcommon.cpp b/src/server/httpcommon.cpp index 8d250a13e7b..e70a69501e3 100644 --- a/src/server/httpcommon.cpp +++ b/src/server/httpcommon.cpp @@ -4,8 +4,6 @@ */ #define BOOST_BIND_GLOBAL_PLACEHOLDERS -#include "src/process.h" - #include #include @@ -20,15 +18,16 @@ #include #include -#include "crypto.h" -#include "httpcommon.h" -#include "network.h" -#include "nvhttp.h" -#include "rtsp.h" #include "src/config.h" #include "src/file_handler.h" #include "src/logging.h" #include "src/platform/common.h" +#include "src/process.h" +#include "src/server/crypto.h" +#include "src/server/httpcommon.h" +#include "src/server/network.h" +#include "src/server/nvhttp.h" +#include "src/server/rtsp.h" #include "src/utility.h" #include "src/uuid.h" diff --git a/src/server/httpcommon.h b/src/server/httpcommon.h index f023da056bd..a666fdb6fcb 100644 --- a/src/server/httpcommon.h +++ b/src/server/httpcommon.h @@ -4,7 +4,7 @@ */ #pragma once -#include "network.h" +#include "src/server/network.h" namespace http { diff --git a/src/server/network.cpp b/src/server/network.cpp index 4b856c9244f..d2e31740bc2 100644 --- a/src/server/network.cpp +++ b/src/server/network.cpp @@ -2,7 +2,7 @@ * @file src/server/network.cpp * @brief Definitions for networking related functions. */ -#include "network.h" +#include "src/server/network.h" #include "src/config.h" #include "src/logging.h" #include "src/utility.h" diff --git a/src/server/nvhttp.cpp b/src/server/nvhttp.cpp index 9ef26bccb05..936b7de1ffb 100644 --- a/src/server/nvhttp.cpp +++ b/src/server/nvhttp.cpp @@ -20,17 +20,17 @@ #include // local includes -#include "crypto.h" -#include "httpcommon.h" -#include "network.h" -#include "rtsp.h" #include "src/config.h" #include "src/file_handler.h" #include "src/globals.h" #include "src/logging.h" #include "src/platform/common.h" #include "src/process.h" +#include "src/server/crypto.h" +#include "src/server/httpcommon.h" +#include "src/server/network.h" #include "src/server/nvhttp.h" +#include "src/server/rtsp.h" #include "src/system_tray.h" #include "src/utility.h" #include "src/uuid.h" diff --git a/src/server/rtsp.cpp b/src/server/rtsp.cpp index 4ae65618100..b36b5a737c9 100644 --- a/src/server/rtsp.cpp +++ b/src/server/rtsp.cpp @@ -16,12 +16,12 @@ extern "C" { #include #include -#include "network.h" -#include "rtsp.h" #include "src/config.h" #include "src/globals.h" #include "src/input/processor.h" #include "src/logging.h" +#include "src/server/network.h" +#include "src/server/rtsp.h" #include "src/stream.h" #include "src/sync.h" #include "src/video.h" diff --git a/src/server/rtsp.h b/src/server/rtsp.h index 249434062b0..2620b467585 100644 --- a/src/server/rtsp.h +++ b/src/server/rtsp.h @@ -6,7 +6,7 @@ #include -#include "crypto.h" +#include "src/server/crypto.h" #include "src/thread_safe.h" namespace rtsp_stream { diff --git a/src/server/upnp.cpp b/src/server/upnp.cpp index a0d47ed90c7..b094f03bd24 100644 --- a/src/server/upnp.cpp +++ b/src/server/upnp.cpp @@ -5,16 +5,16 @@ #include #include -#include "confighttp.h" -#include "network.h" -#include "nvhttp.h" -#include "rtsp.h" #include "src/config.h" #include "src/globals.h" #include "src/logging.h" +#include "src/server/confighttp.h" +#include "src/server/network.h" +#include "src/server/nvhttp.h" +#include "src/server/rtsp.h" +#include "src/server/upnp.h" #include "src/stream.h" #include "src/utility.h" -#include "upnp.h" using namespace std::literals;