From c04dcc2e7d834218ef2d4194331e383402495ae1 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 10 Apr 2024 20:07:22 +0200 Subject: Adding upstream version 2:20.4+dfsg. Signed-off-by: Daniel Baumann --- xbmc/windowing/wayland/InputProcessorTouch.cpp | 130 +++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 xbmc/windowing/wayland/InputProcessorTouch.cpp (limited to 'xbmc/windowing/wayland/InputProcessorTouch.cpp') diff --git a/xbmc/windowing/wayland/InputProcessorTouch.cpp b/xbmc/windowing/wayland/InputProcessorTouch.cpp new file mode 100644 index 0000000..a664e32 --- /dev/null +++ b/xbmc/windowing/wayland/InputProcessorTouch.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2017-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "InputProcessorTouch.h" + +#include "input/touch/generic/GenericTouchInputHandler.h" + +using namespace KODI::WINDOWING::WAYLAND; + +CInputProcessorTouch::CInputProcessorTouch(wayland::surface_t const& surface) +: m_surface{surface} +{ +} + +void CInputProcessorTouch::OnTouchDown(CSeat* seat, + std::uint32_t serial, + std::uint32_t time, + const wayland::surface_t& surface, + std::int32_t id, + double x, + double y) +{ + if (surface != m_surface) + { + return; + } + + // Find free Kodi pointer number + int kodiPointer{-1}; + // Not optimal, but irrelevant for the small number of iterations + for (int testPointer{0}; testPointer < CGenericTouchInputHandler::MAX_POINTERS; testPointer++) + { + if (std::all_of(m_touchPoints.cbegin(), m_touchPoints.cend(), + [=](decltype(m_touchPoints)::value_type const& pair) + { + return (pair.second.kodiPointerNumber != testPointer); + })) + { + kodiPointer = testPointer; + break; + } + } + + if (kodiPointer != -1) + { + auto it = m_touchPoints.emplace(std::piecewise_construct, std::forward_as_tuple(id), std::forward_as_tuple(time, kodiPointer, x * m_coordinateScale, y * m_coordinateScale, 0.0f)).first; + SendTouchPointEvent(TouchInputDown, it->second); + } +} + +void CInputProcessorTouch::OnTouchUp(CSeat* seat, std::uint32_t serial, std::uint32_t time, std::int32_t id) +{ + auto it = m_touchPoints.find(id); + if (it != m_touchPoints.end()) + { + auto& point = it->second; + point.lastEventTime = time; + SendTouchPointEvent(TouchInputUp, point); + m_touchPoints.erase(it); + } +} + +void CInputProcessorTouch::OnTouchMotion(CSeat* seat, std::uint32_t time, std::int32_t id, double x, double y) +{ + auto it = m_touchPoints.find(id); + if (it != m_touchPoints.end()) + { + auto& point = it->second; + point.x = x * m_coordinateScale; + point.y = y * m_coordinateScale; + point.lastEventTime = time; + SendTouchPointEvent(TouchInputMove, point); + } +} + +void CInputProcessorTouch::OnTouchCancel(CSeat* seat) +{ + AbortTouches(); +} + +void CInputProcessorTouch::OnTouchShape(CSeat* seat, std::int32_t id, double major, double minor) +{ + auto it = m_touchPoints.find(id); + if (it != m_touchPoints.end()) + { + auto& point = it->second; + // Kodi only supports size without shape, so use average of both axes + point.size = ((major + minor) / 2.0) * m_coordinateScale; + UpdateTouchPoint(point); + } +} + +CInputProcessorTouch::~CInputProcessorTouch() noexcept +{ + AbortTouches(); +} + +void CInputProcessorTouch::AbortTouches() +{ + // TouchInputAbort aborts for all pointers, so it does not matter which is specified + if (!m_touchPoints.empty()) + { + SendTouchPointEvent(TouchInputAbort, m_touchPoints.begin()->second); + } + m_touchPoints.clear(); +} + +void CInputProcessorTouch::SendTouchPointEvent(TouchInput event, const TouchPoint& point) +{ + if (event == TouchInputMove) + { + for (auto const& point : m_touchPoints) + { + // Contrary to the docs, this must be called before HandleTouchInput or the + // position will not be updated and gesture detection will not work + UpdateTouchPoint(point.second); + } + } + CGenericTouchInputHandler::GetInstance().HandleTouchInput(event, point.x, point.y, point.lastEventTime * INT64_C(1000000), point.kodiPointerNumber, point.size); +} + +void CInputProcessorTouch::UpdateTouchPoint(const TouchPoint& point) +{ + CGenericTouchInputHandler::GetInstance().UpdateTouchPointer(point.kodiPointerNumber, point.x, point.y, point.lastEventTime * INT64_C(1000000), point.size); +} -- cgit v1.2.3