mirror of
https://github.com/LizardByte/Sunshine.git
synced 2025-04-07 13:21:05 +00:00
Absolute mouse coordinates on Windows
This commit is contained in:
parent
2e9a1cfbba
commit
022b2202f6
@ -209,6 +209,14 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_ABS_MOUSE_MOVE_PACKET pack
|
|||||||
float x = util::endian::big(packet->x);
|
float x = util::endian::big(packet->x);
|
||||||
float y = util::endian::big(packet->y);
|
float y = util::endian::big(packet->y);
|
||||||
|
|
||||||
|
// Prevent divide by zero
|
||||||
|
// Don't expect it to happen, but just in case
|
||||||
|
if(!packet->width || !packet->height) {
|
||||||
|
BOOST_LOG(warning) << "Moonlight passed invalid dimensions"sv;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
float width = util::endian::big(packet->width);
|
float width = util::endian::big(packet->width);
|
||||||
float height = util::endian::big(packet->height);
|
float height = util::endian::big(packet->height);
|
||||||
|
|
||||||
@ -220,7 +228,9 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_ABS_MOUSE_MOVE_PACKET pack
|
|||||||
|
|
||||||
void passthrough(std::shared_ptr<input_t> &input, PNV_MOUSE_BUTTON_PACKET packet) {
|
void passthrough(std::shared_ptr<input_t> &input, PNV_MOUSE_BUTTON_PACKET packet) {
|
||||||
auto constexpr BUTTON_RELEASED = 0x09;
|
auto constexpr BUTTON_RELEASED = 0x09;
|
||||||
auto constexpr BUTTON_LEFT = 0x01;
|
|
||||||
|
auto constexpr BUTTON_LEFT = 0x01;
|
||||||
|
auto constexpr BUTTON_RIGHT = 0x03;
|
||||||
|
|
||||||
display_cursor = true;
|
display_cursor = true;
|
||||||
|
|
||||||
@ -228,9 +238,14 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_MOUSE_BUTTON_PACKET packet
|
|||||||
|
|
||||||
auto button = util::endian::big(packet->button);
|
auto button = util::endian::big(packet->button);
|
||||||
if(button > 0 && button < mouse_press.size()) {
|
if(button > 0 && button < mouse_press.size()) {
|
||||||
|
if(mouse_press[button] != release) {
|
||||||
|
// button state is already what we want
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mouse_press[button] = !release;
|
mouse_press[button] = !release;
|
||||||
}
|
}
|
||||||
|
///////////////////////////////////
|
||||||
/*/
|
/*/
|
||||||
* When Moonlight sends mouse input through absolute coordinates,
|
* When Moonlight sends mouse input through absolute coordinates,
|
||||||
* it's possible that BUTTON_RIGHT is pressed down immediately after releasing BUTTON_LEFT.
|
* it's possible that BUTTON_RIGHT is pressed down immediately after releasing BUTTON_LEFT.
|
||||||
@ -247,13 +262,30 @@ void passthrough(std::shared_ptr<input_t> &input, PNV_MOUSE_BUTTON_PACKET packet
|
|||||||
/*/
|
/*/
|
||||||
if(button == BUTTON_LEFT && release && !input->mouse_left_button_timeout) {
|
if(button == BUTTON_LEFT && release && !input->mouse_left_button_timeout) {
|
||||||
input->mouse_left_button_timeout = task_pool.pushDelayed([=]() {
|
input->mouse_left_button_timeout = task_pool.pushDelayed([=]() {
|
||||||
platf::button_mouse(platf_input, button, release);
|
auto left_released = mouse_press[BUTTON_LEFT];
|
||||||
|
if(left_released) {
|
||||||
|
// Already released left button
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
platf::button_mouse(platf_input, BUTTON_LEFT, release);
|
||||||
|
|
||||||
input->mouse_left_button_timeout = nullptr;
|
input->mouse_left_button_timeout = nullptr;
|
||||||
}, 10ms).task_id;
|
}, 10ms).task_id;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(
|
||||||
|
button == BUTTON_RIGHT && !release &&
|
||||||
|
input->mouse_left_button_timeout > DISABLE_LEFT_BUTTON_DELAY
|
||||||
|
) {
|
||||||
|
platf::button_mouse(platf_input, BUTTON_RIGHT, false);
|
||||||
|
platf::button_mouse(platf_input, BUTTON_RIGHT, true);
|
||||||
|
|
||||||
|
mouse_press[BUTTON_RIGHT] = false;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
///////////////////////////////////
|
||||||
|
|
||||||
platf::button_mouse(platf_input, button, release);
|
platf::button_mouse(platf_input, button, release);
|
||||||
}
|
}
|
||||||
|
@ -129,8 +129,10 @@ int display_base_t::init() {
|
|||||||
if(desc.AttachedToDesktop) {
|
if(desc.AttachedToDesktop) {
|
||||||
output = std::move(output_tmp);
|
output = std::move(output_tmp);
|
||||||
|
|
||||||
width = desc.DesktopCoordinates.right - desc.DesktopCoordinates.left;
|
offset_x = desc.DesktopCoordinates.left;
|
||||||
height = desc.DesktopCoordinates.bottom - desc.DesktopCoordinates.top;
|
offset_y = desc.DesktopCoordinates.top;
|
||||||
|
width = desc.DesktopCoordinates.right - offset_x;
|
||||||
|
height = desc.DesktopCoordinates.bottom - offset_y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
@ -17,7 +18,12 @@ using namespace std::literals;
|
|||||||
|
|
||||||
using adapteraddrs_t = util::c_ptr<IP_ADAPTER_ADDRESSES>;
|
using adapteraddrs_t = util::c_ptr<IP_ADAPTER_ADDRESSES>;
|
||||||
|
|
||||||
volatile HDESK _lastKnownInputDesktop = NULL;
|
volatile HDESK _lastKnownInputDesktop = NULL;
|
||||||
|
constexpr touch_port_t target_touch_port {
|
||||||
|
0, 0,
|
||||||
|
65535, 65535
|
||||||
|
};
|
||||||
|
|
||||||
HDESK pairInputDesktop();
|
HDESK pairInputDesktop();
|
||||||
|
|
||||||
class vigem_t {
|
class vigem_t {
|
||||||
@ -165,7 +171,40 @@ input_t input() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) {}
|
void send_input(INPUT &i) {
|
||||||
|
retry:
|
||||||
|
auto send = SendInput(1, &i, sizeof(INPUT));
|
||||||
|
if(send != 1) {
|
||||||
|
auto hDesk = pairInputDesktop();
|
||||||
|
if (_lastKnownInputDesktop != hDesk) {
|
||||||
|
_lastKnownInputDesktop = hDesk;
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
BOOST_LOG(warning) << "Couldn't send input"sv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) {
|
||||||
|
INPUT i {};
|
||||||
|
|
||||||
|
i.type = INPUT_MOUSE;
|
||||||
|
auto &mi = i.mi;
|
||||||
|
|
||||||
|
mi.dwFlags =
|
||||||
|
MOUSEEVENTF_MOVE |
|
||||||
|
MOUSEEVENTF_ABSOLUTE |
|
||||||
|
|
||||||
|
// MOUSEEVENTF_VIRTUALDESK maps to the entirety of the desktop rather than the primary desktop
|
||||||
|
MOUSEEVENTF_VIRTUALDESK;
|
||||||
|
|
||||||
|
auto scaled_x = std::lround((x + touch_port.offset_x) * ((float)target_touch_port.width / (float)touch_port.width));
|
||||||
|
auto scaled_y = std::lround((y + touch_port.offset_y) * ((float)target_touch_port.height / (float)touch_port.height));
|
||||||
|
|
||||||
|
mi.dx = scaled_x;
|
||||||
|
mi.dy = scaled_y;
|
||||||
|
|
||||||
|
send_input(i);
|
||||||
|
}
|
||||||
|
|
||||||
void move_mouse(input_t &input, int deltaX, int deltaY) {
|
void move_mouse(input_t &input, int deltaX, int deltaY) {
|
||||||
INPUT i {};
|
INPUT i {};
|
||||||
|
|
||||||
@ -176,16 +215,7 @@ void move_mouse(input_t &input, int deltaX, int deltaY) {
|
|||||||
mi.dx = deltaX;
|
mi.dx = deltaX;
|
||||||
mi.dy = deltaY;
|
mi.dy = deltaY;
|
||||||
|
|
||||||
retry:
|
send_input(i);
|
||||||
auto send = SendInput(1, &i, sizeof(INPUT));
|
|
||||||
if(send != 1) {
|
|
||||||
auto hDesk = pairInputDesktop();
|
|
||||||
if (_lastKnownInputDesktop != hDesk) {
|
|
||||||
_lastKnownInputDesktop = hDesk;
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
BOOST_LOG(warning) << "Couldn't send mouse movement input"sv;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void button_mouse(input_t &input, int button, bool release) {
|
void button_mouse(input_t &input, int button, bool release) {
|
||||||
@ -228,16 +258,7 @@ void button_mouse(input_t &input, int button, bool release) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
retry:
|
send_input(i);
|
||||||
auto send = SendInput(1, &i, sizeof(INPUT));
|
|
||||||
if(send != 1) {
|
|
||||||
auto hDesk = pairInputDesktop();
|
|
||||||
if (_lastKnownInputDesktop != hDesk) {
|
|
||||||
_lastKnownInputDesktop = hDesk;
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
BOOST_LOG(warning) << "Couldn't send mouse button input"sv;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll(input_t &input, int distance) {
|
void scroll(input_t &input, int distance) {
|
||||||
@ -249,16 +270,7 @@ void scroll(input_t &input, int distance) {
|
|||||||
mi.dwFlags = MOUSEEVENTF_WHEEL;
|
mi.dwFlags = MOUSEEVENTF_WHEEL;
|
||||||
mi.mouseData = distance;
|
mi.mouseData = distance;
|
||||||
|
|
||||||
retry:
|
send_input(i);
|
||||||
auto send = SendInput(1, &i, sizeof(INPUT));
|
|
||||||
if(send != 1) {
|
|
||||||
auto hDesk = pairInputDesktop();
|
|
||||||
if (_lastKnownInputDesktop != hDesk) {
|
|
||||||
_lastKnownInputDesktop = hDesk;
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
BOOST_LOG(warning) << "Couldn't send mouse scroll input"sv;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void keyboard(input_t &input, uint16_t modcode, bool release) {
|
void keyboard(input_t &input, uint16_t modcode, bool release) {
|
||||||
@ -304,16 +316,7 @@ void keyboard(input_t &input, uint16_t modcode, bool release) {
|
|||||||
ki.dwFlags |= KEYEVENTF_KEYUP;
|
ki.dwFlags |= KEYEVENTF_KEYUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
retry:
|
send_input(i);
|
||||||
auto send = SendInput(1, &i, sizeof(INPUT));
|
|
||||||
if(send != 1) {
|
|
||||||
auto hDesk = pairInputDesktop();
|
|
||||||
if (_lastKnownInputDesktop != hDesk) {
|
|
||||||
_lastKnownInputDesktop = hDesk;
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
BOOST_LOG(warning) << "Couldn't send keyboard input"sv;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int alloc_gamepad(input_t &input, int nr) {
|
int alloc_gamepad(input_t &input, int nr) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user