diff --git a/src/input.cpp b/src/input.cpp index 82c761af4..3c861fb12 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -902,6 +902,31 @@ namespace input { input->gamepads[packet->controllerNumber].id = id; } + /** + * @brief Normalizes coordinates to monitor-local logical touch dimensions. + * @param touch_port The current touch port metadata. + * @param coords The in/out coordinate pair to normalize. + * @return The monitor-local touch port, or std::nullopt if dimensions are invalid. + */ + std::optional monitor_touch_port(const input::touch_port_t &touch_port, std::pair &coords) { + const float monitor_logical_w = (touch_port.width * touch_port.scalar_inv) / touch_port.scalar_tpcoords; + const float monitor_logical_h = (touch_port.height * touch_port.scalar_inv) / touch_port.scalar_tpcoords; + if (monitor_logical_w <= 0.0f || monitor_logical_h <= 0.0f) { + BOOST_LOG(warning) << "Ignoring touch/pen input due to invalid logical touch dimensions"sv; + return std::nullopt; + } + + coords.first = (coords.first - touch_port.offset_x) / monitor_logical_w; + coords.second = (coords.second - touch_port.offset_y) / monitor_logical_h; + + return platf::touch_port_t { + touch_port.offset_x, + touch_port.offset_y, + static_cast(monitor_logical_w), + static_cast(monitor_logical_h) + }; + } + /** * @brief Called to pass a touch message to the platform backend. * @param input The input context pointer. @@ -919,16 +944,11 @@ namespace input { } auto &touch_port = input->touch_port; - platf::touch_port_t abs_port { - touch_port.offset_x, - touch_port.offset_y, - touch_port.env_width, - touch_port.env_height - }; - // Renormalize the coordinates - coords->first /= abs_port.width; - coords->second /= abs_port.height; + auto abs_port = monitor_touch_port(touch_port, *coords); + if (!abs_port) { + return; + } // Normalize rotation value to 0-359 degree range auto rotation = util::endian::little(packet->rotation); @@ -941,7 +961,7 @@ namespace input { {from_clamped_netfloat(packet->contactAreaMajor, 0.0f, 1.0f) * 65535.f, from_clamped_netfloat(packet->contactAreaMinor, 0.0f, 1.0f) * 65535.f}, rotation, - {abs_port.width / 65535.f, abs_port.height / 65535.f} + {abs_port->width / 65535.f, abs_port->height / 65535.f} ); platf::touch_input_t touch { @@ -955,7 +975,7 @@ namespace input { contact_area.second, }; - platf::touch_update(input->client_context.get(), abs_port, touch); + platf::touch_update(input->client_context.get(), *abs_port, touch); } /** @@ -975,16 +995,11 @@ namespace input { } auto &touch_port = input->touch_port; - platf::touch_port_t abs_port { - touch_port.offset_x, - touch_port.offset_y, - touch_port.env_width, - touch_port.env_height - }; - // Renormalize the coordinates - coords->first /= abs_port.width; - coords->second /= abs_port.height; + auto abs_port = monitor_touch_port(touch_port, *coords); + if (!abs_port) { + return; + } // Normalize rotation value to 0-359 degree range auto rotation = util::endian::little(packet->rotation); @@ -997,7 +1012,7 @@ namespace input { {from_clamped_netfloat(packet->contactAreaMajor, 0.0f, 1.0f) * 65535.f, from_clamped_netfloat(packet->contactAreaMinor, 0.0f, 1.0f) * 65535.f}, rotation, - {abs_port.width / 65535.f, abs_port.height / 65535.f} + {abs_port->width / 65535.f, abs_port->height / 65535.f} ); platf::pen_input_t pen { @@ -1013,7 +1028,7 @@ namespace input { contact_area.second, }; - platf::pen_update(input->client_context.get(), abs_port, pen); + platf::pen_update(input->client_context.get(), *abs_port, pen); } /** diff --git a/src/platform/linux/wlgrab.cpp b/src/platform/linux/wlgrab.cpp index 9ef3e09f9..589d034ab 100644 --- a/src/platform/linux/wlgrab.cpp +++ b/src/platform/linux/wlgrab.cpp @@ -74,10 +74,26 @@ namespace wl { this->env_width = ::wl::env_width; this->env_height = ::wl::env_height; + this->logical_width = monitor->viewport.logical_width; + this->logical_height = monitor->viewport.logical_height; + + int desktop_logical_width = 0; + int desktop_logical_height = 0; + for (auto &monitor_entry : interface.monitors) { + auto output_monitor = monitor_entry.get(); + desktop_logical_width = std::max(desktop_logical_width, output_monitor->viewport.offset_x + output_monitor->viewport.logical_width); + desktop_logical_height = std::max(desktop_logical_height, output_monitor->viewport.offset_y + output_monitor->viewport.logical_height); + } + + this->env_logical_width = desktop_logical_width; + this->env_logical_height = desktop_logical_height; + BOOST_LOG(info) << "Selected monitor ["sv << monitor->description << "] for streaming"sv; BOOST_LOG(debug) << "Offset: "sv << offset_x << 'x' << offset_y; BOOST_LOG(debug) << "Resolution: "sv << width << 'x' << height; + BOOST_LOG(debug) << "Logical Resolution: "sv << logical_width << 'x' << logical_height; BOOST_LOG(debug) << "Desktop Resolution: "sv << env_width << 'x' << env_height; + BOOST_LOG(debug) << "Logical Desktop Resolution: "sv << env_logical_width << 'x' << env_logical_height; return 0; }