From d912cce5ba8dfd92ecf451f4f19f93bc62476960 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 22 Nov 2022 18:38:27 -0600 Subject: [PATCH 1/2] Update moonlight-common-c to pick up new input structures --- CMakeLists.txt | 7 --- src/input.cpp | 89 ++++++++++++++-------------------- third-party/moonlight-common-c | 2 +- 3 files changed, 38 insertions(+), 60 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bd5ae938..990cad26 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,13 +34,6 @@ endif() set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) set(SUNSHINE_SOURCE_ASSETS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src_assets") -if(WIN32) - # Ugly hack to compile with #include - add_compile_definitions( - QOS_FLOWID=UINT32 - PQOS_FLOWID=UINT32* - QOS_NON_ADAPTIVE_FLOW=2) -endif() if(APPLE) macro(ADD_FRAMEWORK fwname appname) find_library(FRAMEWORK_${fwname} diff --git a/src/input.cpp b/src/input.cpp index c40cdef5..b1745df0 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -4,6 +4,7 @@ #include extern "C" { #include +#include } #include @@ -175,7 +176,7 @@ void print(PNV_ABS_MOUSE_MOVE_PACKET packet) { void print(PNV_MOUSE_BUTTON_PACKET packet) { BOOST_LOG(debug) << "--begin mouse button packet--"sv << std::endl - << "action ["sv << util::hex(packet->action).to_string_view() << ']' << std::endl + << "action ["sv << util::hex(packet->header.magic).to_string_view() << ']' << std::endl << "button ["sv << util::hex(packet->button).to_string_view() << ']' << std::endl << "--end mouse button packet--"sv; } @@ -190,7 +191,7 @@ void print(PNV_SCROLL_PACKET packet) { void print(PNV_KEYBOARD_PACKET packet) { BOOST_LOG(debug) << "--begin keyboard packet--"sv << std::endl - << "keyAction ["sv << util::hex(packet->keyAction).to_string_view() << ']' << 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 << "--end keyboard packet--"sv; @@ -212,33 +213,29 @@ void print(PNV_MULTI_CONTROLLER_PACKET packet) { << "--end controller packet--"sv; } -constexpr int PACKET_TYPE_SCROLL_OR_KEYBOARD = PACKET_TYPE_SCROLL; -void print(void *input) { - int input_type = util::endian::big(*(int *)input); +void print(void *payload) { + auto header = (PNV_INPUT_HEADER)payload; - switch(input_type) { - case PACKET_TYPE_REL_MOUSE_MOVE: - print((PNV_REL_MOUSE_MOVE_PACKET)input); + switch(util::endian::little(header->magic)) { + case MOUSE_MOVE_REL_MAGIC_GEN5: + print((PNV_REL_MOUSE_MOVE_PACKET)payload); break; - case PACKET_TYPE_ABS_MOUSE_MOVE: - print((PNV_ABS_MOUSE_MOVE_PACKET)input); + case MOUSE_MOVE_ABS_MAGIC: + print((PNV_ABS_MOUSE_MOVE_PACKET)payload); break; - case PACKET_TYPE_MOUSE_BUTTON: - print((PNV_MOUSE_BUTTON_PACKET)input); + case MOUSE_BUTTON_DOWN_EVENT_MAGIC_GEN5: + case MOUSE_BUTTON_UP_EVENT_MAGIC_GEN5: + print((PNV_MOUSE_BUTTON_PACKET)payload); break; - case PACKET_TYPE_SCROLL_OR_KEYBOARD: { - char *tmp_input = (char *)input + 4; - if(tmp_input[0] == 0x0A) { - print((PNV_SCROLL_PACKET)input); - } - else { - print((PNV_KEYBOARD_PACKET)input); - } - + case SCROLL_MAGIC_GEN5: + print((PNV_SCROLL_PACKET)payload); break; - } - case PACKET_TYPE_MULTI_CONTROLLER: - print((PNV_MULTI_CONTROLLER_PACKET)input); + case KEY_DOWN_EVENT_MAGIC: + case KEY_UP_EVENT_MAGIC: + print((PNV_KEYBOARD_PACKET)payload); + break; + case MULTI_CONTROLLER_MAGIC_GEN5: + print((PNV_MULTI_CONTROLLER_PACKET)payload); break; } } @@ -294,14 +291,8 @@ void passthrough(std::shared_ptr &input, PNV_ABS_MOUSE_MOVE_PACKET pack } void passthrough(std::shared_ptr &input, PNV_MOUSE_BUTTON_PACKET packet) { - auto constexpr BUTTON_RELEASED = 0x09; - - auto constexpr BUTTON_LEFT = 0x01; - auto constexpr BUTTON_RIGHT = 0x03; - - auto release = packet->action == BUTTON_RELEASED; - - auto button = util::endian::big(packet->button); + auto release = util::endian::little(packet->header.magic) == MOUSE_BUTTON_UP_EVENT_MAGIC_GEN5; + auto button = util::endian::big(packet->button); if(button > 0 && button < mouse_press.size()) { if(mouse_press[button] != release) { // button state is already what we want @@ -417,9 +408,7 @@ void repeat_key(short key_code) { } void passthrough(std::shared_ptr &input, PNV_KEYBOARD_PACKET packet) { - auto constexpr BUTTON_RELEASED = 0x04; - - auto release = packet->keyAction == BUTTON_RELEASED; + auto release = util::endian::little(packet->header.magic) == KEY_UP_EVENT_MAGIC; auto keyCode = packet->keyCode & 0x00FF; auto &pressed = key_press[keyCode]; @@ -600,31 +589,27 @@ void passthrough(std::shared_ptr &input, PNV_MULTI_CONTROLLER_PACKET pa void passthrough_helper(std::shared_ptr input, std::vector &&input_data) { void *payload = input_data.data(); + auto header = (PNV_INPUT_HEADER)payload; - int input_type = util::endian::big(*(int *)payload); - - switch(input_type) { - case PACKET_TYPE_REL_MOUSE_MOVE: + switch(util::endian::little(header->magic)) { + case MOUSE_MOVE_REL_MAGIC_GEN5: passthrough(input, (PNV_REL_MOUSE_MOVE_PACKET)payload); break; - case PACKET_TYPE_ABS_MOUSE_MOVE: + case MOUSE_MOVE_ABS_MAGIC: passthrough(input, (PNV_ABS_MOUSE_MOVE_PACKET)payload); break; - case PACKET_TYPE_MOUSE_BUTTON: + case MOUSE_BUTTON_DOWN_EVENT_MAGIC_GEN5: + case MOUSE_BUTTON_UP_EVENT_MAGIC_GEN5: passthrough(input, (PNV_MOUSE_BUTTON_PACKET)payload); break; - case PACKET_TYPE_SCROLL_OR_KEYBOARD: { - char *tmp_input = (char *)payload + 4; - if(tmp_input[0] == 0x0A) { - passthrough((PNV_SCROLL_PACKET)payload); - } - else { - passthrough(input, (PNV_KEYBOARD_PACKET)payload); - } - + case SCROLL_MAGIC_GEN5: + passthrough((PNV_SCROLL_PACKET)payload); break; - } - case PACKET_TYPE_MULTI_CONTROLLER: + case KEY_DOWN_EVENT_MAGIC: + case KEY_UP_EVENT_MAGIC: + passthrough(input, (PNV_KEYBOARD_PACKET)payload); + break; + case MULTI_CONTROLLER_MAGIC_GEN5: passthrough(input, (PNV_MULTI_CONTROLLER_PACKET)payload); break; } diff --git a/third-party/moonlight-common-c b/third-party/moonlight-common-c index 3b9d8a31..8169a31e 160000 --- a/third-party/moonlight-common-c +++ b/third-party/moonlight-common-c @@ -1 +1 @@ -Subproject commit 3b9d8a31763be77c921bd2581b5e75f4d40a1b11 +Subproject commit 8169a31ecc07a5726fea3f7b809e6fbff312c724 From e39d9bc662057f303987d00ca132ad9516181d11 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 22 Nov 2022 19:17:53 -0600 Subject: [PATCH 2/2] Add support for Unicode input messages on Windows --- src/input.cpp | 19 +++++++++++++++++++ src/platform/common.h | 1 + src/platform/linux/input.cpp | 4 ++++ src/platform/macos/input.cpp | 4 ++++ src/platform/windows/input.cpp | 28 ++++++++++++++++++++++++++++ 5 files changed, 56 insertions(+) diff --git a/src/input.cpp b/src/input.cpp index b1745df0..2238c316 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -197,6 +197,14 @@ void print(PNV_KEYBOARD_PACKET packet) { << "--end keyboard packet--"sv; } +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 print(PNV_MULTI_CONTROLLER_PACKET packet) { // Moonlight spams controller packet even when not necessary BOOST_LOG(verbose) @@ -234,6 +242,9 @@ void print(void *payload) { case KEY_UP_EVENT_MAGIC: print((PNV_KEYBOARD_PACKET)payload); break; + case UTF8_TEXT_EVENT_MAGIC: + print((PNV_UNICODE_PACKET)payload); + break; case MULTI_CONTROLLER_MAGIC_GEN5: print((PNV_MULTI_CONTROLLER_PACKET)payload); break; @@ -448,6 +459,11 @@ void passthrough(PNV_SCROLL_PACKET packet) { platf::scroll(platf_input, util::endian::big(packet->scrollAmt1)); } +void passthrough(PNV_UNICODE_PACKET packet) { + auto size = util::endian::big(packet->header.size) - sizeof(packet->header.magic); + platf::unicode(platf_input, packet->text, size); +} + int updateGamepads(std::vector &gamepads, std::int16_t old_state, std::int16_t new_state, const platf::rumble_queue_t &rumble_queue) { auto xorGamepadMask = old_state ^ new_state; if(!xorGamepadMask) { @@ -609,6 +625,9 @@ void passthrough_helper(std::shared_ptr input, std::vectoralloc_gamepad(nr, std::move(rumble_queue)); } diff --git a/src/platform/macos/input.cpp b/src/platform/macos/input.cpp index 3d9c21a3..f1970944 100644 --- a/src/platform/macos/input.cpp +++ b/src/platform/macos/input.cpp @@ -277,6 +277,10 @@ void keyboard(input_t &input, uint16_t modcode, bool release) { CGEventPost(kCGHIDEventTap, event); } +void unicode(input_t &input, char *utf8, int size) { + BOOST_LOG(info) << "unicode: Unicode input not yet implemented for MacOS."sv; +} + int alloc_gamepad(input_t &input, int nr, rumble_queue_t rumble_queue) { BOOST_LOG(info) << "alloc_gamepad: Gamepad not yet implemented for MacOS."sv; return -1; diff --git a/src/platform/windows/input.cpp b/src/platform/windows/input.cpp index 9ac01a26..dddaf376 100644 --- a/src/platform/windows/input.cpp +++ b/src/platform/windows/input.cpp @@ -326,6 +326,34 @@ void keyboard(input_t &input, uint16_t modcode, bool release) { send_input(i); } +void unicode(input_t &input, char *utf8, int size) { + // We can do no worse than one UTF-16 character per byte of UTF-8 + WCHAR wide[size]; + + int chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8, size, wide, size); + if(chars <= 0) { + return; + } + + // Send all key down events + for(int i = 0; i < chars; i++) { + INPUT input {}; + input.type = INPUT_KEYBOARD; + input.ki.wScan = wide[i]; + input.ki.dwFlags = KEYEVENTF_UNICODE; + send_input(input); + } + + // Send all key up events + for(int i = 0; i < chars; i++) { + INPUT input {}; + input.type = INPUT_KEYBOARD; + input.ki.wScan = wide[i]; + input.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; + send_input(input); + } +} + int alloc_gamepad(input_t &input, int nr, rumble_queue_t rumble_queue) { if(!input) { return 0;