summaryrefslogtreecommitdiffstats
path: root/xbmc/input/joysticks/interfaces
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/input/joysticks/interfaces')
-rw-r--r--xbmc/input/joysticks/interfaces/IButtonMap.h343
-rw-r--r--xbmc/input/joysticks/interfaces/IButtonMapCallback.h47
-rw-r--r--xbmc/input/joysticks/interfaces/IButtonMapper.h124
-rw-r--r--xbmc/input/joysticks/interfaces/IButtonSequence.h31
-rw-r--r--xbmc/input/joysticks/interfaces/IDriverHandler.h77
-rw-r--r--xbmc/input/joysticks/interfaces/IDriverReceiver.h35
-rw-r--r--xbmc/input/joysticks/interfaces/IInputHandler.h169
-rw-r--r--xbmc/input/joysticks/interfaces/IInputProvider.h43
-rw-r--r--xbmc/input/joysticks/interfaces/IInputReceiver.h37
-rw-r--r--xbmc/input/joysticks/interfaces/IKeyHandler.h56
-rw-r--r--xbmc/input/joysticks/interfaces/IKeymapHandler.h52
11 files changed, 1014 insertions, 0 deletions
diff --git a/xbmc/input/joysticks/interfaces/IButtonMap.h b/xbmc/input/joysticks/interfaces/IButtonMap.h
new file mode 100644
index 0000000..0b4b7d5
--- /dev/null
+++ b/xbmc/input/joysticks/interfaces/IButtonMap.h
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2014-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/joysticks/DriverPrimitive.h"
+#include "input/joysticks/JoystickTypes.h"
+
+#include <string>
+#include <vector>
+
+namespace KODI
+{
+namespace JOYSTICK
+{
+/*!
+ * \ingroup joystick
+ * \brief Button map interface to translate between the driver's raw
+ * button/hat/axis elements and physical joystick features.
+ *
+ * \sa IButtonMapper
+ */
+class IButtonMap
+{
+public:
+ virtual ~IButtonMap() = default;
+
+ /*!
+ * \brief The add-on ID of the game controller associated with this button map
+ *
+ * The controller ID provided by the implementation serves as the context
+ * for the feature names below.
+ *
+ * \return The ID of this button map's game controller add-on
+ */
+ virtual std::string ControllerID(void) const = 0;
+
+ /*!
+ * \brief The Location of the peripheral associated with this button map
+ *
+ * \return The peripheral's location
+ */
+ virtual std::string Location(void) const = 0;
+
+ /*!
+ * \brief Load the button map into memory
+ *
+ * \return True if button map is ready to start translating buttons, false otherwise
+ */
+ virtual bool Load(void) = 0;
+
+ /*!
+ * \brief Reset the button map to its defaults, or clear button map if no defaults
+ */
+ virtual void Reset(void) = 0;
+
+ /*!
+ * \brief Check if the button map is empty
+ *
+ * \return True if the button map is empty, false if it has features
+ */
+ virtual bool IsEmpty(void) const = 0;
+
+ /*!
+ * \brief Get the ID of the controller profile that best represents the
+ * appearance of the peripheral
+ *
+ * \return The controller ID, or empty if the appearance is unknown
+ */
+ virtual std::string GetAppearance() const = 0;
+
+ /*!
+ * \brief Set the ID of the controller that best represents the appearance
+ * of the peripheral
+ *
+ * \param controllerId The controller ID, or empty to unset the appearance
+ *
+ * \return True if the appearance was set, false on error
+ */
+ virtual bool SetAppearance(const std::string& controllerId) const = 0;
+
+ /*!
+ * \brief Get the feature associated with a driver primitive
+ *
+ * Multiple primitives can be mapped to the same feature. For example,
+ * analog sticks use one primitive for each direction.
+ *
+ * \param primitive The driver primitive
+ * \param feature The name of the resolved joystick feature, or
+ * invalid if false is returned
+ *
+ * \return True if the driver primitive is associated with a feature, false otherwise
+ */
+ virtual bool GetFeature(const CDriverPrimitive& primitive, FeatureName& feature) = 0;
+
+ /*!
+ * \brief Get the type of the feature for the given name
+ *
+ * \param feature The feature to look up
+ *
+ * \return The feature's type
+ */
+ virtual FEATURE_TYPE GetFeatureType(const FeatureName& feature) = 0;
+
+ /*!
+ * \brief Get the driver primitive for a scalar feature
+ *
+ * When a feature can be represented by a single driver primitive, it is
+ * called a scalar feature.
+ *
+ * - This includes buttons and triggers, because they can be mapped to a
+ * single button/hat/semiaxis
+ *
+ * - This does not include analog sticks, because they require two axes
+ * and four driver primitives (one for each semiaxis)
+ *
+ * \param feature Must be a scalar feature (a feature that only
+ * requires a single driver primitive)
+ * \param primitive The resolved driver primitive
+ *
+ * \return True if the feature resolved to a driver primitive, false if the
+ * feature didn't resolve or isn't a scalar feature
+ */
+ virtual bool GetScalar(const FeatureName& feature, CDriverPrimitive& primitive) = 0;
+
+ /*!
+ * \brief Add or update a scalar feature
+ *
+ * \param feature Must be a scalar feature
+ * \param primitive The feature's driver primitive
+ *
+ * \return True if the feature was updated, false if the feature is
+ * unchanged or failure occurs
+ */
+ virtual void AddScalar(const FeatureName& feature, const CDriverPrimitive& primitive) = 0;
+
+ /*!
+ * \brief Get an analog stick direction from the button map
+ *
+ * \param feature Must be an analog stick or this will return false
+ * \param direction The direction whose primitive is to be retrieved
+ * \param[out] primitive The primitive mapped to the specified direction
+ *
+ * \return True if the feature and direction resolved to a driver primitive
+ */
+ virtual bool GetAnalogStick(const FeatureName& feature,
+ ANALOG_STICK_DIRECTION direction,
+ CDriverPrimitive& primitive) = 0;
+
+ /*!
+ * \brief Add or update an analog stick direction
+ *
+ * \param feature Must be an analog stick or this will return false
+ * \param direction The direction being mapped
+ * \param primitive The driver primitive for the specified analog stick and direction
+ *
+ * \return True if the analog stick was updated, false otherwise
+ */
+ virtual void AddAnalogStick(const FeatureName& feature,
+ ANALOG_STICK_DIRECTION direction,
+ const CDriverPrimitive& primitive) = 0;
+
+ /*!
+ * \brief Get a relative pointer direction from the button map
+ *
+ * \param feature Must be a relative pointer stick or this will return false
+ * \param direction The direction whose primitive is to be retrieved
+ * \param[out] primitive The primitive mapped to the specified direction
+ *
+ * \return True if the feature and direction resolved to a driver primitive
+ */
+ virtual bool GetRelativePointer(const FeatureName& feature,
+ RELATIVE_POINTER_DIRECTION direction,
+ CDriverPrimitive& primitive) = 0;
+
+ /*!
+ * \brief Add or update a relative pointer direction
+ *
+ * \param feature Must be a relative pointer or this will return false
+ * \param direction The direction being mapped
+ * \param primitive The driver primitive for the specified analog stick and direction
+ *
+ * \return True if the analog stick was updated, false otherwise
+ */
+ virtual void AddRelativePointer(const FeatureName& feature,
+ RELATIVE_POINTER_DIRECTION direction,
+ const CDriverPrimitive& primitive) = 0;
+
+ /*!
+ * \brief Get an accelerometer from the button map
+ *
+ * \param feature Must be an accelerometer or this will return false
+ * \param positiveX The semiaxis mapped to the positive X direction (possibly unknown)
+ * \param positiveY The semiaxis mapped to the positive Y direction (possibly unknown)
+ * \param positiveZ The semiaxis mapped to the positive Z direction (possibly unknown)
+ *
+ * \return True if the feature resolved to an accelerometer with at least 1 known axis
+ */
+ virtual bool GetAccelerometer(const FeatureName& feature,
+ CDriverPrimitive& positiveX,
+ CDriverPrimitive& positiveY,
+ CDriverPrimitive& positiveZ) = 0;
+
+ /*!
+ * \brief Get or update an accelerometer
+ *
+ * \param feature Must be an accelerometer or this will return false
+ * \param positiveX The semiaxis corresponding to the positive X direction
+ * \param positiveY The semiaxis corresponding to the positive Y direction
+ * \param positiveZ The semiaxis corresponding to the positive Z direction
+ *
+ * The driver primitives must be mapped to a semiaxis or this function will fail.
+ *
+ * \return True if the accelerometer was updated, false if unchanged or failure occurred
+ */
+ virtual void AddAccelerometer(const FeatureName& feature,
+ const CDriverPrimitive& positiveX,
+ const CDriverPrimitive& positiveY,
+ const CDriverPrimitive& positiveZ) = 0;
+
+ /*!
+ * \brief Get a wheel direction from the button map
+ *
+ * \param feature Must be a wheel or this will return false
+ * \param direction The direction whose primitive is to be retrieved
+ * \param[out] primitive The primitive mapped to the specified direction
+ *
+ * \return True if the feature and direction resolved to a driver primitive
+ */
+ virtual bool GetWheel(const FeatureName& feature,
+ WHEEL_DIRECTION direction,
+ CDriverPrimitive& primitive) = 0;
+
+ /*!
+ * \brief Add or update a wheel direction
+ *
+ * \param feature Must be a wheel or this will return false
+ * \param direction The direction being mapped
+ * \param primitive The driver primitive for the specified analog stick and direction
+ *
+ * \return True if the analog stick was updated, false otherwise
+ */
+ virtual void AddWheel(const FeatureName& feature,
+ WHEEL_DIRECTION direction,
+ const CDriverPrimitive& primitive) = 0;
+
+ /*!
+ * \brief Get a throttle direction from the button map
+ *
+ * \param feature Must be a throttle or this will return false
+ * \param direction The direction whose primitive is to be retrieved
+ * \param[out] primitive The primitive mapped to the specified direction
+ *
+ * \return True if the feature and direction resolved to a driver primitive
+ */
+ virtual bool GetThrottle(const FeatureName& feature,
+ THROTTLE_DIRECTION direction,
+ CDriverPrimitive& primitive) = 0;
+
+ /*!
+ * \brief Add or update a throttle direction
+ *
+ * \param feature Must be a throttle or this will return false
+ * \param direction The direction being mapped
+ * \param primitive The driver primitive for the specified analog stick and direction
+ *
+ * \return True if the analog stick was updated, false otherwise
+ */
+ virtual void AddThrottle(const FeatureName& feature,
+ THROTTLE_DIRECTION direction,
+ const CDriverPrimitive& primitive) = 0;
+
+ /*!
+ * \brief Get the driver primitive for a keyboard key
+ *
+ * \param feature Must be a key
+ * \param primitive The resolved driver primitive
+ *
+ * \return True if the feature resolved to a driver primitive, false if the
+ * feature didn't resolve or isn't a scalar feature
+ */
+ virtual bool GetKey(const FeatureName& feature, CDriverPrimitive& primitive) = 0;
+
+ /*!
+ * \brief Add or update a key
+ *
+ * \param feature Must be a key
+ * \param primitive The feature's driver primitive
+ *
+ * \return True if the feature was updated, false if the feature is
+ * unchanged or failure occurs
+ */
+ virtual void AddKey(const FeatureName& feature, const CDriverPrimitive& primitive) = 0;
+
+ /*!
+ * \brief Set a list of driver primitives to be ignored
+ *
+ * This is necessary to prevent features from interfering with the button
+ * mapping process. This includes accelerometers, as well as PS4 triggers
+ * which send both a button press and an analog value.
+ *
+ * \param primitives The driver primitives to be ignored
+ */
+ virtual void SetIgnoredPrimitives(const std::vector<CDriverPrimitive>& primitives) = 0;
+
+ /*!
+ * \brief Check if a primitive is in the list of primitives to be ignored
+ *
+ * \param primitive The primitive to check
+ *
+ * \return True if the primitive should be ignored in the mapping process
+ */
+ virtual bool IsIgnored(const CDriverPrimitive& primitive) = 0;
+
+ /*!
+ * \brief Get the properties of an axis
+ *
+ * \param axisIndex The index of the axis to check
+ * \param center[out] The center, if known
+ * \param range[out] The range, if known
+ *
+ * \return True if the properties are known, false otherwise
+ */
+ virtual bool GetAxisProperties(unsigned int axisIndex, int& center, unsigned int& range) = 0;
+
+ /*!
+ * \brief Save the button map
+ */
+ virtual void SaveButtonMap() = 0;
+
+ /*!
+ * \brief Revert changes to the button map since the last time it was loaded
+ * or committed to disk
+ */
+ virtual void RevertButtonMap() = 0;
+};
+} // namespace JOYSTICK
+} // namespace KODI
diff --git a/xbmc/input/joysticks/interfaces/IButtonMapCallback.h b/xbmc/input/joysticks/interfaces/IButtonMapCallback.h
new file mode 100644
index 0000000..40744f8
--- /dev/null
+++ b/xbmc/input/joysticks/interfaces/IButtonMapCallback.h
@@ -0,0 +1,47 @@
+/*
+ * 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
+
+namespace KODI
+{
+namespace JOYSTICK
+{
+/*!
+ * \brief Interface for handling button maps
+ */
+class IButtonMapCallback
+{
+public:
+ virtual ~IButtonMapCallback() = default;
+
+ /*!
+ * \brief Save the button map
+ */
+ virtual void SaveButtonMap() = 0;
+
+ /*!
+ * \brief Clear the list of ignored driver primitives
+ *
+ * Called if the user begins capturing primitives to be ignored, and
+ * no primitives are captured before the dialog is accepted by the user.
+ *
+ * In this case, the button mapper won't have been given access to the
+ * button map, so a callback is needed to indicate that no primitives were
+ * captured and the user accepted this.
+ */
+ virtual void ResetIgnoredPrimitives() = 0;
+
+ /*!
+ * \brief Revert changes to the button map since the last time it was loaded
+ * or committed to disk
+ */
+ virtual void RevertButtonMap() = 0;
+};
+} // namespace JOYSTICK
+} // namespace KODI
diff --git a/xbmc/input/joysticks/interfaces/IButtonMapper.h b/xbmc/input/joysticks/interfaces/IButtonMapper.h
new file mode 100644
index 0000000..d0784df
--- /dev/null
+++ b/xbmc/input/joysticks/interfaces/IButtonMapper.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2014-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/joysticks/JoystickTypes.h"
+
+#include <map>
+#include <string>
+
+class IKeymap;
+
+namespace KODI
+{
+namespace JOYSTICK
+{
+class CDriverPrimitive;
+class IButtonMap;
+class IButtonMapCallback;
+
+/*!
+ * \ingroup joystick
+ * \brief Button mapper interface to assign the driver's raw button/hat/axis
+ * elements to physical joystick features using a provided button map.
+ *
+ * \sa IButtonMap
+ */
+class IButtonMapper
+{
+public:
+ IButtonMapper() = default;
+
+ virtual ~IButtonMapper() = default;
+
+ /*!
+ * \brief The add-on ID of the game controller associated with this button mapper
+ *
+ * \return The ID of the add-on extending kodi.game.controller
+ */
+ virtual std::string ControllerID(void) const = 0;
+
+ /*!
+ * \brief Return true if the button mapper wants a cooldown between button
+ * mapping commands
+ *
+ * \return True to only send button mapping commands that occur after a small
+ * timeout from the previous command.
+ */
+ virtual bool NeedsCooldown(void) const = 0;
+
+ /*!
+ * \brief Return true if the button mapper accepts primitives of the given type
+ *
+ * \param type The primitive type
+ *
+ * \return True if the button mapper can map the primitive type, false otherwise
+ */
+ virtual bool AcceptsPrimitive(PRIMITIVE_TYPE type) const = 0;
+
+ /*!
+ * \brief Handle button/hat press or axis threshold
+ *
+ * \param buttonMap The button map being manipulated
+ * \param keymap An interface capable of translating features to Kodi actions
+ * \param primitive The driver primitive
+ *
+ * Called in the same thread as \ref IButtonMapper::OnFrame.
+ *
+ * \return True if driver primitive was mapped to a feature
+ */
+ virtual bool MapPrimitive(IButtonMap* buttonMap,
+ IKeymap* keyMap,
+ const CDriverPrimitive& primitive) = 0;
+
+ /*!
+ * \brief Called once per event frame to notify the implementation of motion status
+ *
+ * \param buttonMap The button map passed to MapPrimitive() (shall not be modified)
+ * \param bMotion True if a previously-mapped axis is still in motion
+ *
+ * This allows the implementer to wait for an axis to be centered before
+ * allowing it to be used as Kodi input.
+ *
+ * If mapping finishes on an axis, then the axis will still be pressed and
+ * sending input every frame when the mapping ends. For example, when the
+ * right analog stick is the last feature to be mapped, it is still pressed
+ * when mapping ends and immediately sends Volume Down actions.
+ *
+ * The fix is to allow implementers to wait until all axes are motionless
+ * before detaching themselves.
+ *
+ * Called in the same thread as \ref IButtonMapper::MapPrimitive.
+ */
+ virtual void OnEventFrame(const IButtonMap* buttonMap, bool bMotion) = 0;
+
+ /*!
+ * \brief Called when an axis has been detected after mapping began
+ *
+ * \param axisIndex The index of the axis being discovered
+ *
+ * Some joystick drivers don't report an initial value for analog axes.
+ *
+ * Called in the same thread as \ref IButtonMapper::MapPrimitive.
+ */
+ virtual void OnLateAxis(const IButtonMap* buttonMap, unsigned int axisIndex) = 0;
+
+ // Button map callback interface
+ void SetButtonMapCallback(const std::string& deviceLocation, IButtonMapCallback* callback)
+ {
+ m_callbacks[deviceLocation] = callback;
+ }
+ void ResetButtonMapCallbacks(void) { m_callbacks.clear(); }
+ std::map<std::string, IButtonMapCallback*>& ButtonMapCallbacks(void) { return m_callbacks; }
+
+private:
+ std::map<std::string, IButtonMapCallback*> m_callbacks; // Device location -> callback
+};
+} // namespace JOYSTICK
+} // namespace KODI
diff --git a/xbmc/input/joysticks/interfaces/IButtonSequence.h b/xbmc/input/joysticks/interfaces/IButtonSequence.h
new file mode 100644
index 0000000..5c642e6
--- /dev/null
+++ b/xbmc/input/joysticks/interfaces/IButtonSequence.h
@@ -0,0 +1,31 @@
+/*
+ * 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/joysticks/JoystickTypes.h"
+
+namespace KODI
+{
+namespace JOYSTICK
+{
+class IButtonSequence
+{
+public:
+ virtual ~IButtonSequence() = default;
+
+ virtual bool OnButtonPress(const FeatureName& feature) = 0;
+
+ /*!
+ * \brief Returns true if a sequence is being captured to prevent input
+ * from falling through to the application
+ */
+ virtual bool IsCapturing() = 0;
+};
+} // namespace JOYSTICK
+} // namespace KODI
diff --git a/xbmc/input/joysticks/interfaces/IDriverHandler.h b/xbmc/input/joysticks/interfaces/IDriverHandler.h
new file mode 100644
index 0000000..48e4da5
--- /dev/null
+++ b/xbmc/input/joysticks/interfaces/IDriverHandler.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014-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/joysticks/JoystickTypes.h"
+
+namespace KODI
+{
+namespace JOYSTICK
+{
+/*!
+ * \brief Interface defining methods to handle joystick events for raw driver
+ * elements (buttons, hats, axes)
+ */
+class IDriverHandler
+{
+public:
+ virtual ~IDriverHandler() = default;
+
+ /*!
+ * \brief Handle button motion
+ *
+ * \param buttonIndex The index of the button as reported by the driver
+ * \param bPressed true for press motion, false for release motion
+ *
+ * \return True if a press was handled, false otherwise
+ */
+ virtual bool OnButtonMotion(unsigned int buttonIndex, bool bPressed) = 0;
+
+ /*!
+ * \brief Handle hat motion
+ *
+ * \param hatIndex The index of the hat as reported by the driver
+ * \param state The direction the hat is now being pressed
+ *
+ * \return True if the new direction was handled, false otherwise
+ */
+ virtual bool OnHatMotion(unsigned int hatIndex, HAT_STATE state) = 0;
+
+ /*!
+ * \brief Handle axis motion
+ *
+ * If a joystick feature requires multiple axes (analog sticks, accelerometers),
+ * they can be buffered for later processing.
+ *
+ * \param axisIndex The index of the axis as reported by the driver
+ * \param position The position of the axis in the closed interval [-1.0, 1.0]
+ * \param center The center point of the axis (either -1, 0 or 1)
+ * \param range The maximum distance the axis can move (either 1 or 2)
+ *
+ * \return True if the motion was handled, false otherwise
+ */
+ virtual bool OnAxisMotion(unsigned int axisIndex,
+ float position,
+ int center,
+ unsigned int range) = 0;
+
+ /*!
+ * \brief Handle buffered input motion for features that require multiple axes
+ *
+ * OnInputFrame() is called at the end of the frame when all axis motions
+ * have been reported. This has several uses, including:
+ *
+ * - Combining multiple axes into a single analog stick or accelerometer event
+ * - Imitating an analog feature with a digital button so that events can be
+ * dispatched every frame.
+ */
+ virtual void OnInputFrame(void) = 0;
+};
+} // namespace JOYSTICK
+} // namespace KODI
diff --git a/xbmc/input/joysticks/interfaces/IDriverReceiver.h b/xbmc/input/joysticks/interfaces/IDriverReceiver.h
new file mode 100644
index 0000000..2a4ff6c
--- /dev/null
+++ b/xbmc/input/joysticks/interfaces/IDriverReceiver.h
@@ -0,0 +1,35 @@
+/*
+ * 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
+
+namespace KODI
+{
+namespace JOYSTICK
+{
+/*!
+ * \ingroup joystick
+ * \brief Interface for sending input events to joystick drivers
+ */
+class IDriverReceiver
+{
+public:
+ virtual ~IDriverReceiver() = default;
+
+ /*!
+ * \brief Set the value of a rumble motor
+ *
+ * \param motorIndex The driver index of the motor to rumble
+ * \param magnitude The motor's new magnitude of vibration in the closed interval [0, 1]
+ *
+ * \return True if the event was handled otherwise false
+ */
+ virtual bool SetMotorState(unsigned int motorIndex, float magnitude) = 0;
+};
+} // namespace JOYSTICK
+} // namespace KODI
diff --git a/xbmc/input/joysticks/interfaces/IInputHandler.h b/xbmc/input/joysticks/interfaces/IInputHandler.h
new file mode 100644
index 0000000..2ddbf5c
--- /dev/null
+++ b/xbmc/input/joysticks/interfaces/IInputHandler.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2014-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/joysticks/JoystickTypes.h"
+
+#include <string>
+
+namespace KODI
+{
+namespace JOYSTICK
+{
+class IInputReceiver;
+
+/*!
+ * \ingroup joystick
+ * \brief Interface for handling input events for game controllers
+ */
+class IInputHandler
+{
+public:
+ virtual ~IInputHandler() = default;
+
+ /*!
+ * \brief The add-on ID of the game controller associated with this input handler
+ *
+ * \return The ID of the add-on extending kodi.game.controller
+ */
+ virtual std::string ControllerID(void) const = 0;
+
+ /*!
+ * \brief Return true if the input handler accepts the given feature
+ *
+ * \param feature A feature belonging to the controller specified by ControllerID()
+ *
+ * \return True if the feature is used for input, false otherwise
+ */
+ virtual bool HasFeature(const FeatureName& feature) const = 0;
+
+ /*!
+ * \brief Return true if the input handler is currently accepting input for the
+ * given feature
+ *
+ * \param feature A feature belonging to the controller specified by ControllerID()
+ *
+ * \return True if the feature is currently accepting input, false otherwise
+ *
+ * This does not prevent the input events from being called, but can return
+ * false to indicate that input wasn't handled for the specified feature.
+ */
+ virtual bool AcceptsInput(const FeatureName& feature) const = 0;
+
+ /*!
+ * \brief A digital button has been pressed or released
+ *
+ * \param feature The feature being pressed
+ * \param bPressed True if pressed, false if released
+ *
+ * \return True if the event was handled otherwise false
+ */
+ virtual bool OnButtonPress(const FeatureName& feature, bool bPressed) = 0;
+
+ /*!
+ * \brief A digital button has been pressed for more than one event frame
+ *
+ * \param feature The feature being held
+ * \param holdTimeMs The time elapsed since the initial press (ms)
+ *
+ * If OnButtonPress() returns true for the initial press, then this callback
+ * is invoked on subsequent frames until the button is released.
+ */
+ virtual void OnButtonHold(const FeatureName& feature, unsigned int holdTimeMs) = 0;
+
+ /*!
+ * \brief An analog button (trigger or a pressure-sensitive button) has changed state
+ *
+ * \param feature The feature changing state
+ * \param magnitude The button pressure or trigger travel distance in the
+ * closed interval [0, 1]
+ * \param motionTimeMs The time elapsed since the magnitude was 0
+ *
+ * \return True if the event was handled otherwise false
+ */
+ virtual bool OnButtonMotion(const FeatureName& feature,
+ float magnitude,
+ unsigned int motionTimeMs) = 0;
+
+ /*!
+ * \brief An analog stick has moved
+ *
+ * \param feature The analog stick being moved
+ * \param x The x coordinate in the closed interval [-1, 1]
+ * \param y The y coordinate in the closed interval [-1, 1]
+ * \param motionTimeMs The time elapsed since this analog stick was centered,
+ * or 0 if the analog stick is centered
+ *
+ * \return True if the event was handled otherwise false
+ */
+ virtual bool OnAnalogStickMotion(const FeatureName& feature,
+ float x,
+ float y,
+ unsigned int motionTimeMs) = 0;
+
+ /*!
+ * \brief An accelerometer's state has changed
+ *
+ * \param feature The accelerometer being accelerated
+ * \param x The x coordinate in the closed interval [-1, 1]
+ * \param y The y coordinate in the closed interval [-1, 1]
+ * \param z The z coordinate in the closed interval [-1, 1]
+ *
+ * \return True if the event was handled otherwise false
+ */
+ virtual bool OnAccelerometerMotion(const FeatureName& feature, float x, float y, float z)
+ {
+ return false;
+ }
+
+ /*!
+ * \brief A wheel has changed state
+ *
+ * Left is negative position, right is positive position
+ *
+ * \param feature The wheel changing state
+ * \param position The position in the closed interval [-1, 1]
+ * \param motionTimeMs The time elapsed since the position was 0
+ *
+ * \return True if the event was handled otherwise false
+ */
+ virtual bool OnWheelMotion(const FeatureName& feature,
+ float position,
+ unsigned int motionTimeMs) = 0;
+
+ /*!
+ * \brief A throttle has changed state
+ *
+ * Up is positive position, down is negative position.
+ *
+ * \param feature The wheel changing state
+ * \param position The position in the closed interval [-1, 1]
+ * \param motionTimeMs The time elapsed since the position was 0
+ *
+ * \return True if the event was handled otherwise false
+ */
+ virtual bool OnThrottleMotion(const FeatureName& feature,
+ float position,
+ unsigned int motionTimeMs) = 0;
+
+ /*!
+ * \brief Called at the end of the frame that provided input
+ */
+ virtual void OnInputFrame() = 0;
+
+ // Input receiver interface
+ void SetInputReceiver(IInputReceiver* receiver) { m_receiver = receiver; }
+ void ResetInputReceiver(void) { m_receiver = nullptr; }
+ IInputReceiver* InputReceiver(void) { return m_receiver; }
+
+private:
+ IInputReceiver* m_receiver = nullptr;
+};
+} // namespace JOYSTICK
+} // namespace KODI
diff --git a/xbmc/input/joysticks/interfaces/IInputProvider.h b/xbmc/input/joysticks/interfaces/IInputProvider.h
new file mode 100644
index 0000000..09a0366
--- /dev/null
+++ b/xbmc/input/joysticks/interfaces/IInputProvider.h
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+namespace KODI
+{
+namespace JOYSTICK
+{
+class IInputHandler;
+
+/*!
+ * \ingroup joystick
+ * \brief Interface for classes that can provide input
+ */
+class IInputProvider
+{
+public:
+ virtual ~IInputProvider() = default;
+
+ /*!
+ * \brief Register a handler for the provided input
+ *
+ * \param handler The handler to receive input provided by this class
+ * \param bPromiscuous If true, receives all input (including handled input)
+ * in the background
+ */
+ virtual void RegisterInputHandler(IInputHandler* handler, bool bPromiscuous) = 0;
+
+ /*!
+ * \brief Unregister a handler
+ *
+ * \param handler The handler that was receiving input
+ */
+ virtual void UnregisterInputHandler(IInputHandler* handler) = 0;
+};
+} // namespace JOYSTICK
+} // namespace KODI
diff --git a/xbmc/input/joysticks/interfaces/IInputReceiver.h b/xbmc/input/joysticks/interfaces/IInputReceiver.h
new file mode 100644
index 0000000..400da3f
--- /dev/null
+++ b/xbmc/input/joysticks/interfaces/IInputReceiver.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014-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/joysticks/JoystickTypes.h"
+
+namespace KODI
+{
+namespace JOYSTICK
+{
+/*!
+ * \ingroup joystick
+ * \brief Interface for sending input events to game controllers
+ */
+class IInputReceiver
+{
+public:
+ virtual ~IInputReceiver() = default;
+
+ /*!
+ * \brief Set the value of a rumble motor
+ *
+ * \param feature The name of the motor to rumble
+ * \param magnitude The motor's new magnitude of vibration in the closed interval [0, 1]
+ *
+ * \return True if the event was handled otherwise false
+ */
+ virtual bool SetRumbleState(const FeatureName& feature, float magnitude) = 0;
+};
+} // namespace JOYSTICK
+} // namespace KODI
diff --git a/xbmc/input/joysticks/interfaces/IKeyHandler.h b/xbmc/input/joysticks/interfaces/IKeyHandler.h
new file mode 100644
index 0000000..30f49c5
--- /dev/null
+++ b/xbmc/input/joysticks/interfaces/IKeyHandler.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015-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
+
+namespace KODI
+{
+namespace JOYSTICK
+{
+/*!
+ * \ingroup joystick
+ * \brief Interface for handling keymap keys
+ *
+ * Keys can be mapped to analog actions (e.g. "AnalogSeekForward") or digital
+ * actions (e.g. "Up").
+ */
+class IKeyHandler
+{
+public:
+ virtual ~IKeyHandler() = default;
+
+ /*!
+ * \brief Return true if the key is "pressed" (has a magnitude greater
+ * than 0.5)
+ *
+ * \return True if the key is "pressed", false otherwise
+ */
+ virtual bool IsPressed() const = 0;
+
+ /*!
+ * \brief A key mapped to a digital feature has been pressed or released
+ *
+ * \param bPressed true if the key's button/axis is activated, false if deactivated
+ * \param holdTimeMs The held time in ms for pressed buttons, or 0 for released
+ *
+ * \return True if the key is mapped to an action, false otherwise
+ */
+ virtual bool OnDigitalMotion(bool bPressed, unsigned int holdTimeMs) = 0;
+
+ /*!
+ * \brief Callback for keys mapped to analog features
+ *
+ * \param magnitude The amount of the analog action
+ * \param motionTimeMs The time since the magnitude was 0
+ *
+ * \return True if the key is mapped to an action, false otherwise
+ */
+ virtual bool OnAnalogMotion(float magnitude, unsigned int motionTimeMs) = 0;
+};
+} // namespace JOYSTICK
+} // namespace KODI
diff --git a/xbmc/input/joysticks/interfaces/IKeymapHandler.h b/xbmc/input/joysticks/interfaces/IKeymapHandler.h
new file mode 100644
index 0000000..f0af427
--- /dev/null
+++ b/xbmc/input/joysticks/interfaces/IKeymapHandler.h
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <set>
+#include <string>
+
+namespace KODI
+{
+namespace JOYSTICK
+{
+/*!
+ * \ingroup joystick
+ * \brief Interface for a class working with a keymap
+ */
+class IKeymapHandler
+{
+public:
+ virtual ~IKeymapHandler() = default;
+
+ /*!
+ * \brief Get the pressed state of the given keys
+ *
+ * \param keyNames The key names
+ *
+ * \return True if all keys are pressed or no keys are given, false otherwise
+ */
+ virtual bool HotkeysPressed(const std::set<std::string>& keyNames) const = 0;
+
+ /*!
+ * \brief Get the key name of the last button pressed
+ *
+ * \return The key name of the last-pressed button, or empty if no button
+ * is pressed
+ */
+ virtual std::string GetLastPressed() const = 0;
+
+ /*!
+ * \brief Called when a key has emitted an action after bring pressed
+ *
+ * \param keyName the key name that emitted the action
+ */
+ virtual void OnPress(const std::string& keyName) = 0;
+};
+} // namespace JOYSTICK
+} // namespace KODI