diff --git a/sunshine/input.cpp b/sunshine/input.cpp index d3eed222..31a02ded 100644 --- a/sunshine/input.cpp +++ b/sunshine/input.cpp @@ -219,13 +219,21 @@ void passthrough(std::shared_ptr &input, PNV_ABS_MOUSE_MOVE_PACKET pack return; } - float width = util::endian::big(packet->width); - float height = util::endian::big(packet->height); + int width = util::endian::big(packet->width); + int height = util::endian::big(packet->height); - auto scale_x = (float)touch_port.width / width; - auto scale_y = (float)touch_port.height / height; + auto offsetX = (width - (float)touch_port.width) * 0.5f; + auto offsetY = (height - (float)touch_port.height) * 0.5f; - platf::abs_mouse(platf_input, touch_port, x * scale_x, y * scale_y); + std::clamp(x, offsetX, width - offsetX); + std::clamp(y, offsetX, height - offsetY); + + platf::touch_port_t abs_port { + touch_port.offset_x, touch_port.offset_y, + touch_port.env_width, touch_port.env_height + }; + + platf::abs_mouse(platf_input, abs_port, x - offsetX, y - offsetY); //touch_port, x * scale_x + offsetX, y * scale_y + offsetY); } void passthrough(std::shared_ptr &input, PNV_MOUSE_BUTTON_PACKET packet) { diff --git a/sunshine/platform/common.h b/sunshine/platform/common.h index 5522dba6..a47937b8 100644 --- a/sunshine/platform/common.h +++ b/sunshine/platform/common.h @@ -105,13 +105,10 @@ inline std::string_view from_pix_fmt(pix_fmt_e pix_fmt) { // Dimensions for touchscreen input struct touch_port_t { - std::uint32_t offset_x, offset_y; - std::uint32_t width, height; + int offset_x, offset_y; + int env_width, env_height; - constexpr touch_port_t( - std::uint32_t offset_x, std::uint32_t offset_y, - std::uint32_t width, std::uint32_t height) noexcept : offset_x { offset_x }, offset_y { offset_y }, - width { width }, height { height } {}; + int width, height; }; struct gamepad_state_t { @@ -202,6 +199,7 @@ public: // Offsets for when streaming a specific monitor. By default, they are 0. int offset_x, offset_y; + int env_width, env_height; int width, height; }; diff --git a/sunshine/platform/linux/display.cpp b/sunshine/platform/linux/display.cpp index 9abae925..867220d3 100644 --- a/sunshine/platform/linux/display.cpp +++ b/sunshine/platform/linux/display.cpp @@ -147,7 +147,7 @@ struct x11_attr_t : public display_t { * Last X (NOT the streamed monitor!) size. * This way we can trigger reinitialization if the dimensions changed while streaming */ - int lastWidth, lastHeight; + // int env_width, env_height; x11_attr_t(mem_type_e mem_type) : xdisplay { XOpenDisplay(nullptr) }, xwindow {}, xattr {}, mem_type { mem_type } { XInitThreads(); @@ -204,8 +204,8 @@ struct x11_attr_t : public display_t { height = xattr.height; } - lastWidth = xattr.width; - lastHeight = xattr.height; + env_width = xattr.width; + env_height = xattr.height; return 0; } @@ -221,7 +221,7 @@ struct x11_attr_t : public display_t { refresh(); //The whole X server changed, so we gotta reinit everything - if(xattr.width != lastWidth || xattr.height != lastHeight) { + if(xattr.width != env_width || xattr.height != env_height) { BOOST_LOG(warning) << "X dimensions changed in non-SHM mode, request reinit"sv; return capture_e::reinit; } @@ -289,7 +289,7 @@ struct shm_attr_t : public x11_attr_t { capture_e snapshot(img_t *img, std::chrono::milliseconds timeout, bool cursor) override { //The whole X server changed, so we gotta reinit everything - if(xattr.width != lastWidth || xattr.height != lastHeight) { + if(xattr.width != env_width || xattr.height != env_height) { BOOST_LOG(warning) << "X dimensions changed in SHM mode, request reinit"sv; return capture_e::reinit; } diff --git a/sunshine/platform/linux/input.cpp b/sunshine/platform/linux/input.cpp index ad3397d5..f7750462 100644 --- a/sunshine/platform/linux/input.cpp +++ b/sunshine/platform/linux/input.cpp @@ -145,8 +145,8 @@ public: void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) { auto touchscreen = ((input_raw_t *)input.get())->touch_input.get(); - auto scaled_x = (int)std::lround((x + touch_port.offset_x) * ((float)target_touch_port.width / (float)touch_port.width)); - auto scaled_y = (int)std::lround((y + touch_port.offset_y) * ((float)target_touch_port.height / (float)touch_port.height)); + auto scaled_x = (int)std::lround((x + touch_port.offset_x) * ((float)target_touch_port.env_width / (float)touch_port.env_width)); + auto scaled_y = (int)std::lround((y + touch_port.offset_y) * ((float)target_touch_port.env_height / (float)touch_port.env_height)); libevdev_uinput_write_event(touchscreen, EV_ABS, ABS_X, scaled_x); libevdev_uinput_write_event(touchscreen, EV_ABS, ABS_Y, scaled_y); @@ -470,7 +470,7 @@ evdev_t touchscreen() { input_absinfo absx { 0, 0, - target_touch_port.width, + target_touch_port.env_width, 1, 0, 28 @@ -479,7 +479,7 @@ evdev_t touchscreen() { input_absinfo absy { 0, 0, - target_touch_port.height, + target_touch_port.env_height, 1, 0, 28 diff --git a/sunshine/video.cpp b/sunshine/video.cpp index 6c4b490d..7df4efcb 100644 --- a/sunshine/video.cpp +++ b/sunshine/video.cpp @@ -1261,6 +1261,28 @@ void captureThreadSync() { while(encode_run_sync(synced_session_ctxs, ctx) == encode_e::reinit) {} } +platf::touch_port_t make_port(platf::display_t *display, const config_t &config) { + float wd = display->width; + float hd = display->height; + + float wt = config.width; + float ht = config.height; + + auto scalar = std::fminf(wt / wd, ht / hd); + + auto w2 = scalar * wd; + auto h2 = scalar * hd; + + return platf::touch_port_t { + display->offset_x, + display->offset_y, + display->env_width, + display->env_height, + (int)w2, + (int)h2, + }; +} + void capture_async( safe::mail_t mail, config_t &config, @@ -1323,7 +1345,7 @@ void capture_async( images->raise(std::move(dummy_img)); // absolute mouse coordinates require that the dimensions of the screen are known - touch_port_event->raise(display->offset_x, display->offset_y, display->width, display->height); + touch_port_event->raise(make_port(display.get(), config)); encode_run( frame_nr, key_frame_nr,