summaryrefslogtreecommitdiffstats
path: root/xbmc/input/mouse/generic
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--xbmc/input/mouse/generic/CMakeLists.txt5
-rw-r--r--xbmc/input/mouse/generic/MouseInputHandling.cpp352
-rw-r--r--xbmc/input/mouse/generic/MouseInputHandling.h66
3 files changed, 423 insertions, 0 deletions
diff --git a/xbmc/input/mouse/generic/CMakeLists.txt b/xbmc/input/mouse/generic/CMakeLists.txt
new file mode 100644
index 0000000..b5c2858
--- /dev/null
+++ b/xbmc/input/mouse/generic/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(SOURCES MouseInputHandling.cpp)
+
+set(HEADERS MouseInputHandling.h)
+
+core_add_library(input_mouse_generic)
diff --git a/xbmc/input/mouse/generic/MouseInputHandling.cpp b/xbmc/input/mouse/generic/MouseInputHandling.cpp
new file mode 100644
index 0000000..0f51ede
--- /dev/null
+++ b/xbmc/input/mouse/generic/MouseInputHandling.cpp
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2016-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 "MouseInputHandling.h"
+
+#include "input/InputTranslator.h"
+#include "input/joysticks/interfaces/IButtonMap.h"
+#include "input/mouse/interfaces/IMouseInputHandler.h"
+
+using namespace KODI;
+using namespace MOUSE;
+
+CMouseInputHandling::CMouseInputHandling(IMouseInputHandler* handler,
+ JOYSTICK::IButtonMap* buttonMap)
+ : m_handler(handler), m_buttonMap(buttonMap)
+{
+}
+
+bool CMouseInputHandling::OnPosition(int x, int y)
+{
+ using namespace JOYSTICK;
+
+ if (!m_bHasPosition)
+ {
+ m_bHasPosition = true;
+ m_x = x;
+ m_y = y;
+ return true;
+ }
+
+ int dx = x - m_x;
+ int dy = y - m_y;
+
+ bool bHandled = false;
+
+ // Get direction of motion
+ POINTER_DIRECTION dir = GetPointerDirection(dx, dy);
+
+ CDriverPrimitive source(dir);
+ if (source.IsValid())
+ {
+ // Get pointer in direction of motion
+ PointerName pointerName;
+ if (m_buttonMap->GetFeature(source, pointerName))
+ {
+ // Get orthogonal direction of motion
+ POINTER_DIRECTION dirCCW = GetOrthogonalDirectionCCW(dir);
+
+ // Get mapped directions of motion for rotation and reflection
+ CDriverPrimitive target;
+ CDriverPrimitive targetCCW;
+
+ if (m_buttonMap->GetRelativePointer(pointerName, dir, target))
+ m_buttonMap->GetRelativePointer(pointerName, dirCCW, targetCCW);
+
+ if (target.IsValid())
+ {
+ // Invert y to right-handed cartesian system
+ dy *= -1;
+
+ // Perform rotation
+ int rotation[2][2] = {{1, 0}, {0, 1}};
+
+ GetRotation(dir, target.PointerDirection(), rotation);
+
+ dx = rotation[0][0] * dx + rotation[0][1] * dy;
+ dy = rotation[1][0] * dx + rotation[1][1] * dy;
+
+ if (targetCCW.IsValid())
+ {
+ // Perform reflection
+ int reflection[2][2] = {{1, 0}, {0, 1}};
+
+ GetReflectionCCW(target.PointerDirection(), targetCCW.PointerDirection(), reflection);
+
+ dx = reflection[0][0] * dx + reflection[0][1] * dy;
+ dy = reflection[1][0] * dx + reflection[1][1] * dy;
+ }
+
+ // Invert y back to left-handed coordinate system
+ dy *= -1;
+ }
+
+ bHandled = m_handler->OnMotion(pointerName, dx, dy);
+ }
+ }
+ else
+ {
+ // Don't fall through - might disrupt the game
+ bHandled = true;
+ }
+
+ m_x = x;
+ m_y = y;
+
+ return bHandled;
+}
+
+bool CMouseInputHandling::OnButtonPress(BUTTON_ID button)
+{
+ bool bHandled = false;
+
+ JOYSTICK::CDriverPrimitive source(button);
+
+ ButtonName buttonName;
+ if (m_buttonMap->GetFeature(source, buttonName))
+ bHandled = m_handler->OnButtonPress(buttonName);
+
+ return bHandled;
+}
+
+void CMouseInputHandling::OnButtonRelease(BUTTON_ID button)
+{
+ JOYSTICK::CDriverPrimitive source(button);
+
+ ButtonName buttonName;
+ if (m_buttonMap->GetFeature(source, buttonName))
+ m_handler->OnButtonRelease(buttonName);
+}
+
+POINTER_DIRECTION CMouseInputHandling::GetPointerDirection(int x, int y)
+{
+ using namespace INPUT;
+
+ return CInputTranslator::VectorToCardinalDirection(static_cast<float>(x), static_cast<float>(-y));
+}
+
+POINTER_DIRECTION CMouseInputHandling::GetOrthogonalDirectionCCW(POINTER_DIRECTION direction)
+{
+ switch (direction)
+ {
+ case POINTER_DIRECTION::RIGHT:
+ return POINTER_DIRECTION::UP;
+ case POINTER_DIRECTION::UP:
+ return POINTER_DIRECTION::LEFT;
+ case POINTER_DIRECTION::LEFT:
+ return POINTER_DIRECTION::DOWN;
+ case POINTER_DIRECTION::DOWN:
+ return POINTER_DIRECTION::RIGHT;
+ default:
+ break;
+ }
+
+ return POINTER_DIRECTION::NONE;
+}
+
+void CMouseInputHandling::GetRotation(POINTER_DIRECTION source,
+ POINTER_DIRECTION target,
+ int (&rotation)[2][2])
+{
+ switch (source)
+ {
+ case POINTER_DIRECTION::RIGHT:
+ {
+ switch (target)
+ {
+ case POINTER_DIRECTION::UP:
+ GetRotation(90, rotation);
+ break;
+ case POINTER_DIRECTION::LEFT:
+ GetRotation(180, rotation);
+ break;
+ case POINTER_DIRECTION::DOWN:
+ GetRotation(270, rotation);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case POINTER_DIRECTION::UP:
+ {
+ switch (target)
+ {
+ case POINTER_DIRECTION::LEFT:
+ GetRotation(90, rotation);
+ break;
+ case POINTER_DIRECTION::DOWN:
+ GetRotation(180, rotation);
+ break;
+ case POINTER_DIRECTION::RIGHT:
+ GetRotation(270, rotation);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case POINTER_DIRECTION::LEFT:
+ {
+ switch (target)
+ {
+ case POINTER_DIRECTION::DOWN:
+ GetRotation(90, rotation);
+ break;
+ case POINTER_DIRECTION::RIGHT:
+ GetRotation(180, rotation);
+ break;
+ case POINTER_DIRECTION::UP:
+ GetRotation(270, rotation);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case POINTER_DIRECTION::DOWN:
+ {
+ switch (target)
+ {
+ case POINTER_DIRECTION::RIGHT:
+ GetRotation(90, rotation);
+ break;
+ case POINTER_DIRECTION::UP:
+ GetRotation(180, rotation);
+ break;
+ case POINTER_DIRECTION::LEFT:
+ GetRotation(270, rotation);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void CMouseInputHandling::GetRotation(int deg, int (&rotation)[2][2])
+{
+ switch (deg)
+ {
+ case 90:
+ {
+ rotation[0][0] = 0;
+ rotation[0][1] = -1;
+ rotation[1][0] = 1;
+ rotation[1][1] = 0;
+ break;
+ }
+ case 180:
+ {
+ rotation[0][0] = -1;
+ rotation[0][1] = 0;
+ rotation[1][0] = 0;
+ rotation[1][1] = -1;
+ break;
+ }
+ case 270:
+ {
+ rotation[0][0] = 0;
+ rotation[0][1] = 1;
+ rotation[1][0] = -1;
+ rotation[1][1] = 0;
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void CMouseInputHandling::GetReflectionCCW(POINTER_DIRECTION source,
+ POINTER_DIRECTION target,
+ int (&rotation)[2][2])
+{
+ switch (source)
+ {
+ case POINTER_DIRECTION::RIGHT:
+ {
+ switch (target)
+ {
+ case POINTER_DIRECTION::DOWN:
+ GetReflection(0, rotation);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case POINTER_DIRECTION::UP:
+ {
+ switch (target)
+ {
+ case POINTER_DIRECTION::RIGHT:
+ GetReflection(90, rotation);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case POINTER_DIRECTION::LEFT:
+ {
+ switch (target)
+ {
+ case POINTER_DIRECTION::UP:
+ GetReflection(180, rotation);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case POINTER_DIRECTION::DOWN:
+ {
+ switch (target)
+ {
+ case POINTER_DIRECTION::LEFT:
+ GetReflection(270, rotation);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void CMouseInputHandling::GetReflection(int deg, int (&reflection)[2][2])
+{
+ switch (deg)
+ {
+ case 0:
+ case 180:
+ {
+ reflection[0][0] = 1;
+ reflection[0][1] = 0;
+ reflection[1][0] = 0;
+ reflection[1][1] = -1;
+ break;
+ }
+ case 90:
+ case 270:
+ {
+ reflection[0][0] = -1;
+ reflection[0][1] = 0;
+ reflection[1][0] = 0;
+ reflection[1][1] = 1;
+ break;
+ }
+ default:
+ break;
+ }
+}
diff --git a/xbmc/input/mouse/generic/MouseInputHandling.h b/xbmc/input/mouse/generic/MouseInputHandling.h
new file mode 100644
index 0000000..6d19da9
--- /dev/null
+++ b/xbmc/input/mouse/generic/MouseInputHandling.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016-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.
+ */
+
+#pragma once
+
+#include "input/mouse/MouseTypes.h"
+#include "input/mouse/interfaces/IMouseDriverHandler.h"
+
+namespace KODI
+{
+namespace JOYSTICK
+{
+class IButtonMap;
+}
+
+namespace MOUSE
+{
+class IMouseInputHandler;
+
+/*!
+ * \ingroup mouse
+ * \brief Class to translate input from driver info to higher-level features
+ */
+class CMouseInputHandling : public IMouseDriverHandler
+{
+public:
+ CMouseInputHandling(IMouseInputHandler* handler, JOYSTICK::IButtonMap* buttonMap);
+
+ ~CMouseInputHandling(void) override = default;
+
+ // implementation of IMouseDriverHandler
+ bool OnPosition(int x, int y) override;
+ bool OnButtonPress(BUTTON_ID button) override;
+ void OnButtonRelease(BUTTON_ID button) override;
+
+private:
+ // Utility functions
+ static POINTER_DIRECTION GetPointerDirection(int x, int y);
+ static POINTER_DIRECTION GetOrthogonalDirectionCCW(POINTER_DIRECTION direction);
+
+ static void GetRotation(POINTER_DIRECTION source,
+ POINTER_DIRECTION target,
+ int (&rotation)[2][2]);
+ static void GetRotation(int deg, int (&rotation)[2][2]);
+
+ static void GetReflectionCCW(POINTER_DIRECTION source,
+ POINTER_DIRECTION target,
+ int (&reflection)[2][2]);
+ static void GetReflection(int deg, int (&reflection)[2][2]);
+
+ // Construction parameters
+ IMouseInputHandler* const m_handler;
+ JOYSTICK::IButtonMap* const m_buttonMap;
+
+ // Mouse parameters
+ bool m_bHasPosition = false;
+ int m_x = 0;
+ int m_y = 0;
+};
+} // namespace MOUSE
+} // namespace KODI