aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett Brown <themagnificentmrb@gmail.com>2018-02-07 21:36:33 -0800
committerGitHub <noreply@github.com>2018-02-07 21:36:33 -0800
commit61febe46913c120ba796243134b2514cbfb5603f (patch)
tree46346c2ccad2a53e3b662a7c4f2805312dd84512
parent42594024405891635ba2001944881e71364c651b (diff)
parent413167c4f6acacc974cbd9c292b021a607d4d977 (diff)
Merge pull request #13482 from garbear/mouse-mapping
Games: Mouse remapping support
-rw-r--r--addons/resource.language.en_gb/resources/strings.po8
-rw-r--r--xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Peripheral.h151
-rw-r--r--xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/PeripheralUtils.h185
-rw-r--r--xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_dll.h11
-rw-r--r--xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_types.h2
-rw-r--r--xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h6
-rw-r--r--xbmc/games/GameServices.cpp5
-rw-r--r--xbmc/games/GameServices.h1
-rw-r--r--xbmc/games/addons/input/GameClientInput.cpp65
-rw-r--r--xbmc/games/addons/input/GameClientMouse.cpp16
-rw-r--r--xbmc/games/addons/input/GameClientMouse.h4
-rw-r--r--xbmc/games/controllers/ControllerIDs.h1
-rw-r--r--xbmc/games/controllers/ControllerManager.cpp5
-rw-r--r--xbmc/games/controllers/ControllerManager.h7
-rw-r--r--xbmc/games/controllers/guicontrols/CMakeLists.txt4
-rw-r--r--xbmc/games/controllers/guicontrols/GUICardinalFeatureButton.cpp (renamed from xbmc/games/controllers/guicontrols/GUIAnalogStickButton.cpp)40
-rw-r--r--xbmc/games/controllers/guicontrols/GUICardinalFeatureButton.h (renamed from xbmc/games/controllers/guicontrols/GUIAnalogStickButton.h)25
-rw-r--r--xbmc/games/controllers/guicontrols/GUIControlTypes.h1
-rw-r--r--xbmc/games/controllers/guicontrols/GUIFeatureButton.h6
-rw-r--r--xbmc/games/controllers/guicontrols/GUIFeatureFactory.cpp5
-rw-r--r--xbmc/games/controllers/guicontrols/GUIFeatureTranslator.cpp4
-rw-r--r--xbmc/games/controllers/guicontrols/GUIThrottleButton.cpp2
-rw-r--r--xbmc/games/controllers/guicontrols/GUIWheelButton.cpp2
-rw-r--r--xbmc/games/controllers/windows/GUIConfigurationWizard.cpp143
-rw-r--r--xbmc/games/controllers/windows/GUIConfigurationWizard.h11
-rw-r--r--xbmc/games/controllers/windows/IConfigurationWindow.h10
-rw-r--r--xbmc/guilib/GUIControl.cpp2
-rw-r--r--xbmc/input/ButtonTranslator.cpp6
-rw-r--r--xbmc/input/CMakeLists.txt11
-rw-r--r--xbmc/input/InputManager.cpp63
-rw-r--r--xbmc/input/InputManager.h20
-rw-r--r--xbmc/input/InputTranslator.cpp51
-rw-r--r--xbmc/input/InputTranslator.h66
-rw-r--r--xbmc/input/InputTypes.h54
-rw-r--r--xbmc/input/JoystickMapper.cpp2
-rw-r--r--xbmc/input/joysticks/DriverPrimitive.cpp35
-rw-r--r--xbmc/input/joysticks/DriverPrimitive.h30
-rw-r--r--xbmc/input/joysticks/JoystickTranslator.cpp22
-rw-r--r--xbmc/input/joysticks/JoystickTranslator.h15
-rw-r--r--xbmc/input/joysticks/JoystickTypes.h43
-rw-r--r--xbmc/input/joysticks/JoystickUtils.cpp6
-rw-r--r--xbmc/input/joysticks/generic/ButtonMapping.cpp98
-rw-r--r--xbmc/input/joysticks/generic/ButtonMapping.h68
-rw-r--r--xbmc/input/joysticks/generic/FeatureHandling.cpp6
-rw-r--r--xbmc/input/joysticks/interfaces/IButtonMap.h6
-rw-r--r--xbmc/input/joysticks/keymaps/KeymapHandler.cpp11
-rw-r--r--xbmc/input/mouse/CMakeLists.txt12
-rw-r--r--xbmc/input/mouse/MouseStat.cpp (renamed from xbmc/input/MouseStat.cpp)0
-rw-r--r--xbmc/input/mouse/MouseStat.h (renamed from xbmc/input/MouseStat.h)0
-rw-r--r--xbmc/input/mouse/MouseTranslator.cpp (renamed from xbmc/input/MouseTranslator.cpp)61
-rw-r--r--xbmc/input/mouse/MouseTranslator.h (renamed from xbmc/input/MouseTranslator.h)15
-rw-r--r--xbmc/input/mouse/MouseTypes.h66
-rw-r--r--xbmc/input/mouse/MouseWindowingButtonMap.cpp84
-rw-r--r--xbmc/input/mouse/MouseWindowingButtonMap.h52
-rw-r--r--xbmc/input/mouse/generic/MouseInputHandling.cpp318
-rw-r--r--xbmc/input/mouse/generic/MouseInputHandling.h31
-rw-r--r--xbmc/input/mouse/interfaces/IMouseButtonMap.h78
-rw-r--r--xbmc/input/mouse/interfaces/IMouseDriverHandler.h9
-rw-r--r--xbmc/input/mouse/interfaces/IMouseInputHandler.h11
-rw-r--r--xbmc/input/mouse/interfaces/IMouseInputProvider.h10
-rw-r--r--xbmc/peripherals/PeripheralTypes.h10
-rw-r--r--xbmc/peripherals/Peripherals.cpp7
-rw-r--r--xbmc/peripherals/addons/AddonButtonMap.cpp45
-rw-r--r--xbmc/peripherals/addons/AddonButtonMap.h7
-rw-r--r--xbmc/peripherals/addons/AddonButtonMapping.cpp22
-rw-r--r--xbmc/peripherals/addons/AddonButtonMapping.h7
-rw-r--r--xbmc/peripherals/addons/AddonInputHandling.cpp47
-rw-r--r--xbmc/peripherals/addons/AddonInputHandling.h19
-rw-r--r--xbmc/peripherals/addons/PeripheralAddon.cpp14
-rw-r--r--xbmc/peripherals/addons/PeripheralAddonTranslator.cpp93
-rw-r--r--xbmc/peripherals/addons/PeripheralAddonTranslator.h7
-rw-r--r--xbmc/peripherals/bus/virtual/PeripheralBusApplication.cpp22
-rw-r--r--xbmc/peripherals/devices/CMakeLists.txt2
-rw-r--r--xbmc/peripherals/devices/Peripheral.cpp23
-rw-r--r--xbmc/peripherals/devices/Peripheral.h17
-rw-r--r--xbmc/peripherals/devices/PeripheralJoystick.cpp4
-rw-r--r--xbmc/peripherals/devices/PeripheralMouse.cpp144
-rw-r--r--xbmc/peripherals/devices/PeripheralMouse.h58
-rw-r--r--xbmc/platform/android/activity/AndroidMouse.cpp2
-rw-r--r--xbmc/platform/android/activity/XBMCApp.cpp2
-rw-r--r--xbmc/platform/darwin/ios/IOSExternalTouchController.mm2
-rw-r--r--xbmc/platform/linux/input/LinuxInputDevices.cpp4
-rw-r--r--xbmc/windowing/WinEventsLinux.cpp2
-rw-r--r--xbmc/windowing/X11/WinEventsX11.cpp2
-rw-r--r--xbmc/windowing/mir/WinEventsMir.cpp2
-rw-r--r--xbmc/windowing/osx/WinEventsSDL.cpp2
-rw-r--r--xbmc/windowing/wayland/InputProcessorPointer.cpp2
-rw-r--r--xbmc/windowing/win10/WinEventsWin10.cpp6
-rw-r--r--xbmc/windowing/windows/WinEventsWin32.cpp4
-rw-r--r--xbmc/windows/GUIWindowPointer.cpp2
90 files changed, 2025 insertions, 637 deletions
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po
index 184f64e309..bccb29802f 100644
--- a/addons/resource.language.en_gb/resources/strings.po
+++ b/addons/resource.language.en_gb/resources/strings.po
@@ -17412,7 +17412,13 @@ msgctxt "#35170"
msgid "Press a key ({1:d})"
msgstr ""
-#empty strings from id 35171 to 35199
+#. Name of mouse connected to the computer
+#: xbmc/peripherals/bus/virtual/PeripheralBusApplication.cpp
+msgctxt "#35171"
+msgid "Mouse"
+msgstr ""
+
+#empty strings from id 35172 to 35199
#. This string is an early meme from the late 1990's that made fun of the poor translation in the 16-bit game Zero Wing from the late 1980's. DO NOT TRANSLATE!
#: system/settings/settings.xml
diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Peripheral.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Peripheral.h
index b50c300a12..75be27eb3a 100644
--- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Peripheral.h
+++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Peripheral.h
@@ -34,6 +34,10 @@ extern "C"
/// @name Peripheral types
///{
+
+ /*!
+ * @brief API error codes
+ */
typedef enum PERIPHERAL_ERROR
{
PERIPHERAL_NO_ERROR = 0, // no error occurred
@@ -45,6 +49,9 @@ extern "C"
PERIPHERAL_ERROR_CONNECTION_FAILED = -6, // peripherals are connected, but command was interrupted
} PERIPHERAL_ERROR;
+ /*!
+ * @brief Peripheral types
+ */
typedef enum PERIPHERAL_TYPE
{
PERIPHERAL_TYPE_UNKNOWN,
@@ -52,6 +59,9 @@ extern "C"
PERIPHERAL_TYPE_KEYBOARD,
} PERIPHERAL_TYPE;
+ /*!
+ * @brief Information shared between peripherals
+ */
typedef struct PERIPHERAL_INFO
{
PERIPHERAL_TYPE type; /*!< @brief type of peripheral */
@@ -63,8 +73,6 @@ extern "C"
/*!
* @brief Peripheral add-on capabilities.
- * If a capability is set to true, then the corresponding methods from
- * kodi_peripheral_dll.h need to be implemented.
*/
typedef struct PERIPHERAL_CAPABILITIES
{
@@ -77,6 +85,10 @@ extern "C"
/// @name Event types
///{
+
+ /*!
+ * @brief Types of events that can be sent and received
+ */
typedef enum PERIPHERAL_EVENT_TYPE
{
PERIPHERAL_EVENT_TYPE_NONE, /*!< @brief unknown event */
@@ -86,12 +98,18 @@ extern "C"
PERIPHERAL_EVENT_TYPE_SET_MOTOR, /*!< @brief set the state for joystick rumble motor */
} PERIPHERAL_EVENT_TYPE;
+ /*!
+ * @brief States a button can have
+ */
typedef enum JOYSTICK_STATE_BUTTON
{
JOYSTICK_STATE_BUTTON_UNPRESSED = 0x0, /*!< @brief button is released */
JOYSTICK_STATE_BUTTON_PRESSED = 0x1, /*!< @brief button is pressed */
} JOYSTICK_STATE_BUTTON;
+ /*!
+ * @brief States a D-pad (also called a hat) can have
+ */
typedef enum JOYSTICK_STATE_HAT
{
JOYSTICK_STATE_HAT_UNPRESSED = 0x0, /*!< @brief no directions are pressed */
@@ -106,7 +124,7 @@ extern "C"
} JOYSTICK_STATE_HAT;
/*!
- * @brief value in the closed interval [-1.0, 1.0]
+ * @brief Axis value in the closed interval [-1.0, 1.0]
*
* The axis state uses the XInput coordinate system:
* - Negative values signify down or to the left
@@ -114,13 +132,25 @@ extern "C"
*/
typedef float JOYSTICK_STATE_AXIS;
+ /*!
+ * @brief Motor value in the closed interval [0.0, 1.0]
+ */
typedef float JOYSTICK_STATE_MOTOR;
+ /*!
+ * @brief Event information
+ */
typedef struct PERIPHERAL_EVENT
{
- unsigned int peripheral_index;
- PERIPHERAL_EVENT_TYPE type;
- unsigned int driver_index;
+ /*! @brief Index of the peripheral handling/receiving the event */
+ unsigned int peripheral_index;
+
+ /*! @brief Type of the event used to determine which enum field to access below */
+ PERIPHERAL_EVENT_TYPE type;
+
+ /*! @brief The index of the event source */
+ unsigned int driver_index;
+
JOYSTICK_STATE_BUTTON driver_button_state;
JOYSTICK_STATE_HAT driver_hat_state;
JOYSTICK_STATE_AXIS driver_axis_state;
@@ -130,6 +160,10 @@ extern "C"
/// @name Joystick types
///{
+
+ /*!
+ * @brief Info specific to joystick peripherals
+ */
typedef struct JOYSTICK_INFO
{
PERIPHERAL_INFO peripheral; /*!< @brief peripheral info for this joystick */
@@ -142,6 +176,15 @@ extern "C"
bool supports_poweroff; /*!< @brief whether the joystick supports being powered off */
} ATTRIBUTE_PACKED JOYSTICK_INFO;
+ /*!
+ * @brief Driver input primitives
+ *
+ * Mapping lower-level driver values to higher-level controller features is
+ * non-injective; two triggers can share a single axis.
+ *
+ * To handle this, driver values are subdivided into "primitives" that map
+ * injectively to higher-level features.
+ */
typedef enum JOYSTICK_DRIVER_PRIMITIVE_TYPE
{
JOYSTICK_DRIVER_PRIMITIVE_TYPE_UNKNOWN,
@@ -150,13 +193,21 @@ extern "C"
JOYSTICK_DRIVER_PRIMITIVE_TYPE_SEMIAXIS,
JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR,
JOYSTICK_DRIVER_PRIMITIVE_TYPE_KEY,
+ JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOUSE_BUTTON,
+ JOYSTICK_DRIVER_PRIMITIVE_TYPE_RELPOINTER_DIRECTION,
} JOYSTICK_DRIVER_PRIMITIVE_TYPE;
+ /*!
+ * @brief Button primitive
+ */
typedef struct JOYSTICK_DRIVER_BUTTON
{
int index;
} ATTRIBUTE_PACKED JOYSTICK_DRIVER_BUTTON;
+ /*!
+ * @brief Hat direction
+ */
typedef enum JOYSTICK_DRIVER_HAT_DIRECTION
{
JOYSTICK_DRIVER_HAT_UNKNOWN,
@@ -166,12 +217,18 @@ extern "C"
JOYSTICK_DRIVER_HAT_DOWN,
} JOYSTICK_DRIVER_HAT_DIRECTION;
+ /*!
+ * @brief Hat direction primitive
+ */
typedef struct JOYSTICK_DRIVER_HAT
{
int index;
JOYSTICK_DRIVER_HAT_DIRECTION direction;
} ATTRIBUTE_PACKED JOYSTICK_DRIVER_HAT;
+ /*!
+ * @brief Semiaxis direction
+ */
typedef enum JOYSTICK_DRIVER_SEMIAXIS_DIRECTION
{
JOYSTICK_DRIVER_SEMIAXIS_NEGATIVE = -1, /*!< @brief negative half of the axis */
@@ -179,6 +236,9 @@ extern "C"
JOYSTICK_DRIVER_SEMIAXIS_POSITIVE = 1, /*!< @brief positive half of the axis */
} JOYSTICK_DRIVER_SEMIAXIS_DIRECTION;
+ /*!
+ * @brief Semiaxis primitive
+ */
typedef struct JOYSTICK_DRIVER_SEMIAXIS
{
int index;
@@ -187,16 +247,70 @@ extern "C"
unsigned int range;
} ATTRIBUTE_PACKED JOYSTICK_DRIVER_SEMIAXIS;
+ /*!
+ * @brief Motor primitive
+ */
typedef struct JOYSTICK_DRIVER_MOTOR
{
int index;
} ATTRIBUTE_PACKED JOYSTICK_DRIVER_MOTOR;
+ /*!
+ * @brief Keyboard key primitive
+ */
typedef struct JOYSTICK_DRIVER_KEY
{
char keycode[16];
} ATTRIBUTE_PACKED JOYSTICK_DRIVER_KEY;
+ /*!
+ * @brief Mouse buttons
+ */
+ typedef enum JOYSTICK_DRIVER_MOUSE_INDEX
+ {
+ JOYSTICK_DRIVER_MOUSE_INDEX_UNKNOWN,
+ JOYSTICK_DRIVER_MOUSE_INDEX_LEFT,
+ JOYSTICK_DRIVER_MOUSE_INDEX_RIGHT,
+ JOYSTICK_DRIVER_MOUSE_INDEX_MIDDLE,
+ JOYSTICK_DRIVER_MOUSE_INDEX_BUTTON4,
+ JOYSTICK_DRIVER_MOUSE_INDEX_BUTTON5,
+ JOYSTICK_DRIVER_MOUSE_INDEX_WHEEL_UP,
+ JOYSTICK_DRIVER_MOUSE_INDEX_WHEEL_DOWN,
+ JOYSTICK_DRIVER_MOUSE_INDEX_HORIZ_WHEEL_LEFT,
+ JOYSTICK_DRIVER_MOUSE_INDEX_HORIZ_WHEEL_RIGHT,
+ } JOYSTICK_DRIVER_MOUSE_INDEX;
+
+ /*!
+ * @brief Mouse button primitive
+ */
+ typedef struct JOYSTICK_DRIVER_MOUSE_BUTTON
+ {
+ JOYSTICK_DRIVER_MOUSE_INDEX button;
+ } ATTRIBUTE_PACKED JOYSTICK_DRIVER_MOUSE_BUTTON;
+
+ /*!
+ * @brief Relative pointer direction
+ */
+ typedef enum JOYSTICK_DRIVER_RELPOINTER_DIRECTION
+ {
+ JOYSTICK_DRIVER_RELPOINTER_UNKNOWN,
+ JOYSTICK_DRIVER_RELPOINTER_LEFT,
+ JOYSTICK_DRIVER_RELPOINTER_RIGHT,
+ JOYSTICK_DRIVER_RELPOINTER_UP,
+ JOYSTICK_DRIVER_RELPOINTER_DOWN,
+ } JOYSTICK_DRIVER_RELPOINTER_DIRECTION;
+
+ /*!
+ * @brief Relative pointer direction primitive
+ */
+ typedef struct JOYSTICK_DRIVER_RELPOINTER
+ {
+ JOYSTICK_DRIVER_RELPOINTER_DIRECTION direction;
+ } ATTRIBUTE_PACKED JOYSTICK_DRIVER_RELPOINTER;
+
+ /*!
+ * @brief Driver primitive struct
+ */
typedef struct JOYSTICK_DRIVER_PRIMITIVE
{
JOYSTICK_DRIVER_PRIMITIVE_TYPE type;
@@ -207,9 +321,17 @@ extern "C"
struct JOYSTICK_DRIVER_SEMIAXIS semiaxis;
struct JOYSTICK_DRIVER_MOTOR motor;
struct JOYSTICK_DRIVER_KEY key;
+ struct JOYSTICK_DRIVER_MOUSE_BUTTON mouse;
+ struct JOYSTICK_DRIVER_RELPOINTER relpointer;
};
} ATTRIBUTE_PACKED JOYSTICK_DRIVER_PRIMITIVE;
+ /*!
+ * @brief Controller feature
+ *
+ * Controller features are an abstraction over driver values. Each feature
+ * maps to one or more driver primitives.
+ */
typedef enum JOYSTICK_FEATURE_TYPE
{
JOYSTICK_FEATURE_TYPE_UNKNOWN,
@@ -224,9 +346,12 @@ extern "C"
JOYSTICK_FEATURE_TYPE_KEY,
} JOYSTICK_FEATURE_TYPE;
+ /*!
+ * @brief Indices used to access a feature's driver primitives
+ */
typedef enum JOYSTICK_FEATURE_PRIMITIVE
{
- // Scalar feature
+ // Scalar feature (a button, hat direction or semiaxis)
JOYSTICK_SCALAR_PRIMITIVE = 0,
// Analog stick
@@ -254,10 +379,22 @@ extern "C"
// Key
JOYSTICK_KEY_PRIMITIVE = 0,
+ // Mouse button
+ JOYSTICK_MOUSE_BUTTON = 0,
+
+ // Relative pointer direction
+ JOYSTICK_RELPOINTER_UP = 0,
+ JOYSTICK_RELPOINTER_DOWN = 1,
+ JOYSTICK_RELPOINTER_RIGHT = 2,
+ JOYSTICK_RELPOINTER_LEFT = 3,
+
// Maximum number of primitives
JOYSTICK_PRIMITIVE_MAX = 4,
} JOYSTICK_FEATURE_PRIMITIVE;
+ /*!
+ * @brief Mapping between higher-level controller feature and its driver primitives
+ */
typedef struct JOYSTICK_FEATURE
{
char* name;
diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/PeripheralUtils.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/PeripheralUtils.h
index 98f3e0074b..c2efc05701 100644
--- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/PeripheralUtils.h
+++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/PeripheralUtils.h
@@ -164,62 +164,70 @@ namespace addon
class PeripheralEvent
{
public:
- PeripheralEvent(void) :
- m_event()
+ PeripheralEvent(void)
{
}
PeripheralEvent(unsigned int peripheralIndex, unsigned int buttonIndex, JOYSTICK_STATE_BUTTON state) :
- m_event()
+ m_type(PERIPHERAL_EVENT_TYPE_DRIVER_BUTTON),
+ m_peripheralIndex(peripheralIndex),
+ m_driverIndex(buttonIndex),
+ m_buttonState(state)
{
- SetType(PERIPHERAL_EVENT_TYPE_DRIVER_BUTTON);
- SetPeripheralIndex(peripheralIndex);
- SetDriverIndex(buttonIndex);
- SetButtonState(state);
}
PeripheralEvent(unsigned int peripheralIndex, unsigned int hatIndex, JOYSTICK_STATE_HAT state) :
- m_event()
+ m_type(PERIPHERAL_EVENT_TYPE_DRIVER_HAT),
+ m_peripheralIndex(peripheralIndex),
+ m_driverIndex(hatIndex),
+ m_hatState(state)
{
- SetType(PERIPHERAL_EVENT_TYPE_DRIVER_HAT);
- SetPeripheralIndex(peripheralIndex);
- SetDriverIndex(hatIndex);
- SetHatState(state);
}
PeripheralEvent(unsigned int peripheralIndex, unsigned int axisIndex, JOYSTICK_STATE_AXIS state) :
- m_event()
+ m_type(PERIPHERAL_EVENT_TYPE_DRIVER_AXIS),
+ m_peripheralIndex(peripheralIndex),
+ m_driverIndex(axisIndex),
+ m_axisState(state)
{
- SetType(PERIPHERAL_EVENT_TYPE_DRIVER_AXIS);
- SetPeripheralIndex(peripheralIndex);
- SetDriverIndex(axisIndex);
- SetAxisState(state);
}
explicit PeripheralEvent(const PERIPHERAL_EVENT& event) :
- m_event(event)
- {
- }
-
- PERIPHERAL_EVENT_TYPE Type(void) const { return m_event.type; }
- unsigned int PeripheralIndex(void) const { return m_event.peripheral_index; }
- unsigned int DriverIndex(void) const { return m_event.driver_index; }
- JOYSTICK_STATE_BUTTON ButtonState(void) const { return m_event.driver_button_state; }
- JOYSTICK_STATE_HAT HatState(void) const { return m_event.driver_hat_state; }
- JOYSTICK_STATE_AXIS AxisState(void) const { return m_event.driver_axis_state; }
- JOYSTICK_STATE_MOTOR MotorState(void) const { return m_event.motor_state; }
-
- void SetType(PERIPHERAL_EVENT_TYPE type) { m_event.type = type; }
- void SetPeripheralIndex(unsigned int index) { m_event.peripheral_index = index; }
- void SetDriverIndex(unsigned int index) { m_event.driver_index = index; }
- void SetButtonState(JOYSTICK_STATE_BUTTON state) { m_event.driver_button_state = state; }
- void SetHatState(JOYSTICK_STATE_HAT state) { m_event.driver_hat_state = state; }
- void SetAxisState(JOYSTICK_STATE_AXIS state) { m_event.driver_axis_state = state; }
- void SetMotorState(JOYSTICK_STATE_MOTOR state) { m_event.motor_state = state; }
+ m_type(event.type),
+ m_peripheralIndex(event.peripheral_index),
+ m_driverIndex(event.driver_index),
+ m_buttonState(event.driver_button_state),
+ m_hatState(event.driver_hat_state),
+ m_axisState(event.driver_axis_state),
+ m_motorState(event.motor_state)
+ {
+ }
+
+ PERIPHERAL_EVENT_TYPE Type(void) const { return m_type; }
+ unsigned int PeripheralIndex(void) const { return m_peripheralIndex; }
+ unsigned int DriverIndex(void) const { return m_driverIndex; }
+ JOYSTICK_STATE_BUTTON ButtonState(void) const { return m_buttonState; }
+ JOYSTICK_STATE_HAT HatState(void) const { return m_hatState; }
+ JOYSTICK_STATE_AXIS AxisState(void) const { return m_axisState; }
+ JOYSTICK_STATE_MOTOR MotorState(void) const { return m_motorState; }
+
+ void SetType(PERIPHERAL_EVENT_TYPE type) { m_type = type; }
+ void SetPeripheralIndex(unsigned int index) { m_peripheralIndex = index; }
+ void SetDriverIndex(unsigned int index) { m_driverIndex = index; }
+ void SetButtonState(JOYSTICK_STATE_BUTTON state) { m_buttonState = state; }
+ void SetHatState(JOYSTICK_STATE_HAT state) { m_hatState = state; }
+ void SetAxisState(JOYSTICK_STATE_AXIS state) { m_axisState = state; }
+ void SetMotorState(JOYSTICK_STATE_MOTOR state) { m_motorState = state; }
void ToStruct(PERIPHERAL_EVENT& event) const
{
- event = m_event;
+ event.type = m_type;
+ event.peripheral_index = m_peripheralIndex;
+ event.driver_index = m_driverIndex;
+ event.driver_button_state = m_buttonState;
+ event.driver_hat_state = m_hatState;
+ event.driver_axis_state = m_axisState;
+ event.motor_state = m_motorState;
}
static void FreeStruct(PERIPHERAL_EVENT& event)
@@ -228,7 +236,13 @@ namespace addon
}
private:
- PERIPHERAL_EVENT m_event;
+ PERIPHERAL_EVENT_TYPE m_type = PERIPHERAL_EVENT_TYPE_NONE;
+ unsigned int m_peripheralIndex = 0;
+ unsigned int m_driverIndex = 0;
+ JOYSTICK_STATE_BUTTON m_buttonState = JOYSTICK_STATE_BUTTON_UNPRESSED;
+ JOYSTICK_STATE_HAT m_hatState = JOYSTICK_STATE_HAT_UNPRESSED;
+ JOYSTICK_STATE_AXIS m_axisState = 0.0f;
+ JOYSTICK_STATE_MOTOR m_motorState = 0.0f;
};
typedef PeripheralVector<PeripheralEvent, PERIPHERAL_EVENT> PeripheralEvents;
@@ -298,9 +312,6 @@ namespace addon
unsigned int MotorCount(void) const { return m_motorCount; }
bool SupportsPowerOff(void) const { return m_supportsPowerOff; }
- // Derived property: Counts are unknown if all are zero
- bool AreElementCountsKnown(void) const { return m_buttonCount != 0 || m_hatCount != 0 || m_axisCount != 0; }
-
void SetProvider(const std::string& provider) { m_provider = provider; }
void SetRequestedPort(int requestedPort) { m_requestedPort = requestedPort; }
void SetButtonCount(unsigned int buttonCount) { m_buttonCount = buttonCount; }
@@ -352,6 +363,9 @@ namespace addon
* 2) a hat direction
* 3) a semiaxis (either the positive or negative half of an axis)
* 4) a motor
+ * 5) a keyboard key
+ * 6) a mouse button
+ * 7) a relative pointer direction
*
* The type determines the fields in use:
*
@@ -370,6 +384,15 @@ namespace addon
*
* Motor:
* - driver index
+ *
+ * Key:
+ * - key code
+ *
+ * Mouse button:
+ * - driver index
+ *
+ * Relative pointer direction:
+ * - relative pointer direction
*/
struct DriverPrimitive
{
@@ -383,7 +406,8 @@ namespace addon
m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN),
m_center(0),
m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN),
- m_range(1)
+ m_range(1),
+ m_relPointerDirection(JOYSTICK_DRIVER_RELPOINTER_UNKNOWN)
{
}
@@ -397,12 +421,13 @@ namespace addon
m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN),
m_center(0),
m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN),
- m_range(1)
+ m_range(1),
+ m_relPointerDirection(JOYSTICK_DRIVER_RELPOINTER_UNKNOWN)
{
}
/*!
- * \brief Construct a driver primitive representing a button
+ * \brief Construct a driver primitive representing a joystick button
*/
static DriverPrimitive CreateButton(unsigned int buttonIndex)
{
@@ -419,7 +444,8 @@ namespace addon
m_hatDirection(direction),
m_center(0),
m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN),
- m_range(1)
+ m_range(1),
+ m_relPointerDirection(JOYSTICK_DRIVER_RELPOINTER_UNKNOWN)
{
}
@@ -433,7 +459,8 @@ namespace addon
m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN),
m_center(center),
m_semiAxisDirection(direction),
- m_range(range)
+ m_range(range),
+ m_relPointerDirection(JOYSTICK_DRIVER_RELPOINTER_UNKNOWN)
{
}
@@ -455,7 +482,31 @@ namespace addon
m_center(0),
m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN),
m_range(1),
- m_keycode(std::move(keycode))
+ m_keycode(std::move(keycode)),
+ m_relPointerDirection(JOYSTICK_DRIVER_RELPOINTER_UNKNOWN)
+ {
+ }
+
+ /*!
+ * \brief Construct a driver primitive representing a mouse button
+ */
+ static DriverPrimitive CreateMouseButton(JOYSTICK_DRIVER_MOUSE_INDEX buttonIndex)
+ {
+ return DriverPrimitive(JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOUSE_BUTTON, static_cast<unsigned int>(buttonIndex));
+ }
+
+ /*!
+ * \brief Construct a driver primitive representing one of the four
+ * direction in which a relative pointer can move
+ */
+ DriverPrimitive(JOYSTICK_DRIVER_RELPOINTER_DIRECTION direction) :
+ m_type(JOYSTICK_DRIVER_PRIMITIVE_TYPE_RELPOINTER_DIRECTION),
+ m_driverIndex(0),
+ m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN),
+ m_center(0),
+ m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN),
+ m_range(1),
+ m_relPointerDirection(direction)
{
}
@@ -465,7 +516,8 @@ namespace addon
m_hatDirection(JOYSTICK_DRIVER_HAT_UNKNOWN),
m_center(0),
m_semiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN),
- m_range(1)
+ m_range(1),
+ m_relPointerDirection(JOYSTICK_DRIVER_RELPOINTER_UNKNOWN)
{
switch (m_type)
{
@@ -498,6 +550,16 @@ namespace addon
m_keycode = primitive.key.keycode;
break;
}
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOUSE_BUTTON:
+ {
+ m_driverIndex = primitive.mouse.button;
+ break;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_RELPOINTER_DIRECTION:
+ {
+ m_relPointerDirection = primitive.relpointer.direction;
+ break;
+ }
default:
break;
}
@@ -510,6 +572,8 @@ namespace addon
JOYSTICK_DRIVER_SEMIAXIS_DIRECTION SemiAxisDirection(void) const { return m_semiAxisDirection; }
unsigned int Range(void) const { return m_range; }
const std::string& Keycode(void) const { return m_keycode; }
+ JOYSTICK_DRIVER_MOUSE_INDEX MouseIndex(void) const { return static_cast<JOYSTICK_DRIVER_MOUSE_INDEX>(m_driverIndex); }
+ JOYSTICK_DRIVER_RELPOINTER_DIRECTION RelPointerDirection(void) const { return m_relPointerDirection; }
bool operator==(const DriverPrimitive& other) const
{
@@ -518,7 +582,6 @@ namespace addon
switch (m_type)
{
case JOYSTICK_DRIVER_PRIMITIVE_TYPE_BUTTON:
- case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
{
return m_driverIndex == other.m_driverIndex;
}
@@ -538,6 +601,18 @@ namespace addon
{
return m_keycode == other.m_keycode;
}
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOTOR:
+ {
+ return m_driverIndex == other.m_driverIndex;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOUSE_BUTTON:
+ {
+ return m_driverIndex == other.m_driverIndex;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_RELPOINTER_DIRECTION:
+ {
+ return m_relPointerDirection == other.m_relPointerDirection;
+ }
default:
break;
}
@@ -581,6 +656,16 @@ namespace addon
driver_primitive.key.keycode[size - 1] = '\0';
break;
}
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOUSE_BUTTON:
+ {
+ driver_primitive.mouse.button = static_cast<JOYSTICK_DRIVER_MOUSE_INDEX>(m_driverIndex);
+ break;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_RELPOINTER_DIRECTION:
+ {
+ driver_primitive.relpointer.direction = m_relPointerDirection;
+ break;
+ }
default:
break;
}
@@ -599,6 +684,7 @@ namespace addon
JOYSTICK_DRIVER_SEMIAXIS_DIRECTION m_semiAxisDirection;
unsigned int m_range;
std::string m_keycode;
+ JOYSTICK_DRIVER_RELPOINTER_DIRECTION m_relPointerDirection;
};
typedef PeripheralVector<DriverPrimitive, JOYSTICK_DRIVER_PRIMITIVE> DriverPrimitives;
@@ -705,4 +791,3 @@ namespace addon
} /* namespace addon */
} /* namespace kodi */
-
diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_dll.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_dll.h
index 6501b43458..691dd5ee43 100644
--- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_dll.h
+++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_dll.h
@@ -166,6 +166,16 @@ bool HasFeature(const char* controller_id, const char* feature_name);
bool EnableKeyboard(bool enable, const game_controller* controller);
/*!
+ * \brief Enable/disable mouse input using the specified controller
+ *
+ * \param enable True to enable input, false otherwise
+ * \param controller The controller info if enabling, or unused if disabling
+ *
+ * \return True if mouse input was enabled, false otherwise
+ */
+bool EnableMouse(bool enable, const game_controller* controller);
+
+/*!
* \brief Notify the add-on of an input event
*
* \param event The input event
@@ -260,6 +270,7 @@ void __declspec(dllexport) get_addon(void* ptr)
pClient->toAddon.UpdatePort = UpdatePort;
pClient->toAddon.HasFeature = HasFeature;
pClient->toAddon.EnableKeyboard = EnableKeyboard;
+ pClient->toAddon.EnableMouse = EnableMouse;
pClient->toAddon.InputEvent = InputEvent;
pClient->toAddon.SerializeSize = SerializeSize;
pClient->toAddon.Serialize = Serialize;
diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_types.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_types.h
index d54ee22b0c..54196afa01 100644
--- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_types.h
+++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/kodi_game_types.h
@@ -162,7 +162,6 @@ typedef enum GAME_HW_CONTEXT_TYPE
typedef enum GAME_INPUT_PORT
{
GAME_INPUT_PORT_JOYSTICK_START = 0, // Non-negative values are for joystick ports
- GAME_INPUT_PORT_MOUSE = -2,
} GAME_INPUT_PORT;
typedef enum GAME_INPUT_EVENT_SOURCE
@@ -502,6 +501,7 @@ typedef struct KodiToAddonFuncTable_Game
void (__cdecl* UpdatePort)(int, bool, const game_controller*);
bool (__cdecl* HasFeature)(const char* controller_id, const char* feature_name);
bool (__cdecl* EnableKeyboard)(bool, const game_controller*);
+ bool (__cdecl* EnableMouse)(bool, const game_controller*);
bool (__cdecl* InputEvent)(const game_input_event*);
size_t (__cdecl* SerializeSize)(void);
GAME_ERROR (__cdecl* Serialize)(uint8_t*, size_t);
diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h
index f547ff72c9..0e3c9e31a4 100644
--- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h
+++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/versions.h
@@ -91,8 +91,8 @@
#define ADDON_INSTANCE_VERSION_AUDIOENCODER_XML_ID "kodi.binary.instance.audioencoder"
#define ADDON_INSTANCE_VERSION_AUDIOENCODER_DEPENDS "addon-instance/AudioEncoder.h"
-#define ADDON_INSTANCE_VERSION_GAME "1.0.34"
-#define ADDON_INSTANCE_VERSION_GAME_MIN "1.0.34"
+#define ADDON_INSTANCE_VERSION_GAME "1.0.35"
+#define ADDON_INSTANCE_VERSION_GAME_MIN "1.0.35"
#define ADDON_INSTANCE_VERSION_GAME_XML_ID "kodi.binary.instance.game"
#define ADDON_INSTANCE_VERSION_GAME_DEPENDS "kodi_game_dll.h" \
"kodi_game_types.h" \
@@ -108,7 +108,7 @@
#define ADDON_INSTANCE_VERSION_INPUTSTREAM_XML_ID "kodi.binary.instance.inputstream"
#define ADDON_INSTANCE_VERSION_INPUTSTREAM_DEPENDS "addon-instance/Inputstream.h"
-#define ADDON_INSTANCE_VERSION_PERIPHERAL "1.3.6"
+#define ADDON_INSTANCE_VERSION_PERIPHERAL "1.3.7"
#define ADDON_INSTANCE_VERSION_PERIPHERAL_MIN "1.3.4"
#define ADDON_INSTANCE_VERSION_PERIPHERAL_XML_ID "kodi.binary.instance.peripheral"
#define ADDON_INSTANCE_VERSION_PERIPHERAL_DEPENDS "addon-instance/Peripheral.h" \
diff --git a/xbmc/games/GameServices.cpp b/xbmc/games/GameServices.cpp
index e6a4d5c90c..b58a620b6f 100644
--- a/xbmc/games/GameServices.cpp
+++ b/xbmc/games/GameServices.cpp
@@ -58,6 +58,11 @@ ControllerPtr CGameServices::GetDefaultKeyboard()
return m_controllerManager.GetDefaultKeyboard();
}
+ControllerPtr CGameServices::GetDefaultMouse()
+{
+ return m_controllerManager.GetDefaultMouse();
+}
+
ControllerVector CGameServices::GetControllers()
{
return m_controllerManager.GetControllers();
diff --git a/xbmc/games/GameServices.h b/xbmc/games/GameServices.h
index 300cbec644..466c3f0e88 100644
--- a/xbmc/games/GameServices.h
+++ b/xbmc/games/GameServices.h
@@ -58,6 +58,7 @@ namespace GAME
ControllerPtr GetController(const std::string& controllerId);
ControllerPtr GetDefaultController();
ControllerPtr GetDefaultKeyboard();
+ ControllerPtr GetDefaultMouse();
ControllerVector GetControllers();
std::string GetSavestatesFolder() const;
diff --git a/xbmc/games/addons/input/GameClientInput.cpp b/xbmc/games/addons/input/GameClientInput.cpp
index 6b95c719fc..a1809ae73a 100644
--- a/xbmc/games/addons/input/GameClientInput.cpp
+++ b/xbmc/games/addons/input/GameClientInput.cpp
@@ -31,7 +31,6 @@
#include "guilib/GUIWindowManager.h"
#include "guilib/WindowIDs.h"
#include "input/joysticks/JoystickTypes.h"
-#include "input/InputManager.h"
#include "peripherals/Peripherals.h"
#include "peripherals/PeripheralTypes.h" //! @todo
//#include "threads/SingleLock.h"
@@ -251,34 +250,74 @@ void CGameClientInput::CloseKeyboard()
void CGameClientInput::OpenMouse()
{
- m_mouse.reset(new CGameClientMouse(m_gameClient, m_struct.toAddon, &CServiceBroker::GetInputManager()));
+ using namespace JOYSTICK;
- CSingleLock lock(m_clientAccess);
+ //! @todo Move to player manager
+ PERIPHERALS::PeripheralVector mice;
+ CServiceBroker::GetPeripherals().GetPeripheralsWithFeature(mice, PERIPHERALS::FEATURE_MOUSE);
- if (m_gameClient.Initialized())
- {
- std::string strId = m_mouse->ControllerID();
+ if (mice.empty())
+ return;
- game_controller controllerStruct = { strId.c_str() };
+ CGameServices& gameServices = CServiceBroker::GetGameServices();
- try { m_struct.toAddon.UpdatePort(GAME_INPUT_PORT_MOUSE, true, &controllerStruct); }
- catch (...) { m_gameClient.LogException("UpdatePort()"); }
+ ControllerPtr controller = gameServices.GetDefaultMouse(); //! @todo
+
+ std::string controllerId = controller->ID();
+
+ game_controller controllerStruct{};
+
+ controllerStruct.controller_id = controllerId.c_str();
+ controllerStruct.digital_button_count = controller->FeatureCount(FEATURE_TYPE::SCALAR, INPUT_TYPE::DIGITAL);
+ controllerStruct.analog_button_count = controller->FeatureCount(FEATURE_TYPE::SCALAR, INPUT_TYPE::ANALOG);
+ controllerStruct.analog_stick_count = controller->FeatureCount(FEATURE_TYPE::ANALOG_STICK);
+ controllerStruct.accelerometer_count = controller->FeatureCount(FEATURE_TYPE::ACCELEROMETER);
+ controllerStruct.key_count = controller->FeatureCount(FEATURE_TYPE::KEY);
+ controllerStruct.rel_pointer_count = controller->FeatureCount(FEATURE_TYPE::RELPOINTER);
+ controllerStruct.abs_pointer_count = controller->FeatureCount(FEATURE_TYPE::ABSPOINTER);
+ controllerStruct.motor_count = controller->FeatureCount(FEATURE_TYPE::MOTOR);
+
+ bool bSuccess = false;
+
+ {
+ CSingleLock lock(m_clientAccess);
+
+ if (m_gameClient.Initialized())
+ {
+ try
+ {
+ bSuccess = m_struct.toAddon.EnableMouse(true, &controllerStruct);
+ }
+ catch (...)
+ {
+ m_gameClient.LogException("EnableMouse()");
+ }
+ }
}
+
+ if (bSuccess)
+ m_mouse.reset(new CGameClientMouse(m_gameClient, controllerId, m_struct.toAddon, mice.at(0).get()));
}
void CGameClientInput::CloseMouse()
{
+ m_mouse.reset();
+
{
CSingleLock lock(m_clientAccess);
if (m_gameClient.Initialized())
{
- try { m_struct.toAddon.UpdatePort(GAME_INPUT_PORT_MOUSE, false, nullptr); }
- catch (...) { m_gameClient.LogException("UpdatePort()"); }
+ try
+ {
+ m_struct.toAddon.EnableMouse(false, nullptr);
+ }
+ catch (...)
+ {
+ m_gameClient.LogException("EnableMouse()");
+ }
}
}
-
- m_mouse.reset();
}
bool CGameClientInput::SetRumble(unsigned int port, const std::string& feature, float magnitude)
diff --git a/xbmc/games/addons/input/GameClientMouse.cpp b/xbmc/games/addons/input/GameClientMouse.cpp
index 98adb6ca18..1a37d8995a 100644
--- a/xbmc/games/addons/input/GameClientMouse.cpp
+++ b/xbmc/games/addons/input/GameClientMouse.cpp
@@ -26,17 +26,21 @@
#include "input/Key.h"
#include "utils/log.h"
+#include <utility>
+
using namespace KODI;
using namespace GAME;
CGameClientMouse::CGameClientMouse(const CGameClient &gameClient,
+ std::string controllerId,
const KodiToAddonFuncTable_Game &dllStruct,
MOUSE::IMouseInputProvider *inputProvider) :
m_gameClient(gameClient),
+ m_controllerId(std::move(controllerId)),
m_dllStruct(dllStruct),
- m_inputProvider(inputProvider),
- m_controllerId(inputProvider->RegisterMouseHandler(this))
+ m_inputProvider(inputProvider)
{
+ inputProvider->RegisterMouseHandler(this, false);
}
CGameClientMouse::~CGameClientMouse()
@@ -59,10 +63,12 @@ bool CGameClientMouse::OnMotion(const std::string& relpointer, int dx, int dy)
bool bHandled = false;
+ const std::string controllerId = ControllerID();
+
game_input_event event;
event.type = GAME_INPUT_EVENT_RELATIVE_POINTER;
- event.port = GAME_INPUT_PORT_MOUSE;
+ event.port = -1; //! @todo Remove in port refactor
event.controller_id = m_controllerId.c_str();
event.feature_name = relpointer.c_str();
event.rel_pointer.x = dx;
@@ -93,7 +99,7 @@ bool CGameClientMouse::OnButtonPress(const std::string& button)
game_input_event event;
event.type = GAME_INPUT_EVENT_DIGITAL_BUTTON;
- event.port = GAME_INPUT_PORT_MOUSE;
+ event.port = -1; //! @todo Remove in port refactor
event.controller_id = m_controllerId.c_str();
event.feature_name = button.c_str();
event.digital_button.pressed = true;
@@ -115,7 +121,7 @@ void CGameClientMouse::OnButtonRelease(const std::string& button)
game_input_event event;
event.type = GAME_INPUT_EVENT_DIGITAL_BUTTON;
- event.port = GAME_INPUT_PORT_MOUSE;
+ event.port = -1; //! @todo Remove in port refactor
event.controller_id = m_controllerId.c_str();
event.feature_name = button.c_str();
event.digital_button.pressed = false;
diff --git a/xbmc/games/addons/input/GameClientMouse.h b/xbmc/games/addons/input/GameClientMouse.h
index c5d253ea37..39043371ec 100644
--- a/xbmc/games/addons/input/GameClientMouse.h
+++ b/xbmc/games/addons/input/GameClientMouse.h
@@ -46,10 +46,12 @@ namespace GAME
/*!
* \brief Constructor registers for mouse events at CInputManager.
* \param gameClient The game client implementation.
+ * \param controllerId The controller profile used for input
* \param dllStruct The emulator or game to which the events are sent.
* \param inputProvider The interface providing us with mouse input.
*/
CGameClientMouse(const CGameClient &gameClient,
+ std::string controllerId,
const KodiToAddonFuncTable_Game &dllStruct,
MOUSE::IMouseInputProvider *inputProvider);
@@ -67,9 +69,9 @@ namespace GAME
private:
// Construction parameters
const CGameClient &m_gameClient;
+ const std::string m_controllerId;
const KodiToAddonFuncTable_Game &m_dllStruct;
MOUSE::IMouseInputProvider *const m_inputProvider;
- const std::string m_controllerId;
};
}
}
diff --git a/xbmc/games/controllers/ControllerIDs.h b/xbmc/games/controllers/ControllerIDs.h
index 427c14f12a..98eb7fd47c 100644
--- a/xbmc/games/controllers/ControllerIDs.h
+++ b/xbmc/games/controllers/ControllerIDs.h
@@ -22,4 +22,5 @@
// Default controller IDs
#define DEFAULT_CONTROLLER_ID "game.controller.default"
#define DEFAULT_KEYBOARD_ID "game.controller.keyboard"
+#define DEFAULT_MOUSE_ID "game.controller.mouse"
#define DEFAULT_REMOTE_ID "game.controller.remote"
diff --git a/xbmc/games/controllers/ControllerManager.cpp b/xbmc/games/controllers/ControllerManager.cpp
index feffa5c7d6..1199aff385 100644
--- a/xbmc/games/controllers/ControllerManager.cpp
+++ b/xbmc/games/controllers/ControllerManager.cpp
@@ -53,6 +53,11 @@ ControllerPtr CControllerManager::GetDefaultKeyboard()
return GetController(DEFAULT_KEYBOARD_ID);
}
+ControllerPtr CControllerManager::GetDefaultMouse()
+{
+ return GetController(DEFAULT_MOUSE_ID);
+}
+
ControllerVector CControllerManager::GetControllers()
{
using namespace ADDON;
diff --git a/xbmc/games/controllers/ControllerManager.h b/xbmc/games/controllers/ControllerManager.h
index 540ef59fef..63765b90b8 100644
--- a/xbmc/games/controllers/ControllerManager.h
+++ b/xbmc/games/controllers/ControllerManager.h
@@ -64,6 +64,13 @@ namespace GAME
ControllerPtr GetDefaultKeyboard();
/*!
+ * \brief Get the default mouse
+ *
+ * \return The mouse controller, or empty if the controller failed to load
+ */
+ ControllerPtr GetDefaultMouse();
+
+ /*!
* \brief Get installed controllers
*
* \return The installed controllers that loaded successfully
diff --git a/xbmc/games/controllers/guicontrols/CMakeLists.txt b/xbmc/games/controllers/guicontrols/CMakeLists.txt
index bbec218bbf..e6babcc9e5 100644
--- a/xbmc/games/controllers/guicontrols/CMakeLists.txt
+++ b/xbmc/games/controllers/guicontrols/CMakeLists.txt
@@ -1,4 +1,4 @@
-set(SOURCES GUIAnalogStickButton.cpp
+set(SOURCES GUICardinalFeatureButton.cpp
GUIControllerButton.cpp
GUIFeatureButton.cpp
GUIFeatureControls.cpp
@@ -11,7 +11,7 @@ set(SOURCES GUIAnalogStickButton.cpp
GUIWheelButton.cpp
)
-set(HEADERS GUIAnalogStickButton.h
+set(HEADERS GUICardinalFeatureButton.h
GUIControllerButton.h
GUIControlTypes.h
GUIFeatureButton.h
diff --git a/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.cpp b/xbmc/games/controllers/guicontrols/GUICardinalFeatureButton.cpp
index 661a6f4884..73a5819988 100644
--- a/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.cpp
+++ b/xbmc/games/controllers/guicontrols/GUICardinalFeatureButton.cpp
@@ -18,7 +18,7 @@
*
*/
-#include "GUIAnalogStickButton.h"
+#include "GUICardinalFeatureButton.h"
#include "guilib/LocalizeStrings.h"
#include "utils/StringUtils.h"
@@ -27,16 +27,16 @@
using namespace KODI;
using namespace GAME;
-CGUIAnalogStickButton::CGUIAnalogStickButton(const CGUIButtonControl& buttonTemplate,
- IConfigurationWizard* wizard,
- const CControllerFeature& feature,
- unsigned int index) :
+CGUICardinalFeatureButton::CGUICardinalFeatureButton(const CGUIButtonControl& buttonTemplate,
+ IConfigurationWizard* wizard,
+ const CControllerFeature& feature,
+ unsigned int index) :
CGUIFeatureButton(buttonTemplate, wizard, feature, index)
{
Reset();
}
-bool CGUIAnalogStickButton::PromptForInput(CEvent& waitEvent)
+bool CGUICardinalFeatureButton::PromptForInput(CEvent& waitEvent)
{
using namespace JOYSTICK;
@@ -47,19 +47,19 @@ bool CGUIAnalogStickButton::PromptForInput(CEvent& waitEvent)
std::string strWarn;
switch (m_state)
{
- case STATE::ANALOG_STICK_UP:
+ case STATE::CARDINAL_DIRECTION_UP:
strPrompt = g_localizeStrings.Get(35092); // "Move %s up"
strWarn = g_localizeStrings.Get(35093); // "Move %s up (%d)"
break;
- case STATE::ANALOG_STICK_RIGHT:
+ case STATE::CARDINAL_DIRECTION_RIGHT:
strPrompt = g_localizeStrings.Get(35096); // "Move %s right"
strWarn = g_localizeStrings.Get(35097); // "Move %s right (%d)"
break;
- case STATE::ANALOG_STICK_DOWN:
+ case STATE::CARDINAL_DIRECTION_DOWN:
strPrompt = g_localizeStrings.Get(35094); // "Move %s down"
strWarn = g_localizeStrings.Get(35095); // "Move %s down (%d)"
break;
- case STATE::ANALOG_STICK_LEFT:
+ case STATE::CARDINAL_DIRECTION_LEFT:
strPrompt = g_localizeStrings.Get(35098); // "Move %s left"
strWarn = g_localizeStrings.Get(35099); // "Move %s left (%d)"
break;
@@ -80,29 +80,29 @@ bool CGUIAnalogStickButton::PromptForInput(CEvent& waitEvent)
return bInterrupted;
}
-bool CGUIAnalogStickButton::IsFinished(void) const
+bool CGUICardinalFeatureButton::IsFinished(void) const
{
return m_state >= STATE::FINISHED;
}
-JOYSTICK::ANALOG_STICK_DIRECTION CGUIAnalogStickButton::GetAnalogStickDirection(void) const
+KODI::INPUT::CARDINAL_DIRECTION CGUICardinalFeatureButton::GetCardinalDirection(void) const
{
- using namespace JOYSTICK;
+ using namespace INPUT;
switch (m_state)
{
- case STATE::ANALOG_STICK_UP: return ANALOG_STICK_DIRECTION::UP;
- case STATE::ANALOG_STICK_RIGHT: return ANALOG_STICK_DIRECTION::RIGHT;
- case STATE::ANALOG_STICK_DOWN: return ANALOG_STICK_DIRECTION::DOWN;
- case STATE::ANALOG_STICK_LEFT: return ANALOG_STICK_DIRECTION::LEFT;
+ case STATE::CARDINAL_DIRECTION_UP: return CARDINAL_DIRECTION::UP;
+ case STATE::CARDINAL_DIRECTION_RIGHT: return CARDINAL_DIRECTION::RIGHT;
+ case STATE::CARDINAL_DIRECTION_DOWN: return CARDINAL_DIRECTION::DOWN;
+ case STATE::CARDINAL_DIRECTION_LEFT: return CARDINAL_DIRECTION::LEFT;
default:
break;
}
- return ANALOG_STICK_DIRECTION::UNKNOWN;
+ return CARDINAL_DIRECTION::NONE;
}
-void CGUIAnalogStickButton::Reset(void)
+void CGUICardinalFeatureButton::Reset(void)
{
- m_state = STATE::ANALOG_STICK_UP;
+ m_state = STATE::CARDINAL_DIRECTION_UP;
}
diff --git a/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.h b/xbmc/games/controllers/guicontrols/GUICardinalFeatureButton.h
index 6b918e525e..f8180c877d 100644
--- a/xbmc/games/controllers/guicontrols/GUIAnalogStickButton.h
+++ b/xbmc/games/controllers/guicontrols/GUICardinalFeatureButton.h
@@ -25,33 +25,36 @@ namespace KODI
{
namespace GAME
{
- class CGUIAnalogStickButton : public CGUIFeatureButton
+ class CGUICardinalFeatureButton : public CGUIFeatureButton
{
public:
- CGUIAnalogStickButton(const CGUIButtonControl& buttonTemplate,
- IConfigurationWizard* wizard,
- const CControllerFeature& feature,
- unsigned int index);
+ CGUICardinalFeatureButton(const CGUIButtonControl& buttonTemplate,
+ IConfigurationWizard* wizard,
+ const CControllerFeature& feature,
+ unsigned int index);
- virtual ~CGUIAnalogStickButton() = default;
+ virtual ~CGUICardinalFeatureButton() = default;
// implementation of IFeatureButton
virtual bool PromptForInput(CEvent& waitEvent) override;
virtual bool IsFinished(void) const override;
- virtual JOYSTICK::ANALOG_STICK_DIRECTION GetAnalogStickDirection(void) const override;
+ virtual INPUT::CARDINAL_DIRECTION GetCardinalDirection(void) const override;
virtual void Reset(void) override;
private:
enum class STATE
{
- ANALOG_STICK_UP,
- ANALOG_STICK_RIGHT,
- ANALOG_STICK_DOWN,
- ANALOG_STICK_LEFT,
+ CARDINAL_DIRECTION_UP,
+ CARDINAL_DIRECTION_RIGHT,
+ CARDINAL_DIRECTION_DOWN,
+ CARDINAL_DIRECTION_LEFT,
FINISHED,
};
STATE m_state;
};
+
+ using CGUIAnalogStickButton = CGUICardinalFeatureButton;
+ using CGUIRelativePointerButton = CGUICardinalFeatureButton;
}
}
diff --git a/xbmc/games/controllers/guicontrols/GUIControlTypes.h b/xbmc/games/controllers/guicontrols/GUIControlTypes.h
index ef32908a5a..b4feae8955 100644
--- a/xbmc/games/controllers/guicontrols/GUIControlTypes.h
+++ b/xbmc/games/controllers/guicontrols/GUIControlTypes.h
@@ -31,6 +31,7 @@ namespace GAME
UNKNOWN,
BUTTON,
ANALOG_STICK,
+ RELATIVE_POINTER,
WHEEL,
THROTTLE,
SELECT_KEY,
diff --git a/xbmc/games/controllers/guicontrols/GUIFeatureButton.h b/xbmc/games/controllers/guicontrols/GUIFeatureButton.h
index 990a831887..b71642529a 100644
--- a/xbmc/games/controllers/guicontrols/GUIFeatureButton.h
+++ b/xbmc/games/controllers/guicontrols/GUIFeatureButton.h
@@ -45,9 +45,9 @@ namespace GAME
// partial implementation of IFeatureButton
virtual const CControllerFeature& Feature(void) const override { return m_feature; }
- virtual JOYSTICK::ANALOG_STICK_DIRECTION GetAnalogStickDirection(void) const override { return JOYSTICK::ANALOG_STICK_DIRECTION::UNKNOWN; }
- virtual JOYSTICK::WHEEL_DIRECTION GetWheelDirection(void) const override { return JOYSTICK::WHEEL_DIRECTION::UNKNOWN; }
- virtual JOYSTICK::THROTTLE_DIRECTION GetThrottleDirection(void) const override { return JOYSTICK::THROTTLE_DIRECTION::UNKNOWN; }
+ virtual INPUT::CARDINAL_DIRECTION GetCardinalDirection(void) const override { return INPUT::CARDINAL_DIRECTION::NONE; }
+ virtual JOYSTICK::WHEEL_DIRECTION GetWheelDirection(void) const override { return JOYSTICK::WHEEL_DIRECTION::NONE; }
+ virtual JOYSTICK::THROTTLE_DIRECTION GetThrottleDirection(void) const override { return JOYSTICK::THROTTLE_DIRECTION::NONE; }
protected:
bool DoPrompt(const std::string& strPrompt, const std::string& strWarn, const std::string& strFeature, CEvent& waitEvent);
diff --git a/xbmc/games/controllers/guicontrols/GUIFeatureFactory.cpp b/xbmc/games/controllers/guicontrols/GUIFeatureFactory.cpp
index ce445465c7..642543aa62 100644
--- a/xbmc/games/controllers/guicontrols/GUIFeatureFactory.cpp
+++ b/xbmc/games/controllers/guicontrols/GUIFeatureFactory.cpp
@@ -19,7 +19,7 @@
*/
#include "GUIFeatureFactory.h"
-#include "GUIAnalogStickButton.h"
+#include "GUICardinalFeatureButton.h"
#include "GUIScalarFeatureButton.h"
#include "GUISelectKeyButton.h"
#include "GUIThrottleButton.h"
@@ -51,6 +51,9 @@ CGUIButtonControl* CGUIFeatureFactory::CreateButton(BUTTON_TYPE type,
case BUTTON_TYPE::SELECT_KEY:
return new CGUISelectKeyButton(buttonTemplate, wizard, index);
+ case BUTTON_TYPE::RELATIVE_POINTER:
+ return new CGUIRelativePointerButton(buttonTemplate, wizard, feature, index);
+
default:
break;
}
diff --git a/xbmc/games/controllers/guicontrols/GUIFeatureTranslator.cpp b/xbmc/games/controllers/guicontrols/GUIFeatureTranslator.cpp
index 9a7a67b1c9..92a09e342a 100644
--- a/xbmc/games/controllers/guicontrols/GUIFeatureTranslator.cpp
+++ b/xbmc/games/controllers/guicontrols/GUIFeatureTranslator.cpp
@@ -34,10 +34,8 @@ BUTTON_TYPE CGUIFeatureTranslator::GetButtonType(JOYSTICK::FEATURE_TYPE featureT
case JOYSTICK::FEATURE_TYPE::ANALOG_STICK:
return BUTTON_TYPE::ANALOG_STICK;
- //! @todo Create button control for relative pointers. Use analog sticks for
- // now, as four directions are sufficient for relative pointers.
case JOYSTICK::FEATURE_TYPE::RELPOINTER:
- return BUTTON_TYPE::ANALOG_STICK;
+ return BUTTON_TYPE::RELATIVE_POINTER;
case JOYSTICK::FEATURE_TYPE::WHEEL:
return BUTTON_TYPE::WHEEL;
diff --git a/xbmc/games/controllers/guicontrols/GUIThrottleButton.cpp b/xbmc/games/controllers/guicontrols/GUIThrottleButton.cpp
index 210d7bd115..34c0f0155e 100644
--- a/xbmc/games/controllers/guicontrols/GUIThrottleButton.cpp
+++ b/xbmc/games/controllers/guicontrols/GUIThrottleButton.cpp
@@ -89,7 +89,7 @@ JOYSTICK::THROTTLE_DIRECTION CGUIThrottleButton::GetThrottleDirection(void) cons
break;
}
- return THROTTLE_DIRECTION::UNKNOWN;
+ return THROTTLE_DIRECTION::NONE;
}
void CGUIThrottleButton::Reset(void)
diff --git a/xbmc/games/controllers/guicontrols/GUIWheelButton.cpp b/xbmc/games/controllers/guicontrols/GUIWheelButton.cpp
index 3c85f32e61..382b7dd550 100644
--- a/xbmc/games/controllers/guicontrols/GUIWheelButton.cpp
+++ b/xbmc/games/controllers/guicontrols/GUIWheelButton.cpp
@@ -89,7 +89,7 @@ JOYSTICK::WHEEL_DIRECTION CGUIWheelButton::GetWheelDirection(void) const
break;
}
- return WHEEL_DIRECTION::UNKNOWN;
+ return WHEEL_DIRECTION::NONE;
}
void CGUIWheelButton::Reset(void)
diff --git a/xbmc/games/controllers/windows/GUIConfigurationWizard.cpp b/xbmc/games/controllers/windows/GUIConfigurationWizard.cpp
index f89aa44880..d09941e14a 100644
--- a/xbmc/games/controllers/windows/GUIConfigurationWizard.cpp
+++ b/xbmc/games/controllers/windows/GUIConfigurationWizard.cpp
@@ -56,9 +56,9 @@ CGUIConfigurationWizard::~CGUIConfigurationWizard(void) = default;
void CGUIConfigurationWizard::InitializeState(void)
{
m_currentButton = nullptr;
- m_analogStickDirection = JOYSTICK::ANALOG_STICK_DIRECTION::UNKNOWN;
- m_wheelDirection = JOYSTICK::WHEEL_DIRECTION::UNKNOWN;
- m_throttleDirection = JOYSTICK::THROTTLE_DIRECTION::UNKNOWN;
+ m_cardinalDirection = INPUT::CARDINAL_DIRECTION::NONE;
+ m_wheelDirection = JOYSTICK::WHEEL_DIRECTION::NONE;
+ m_throttleDirection = JOYSTICK::THROTTLE_DIRECTION::NONE;
m_history.clear();
m_lateAxisDetected = false;
m_deviceName.clear();
@@ -139,7 +139,7 @@ void CGUIConfigurationWizard::Process(void)
while (!button->IsFinished())
{
// Allow other threads to access which direction the prompt is on
- m_analogStickDirection = button->GetAnalogStickDirection();
+ m_cardinalDirection = button->GetCardinalDirection();
m_wheelDirection = button->GetWheelDirection();
m_throttleDirection = button->GetThrottleDirection();
@@ -209,6 +209,7 @@ bool CGUIConfigurationWizard::MapPrimitive(JOYSTICK::IButtonMap* buttonMap,
IKeymap* keymap,
const JOYSTICK::CDriverPrimitive& primitive)
{
+ using namespace INPUT;
using namespace JOYSTICK;
bool bHandled = false;
@@ -216,8 +217,6 @@ bool CGUIConfigurationWizard::MapPrimitive(JOYSTICK::IButtonMap* buttonMap,
// Abort if another controller cancels the prompt
if (IsMapping() && !IsMapping(buttonMap->DeviceName()))
{
- bool bIsCancelAction = false;
-
//! @todo This only succeeds for game.controller.default; no actions are
// currently defined for other controllers
if (keymap)
@@ -229,27 +228,11 @@ bool CGUIConfigurationWizard::MapPrimitive(JOYSTICK::IButtonMap* buttonMap,
if (!actions.empty())
{
//! @todo Handle multiple actions mapped to the same key
- switch (actions.begin()->actionId)
- {
- case ACTION_NAV_BACK:
- case ACTION_PREVIOUS_MENU:
- bIsCancelAction = true;
- break;
- default:
- break;
- }
+ OnAction(actions.begin()->actionId);
}
}
}
- if (bIsCancelAction)
- {
- CLog::Log(LOGDEBUG, "%s: device \"%s\" is cancelling prompt", buttonMap->ControllerID().c_str(), buttonMap->DeviceName().c_str());
- Abort(false);
- }
- else
- CLog::Log(LOGDEBUG, "%s: ignoring input for device \"%s\"", buttonMap->ControllerID().c_str(), buttonMap->DeviceName().c_str());
-
// Discard input
bHandled = true;
}
@@ -266,13 +249,13 @@ bool CGUIConfigurationWizard::MapPrimitive(JOYSTICK::IButtonMap* buttonMap,
{
// Get the current state of the thread
IFeatureButton* currentButton;
- ANALOG_STICK_DIRECTION analogStickDirection;
+ CARDINAL_DIRECTION cardinalDirection;
WHEEL_DIRECTION wheelDirection;
THROTTLE_DIRECTION throttleDirection;
{
CSingleLock lock(m_stateMutex);
currentButton = m_currentButton;
- analogStickDirection = m_analogStickDirection;
+ cardinalDirection = m_cardinalDirection;
wheelDirection = m_wheelDirection;
throttleDirection = m_throttleDirection;
}
@@ -302,56 +285,67 @@ bool CGUIConfigurationWizard::MapPrimitive(JOYSTICK::IButtonMap* buttonMap,
{
const CControllerFeature& feature = currentButton->Feature();
- CLog::Log(LOGDEBUG, "%s: mapping feature \"%s\" for device %s",
- m_strControllerId.c_str(), feature.Name().c_str(), buttonMap->DeviceName().c_str());
-
- switch (feature.Type())
+ if (primitive.Type() == PRIMITIVE_TYPE::RELATIVE_POINTER &&
+ feature.Type() != FEATURE_TYPE::RELPOINTER)
{
- case FEATURE_TYPE::SCALAR:
- {
- buttonMap->AddScalar(feature.Name(), primitive);
- bHandled = true;
- break;
- }
- case FEATURE_TYPE::ANALOG_STICK:
- {
- buttonMap->AddAnalogStick(feature.Name(), analogStickDirection, primitive);
- bHandled = true;
- break;
- }
- case FEATURE_TYPE::RELPOINTER:
- {
- buttonMap->AddRelativePointer(feature.Name(), analogStickDirection, primitive);
- bHandled = true;
- break;
- }
- case FEATURE_TYPE::WHEEL:
- {
- buttonMap->AddWheel(feature.Name(), wheelDirection, primitive);
- bHandled = true;
- break;
- }
- case FEATURE_TYPE::THROTTLE:
- {
- buttonMap->AddThrottle(feature.Name(), throttleDirection, primitive);
- bHandled = true;
- break;
- }
- case FEATURE_TYPE::KEY:
+ // Don't allow relative pointers to map to other features
+ }
+ else
+ {
+ CLog::Log(LOGDEBUG, "%s: mapping feature \"%s\" for device %s",
+ m_strControllerId.c_str(), feature.Name().c_str(), buttonMap->DeviceName().c_str());
+
+ switch (feature.Type())
{
- buttonMap->AddKey(feature.Name(), primitive);
- bHandled = true;
- break;
+ case FEATURE_TYPE::SCALAR:
+ {
+ buttonMap->AddScalar(feature.Name(), primitive);
+ bHandled = true;
+ break;
+ }
+ case FEATURE_TYPE::ANALOG_STICK:
+ {
+ buttonMap->AddAnalogStick(feature.Name(), cardinalDirection, primitive);
+ bHandled = true;
+ break;
+ }
+ case FEATURE_TYPE::RELPOINTER:
+ {
+ buttonMap->AddRelativePointer(feature.Name(), cardinalDirection, primitive);
+ bHandled = true;
+ break;
+ }
+ case FEATURE_TYPE::WHEEL:
+ {
+ buttonMap->AddWheel(feature.Name(), wheelDirection, primitive);
+ bHandled = true;
+ break;
+ }
+ case FEATURE_TYPE::THROTTLE:
+ {
+ buttonMap->AddThrottle(feature.Name(), throttleDirection, primitive);
+ bHandled = true;
+ break;
+ }
+ case FEATURE_TYPE::KEY:
+ {
+ buttonMap->AddKey(feature.Name(), primitive);
+ bHandled = true;
+ break;
+ }
+ default:
+ break;
}
- default:
- break;
}
if (bHandled)
{
m_history.insert(primitive);
- OnMotion(buttonMap);
+ // Don't record motion for relative pointers
+ if (primitive.Type() != PRIMITIVE_TYPE::RELATIVE_POINTER)
+ OnMotion(buttonMap);
+
m_inputEvent.Set();
if (m_deviceName.empty())
@@ -410,7 +404,7 @@ bool CGUIConfigurationWizard::OnKeyPress(const CKey& key)
if (bIsMappingController)
{
- bHandled = OnKeyAction(m_actionMap->GetActionID(key));
+ bHandled = OnAction(m_actionMap->GetActionID(key));
}
else
{
@@ -421,7 +415,7 @@ bool CGUIConfigurationWizard::OnKeyPress(const CKey& key)
return bHandled;
}
-bool CGUIConfigurationWizard::OnKeyAction(unsigned int actionId)
+bool CGUIConfigurationWizard::OnAction(unsigned int actionId)
{
bool bHandled = false;
@@ -441,6 +435,7 @@ bool CGUIConfigurationWizard::OnKeyAction(unsigned int actionId)
case ACTION_PARENT_DIR:
case ACTION_PREVIOUS_MENU:
case ACTION_STOP:
+ case ACTION_NAV_BACK:
// Abort and prevent action
Abort(false);
bHandled = true;
@@ -455,11 +450,6 @@ bool CGUIConfigurationWizard::OnKeyAction(unsigned int actionId)
return bHandled;
}
-bool CGUIConfigurationWizard::OnButtonPress(const std::string& button)
-{
- return Abort(false);
-}
-
bool CGUIConfigurationWizard::IsMapping() const
{
return !m_deviceName.empty();
@@ -472,15 +462,18 @@ bool CGUIConfigurationWizard::IsMapping(const std::string &deviceName) const
void CGUIConfigurationWizard::InstallHooks(void)
{
+ // Install button mapper with lowest priority
CServiceBroker::GetPeripherals().RegisterJoystickButtonMapper(this);
+
+ // Install hook to reattach button mapper when peripherals change
CServiceBroker::GetPeripherals().RegisterObserver(this);
+
+ // Install hook to cancel the button mapper
CServiceBroker::GetInputManager().RegisterKeyboardDriverHandler(this);
- CServiceBroker::GetInputManager().RegisterMouseHandler(this);
}
void CGUIConfigurationWizard::RemoveHooks(void)
{
- CServiceBroker::GetInputManager().UnregisterMouseHandler(this);
CServiceBroker::GetInputManager().UnregisterKeyboardDriverHandler(this);
CServiceBroker::GetPeripherals().UnregisterObserver(this);
CServiceBroker::GetPeripherals().UnregisterJoystickButtonMapper(this);
diff --git a/xbmc/games/controllers/windows/GUIConfigurationWizard.h b/xbmc/games/controllers/windows/GUIConfigurationWizard.h
index b980bc5ae7..4ae26bf54c 100644
--- a/xbmc/games/controllers/windows/GUIConfigurationWizard.h
+++ b/xbmc/games/controllers/windows/GUIConfigurationWizard.h
@@ -24,7 +24,6 @@
#include "input/joysticks/DriverPrimitive.h"
#include "input/joysticks/interfaces/IButtonMapper.h"
#include "input/keyboard/interfaces/IKeyboardDriverHandler.h"
-#include "input/mouse/interfaces/IMouseInputHandler.h"
#include "input/XBMC_keysym.h"
#include "threads/CriticalSection.h"
#include "threads/Event.h"
@@ -49,7 +48,6 @@ namespace GAME
class CGUIConfigurationWizard : public IConfigurationWizard,
public JOYSTICK::IButtonMapper,
public KEYBOARD::IKeyboardDriverHandler,
- public MOUSE::IMouseInputHandler,
public Observer,
protected CThread
{
@@ -78,11 +76,6 @@ namespace GAME
virtual bool OnKeyPress(const CKey& key) override;
virtual void OnKeyRelease(const CKey& key) override { }
- // implementation of IMouseInputHandler
- virtual bool OnMotion(const std::string& relpointer, int dx, int dy) override { return false; }
- virtual bool OnButtonPress(const std::string& button) override;
- virtual void OnButtonRelease(const std::string& button) override { }
-
// implementation of Observer
virtual void Notify(const Observable& obs, const ObservableMessage msg) override;
@@ -102,7 +95,7 @@ namespace GAME
void OnMotion(const JOYSTICK::IButtonMap* buttonMap);
void OnMotionless(const JOYSTICK::IButtonMap* buttonMap);
- bool OnKeyAction(unsigned int actionId);
+ bool OnAction(unsigned int actionId);
// Run() parameters
std::string m_strControllerId;
@@ -110,7 +103,7 @@ namespace GAME
// State variables and mutex
IFeatureButton* m_currentButton;
- JOYSTICK::ANALOG_STICK_DIRECTION m_analogStickDirection;
+ INPUT::CARDINAL_DIRECTION m_cardinalDirection;
JOYSTICK::WHEEL_DIRECTION m_wheelDirection;
JOYSTICK::THROTTLE_DIRECTION m_throttleDirection;
std::set<JOYSTICK::CDriverPrimitive> m_history; // History to avoid repeated features
diff --git a/xbmc/games/controllers/windows/IConfigurationWindow.h b/xbmc/games/controllers/windows/IConfigurationWindow.h
index 870a773165..72c0cf60e9 100644
--- a/xbmc/games/controllers/windows/IConfigurationWindow.h
+++ b/xbmc/games/controllers/windows/IConfigurationWindow.h
@@ -21,6 +21,7 @@
#include "games/controllers/ControllerTypes.h"
#include "input/joysticks/JoystickTypes.h"
+#include "input/InputTypes.h"
#include <string>
#include <vector>
@@ -187,11 +188,12 @@ namespace GAME
virtual bool IsFinished(void) const = 0;
/*!
- * \brief Get the direction of the next analog stick prompt
- * \return The next direction to be prompted, or UNKNOWN if this isn't an
- * analog stick or the prompt is finished
+ * \brief Get the direction of the next analog stick or relative pointer
+ * prompt
+ * \return The next direction to be prompted, or UNKNOWN if this isn't a
+ * cardinal feature or the prompt is finished
*/
- virtual JOYSTICK::ANALOG_STICK_DIRECTION GetAnalogStickDirection(void) const = 0;
+ virtual INPUT::CARDINAL_DIRECTION GetCardinalDirection(void) const = 0;
/*!
* \brief Get the direction of the next wheel prompt
diff --git a/xbmc/guilib/GUIControl.cpp b/xbmc/guilib/GUIControl.cpp
index 7837ff674a..8f57681305 100644
--- a/xbmc/guilib/GUIControl.cpp
+++ b/xbmc/guilib/GUIControl.cpp
@@ -25,7 +25,7 @@
#include "GUIWindowManager.h"
#include "GUIControlProfiler.h"
#include "GUITexture.h"
-#include "input/MouseStat.h"
+#include "input/mouse/MouseStat.h"
#include "input/InputManager.h"
#include "input/Key.h"
#include "ServiceBroker.h"
diff --git a/xbmc/input/ButtonTranslator.cpp b/xbmc/input/ButtonTranslator.cpp
index 90e94e13e9..bbdc7dbec8 100644
--- a/xbmc/input/ButtonTranslator.cpp
+++ b/xbmc/input/ButtonTranslator.cpp
@@ -32,14 +32,14 @@
#include "IButtonMapper.h"
#include "Key.h"
#include "KeyboardTranslator.h"
-#include "MouseTranslator.h"
#include "WindowTranslator.h"
-#include "FileItem.h"
#include "filesystem/Directory.h"
#include "guilib/WindowIDs.h"
-#include "Util.h"
+#include "input/mouse/MouseTranslator.h"
#include "utils/log.h"
#include "utils/XBMCTinyXML.h"
+#include "FileItem.h"
+#include "Util.h"
using namespace KODI;
diff --git a/xbmc/input/CMakeLists.txt b/xbmc/input/CMakeLists.txt
index c2cb7a0825..2c4e3feb04 100644
--- a/xbmc/input/CMakeLists.txt
+++ b/xbmc/input/CMakeLists.txt
@@ -10,6 +10,7 @@ set(SOURCES Action.cpp
InputCodingTableFactory.cpp
InputCodingTableKorean.cpp
InputManager.cpp
+ InputTranslator.cpp
IRTranslator.cpp
JoystickMapper.cpp
Key.cpp
@@ -19,18 +20,12 @@ set(SOURCES Action.cpp
KeyboardTranslator.cpp
Keymap.cpp
KeymapEnvironment.cpp
- MouseStat.cpp
- MouseTranslator.cpp
TouchTranslator.cpp
WindowKeymap.cpp
WindowTranslator.cpp
XBMC_keytable.cpp)
set(HEADERS hardware/IHardwareInput.h
- mouse/interfaces/IMouseButtonMap.h
- mouse/interfaces/IMouseDriverHandler.h
- mouse/interfaces/IMouseInputHandler.h
- mouse/interfaces/IMouseInputProvider.h
Action.h
ActionIDs.h
ActionTranslator.h
@@ -48,6 +43,8 @@ set(HEADERS hardware/IHardwareInput.h
InputCodingTableFactory.h
InputCodingTableKorean.h
InputManager.h
+ InputTranslator.h
+ InputTypes.h
IRTranslator.h
JoystickMapper.h
Key.h
@@ -57,8 +54,6 @@ set(HEADERS hardware/IHardwareInput.h
KeyboardTranslator.h
Keymap.h
KeymapEnvironment.h
- MouseStat.h
- MouseTranslator.h
TouchTranslator.h
WindowTranslator.h
WindowKeymap.h
diff --git a/xbmc/input/InputManager.cpp b/xbmc/input/InputManager.cpp
index fcaee017f9..6adf6ac512 100644
--- a/xbmc/input/InputManager.cpp
+++ b/xbmc/input/InputManager.cpp
@@ -29,10 +29,9 @@
#include "KeymapEnvironment.h"
#include "TouchTranslator.h"
#include "input/keyboard/interfaces/IKeyboardDriverHandler.h"
-#include "input/mouse/generic/MouseInputHandling.h"
-#include "input/mouse/interfaces/IMouseDriverHandler.h"
-#include "input/mouse/MouseWindowingButtonMap.h"
#include "input/keyboard/KeyboardEasterEgg.h"
+#include "input/mouse/interfaces/IMouseDriverHandler.h"
+#include "input/mouse/MouseTranslator.h"
#include "input/Key.h"
#include "input/WindowTranslator.h"
#include "messaging/ApplicationMessenger.h"
@@ -78,7 +77,6 @@ CInputManager::CInputManager(const CAppParamParser &params,
m_customControllerTranslator(new CCustomControllerTranslator),
m_touchTranslator(new CTouchTranslator),
m_joystickTranslator(new CJoystickMapper),
- m_mouseButtonMap(new MOUSE::CMouseWindowingButtonMap),
m_keyboardEasterEgg(new KEYBOARD::CKeyboardEasterEgg)
{
m_buttonTranslator->RegisterMapper("touch", m_touchTranslator.get());
@@ -397,24 +395,35 @@ bool CInputManager::OnEvent(XBMC_Event& newEvent)
{
bool handled = false;
- for (auto it = m_mouseHandlers.begin(); it != m_mouseHandlers.end(); ++it)
+ for (auto driverHandler : m_mouseHandlers)
{
- if (newEvent.type == XBMC_MOUSEMOTION)
+ switch (newEvent.type)
+ {
+ case XBMC_MOUSEMOTION:
{
- if (it->driverHandler->OnPosition(newEvent.motion.x, newEvent.motion.y))
+ if (driverHandler->OnPosition(newEvent.motion.x, newEvent.motion.y))
handled = true;
+ break;
}
- else
+ case XBMC_MOUSEBUTTONDOWN:
{
- if (newEvent.type == XBMC_MOUSEBUTTONDOWN)
+ MOUSE::BUTTON_ID buttonId;
+ if (CMouseTranslator::TranslateEventID(newEvent.button.button, buttonId))
{
- if (it->driverHandler->OnButtonPress(newEvent.button.button))
+ if (driverHandler->OnButtonPress(buttonId))
handled = true;
}
- else if (newEvent.type == XBMC_MOUSEBUTTONUP)
- {
- it->driverHandler->OnButtonRelease(newEvent.button.button);
- }
+ break;
+ }
+ case XBMC_MOUSEBUTTONUP:
+ {
+ MOUSE::BUTTON_ID buttonId;
+ if (CMouseTranslator::TranslateEventID(newEvent.button.button, buttonId))
+ driverHandler->OnButtonRelease(buttonId);
+ break;
+ }
+ default:
+ break;
}
if (handled)
@@ -1006,29 +1015,13 @@ void CInputManager::UnregisterKeyboardDriverHandler(KEYBOARD::IKeyboardDriverHan
m_keyboardHandlers.erase(std::remove(m_keyboardHandlers.begin(), m_keyboardHandlers.end(), handler), m_keyboardHandlers.end());
}
-std::string CInputManager::RegisterMouseHandler(MOUSE::IMouseInputHandler* handler)
+void CInputManager::RegisterMouseDriverHandler(MOUSE::IMouseDriverHandler* handler)
{
- auto it = std::find_if(m_mouseHandlers.begin(), m_mouseHandlers.end(),
- [handler](const MouseHandlerHandle& element)
- {
- return element.inputHandler == handler;
- });
-
- if (it == m_mouseHandlers.end())
- {
- std::unique_ptr<MOUSE::IMouseDriverHandler> driverHandler(new MOUSE::CMouseInputHandling(handler, m_mouseButtonMap.get()));
- MouseHandlerHandle handle = { handler, std::move(driverHandler) };
- m_mouseHandlers.insert(m_mouseHandlers.begin(), std::move(handle));
- }
-
- return m_mouseButtonMap->ControllerID();
+ if (std::find(m_mouseHandlers.begin(), m_mouseHandlers.end(), handler) == m_mouseHandlers.end())
+ m_mouseHandlers.insert(m_mouseHandlers.begin(), handler);
}
-void CInputManager::UnregisterMouseHandler(MOUSE::IMouseInputHandler* handler)
+void CInputManager::UnregisterMouseDriverHandler(MOUSE::IMouseDriverHandler* handler)
{
- m_mouseHandlers.erase(std::remove_if(m_mouseHandlers.begin(), m_mouseHandlers.end(),
- [handler](const MouseHandlerHandle& handle)
- {
- return handle.inputHandler == handler;
- }), m_mouseHandlers.end());
+ m_mouseHandlers.erase(std::remove(m_mouseHandlers.begin(), m_mouseHandlers.end(), handler), m_mouseHandlers.end());
}
diff --git a/xbmc/input/InputManager.h b/xbmc/input/InputManager.h
index 97266c45ae..2d623b39a1 100644
--- a/xbmc/input/InputManager.h
+++ b/xbmc/input/InputManager.h
@@ -34,8 +34,8 @@
#include "Action.h"
#include "windowing/XBMC_events.h"
#include "input/mouse/interfaces/IMouseInputProvider.h"
+#include "input/mouse/MouseStat.h"
#include "input/KeyboardStat.h"
-#include "input/MouseStat.h"
#include "interfaces/IActionListener.h"
#include "settings/lib/ISettingCallback.h"
#include "threads/CriticalSection.h"
@@ -61,9 +61,7 @@ namespace KEYBOARD
namespace MOUSE
{
- class IMouseButtonMap;
class IMouseDriverHandler;
- class IMouseInputHandler;
}
}
@@ -82,7 +80,6 @@ namespace MOUSE
*/
class CInputManager : public ISettingCallback,
public IActionListener,
- public KODI::MOUSE::IMouseInputProvider,
public Observable
{
public:
@@ -288,9 +285,8 @@ public:
void RegisterKeyboardDriverHandler(KODI::KEYBOARD::IKeyboardDriverHandler* handler);
void UnregisterKeyboardDriverHandler(KODI::KEYBOARD::IKeyboardDriverHandler* handler);
- // implementation of IMouseInputProvider
- virtual std::string RegisterMouseHandler(KODI::MOUSE::IMouseInputHandler* handler) override;
- virtual void UnregisterMouseHandler(KODI::MOUSE::IMouseInputHandler* handler) override;
+ virtual void RegisterMouseDriverHandler(KODI::MOUSE::IMouseDriverHandler* handler);
+ virtual void UnregisterMouseDriverHandler(KODI::MOUSE::IMouseDriverHandler* handler);
private:
@@ -364,15 +360,7 @@ private:
std::unique_ptr<CJoystickMapper> m_joystickTranslator;
std::vector<KODI::KEYBOARD::IKeyboardDriverHandler*> m_keyboardHandlers;
-
- struct MouseHandlerHandle
- {
- KODI::MOUSE::IMouseInputHandler* inputHandler;
- std::unique_ptr<KODI::MOUSE::IMouseDriverHandler> driverHandler;
- };
-
- std::vector<MouseHandlerHandle> m_mouseHandlers;
- std::unique_ptr<KODI::MOUSE::IMouseButtonMap> m_mouseButtonMap;
+ std::vector<KODI::MOUSE::IMouseDriverHandler*> m_mouseHandlers;
std::unique_ptr<KODI::KEYBOARD::IKeyboardDriverHandler> m_keyboardEasterEgg;
};
diff --git a/xbmc/input/InputTranslator.cpp b/xbmc/input/InputTranslator.cpp
new file mode 100644
index 0000000000..e3b1747f2c
--- /dev/null
+++ b/xbmc/input/InputTranslator.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 Team Kodi
+ * http://kodi.tv
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "InputTranslator.h"
+
+using namespace KODI;
+using namespace INPUT;
+
+#define TAN_1_8_PI 0.4142136f // tan(1/8*PI)
+#define TAN_3_8_PI 2.4142136f // tan(3/8*PI)
+
+CARDINAL_DIRECTION CInputTranslator::VectorToCardinalDirection(float x, float y)
+{
+ if (y >= -x && y > x) return CARDINAL_DIRECTION::UP;
+ else if (y <= x && y > -x) return CARDINAL_DIRECTION::RIGHT;
+ else if (y <= -x && y < x) return CARDINAL_DIRECTION::DOWN;
+ else if (y >= x && y < -x) return CARDINAL_DIRECTION::LEFT;
+
+ return CARDINAL_DIRECTION::NONE;
+}
+
+INTERCARDINAL_DIRECTION CInputTranslator::VectorToIntercardinalDirection(float x, float y)
+{
+ if (y >= TAN_3_8_PI * -x && y > TAN_3_8_PI * x) return INTERCARDINAL_DIRECTION::UP;
+ else if (y <= TAN_3_8_PI * x && y > TAN_1_8_PI * x) return INTERCARDINAL_DIRECTION::RIGHTUP;
+ else if (y <= TAN_1_8_PI * x && y > TAN_1_8_PI * -x) return INTERCARDINAL_DIRECTION::RIGHT;
+ else if (y <= TAN_1_8_PI * -x && y > TAN_3_8_PI * -x) return INTERCARDINAL_DIRECTION::RIGHTDOWN;
+ else if (y <= TAN_3_8_PI * -x && y < TAN_3_8_PI * x) return INTERCARDINAL_DIRECTION::DOWN;
+ else if (y >= TAN_3_8_PI * x && y < TAN_1_8_PI * x) return INTERCARDINAL_DIRECTION::LEFTDOWN;
+ else if (y >= TAN_1_8_PI * x && y < TAN_1_8_PI * -x) return INTERCARDINAL_DIRECTION::LEFT;
+ else if (y >= TAN_1_8_PI * -x && y < TAN_3_8_PI * -x) return INTERCARDINAL_DIRECTION::LEFTUP;
+
+ return INTERCARDINAL_DIRECTION::NONE;
+}
diff --git a/xbmc/input/InputTranslator.h b/xbmc/input/InputTranslator.h
new file mode 100644
index 0000000000..d3e02a984a
--- /dev/null
+++ b/xbmc/input/InputTranslator.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 Team Kodi
+ * http://kodi.tv
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include "InputTypes.h"
+
+namespace KODI
+{
+namespace INPUT
+{
+ class CInputTranslator
+ {
+ public:
+ /*!
+ * \brief Get the closest cardinal direction to the given vector
+ *
+ * This function assumes a right-handed cartesian coordinate system; postive
+ * X is right, positive Y is up.
+ *
+ * Ties are resolved in the clockwise direction: (0.5, 0.5) will resolve to
+ * RIGHT.
+ *
+ * \param x The x component of the vector
+ * \param y The y component of the vector
+ *
+ * \return The closest cardinal direction (up, down, right or left), or
+ * CARDINAL_DIRECTION::NONE if x and y are both 0
+ */
+ static CARDINAL_DIRECTION VectorToCardinalDirection(float x, float y);
+
+ /*!
+ * \brief Get the closest cardinal or intercardinal direction to the given
+ * vector
+ *
+ * This function assumes a right-handed cartesian coordinate system; postive
+ * X is right, positive Y is up.
+ *
+ * Ties are resolved in the clockwise direction.
+ *
+ * \param x The x component of the vector
+ * \param y The y component of the vector
+ *
+ * \return The closest intercardinal direction, or
+ * INTERCARDINAL_DIRECTION::NONE if x and y are both 0
+ */
+ static INTERCARDINAL_DIRECTION VectorToIntercardinalDirection(float x, float y);
+ };
+}
+}
diff --git a/xbmc/input/InputTypes.h b/xbmc/input/InputTypes.h
new file mode 100644
index 0000000000..adf36cbac2
--- /dev/null
+++ b/xbmc/input/InputTypes.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 Team Kodi
+ * http://kodi.tv
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+namespace KODI
+{
+namespace INPUT
+{
+ /*!
+ * \brief Cardinal directions, used for input device motions
+ */
+ enum class CARDINAL_DIRECTION
+ {
+ NONE = 0x0,
+ UP = 0x1,
+ DOWN = 0x2,
+ RIGHT = 0x4,
+ LEFT = 0x8,
+ };
+
+ /*!
+ * \brief Cardinal and intercardinal directions, used for input device motions
+ */
+ enum class INTERCARDINAL_DIRECTION
+ {
+ NONE = static_cast<unsigned int>(CARDINAL_DIRECTION::NONE),
+ UP = static_cast<unsigned int>(CARDINAL_DIRECTION::UP),
+ DOWN = static_cast<unsigned int>(CARDINAL_DIRECTION::DOWN),
+ RIGHT = static_cast<unsigned int>(CARDINAL_DIRECTION::RIGHT),
+ LEFT = static_cast<unsigned int>(CARDINAL_DIRECTION::LEFT),
+ RIGHTUP = RIGHT | UP,
+ RIGHTDOWN = RIGHT | DOWN,
+ LEFTUP = LEFT | UP,
+ LEFTDOWN = LEFT | DOWN,
+ };
+}
+}
diff --git a/xbmc/input/JoystickMapper.cpp b/xbmc/input/JoystickMapper.cpp
index fcc37df37a..c1a1bfbf74 100644
--- a/xbmc/input/JoystickMapper.cpp
+++ b/xbmc/input/JoystickMapper.cpp
@@ -134,7 +134,7 @@ bool CJoystickMapper::DeserializeButton(const TiXmlElement *pButton, std::string
if (!feature.empty() && !actionStr.empty())
{
// Handle direction
- dir = JOYSTICK::ANALOG_STICK_DIRECTION::UNKNOWN;
+ dir = JOYSTICK::ANALOG_STICK_DIRECTION::NONE;
const char *szDirection = pButton->Attribute(JOYSTICK_XML_ATTR_DIRECTION);
if (szDirection != nullptr)
dir = JOYSTICK::CJoystickTranslator::TranslateAnalogStickDirection(szDirection);
diff --git a/xbmc/input/joysticks/DriverPrimitive.cpp b/xbmc/input/joysticks/DriverPrimitive.cpp
index 66cc47c9ea..10f3e52474 100644
--- a/xbmc/input/joysticks/DriverPrimitive.cpp
+++ b/xbmc/input/joysticks/DriverPrimitive.cpp
@@ -55,6 +55,18 @@ CDriverPrimitive::CDriverPrimitive(XBMCKey keycode) :
{
}
+CDriverPrimitive::CDriverPrimitive(MOUSE::BUTTON_ID index) :
+ m_type(PRIMITIVE_TYPE::MOUSE_BUTTON),
+ m_driverIndex(static_cast<unsigned int>(index))
+{
+}
+
+CDriverPrimitive::CDriverPrimitive(RELATIVE_POINTER_DIRECTION direction) :
+ m_type(PRIMITIVE_TYPE::RELATIVE_POINTER),
+ m_pointerDirection(direction)
+{
+}
+
bool CDriverPrimitive::operator==(const CDriverPrimitive& rhs) const
{
if (m_type == rhs.m_type)
@@ -63,6 +75,7 @@ bool CDriverPrimitive::operator==(const CDriverPrimitive& rhs) const
{
case PRIMITIVE_TYPE::BUTTON:
case PRIMITIVE_TYPE::MOTOR:
+ case PRIMITIVE_TYPE::MOUSE_BUTTON:
return m_driverIndex == rhs.m_driverIndex;
case PRIMITIVE_TYPE::HAT:
return m_driverIndex == rhs.m_driverIndex && m_hatDirection == rhs.m_hatDirection;
@@ -73,6 +86,8 @@ bool CDriverPrimitive::operator==(const CDriverPrimitive& rhs) const
m_range == rhs.m_range;
case PRIMITIVE_TYPE::KEY:
return m_keycode == rhs.m_keycode;
+ case PRIMITIVE_TYPE::RELATIVE_POINTER:
+ return m_pointerDirection == rhs.m_pointerDirection;
default:
return true;
}
@@ -88,7 +103,8 @@ bool CDriverPrimitive::operator<(const CDriverPrimitive& rhs) const
if (m_type == PRIMITIVE_TYPE::BUTTON ||
m_type == PRIMITIVE_TYPE::HAT ||
m_type == PRIMITIVE_TYPE::SEMIAXIS ||
- m_type == PRIMITIVE_TYPE::MOTOR)
+ m_type == PRIMITIVE_TYPE::MOTOR ||
+ m_type == PRIMITIVE_TYPE::MOUSE_BUTTON)
{
if (m_driverIndex < rhs.m_driverIndex) return true;
if (m_driverIndex > rhs.m_driverIndex) return false;
@@ -118,13 +134,20 @@ bool CDriverPrimitive::operator<(const CDriverPrimitive& rhs) const
if (m_keycode > rhs.m_keycode) return false;
}
+ if (m_type == PRIMITIVE_TYPE::RELATIVE_POINTER)
+ {
+ if (m_pointerDirection < rhs.m_pointerDirection) return true;
+ if (m_pointerDirection > rhs.m_pointerDirection) return false;
+ }
+
return false;
}
bool CDriverPrimitive::IsValid(void) const
{
if (m_type == PRIMITIVE_TYPE::BUTTON ||
- m_type == PRIMITIVE_TYPE::MOTOR)
+ m_type == PRIMITIVE_TYPE::MOTOR ||
+ m_type == PRIMITIVE_TYPE::MOUSE_BUTTON)
return true;
if (m_type == PRIMITIVE_TYPE::HAT)
@@ -172,5 +195,13 @@ bool CDriverPrimitive::IsValid(void) const
if (m_type == PRIMITIVE_TYPE::KEY)
return m_keycode != XBMCK_UNKNOWN;
+ if (m_type == PRIMITIVE_TYPE::RELATIVE_POINTER)
+ {
+ return m_pointerDirection == RELATIVE_POINTER_DIRECTION::UP ||
+ m_pointerDirection == RELATIVE_POINTER_DIRECTION::DOWN ||
+ m_pointerDirection == RELATIVE_POINTER_DIRECTION::RIGHT ||
+ m_pointerDirection == RELATIVE_POINTER_DIRECTION::LEFT;
+ }
+
return false;
}
diff --git a/xbmc/input/joysticks/DriverPrimitive.h b/xbmc/input/joysticks/DriverPrimitive.h
index 32be317992..65eca9b831 100644
--- a/xbmc/input/joysticks/DriverPrimitive.h
+++ b/xbmc/input/joysticks/DriverPrimitive.h
@@ -20,6 +20,7 @@
#pragma once
#include "JoystickTypes.h"
+#include "input/mouse/MouseTypes.h"
#include "input/XBMC_keysym.h"
#include <stdint.h>
@@ -67,6 +68,12 @@ namespace JOYSTICK
* Key:
* - keycode
*
+ * Mouse button:
+ * - driver index
+ *
+ * Relative pointer:
+ * - pointer direction
+ *
* For more info, see "Chapter 2. Joystick drivers" in the documentation
* thread: http://forum.kodi.tv/showthread.php?tid=257764
*/
@@ -100,6 +107,16 @@ namespace JOYSTICK
*/
CDriverPrimitive(XBMCKey keycode);
+ /*!
+ * \brief Construct a driver primitive representing a mouse button
+ */
+ CDriverPrimitive(MOUSE::BUTTON_ID index);
+
+ /*!
+ * \brief Construct a driver primitive representing a relative pointer
+ */
+ CDriverPrimitive(RELATIVE_POINTER_DIRECTION direction);
+
bool operator==(const CDriverPrimitive& rhs) const;
bool operator<(const CDriverPrimitive& rhs) const;
@@ -150,6 +167,16 @@ namespace JOYSTICK
XBMCKey Keycode() const { return m_keycode; }
/*!
+ * \brief The mouse button ID (valid for mouse buttons)
+ */
+ MOUSE::BUTTON_ID MouseButton() const { return static_cast<MOUSE::BUTTON_ID>(m_driverIndex); }
+
+ /*!
+ * \brief The relative pointer direction (valid for relative pointers)
+ */
+ RELATIVE_POINTER_DIRECTION PointerDirection() const { return m_pointerDirection; }
+
+ /*!
* \brief Test if an driver primitive is valid
*
* A driver primitive is valid if it has a known type and:
@@ -163,11 +190,12 @@ namespace JOYSTICK
private:
PRIMITIVE_TYPE m_type = PRIMITIVE_TYPE::UNKNOWN;
unsigned int m_driverIndex = 0;
- HAT_DIRECTION m_hatDirection = HAT_DIRECTION::UNKNOWN;
+ HAT_DIRECTION m_hatDirection = HAT_DIRECTION::NONE;
int m_center = 0;
SEMIAXIS_DIRECTION m_semiAxisDirection = SEMIAXIS_DIRECTION::ZERO;
unsigned int m_range = 1;
XBMCKey m_keycode = XBMCK_UNKNOWN;
+ RELATIVE_POINTER_DIRECTION m_pointerDirection = RELATIVE_POINTER_DIRECTION::NONE;
};
}
}
diff --git a/xbmc/input/joysticks/JoystickTranslator.cpp b/xbmc/input/joysticks/JoystickTranslator.cpp
index 07e049e801..0312fb3ef8 100644
--- a/xbmc/input/joysticks/JoystickTranslator.cpp
+++ b/xbmc/input/joysticks/JoystickTranslator.cpp
@@ -21,6 +21,7 @@
#include "JoystickTranslator.h"
#include "guilib/LocalizeStrings.h"
#include "input/joysticks/DriverPrimitive.h"
+#include "input/mouse/MouseStat.h"
#include "utils/StringUtils.h"
using namespace KODI;
@@ -38,7 +39,6 @@ const char* CJoystickTranslator::HatStateToString(HAT_STATE state)
case HAT_STATE::RIGHTDOWN: return "DOWN RIGHT";
case HAT_STATE::LEFTUP: return "UP LEFT";
case HAT_STATE::LEFTDOWN: return "DOWN LEFT";
- case HAT_STATE::UNPRESSED:
default:
break;
}
@@ -68,7 +68,7 @@ ANALOG_STICK_DIRECTION CJoystickTranslator::TranslateAnalogStickDirection(const
if (dir == "right") return ANALOG_STICK_DIRECTION::RIGHT;
if (dir == "left") return ANALOG_STICK_DIRECTION::LEFT;
- return ANALOG_STICK_DIRECTION::UNKNOWN;
+ return ANALOG_STICK_DIRECTION::NONE;
}
const char* CJoystickTranslator::TranslateWheelDirection(WHEEL_DIRECTION dir)
@@ -89,7 +89,7 @@ WHEEL_DIRECTION CJoystickTranslator::TranslateWheelDirection(const std::string &
if (dir == "right") return WHEEL_DIRECTION::RIGHT;
if (dir == "left") return WHEEL_DIRECTION::LEFT;
- return WHEEL_DIRECTION::UNKNOWN;
+ return WHEEL_DIRECTION::NONE;
}
const char* CJoystickTranslator::TranslateThrottleDirection(THROTTLE_DIRECTION dir)
@@ -110,7 +110,7 @@ THROTTLE_DIRECTION CJoystickTranslator::TranslateThrottleDirection(const std::st
if (dir == "up") return THROTTLE_DIRECTION::UP;
if (dir == "down") return THROTTLE_DIRECTION::DOWN;
- return THROTTLE_DIRECTION::UNKNOWN;
+ return THROTTLE_DIRECTION::NONE;
}
SEMIAXIS_DIRECTION CJoystickTranslator::PositionToSemiAxisDirection(float position)
@@ -126,7 +126,7 @@ WHEEL_DIRECTION CJoystickTranslator::PositionToWheelDirection(float position)
if (position > 0.0f) return WHEEL_DIRECTION::RIGHT;
else if (position < 0.0f) return WHEEL_DIRECTION::LEFT;
- return WHEEL_DIRECTION::UNKNOWN;
+ return WHEEL_DIRECTION::NONE;
}
THROTTLE_DIRECTION CJoystickTranslator::PositionToThrottleDirection(float position)
@@ -134,17 +134,7 @@ THROTTLE_DIRECTION CJoystickTranslator::PositionToThrottleDirection(float positi
if (position > 0.0f) return THROTTLE_DIRECTION::UP;
else if (position < 0.0f) return THROTTLE_DIRECTION::DOWN;
- return THROTTLE_DIRECTION::UNKNOWN;
-}
-
-ANALOG_STICK_DIRECTION CJoystickTranslator::VectorToAnalogStickDirection(float x, float y)
-{
- if (y >= x && y > -x) return ANALOG_STICK_DIRECTION::UP;
- else if (y < x && y >= -x) return ANALOG_STICK_DIRECTION::RIGHT;
- else if (y <= x && y < -x) return ANALOG_STICK_DIRECTION::DOWN;
- else if (y > x && y <= -x) return ANALOG_STICK_DIRECTION::LEFT;
-
- return ANALOG_STICK_DIRECTION::UNKNOWN;
+ return THROTTLE_DIRECTION::NONE;
}
std::string CJoystickTranslator::GetPrimitiveName(const CDriverPrimitive& primitive)
diff --git a/xbmc/input/joysticks/JoystickTranslator.h b/xbmc/input/joysticks/JoystickTranslator.h
index 6ff92f54f4..41a4b1c5fd 100644
--- a/xbmc/input/joysticks/JoystickTranslator.h
+++ b/xbmc/input/joysticks/JoystickTranslator.h
@@ -20,6 +20,7 @@
#pragma once
#include "JoystickTypes.h"
+#include "input/mouse/MouseTypes.h"
namespace KODI
{
@@ -124,20 +125,6 @@ namespace JOYSTICK
static THROTTLE_DIRECTION PositionToThrottleDirection(float position);
/*!
- * \brief Get the closest cardinal direction to the given vector
- *
- * Ties are resolved in the clockwise direction: (0.5, 0.5) will resolve to
- * RIGHT.
- *
- * \param x The x component of the vector
- * \param y The y component of the vector
- *
- * \return The closest analog stick direction (up, down, right or left), or
- * ANALOG_STICK_DIRECTION::UNKNOWN if x and y are both 0
- */
- static ANALOG_STICK_DIRECTION VectorToAnalogStickDirection(float x, float y);
-
- /*!
* \brief Get the localized name of the primitive
*
* \param primitive The primitive, currently only buttons and axes are supported
diff --git a/xbmc/input/joysticks/JoystickTypes.h b/xbmc/input/joysticks/JoystickTypes.h
index 44f0214bc3..86311372ae 100644
--- a/xbmc/input/joysticks/JoystickTypes.h
+++ b/xbmc/input/joysticks/JoystickTypes.h
@@ -24,6 +24,8 @@
\ingroup joystick
*/
+#include "input/InputTypes.h"
+
#include <set>
#include <string>
@@ -96,35 +98,22 @@ namespace JOYSTICK
/*!
* \brief Direction arrows on the hat (directional pad)
*/
- enum class HAT_DIRECTION
- {
- UNKNOWN = 0x0,
- UP = 0x1,
- DOWN = 0x2,
- RIGHT = 0x4,
- LEFT = 0x8,
- };
+ using HAT_DIRECTION = INPUT::CARDINAL_DIRECTION;
+
+ /*!
+ * \brief States in which a hat can be
+ */
+ using HAT_STATE = INPUT::INTERCARDINAL_DIRECTION;
/*!
* \brief Typedef for analog stick directions
*/
- using ANALOG_STICK_DIRECTION = HAT_DIRECTION;
+ using ANALOG_STICK_DIRECTION = INPUT::CARDINAL_DIRECTION;
/*!
- * \brief States in which a hat can be
+ * \brief Directions of motion for a relative pointer
*/
- enum class HAT_STATE
- {
- UNPRESSED = 0x0, /*!< @brief no directions are pressed */
- UP = 0x1, /*!< @brief only up is pressed */
- DOWN = 0x2, /*!< @brief only down is pressed */
- RIGHT = 0x4, /*!< @brief only right is pressed */
- LEFT = 0x8, /*!< @brief only left is pressed */
- RIGHTUP = RIGHT | UP,
- RIGHTDOWN = RIGHT | DOWN,
- LEFTUP = LEFT | UP,
- LEFTDOWN = LEFT | DOWN,
- };
+ using RELATIVE_POINTER_DIRECTION = INPUT::CARDINAL_DIRECTION;
/*!
* \brief Directions in which a semiaxis can point
@@ -141,7 +130,7 @@ namespace JOYSTICK
*/
enum class WHEEL_DIRECTION
{
- UNKNOWN,
+ NONE,
RIGHT,
LEFT,
};
@@ -151,7 +140,7 @@ namespace JOYSTICK
*/
enum class THROTTLE_DIRECTION
{
- UNKNOWN,
+ NONE,
UP,
DOWN,
};
@@ -176,9 +165,11 @@ namespace JOYSTICK
HAT, // one of the four direction arrows on a D-pad
SEMIAXIS, // the positive or negative half of an axis
MOTOR, // a rumble motor
- KEY // a keyboard key
+ KEY, // a keyboard key
+ MOUSE_BUTTON, // a mouse button
+ RELATIVE_POINTER, // a relative pointer, such as on a mouse
};
-
+
/*!
* \ingroup joystick
* \brief Action entry in joystick.xml
diff --git a/xbmc/input/joysticks/JoystickUtils.cpp b/xbmc/input/joysticks/JoystickUtils.cpp
index e2bbd5cabb..cf115dabab 100644
--- a/xbmc/input/joysticks/JoystickUtils.cpp
+++ b/xbmc/input/joysticks/JoystickUtils.cpp
@@ -34,7 +34,7 @@ std::string CJoystickUtils::MakeKeyName(const FeatureName &feature, ANALOG_STICK
{
std::string keyName = feature;
- if (dir != ANALOG_STICK_DIRECTION::UNKNOWN)
+ if (dir != ANALOG_STICK_DIRECTION::NONE)
keyName += CJoystickTranslator::TranslateAnalogStickDirection(dir);
return keyName;
@@ -42,7 +42,7 @@ std::string CJoystickUtils::MakeKeyName(const FeatureName &feature, ANALOG_STICK
std::string CJoystickUtils::MakeKeyName(const FeatureName &feature, WHEEL_DIRECTION dir)
{
- ANALOG_STICK_DIRECTION stickDir = ANALOG_STICK_DIRECTION::UNKNOWN;
+ ANALOG_STICK_DIRECTION stickDir = ANALOG_STICK_DIRECTION::NONE;
switch (dir)
{
@@ -61,7 +61,7 @@ std::string CJoystickUtils::MakeKeyName(const FeatureName &feature, WHEEL_DIRECT
std::string CJoystickUtils::MakeKeyName(const FeatureName &feature, THROTTLE_DIRECTION dir)
{
- ANALOG_STICK_DIRECTION stickDir = ANALOG_STICK_DIRECTION::UNKNOWN;
+ ANALOG_STICK_DIRECTION stickDir = ANALOG_STICK_DIRECTION::NONE;
switch (dir)
{
diff --git a/xbmc/input/joysticks/generic/ButtonMapping.cpp b/xbmc/input/joysticks/generic/ButtonMapping.cpp
index 4c7c7c2194..3f5af89d60 100644
--- a/xbmc/input/joysticks/generic/ButtonMapping.cpp
+++ b/xbmc/input/joysticks/generic/ButtonMapping.cpp
@@ -27,6 +27,7 @@
#include "input/joysticks/DriverPrimitive.h"
#include "input/joysticks/JoystickTranslator.h"
#include "input/joysticks/JoystickUtils.h"
+#include "input/InputTranslator.h"
#include "input/IKeymap.h"
#include "input/Key.h"
#include "threads/SystemClock.h"
@@ -261,6 +262,67 @@ bool CKeyDetector::OnMotion(bool bPressed)
return false;
}
+// --- CMouseButtonDetector ----------------------------------------------------
+
+CMouseButtonDetector::CMouseButtonDetector(CButtonMapping* buttonMapping, MOUSE::BUTTON_ID buttonIndex) :
+ CPrimitiveDetector(buttonMapping),
+ m_buttonIndex(buttonIndex)
+{
+}
+
+bool CMouseButtonDetector::OnMotion(bool bPressed)
+{
+ if (bPressed)
+ return MapPrimitive(CDriverPrimitive(m_buttonIndex));
+
+ return false;
+}
+
+// --- CPointerDetector --------------------------------------------------------
+
+CPointerDetector::CPointerDetector(CButtonMapping* buttonMapping) :
+ CPrimitiveDetector(buttonMapping)
+{
+}
+
+bool CPointerDetector::OnMotion(int x, int y)
+{
+ if (!m_bStarted)
+ {
+ m_bStarted = true;
+ m_startX = x;
+ m_startY = y;
+ m_frameCount = 0;
+ }
+
+ if (m_frameCount++ >= MIN_FRAME_COUNT)
+ {
+ int dx = x - m_startX;
+ int dy = y - m_startY;
+
+ INPUT::INTERCARDINAL_DIRECTION dir = GetPointerDirection(dx, dy);
+
+ CDriverPrimitive primitive(static_cast<RELATIVE_POINTER_DIRECTION>(dir));
+ if (primitive.IsValid())
+ {
+ if (MapPrimitive(primitive))
+ m_bStarted = false;
+ }
+ }
+
+ return true;
+}
+
+KODI::INPUT::INTERCARDINAL_DIRECTION CPointerDetector::GetPointerDirection(int x, int y)
+{
+ using namespace INPUT;
+
+ // Translate from left-handed coordinate system to right-handed coordinate system
+ y *= -1;
+
+ return CInputTranslator::VectorToIntercardinalDirection(static_cast<float>(x), static_cast<float>(y));
+}
+
// --- CButtonMapping ----------------------------------------------------------
CButtonMapping::CButtonMapping(IButtonMapper* buttonMapper, IButtonMap* buttonMap, IKeymap* keymap) :
@@ -342,6 +404,21 @@ bool CButtonMapping::OnKeyPress(const CKey& key)
return GetKey(static_cast<XBMCKey>(key.GetKeycode())).OnMotion(true);
}
+bool CButtonMapping::OnPosition(int x, int y)
+{
+ return GetPointer().OnMotion(x, y);
+}
+
+bool CButtonMapping::OnButtonPress(MOUSE::BUTTON_ID button)
+{
+ return GetMouseButton(button).OnMotion(true);
+}
+
+void CButtonMapping::OnButtonRelease(MOUSE::BUTTON_ID button)
+{
+ GetMouseButton(button).OnMotion(false);
+}
+
void CButtonMapping::SaveButtonMap()
{
m_buttonMap->SaveButtonMap();
@@ -468,6 +545,27 @@ CKeyDetector& CButtonMapping::GetKey(XBMCKey keycode)
return itKey->second;
}
+CMouseButtonDetector& CButtonMapping::GetMouseButton(MOUSE::BUTTON_ID buttonIndex)
+{
+ auto itButton = m_mouseButtons.find(buttonIndex);
+
+ if (itButton == m_mouseButtons.end())
+ {
+ m_mouseButtons.insert(std::make_pair(buttonIndex, CMouseButtonDetector(this, buttonIndex)));
+ itButton = m_mouseButtons.find(buttonIndex);
+ }
+
+ return itButton->second;
+}
+
+CPointerDetector &CButtonMapping::GetPointer()
+{
+ if (!m_pointer)
+ m_pointer.reset(new CPointerDetector(this));
+
+ return *m_pointer;
+}
+
void CButtonMapping::OnLateDiscovery(unsigned int axisIndex)
{
m_buttonMapper->OnLateAxis(m_buttonMap, axisIndex);
diff --git a/xbmc/input/joysticks/generic/ButtonMapping.h b/xbmc/input/joysticks/generic/ButtonMapping.h
index 22f124271c..e0eebd00dc 100644
--- a/xbmc/input/joysticks/generic/ButtonMapping.h
+++ b/xbmc/input/joysticks/generic/ButtonMapping.h
@@ -23,8 +23,11 @@
#include "input/joysticks/interfaces/IDriverHandler.h"
#include "input/joysticks/DriverPrimitive.h"
#include "input/keyboard/interfaces/IKeyboardDriverHandler.h"
+#include "input/mouse/interfaces/IMouseDriverHandler.h"
+#include "input/mouse/MouseTypes.h"
#include <map>
+#include <memory>
#include <stdint.h>
class IKeymap;
@@ -248,6 +251,61 @@ namespace JOYSTICK
};
/*!
+ * \brief Detects when a mouse button should be mapped
+ */
+ class CMouseButtonDetector : public CPrimitiveDetector
+ {
+ public:
+ CMouseButtonDetector(CButtonMapping* buttonMapping, MOUSE::BUTTON_ID buttonIndex);
+
+ /*!
+ * \brief Button state has been updated
+ *
+ * \param bPressed The new state
+ *
+ * \return True if this press was handled, false if it should fall through
+ * to the next driver handler
+ */
+ bool OnMotion(bool bPressed);
+
+ private:
+ // Construction parameters
+ const MOUSE::BUTTON_ID m_buttonIndex;
+ };
+
+ /*!
+ * \brief Detects when a mouse button should be mapped
+ */
+ class CPointerDetector : public CPrimitiveDetector
+ {
+ public:
+ CPointerDetector(CButtonMapping* buttonMapping);
+
+ /*!
+ * \brief Pointer position has been updated
+ *
+ * \param x The new x coordinate
+ * \param y The new y coordinate
+ *
+ * \return Always true - pointer motion events are always absorbed while
+ * button mapping
+ */
+ bool OnMotion(int x, int y);
+
+ private:
+ // Utility function
+ static INPUT::INTERCARDINAL_DIRECTION GetPointerDirection(int x, int y);
+
+ static const unsigned int MIN_FRAME_COUNT = 10;
+
+ // State variables
+ bool m_bStarted = false;
+ int m_startX = 0;
+ int m_startY = 0;
+ unsigned int m_frameCount = 0;
+ };
+
+ /*!
* \ingroup joystick
* \brief Generic implementation of a class that provides button mapping by
* translating driver events to button mapping commands
@@ -260,6 +318,7 @@ namespace JOYSTICK
*/
class CButtonMapping : public IDriverHandler,
public KEYBOARD::IKeyboardDriverHandler,
+ public MOUSE::IMouseDriverHandler,
public IButtonMapCallback
{
public:
@@ -283,6 +342,11 @@ namespace JOYSTICK
bool OnKeyPress(const CKey& key) override;
void OnKeyRelease(const CKey& key) override { }
+ // implementation of IMouseDriverHandler
+ bool OnPosition(int x, int y) override;
+ bool OnButtonPress(MOUSE::BUTTON_ID button) override;
+ void OnButtonRelease(MOUSE::BUTTON_ID button) override;
+
// implementation of IButtonMapCallback
virtual void SaveButtonMap() override;
virtual void ResetIgnoredPrimitives() override;
@@ -310,6 +374,8 @@ namespace JOYSTICK
CHatDetector& GetHat(unsigned int hatIndex);
CAxisDetector& GetAxis(unsigned int axisIndex, float position, const AxisConfiguration& initialConfig = AxisConfiguration());
CKeyDetector& GetKey(XBMCKey keycode);
+ CMouseButtonDetector& GetMouseButton(MOUSE::BUTTON_ID buttonIndex);
+ CPointerDetector &GetPointer();
// Construction parameters
IButtonMapper* const m_buttonMapper;
@@ -320,6 +386,8 @@ namespace JOYSTICK
std::map<unsigned int, CHatDetector> m_hats;
std::map<unsigned int, CAxisDetector> m_axes;
std::map<XBMCKey, CKeyDetector> m_keys;
+ std::map<MOUSE::BUTTON_ID, CMouseButtonDetector> m_mouseButtons;
+ std::unique_ptr<CPointerDetector> m_pointer;
unsigned int m_lastAction;
uint64_t m_frameCount;
};
diff --git a/xbmc/input/joysticks/generic/FeatureHandling.cpp b/xbmc/input/joysticks/generic/FeatureHandling.cpp
index 7e186c9472..d35d585efb 100644
--- a/xbmc/input/joysticks/generic/FeatureHandling.cpp
+++ b/xbmc/input/joysticks/generic/FeatureHandling.cpp
@@ -300,7 +300,7 @@ CWheel::CWheel(const FeatureName& name, IInputHandler* handler, IButtonMap* butt
bool CWheel::OnAnalogMotion(const CDriverPrimitive& source, float magnitude)
{
- WHEEL_DIRECTION direction = WHEEL_DIRECTION::UNKNOWN;
+ WHEEL_DIRECTION direction = WHEEL_DIRECTION::NONE;
std::vector<WHEEL_DIRECTION> dirs = {
WHEEL_DIRECTION::RIGHT,
@@ -346,7 +346,7 @@ CThrottle::CThrottle(const FeatureName& name, IInputHandler* handler, IButtonMap
bool CThrottle::OnAnalogMotion(const CDriverPrimitive& source, float magnitude)
{
- THROTTLE_DIRECTION direction = THROTTLE_DIRECTION::UNKNOWN;
+ THROTTLE_DIRECTION direction = THROTTLE_DIRECTION::NONE;
std::vector<THROTTLE_DIRECTION> dirs = {
THROTTLE_DIRECTION::UP,
@@ -399,7 +399,7 @@ bool CAnalogStick::OnDigitalMotion(const CDriverPrimitive& source, bool bPressed
bool CAnalogStick::OnAnalogMotion(const CDriverPrimitive& source, float magnitude)
{
- ANALOG_STICK_DIRECTION direction = ANALOG_STICK_DIRECTION::UNKNOWN;
+ ANALOG_STICK_DIRECTION direction = ANALOG_STICK_DIRECTION::NONE;
std::vector<ANALOG_STICK_DIRECTION> dirs = {
ANALOG_STICK_DIRECTION::UP,
diff --git a/xbmc/input/joysticks/interfaces/IButtonMap.h b/xbmc/input/joysticks/interfaces/IButtonMap.h
index ed76f2835b..766d266654 100644
--- a/xbmc/input/joysticks/interfaces/IButtonMap.h
+++ b/xbmc/input/joysticks/interfaces/IButtonMap.h
@@ -83,7 +83,7 @@ namespace JOYSTICK
* Multiple primitives can be mapped to the same feature. For example,
* analog sticks use one primitive for each direction.
*
- * \param primitive The driver primitive (a button, hat direction or semi-axis)
+ * \param primitive The driver primitive
* \param feature The name of the resolved joystick feature, or
* invalid if false is returned
*
@@ -182,7 +182,7 @@ namespace JOYSTICK
*/
virtual bool GetRelativePointer(
const FeatureName& feature,
- ANALOG_STICK_DIRECTION direction,
+ RELATIVE_POINTER_DIRECTION direction,
CDriverPrimitive& primitive
) = 0;
@@ -197,7 +197,7 @@ namespace JOYSTICK
*/
virtual void AddRelativePointer(
const FeatureName& feature,
- ANALOG_STICK_DIRECTION direction,
+ RELATIVE_POINTER_DIRECTION direction,
const CDriverPrimitive& primitive
) = 0;
diff --git a/xbmc/input/joysticks/keymaps/KeymapHandler.cpp b/xbmc/input/joysticks/keymaps/KeymapHandler.cpp
index 8b5e455e44..c0fcee5e73 100644
--- a/xbmc/input/joysticks/keymaps/KeymapHandler.cpp
+++ b/xbmc/input/joysticks/keymaps/KeymapHandler.cpp
@@ -28,6 +28,7 @@
#include "input/joysticks/JoystickUtils.h"
#include "input/IKeymap.h"
#include "input/IKeymapEnvironment.h"
+#include "input/InputTranslator.h"
#include <algorithm>
#include <assert.h>
@@ -113,10 +114,12 @@ bool CKeymapHandler::OnButtonMotion(const FeatureName& feature, float magnitude,
bool CKeymapHandler::OnAnalogStickMotion(const FeatureName& feature, float x, float y, unsigned int motionTimeMs)
{
+ using namespace INPUT;
+
bool bHandled = false;
// Calculate the direction of the stick's position
- const ANALOG_STICK_DIRECTION analogStickDir = CJoystickTranslator::VectorToAnalogStickDirection(x, y);
+ const ANALOG_STICK_DIRECTION analogStickDir = CInputTranslator::VectorToCardinalDirection(x, y);
// Calculate the magnitude projected onto that direction
const float magnitude = std::max(std::fabs(x), std::fabs(y));
@@ -129,7 +132,7 @@ bool CKeymapHandler::OnAnalogStickMotion(const FeatureName& feature, float x, fl
}
// Now activate direction the analog stick is pointing
- if (analogStickDir != ANALOG_STICK_DIRECTION::UNKNOWN)
+ if (analogStickDir != ANALOG_STICK_DIRECTION::NONE)
bHandled = ActivateDirection(feature, magnitude, analogStickDir, motionTimeMs);
return bHandled;
@@ -153,7 +156,7 @@ bool CKeymapHandler::OnWheelMotion(const FeatureName& feature, float position, u
}
// Now activate direction in which the wheel is positioned
- if (direction != WHEEL_DIRECTION::UNKNOWN)
+ if (direction != WHEEL_DIRECTION::NONE)
bHandled = ActivateDirection(feature, magnitude, direction, motionTimeMs);
return bHandled;
@@ -177,7 +180,7 @@ bool CKeymapHandler::OnThrottleMotion(const FeatureName& feature, float position
}
// Now activate direction in which the throttle is positioned
- if (direction != THROTTLE_DIRECTION::UNKNOWN)
+ if (direction != THROTTLE_DIRECTION::NONE)
bHandled = ActivateDirection(feature, magnitude, direction, motionTimeMs);
return bHandled;
diff --git a/xbmc/input/mouse/CMakeLists.txt b/xbmc/input/mouse/CMakeLists.txt
index bebe854d7a..214adf01e8 100644
--- a/xbmc/input/mouse/CMakeLists.txt
+++ b/xbmc/input/mouse/CMakeLists.txt
@@ -1,9 +1,13 @@
-set(SOURCES MouseWindowingButtonMap.cpp)
+set(SOURCES MouseStat.cpp
+ MouseTranslator.cpp
+)
-set(HEADERS interfaces/IMouseButtonMap.h
- interfaces/IMouseDriverHandler.h
+set(HEADERS interfaces/IMouseDriverHandler.h
interfaces/IMouseInputHandler.h
interfaces/IMouseInputProvider.h
- MouseWindowingButtonMap.h)
+ MouseStat.h
+ MouseTranslator.h
+ MouseTypes.h
+)
core_add_library(input_mouse)
diff --git a/xbmc/input/MouseStat.cpp b/xbmc/input/mouse/MouseStat.cpp
index 606b233995..606b233995 100644
--- a/xbmc/input/MouseStat.cpp
+++ b/xbmc/input/mouse/MouseStat.cpp
diff --git a/xbmc/input/MouseStat.h b/xbmc/input/mouse/MouseStat.h
index 4eab9ae6fe..4eab9ae6fe 100644
--- a/xbmc/input/MouseStat.h
+++ b/xbmc/input/mouse/MouseStat.h
diff --git a/xbmc/input/MouseTranslator.cpp b/xbmc/input/mouse/MouseTranslator.cpp
index 26c486bb49..baf7771a89 100644
--- a/xbmc/input/MouseTranslator.cpp
+++ b/xbmc/input/mouse/MouseTranslator.cpp
@@ -19,14 +19,17 @@
*/
#include "MouseTranslator.h"
-#include "Key.h"
#include "MouseStat.h"
+#include "input/Key.h"
#include "utils/log.h"
#include "utils/StringUtils.h"
#include "utils/XBMCTinyXML.h"
#include <string>
+using namespace KODI;
+using namespace MOUSE;
+
namespace
{
@@ -87,3 +90,59 @@ uint32_t CMouseTranslator::TranslateCommand(const TiXmlElement *pButton)
return buttonId;
}
+
+bool CMouseTranslator::TranslateEventID(unsigned int eventId, BUTTON_ID &buttonId)
+{
+ switch (eventId)
+ {
+ case XBMC_BUTTON_LEFT:
+ {
+ buttonId = BUTTON_ID::LEFT;
+ return true;
+ }
+ case XBMC_BUTTON_MIDDLE:
+ {
+ buttonId = BUTTON_ID::MIDDLE;
+ return true;
+ }
+ case XBMC_BUTTON_RIGHT:
+ {
+ buttonId = BUTTON_ID::RIGHT;
+ return true;
+ }
+ case XBMC_BUTTON_WHEELUP:
+ {
+ buttonId = BUTTON_ID::WHEEL_UP;
+ return true;
+ }
+ case XBMC_BUTTON_WHEELDOWN:
+ {
+ buttonId = BUTTON_ID::WHEEL_DOWN;
+ return true;
+ }
+ case XBMC_BUTTON_X1:
+ {
+ buttonId = BUTTON_ID::BUTTON4;
+ return true;
+ }
+ case XBMC_BUTTON_X2:
+ {
+ buttonId = BUTTON_ID::BUTTON5;
+ return true;
+ }
+ case XBMC_BUTTON_X3:
+ {
+ buttonId = BUTTON_ID::HORIZ_WHEEL_LEFT;
+ return true;
+ }
+ case XBMC_BUTTON_X4:
+ {
+ buttonId = BUTTON_ID::HORIZ_WHEEL_RIGHT;
+ return true;
+ }
+ default:
+ break;
+ }
+
+ return false;
+}
diff --git a/xbmc/input/MouseTranslator.h b/xbmc/input/mouse/MouseTranslator.h
index 0381d57e4d..085af845f2 100644
--- a/xbmc/input/MouseTranslator.h
+++ b/xbmc/input/mouse/MouseTranslator.h
@@ -19,6 +19,8 @@
*/
#pragma once
+#include "MouseTypes.h"
+
#include <stdint.h>
class TiXmlElement;
@@ -26,5 +28,18 @@ class TiXmlElement;
class CMouseTranslator
{
public:
+ /*!
+ * \brief Translate a keymap element to a key ID
+ */
static uint32_t TranslateCommand(const TiXmlElement *pButton);
+
+ /*!
+ * \brief Translate a mouse event ID to a mouse button index
+ *
+ * \param eventId The event ID from MouseStat.h
+ * \param[out] buttonId The button ID from MouseTypes.h, or unmodified if unsuccessful
+ *
+ * \return True if successful, false otherwise
+ */
+ static bool TranslateEventID(unsigned int eventId, KODI::MOUSE::BUTTON_ID &buttonId);
};
diff --git a/xbmc/input/mouse/MouseTypes.h b/xbmc/input/mouse/MouseTypes.h
new file mode 100644
index 0000000000..da00b3eda8
--- /dev/null
+++ b/xbmc/input/mouse/MouseTypes.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 Team Kodi
+ * http://kodi.tv
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include "input/InputTypes.h"
+
+#include <string>
+
+namespace KODI
+{
+namespace MOUSE
+{
+ /*!
+ * \brief Buttons on a mouse
+ */
+ enum class BUTTON_ID
+ {
+ UNKNOWN,
+ LEFT,
+ RIGHT,
+ MIDDLE,
+ BUTTON4,
+ BUTTON5,
+ WHEEL_UP,
+ WHEEL_DOWN,
+ HORIZ_WHEEL_LEFT,
+ HORIZ_WHEEL_RIGHT,
+ };
+
+ /*!
+ * \brief Name of a mouse button
+ *
+ * Names are defined in the mouse's controller profile.
+ */
+ using ButtonName = std::string;
+
+ /*!
+ * \brief Directions of motion for a mouse pointer
+ */
+ using POINTER_DIRECTION = INPUT::CARDINAL_DIRECTION;
+
+ /*!
+ * \brief Name of the mouse pointer
+ *
+ * Names are defined in the mouse's controller profile.
+ */
+ using PointerName = std::string;
+}
+}
diff --git a/xbmc/input/mouse/MouseWindowingButtonMap.cpp b/xbmc/input/mouse/MouseWindowingButtonMap.cpp
deleted file mode 100644
index 328a2f59bb..0000000000
--- a/xbmc/input/mouse/MouseWindowingButtonMap.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2016-2017 Team Kodi
- * http://kodi.tv
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this Program; see the file COPYING. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "MouseWindowingButtonMap.h"
-#include "input/MouseStat.h"
-
-#include <algorithm>
-
-using namespace KODI;
-using namespace MOUSE;
-
-#define CONTROLLER_PROFILE "game.controller.mouse"
-
-std::vector<std::pair<unsigned int, std::string>> CMouseWindowingButtonMap::m_buttonMap = {
- { XBMC_BUTTON_LEFT, "left" },
- { XBMC_BUTTON_MIDDLE, "middle" },
- { XBMC_BUTTON_RIGHT, "right" },
- { XBMC_BUTTON_WHEELUP, "wheelup" },
- { XBMC_BUTTON_WHEELDOWN, "wheeldown" },
-};
-
-std::string CMouseWindowingButtonMap::m_pointerName = "pointer";
-
-std::string CMouseWindowingButtonMap::ControllerID(void) const
-{
- return CONTROLLER_PROFILE;
-}
-
-bool CMouseWindowingButtonMap::GetButton(unsigned int buttonIndex, std::string& feature)
-{
- auto it = std::find_if(m_buttonMap.begin(), m_buttonMap.end(),
- [buttonIndex](const std::pair<unsigned int, std::string>& entry)
- {
- return entry.first == buttonIndex;
- });
-
- if (it != m_buttonMap.end())
- {
- feature = it->second;
- return true;
- }
-
- return false;
-}
-
-bool CMouseWindowingButtonMap::GetRelativePointer(std::string& feature)
-{
- feature = m_pointerName;
- return true;
-}
-
-bool CMouseWindowingButtonMap::GetButtonIndex(const std::string& feature, unsigned int& buttonIndex)
-{
- auto it = std::find_if(m_buttonMap.begin(), m_buttonMap.end(),
- [&feature](const std::pair<unsigned int, std::string>& entry)
- {
- return entry.second == feature;
- });
-
- if (it != m_buttonMap.end())
- {
- buttonIndex = it->first;
- return true;
- }
-
- return false;
-}
diff --git a/xbmc/input/mouse/MouseWindowingButtonMap.h b/xbmc/input/mouse/MouseWindowingButtonMap.h
deleted file mode 100644
index 55262178ac..0000000000
--- a/xbmc/input/mouse/MouseWindowingButtonMap.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2016-2017 Team Kodi
- * http://kodi.tv
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this Program; see the file COPYING. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-#pragma once
-
-#include "input/mouse/interfaces/IMouseButtonMap.h"
-
-#include <string>
-#include <utility>
-#include <vector>
-
-namespace KODI
-{
-namespace MOUSE
-{
- /*!
- * \ingroup mouse
- * \brief Maps mouse windowing events to higher-level features understood by IMouseInputHandler implementations.
- */
- class CMouseWindowingButtonMap : public IMouseButtonMap
- {
- public:
- ~CMouseWindowingButtonMap(void) override = default;
-
- // implementation of IMouseButtonMap
- std::string ControllerID(void) const override;
- bool GetButton(unsigned int buttonIndex, std::string& feature) override;
- bool GetRelativePointer(std::string& feature) override;
- bool GetButtonIndex(const std::string& feature, unsigned int& buttonIndex) override;
-
- private:
- static std::vector<std::pair<unsigned int, std::string>> m_buttonMap;
- static std::string m_pointerName;
- };
-}
-}
diff --git a/xbmc/input/mouse/generic/MouseInputHandling.cpp b/xbmc/input/mouse/generic/MouseInputHandling.cpp
index a4e55e63c1..ce95bd663f 100644
--- a/xbmc/input/mouse/generic/MouseInputHandling.cpp
+++ b/xbmc/input/mouse/generic/MouseInputHandling.cpp
@@ -19,30 +19,92 @@
*/
#include "MouseInputHandling.h"
-#include "input/mouse/interfaces/IMouseButtonMap.h"
+#include "input/joysticks/interfaces/IButtonMap.h"
#include "input/mouse/interfaces/IMouseInputHandler.h"
+#include "input/InputTranslator.h"
using namespace KODI;
using namespace MOUSE;
-CMouseInputHandling::CMouseInputHandling(IMouseInputHandler* handler, IMouseButtonMap* buttonMap) :
+CMouseInputHandling::CMouseInputHandling(IMouseInputHandler* handler, JOYSTICK::IButtonMap* buttonMap) :
m_handler(handler),
- m_buttonMap(buttonMap),
- m_x(0),
- m_y(0)
+ 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;
- std::string featureName;
- if (m_buttonMap->GetRelativePointer(featureName))
- bHandled = m_handler->OnMotion(featureName, dx, dy);
+ // 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;
@@ -50,20 +112,244 @@ bool CMouseInputHandling::OnPosition(int x, int y)
return bHandled;
}
-bool CMouseInputHandling::OnButtonPress(unsigned int button)
+bool CMouseInputHandling::OnButtonPress(BUTTON_ID button)
{
bool bHandled = false;
- std::string featureName;
- if (m_buttonMap->GetButton(button, featureName))
- bHandled = m_handler->OnButtonPress(featureName);
+ JOYSTICK::CDriverPrimitive source(button);
+
+ ButtonName buttonName;
+ if (m_buttonMap->GetFeature(source, buttonName))
+ bHandled = m_handler->OnButtonPress(buttonName);
return bHandled;
}
-void CMouseInputHandling::OnButtonRelease(unsigned int button)
+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])
{
- std::string featureName;
- if (m_buttonMap->GetButton(button, featureName))
- m_handler->OnButtonRelease(featureName);
+ 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
index e41973534c..6d84261641 100644
--- a/xbmc/input/mouse/generic/MouseInputHandling.h
+++ b/xbmc/input/mouse/generic/MouseInputHandling.h
@@ -20,14 +20,18 @@
#pragma once
#include "input/mouse/interfaces/IMouseDriverHandler.h"
+#include "input/mouse/MouseTypes.h"
namespace KODI
{
+namespace JOYSTICK
+{
+ class IButtonMap;
+}
+
namespace MOUSE
{
class IMouseInputHandler;
- class IMouseButtonMap;
- class CRelativePointer;
/*!
* \ingroup mouse
@@ -36,23 +40,34 @@ namespace MOUSE
class CMouseInputHandling : public IMouseDriverHandler
{
public:
- CMouseInputHandling(IMouseInputHandler* handler, IMouseButtonMap* buttonMap);
+ CMouseInputHandling(IMouseInputHandler* handler, JOYSTICK::IButtonMap* buttonMap);
~CMouseInputHandling(void) override = default;
// implementation of IMouseDriverHandler
bool OnPosition(int x, int y) override;
- bool OnButtonPress(unsigned int button) override;
- void OnButtonRelease(unsigned int button) 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;
- IMouseButtonMap* const m_buttonMap;
+ JOYSTICK::IButtonMap* const m_buttonMap;
// Mouse parameters
- int m_x;
- int m_y;
+ bool m_bHasPosition = false;
+ int m_x = 0;
+ int m_y = 0;
};
}
}
diff --git a/xbmc/input/mouse/interfaces/IMouseButtonMap.h b/xbmc/input/mouse/interfaces/IMouseButtonMap.h
deleted file mode 100644
index b237f483ad..0000000000
--- a/xbmc/input/mouse/interfaces/IMouseButtonMap.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2016-2017 Team Kodi
- * http://kodi.tv
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this Program; see the file COPYING. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-#pragma once
-
-#include <string>
-
-namespace KODI
-{
-namespace MOUSE
-{
- /*!
- * \ingroup mouse
- * \brief Button map interface to translate between the mouse's driver data
- * and its higher-level features.
- */
- class IMouseButtonMap
- {
- public:
- virtual ~IMouseButtonMap(void) = default;
-
- /*!
- * \brief The ID of the controller profile 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 controller profile
- */
- virtual std::string ControllerID(void) const = 0;
-
- /*!
- * \brief Get the name of a button by its index
- *
- * \param buttonIndex The index of the button
- * \param[out] feature The name of the feature with the specified button index
- *
- * \return True if the button index is associated with a feature, false otherwise
- */
- virtual bool GetButton(unsigned int buttonIndex, std::string& feature) = 0;
-
- /*!
- * \brief Get the name of the mouse's relative pointer
- *
- * \param[out] feature The name of the relative pointer
- *
- * \return True if the mouse has a relative pointer, false otherwise
- */
- virtual bool GetRelativePointer(std::string& feature) = 0;
-
- /*!
- * \brief Get the button index for a button
- *
- * \param feature The name of the button
- * \param buttonIndex The resolved button index
- *
- * \return True if the feature resolved to a button index, or false otherwise
- */
- virtual bool GetButtonIndex(const std::string& feature, unsigned int& buttonIndex) = 0;
- };
-}
-}
diff --git a/xbmc/input/mouse/interfaces/IMouseDriverHandler.h b/xbmc/input/mouse/interfaces/IMouseDriverHandler.h
index 41f7096d57..2ca0c103cc 100644
--- a/xbmc/input/mouse/interfaces/IMouseDriverHandler.h
+++ b/xbmc/input/mouse/interfaces/IMouseDriverHandler.h
@@ -19,6 +19,8 @@
*/
#pragma once
+#include "input/mouse/MouseTypes.h"
+
namespace KODI
{
namespace MOUSE
@@ -38,6 +40,9 @@ namespace MOUSE
* \param x The new x coordinate of the pointer
* \param y The new y coordinate of the pointer
*
+ * The mouse uses a left-handed (graphics) cartesian coordinate system.
+ * Positive X is right, positive Y is down.
+ *
* \return True if the event was handled, false otherwise
*/
virtual bool OnPosition(int x, int y) = 0;
@@ -49,14 +54,14 @@ namespace MOUSE
*
* \return True if the event was handled, otherwise false
*/
- virtual bool OnButtonPress(unsigned int button) = 0;
+ virtual bool OnButtonPress(BUTTON_ID button) = 0;
/*!
* \brief A mouse button has been released
*
* \param button The index of the released button
*/
- virtual void OnButtonRelease(unsigned int button) = 0;
+ virtual void OnButtonRelease(BUTTON_ID button) = 0;
};
}
}
diff --git a/xbmc/input/mouse/interfaces/IMouseInputHandler.h b/xbmc/input/mouse/interfaces/IMouseInputHandler.h
index 1e9e093cc2..82c820f83a 100644
--- a/xbmc/input/mouse/interfaces/IMouseInputHandler.h
+++ b/xbmc/input/mouse/interfaces/IMouseInputHandler.h
@@ -19,6 +19,8 @@
*/
#pragma once
+#include "input/mouse/MouseTypes.h"
+
#include <string>
namespace KODI
@@ -48,9 +50,12 @@ namespace MOUSE
* \param dx The relative x coordinate of motion
* \param dy The relative y coordinate of motion
*
+ * The mouse uses a left-handed (graphics) cartesian coordinate system.
+ * Positive X is right, positive Y is down.
+ *
* \return True if the event was handled, otherwise false
*/
- virtual bool OnMotion(const std::string& relpointer, int dx, int dy) = 0;
+ virtual bool OnMotion(const PointerName& relpointer, int dx, int dy) = 0;
/*!
* \brief A mouse button has been pressed
@@ -59,14 +64,14 @@ namespace MOUSE
*
* \return True if the event was handled, otherwise false
*/
- virtual bool OnButtonPress(const std::string& button) = 0;
+ virtual bool OnButtonPress(const ButtonName& button) = 0;
/*!
* \brief A mouse button has been released
*
* \param button The name of the feature being released
*/
- virtual void OnButtonRelease(const std::string& button) = 0;
+ virtual void OnButtonRelease(const ButtonName& button) = 0;
};
}
}
diff --git a/xbmc/input/mouse/interfaces/IMouseInputProvider.h b/xbmc/input/mouse/interfaces/IMouseInputProvider.h
index b2069aa1e6..5a6fbad156 100644
--- a/xbmc/input/mouse/interfaces/IMouseInputProvider.h
+++ b/xbmc/input/mouse/interfaces/IMouseInputProvider.h
@@ -38,17 +38,15 @@ namespace MOUSE
* \brief Registers a handler to be called on mouse input
*
* \param handler The handler to receive mouse input provided by this class
- *
- * \return The controller ID that serves as a context for incoming mouse events
- *
- * \sa IMouseButtonMap
+ * \param bPromiscuous True to observe all events without affecting
+ * subsequent handlers
*/
- virtual std::string RegisterMouseHandler(IMouseInputHandler* handler) = 0;
+ virtual void RegisterMouseHandler(IMouseInputHandler* handler, bool bPromiscuous) = 0;
/*!
* \brief Unregisters handler from mouse input
*
- * \param[in] handler The handler that was receiving mouse input
+ * \param handler The handler that was receiving mouse input
*/
virtual void UnregisterMouseHandler(IMouseInputHandler* handler) = 0;
};
diff --git a/xbmc/peripherals/PeripheralTypes.h b/xbmc/peripherals/PeripheralTypes.h
index acde742d3e..984a08d9dd 100644
--- a/xbmc/peripherals/PeripheralTypes.h
+++ b/xbmc/peripherals/PeripheralTypes.h
@@ -63,6 +63,7 @@ namespace PERIPHERALS
FEATURE_RUMBLE,
FEATURE_POWER_OFF,
FEATURE_KEYBOARD,
+ FEATURE_MOUSE,
};
enum PeripheralType
@@ -78,6 +79,7 @@ namespace PERIPHERALS
PERIPHERAL_IMON,
PERIPHERAL_JOYSTICK,
PERIPHERAL_KEYBOARD,
+ PERIPHERAL_MOUSE,
};
class CPeripheral;
@@ -140,6 +142,8 @@ namespace PERIPHERALS
return "joystick";
case PERIPHERAL_KEYBOARD:
return "keyboard";
+ case PERIPHERAL_MOUSE:
+ return "mouse";
default:
return "unknown";
}
@@ -170,6 +174,8 @@ namespace PERIPHERALS
return PERIPHERAL_JOYSTICK;
else if (strTypeLowerCase == "keyboard")
return PERIPHERAL_KEYBOARD;
+ else if (strTypeLowerCase == "mouse")
+ return PERIPHERAL_MOUSE;
return PERIPHERAL_UNKNOWN;
};
@@ -252,6 +258,8 @@ namespace PERIPHERALS
return "poweroff";
case FEATURE_KEYBOARD:
return "keyboard";
+ case FEATURE_MOUSE:
+ return "mouse";
case FEATURE_UNKNOWN:
default:
return "unknown";
@@ -285,6 +293,8 @@ namespace PERIPHERALS
return FEATURE_POWER_OFF;
else if (strTypeLowerCase == "keyboard")
return FEATURE_KEYBOARD;
+ else if (strTypeLowerCase == "mouse")
+ return FEATURE_MOUSE;
return FEATURE_UNKNOWN;
};
diff --git a/xbmc/peripherals/Peripherals.cpp b/xbmc/peripherals/Peripherals.cpp
index 68b0f74cc1..ffcac0d839 100644
--- a/xbmc/peripherals/Peripherals.cpp
+++ b/xbmc/peripherals/Peripherals.cpp
@@ -40,6 +40,7 @@
#include "devices/PeripheralImon.h"
#include "devices/PeripheralJoystick.h"
#include "devices/PeripheralKeyboard.h"
+#include "devices/PeripheralMouse.h"
#include "devices/PeripheralNIC.h"
#include "devices/PeripheralNyxboard.h"
#include "devices/PeripheralTuner.h"
@@ -358,6 +359,10 @@ void CPeripherals::CreatePeripheral(CPeripheralBus &bus, const PeripheralScanRes
peripheral = PeripheralPtr(new CPeripheralKeyboard(*this, mappedResult, &bus));
break;
+ case PERIPHERAL_MOUSE:
+ peripheral = PeripheralPtr(new CPeripheralMouse(*this, mappedResult, &bus));
+ break;
+
default:
break;
}
@@ -870,6 +875,7 @@ void CPeripherals::RegisterJoystickButtonMapper(IButtonMapper* mapper)
PeripheralVector peripherals;
GetPeripheralsWithFeature(peripherals, FEATURE_JOYSTICK);
GetPeripheralsWithFeature(peripherals, FEATURE_KEYBOARD);
+ GetPeripheralsWithFeature(peripherals, FEATURE_MOUSE);
for (auto& peripheral : peripherals)
peripheral->RegisterJoystickButtonMapper(mapper);
@@ -882,6 +888,7 @@ void CPeripherals::UnregisterJoystickButtonMapper(IButtonMapper* mapper)
PeripheralVector peripherals;
GetPeripheralsWithFeature(peripherals, FEATURE_JOYSTICK);
GetPeripheralsWithFeature(peripherals, FEATURE_KEYBOARD);
+ GetPeripheralsWithFeature(peripherals, FEATURE_MOUSE);
for (auto& peripheral : peripherals)
peripheral->UnregisterJoystickButtonMapper(mapper);
diff --git a/xbmc/peripherals/addons/AddonButtonMap.cpp b/xbmc/peripherals/addons/AddonButtonMap.cpp
index f6cd1a8d36..5e2d805c99 100644
--- a/xbmc/peripherals/addons/AddonButtonMap.cpp
+++ b/xbmc/peripherals/addons/AddonButtonMap.cpp
@@ -176,7 +176,7 @@ bool CAddonButtonMap::GetAnalogStick(const FeatureName& feature,
if (addonFeature.Type() == JOYSTICK_FEATURE_TYPE_ANALOG_STICK)
{
- primitive = CPeripheralAddonTranslator::TranslatePrimitive(addonFeature.Primitive(GetPrimitiveIndex(direction)));
+ primitive = CPeripheralAddonTranslator::TranslatePrimitive(addonFeature.Primitive(GetAnalogStickIndex(direction)));
retVal = primitive.IsValid();
}
}
@@ -190,7 +190,7 @@ void CAddonButtonMap::AddAnalogStick(const FeatureName& feature,
{
using namespace JOYSTICK;
- JOYSTICK_FEATURE_PRIMITIVE primitiveIndex = GetPrimitiveIndex(direction);
+ JOYSTICK_FEATURE_PRIMITIVE primitiveIndex = GetAnalogStickIndex(direction);
kodi::addon::DriverPrimitive addonPrimitive = CPeripheralAddonTranslator::TranslatePrimitive(primitive);
kodi::addon::JoystickFeature analogStick(feature, JOYSTICK_FEATURE_TYPE_ANALOG_STICK);
@@ -216,7 +216,7 @@ void CAddonButtonMap::AddAnalogStick(const FeatureName& feature,
}
bool CAddonButtonMap::GetRelativePointer(const FeatureName& feature,
- JOYSTICK::ANALOG_STICK_DIRECTION direction,
+ JOYSTICK::RELATIVE_POINTER_DIRECTION direction,
JOYSTICK::CDriverPrimitive& primitive)
{
bool retVal(false);
@@ -230,7 +230,7 @@ bool CAddonButtonMap::GetRelativePointer(const FeatureName& feature,
if (addonFeature.Type() == JOYSTICK_FEATURE_TYPE_RELPOINTER)
{
- primitive = CPeripheralAddonTranslator::TranslatePrimitive(addonFeature.Primitive(GetPrimitiveIndex(direction)));
+ primitive = CPeripheralAddonTranslator::TranslatePrimitive(addonFeature.Primitive(GetRelativePointerIndex(direction)));
retVal = primitive.IsValid();
}
}
@@ -239,12 +239,12 @@ bool CAddonButtonMap::GetRelativePointer(const FeatureName& feature,
}
void CAddonButtonMap::AddRelativePointer(const FeatureName& feature,
- JOYSTICK::ANALOG_STICK_DIRECTION direction,
+ JOYSTICK::RELATIVE_POINTER_DIRECTION direction,
const JOYSTICK::CDriverPrimitive& primitive)
{
using namespace JOYSTICK;
- JOYSTICK_FEATURE_PRIMITIVE primitiveIndex = GetPrimitiveIndex(direction);
+ JOYSTICK_FEATURE_PRIMITIVE primitiveIndex = GetRelativePointerIndex(direction);
kodi::addon::DriverPrimitive addonPrimitive = CPeripheralAddonTranslator::TranslatePrimitive(primitive);
kodi::addon::JoystickFeature relPointer(feature, JOYSTICK_FEATURE_TYPE_RELPOINTER);
@@ -515,7 +515,6 @@ CAddonButtonMap::DriverMap CAddonButtonMap::CreateLookupTable(const FeatureMap&
}
case JOYSTICK_FEATURE_TYPE_ANALOG_STICK:
- case JOYSTICK_FEATURE_TYPE_RELPOINTER:
{
std::vector<JOYSTICK_FEATURE_PRIMITIVE> primitives = {
JOYSTICK_ANALOG_STICK_UP,
@@ -573,6 +572,20 @@ CAddonButtonMap::DriverMap CAddonButtonMap::CreateLookupTable(const FeatureMap&
break;
}
+ case JOYSTICK_FEATURE_TYPE_RELPOINTER:
+ {
+ std::vector<JOYSTICK_FEATURE_PRIMITIVE> primitives = {
+ JOYSTICK_RELPOINTER_UP,
+ JOYSTICK_RELPOINTER_DOWN,
+ JOYSTICK_RELPOINTER_RIGHT,
+ JOYSTICK_RELPOINTER_LEFT,
+ };
+
+ for (auto primitive : primitives)
+ driverMap[CPeripheralAddonTranslator::TranslatePrimitive(feature.Primitive(primitive))] = it->first;
+ break;
+ }
+
default:
break;
}
@@ -581,7 +594,7 @@ CAddonButtonMap::DriverMap CAddonButtonMap::CreateLookupTable(const FeatureMap&
return driverMap;
}
-JOYSTICK_FEATURE_PRIMITIVE CAddonButtonMap::GetPrimitiveIndex(JOYSTICK::ANALOG_STICK_DIRECTION dir)
+JOYSTICK_FEATURE_PRIMITIVE CAddonButtonMap::GetAnalogStickIndex(JOYSTICK::ANALOG_STICK_DIRECTION dir)
{
using namespace JOYSTICK;
@@ -597,6 +610,22 @@ JOYSTICK_FEATURE_PRIMITIVE CAddonButtonMap::GetPrimitiveIndex(JOYSTICK::ANALOG_S
return static_cast<JOYSTICK_FEATURE_PRIMITIVE>(0);
}
+JOYSTICK_FEATURE_PRIMITIVE CAddonButtonMap::GetRelativePointerIndex(JOYSTICK::RELATIVE_POINTER_DIRECTION dir)
+{
+ using namespace JOYSTICK;
+
+ switch (dir)
+ {
+ case RELATIVE_POINTER_DIRECTION::UP: return JOYSTICK_RELPOINTER_UP;
+ case RELATIVE_POINTER_DIRECTION::DOWN: return JOYSTICK_RELPOINTER_DOWN;
+ case RELATIVE_POINTER_DIRECTION::RIGHT: return JOYSTICK_RELPOINTER_RIGHT;
+ case RELATIVE_POINTER_DIRECTION::LEFT: return JOYSTICK_RELPOINTER_LEFT;
+ default: break;
+ }
+
+ return static_cast<JOYSTICK_FEATURE_PRIMITIVE>(0);
+}
+
JOYSTICK_FEATURE_PRIMITIVE CAddonButtonMap::GetPrimitiveIndex(JOYSTICK::WHEEL_DIRECTION dir)
{
using namespace JOYSTICK;
diff --git a/xbmc/peripherals/addons/AddonButtonMap.h b/xbmc/peripherals/addons/AddonButtonMap.h
index 628cb0d194..2a920cd527 100644
--- a/xbmc/peripherals/addons/AddonButtonMap.h
+++ b/xbmc/peripherals/addons/AddonButtonMap.h
@@ -82,13 +82,13 @@ namespace PERIPHERALS
bool GetRelativePointer(
const KODI::JOYSTICK::FeatureName& feature,
- KODI::JOYSTICK::ANALOG_STICK_DIRECTION direction,
+ KODI::JOYSTICK::RELATIVE_POINTER_DIRECTION direction,
KODI::JOYSTICK::CDriverPrimitive& primitive
) override;
void AddRelativePointer(
const KODI::JOYSTICK::FeatureName& feature,
- KODI::JOYSTICK::ANALOG_STICK_DIRECTION direction,
+ KODI::JOYSTICK::RELATIVE_POINTER_DIRECTION direction,
const KODI::JOYSTICK::CDriverPrimitive& primitive
) override;
@@ -157,7 +157,8 @@ namespace PERIPHERALS
// Utility functions
static DriverMap CreateLookupTable(const FeatureMap& features);
- static JOYSTICK_FEATURE_PRIMITIVE GetPrimitiveIndex(KODI::JOYSTICK::ANALOG_STICK_DIRECTION dir);
+ static JOYSTICK_FEATURE_PRIMITIVE GetAnalogStickIndex(KODI::JOYSTICK::ANALOG_STICK_DIRECTION dir);
+ static JOYSTICK_FEATURE_PRIMITIVE GetRelativePointerIndex(KODI::JOYSTICK::RELATIVE_POINTER_DIRECTION dir);
static JOYSTICK_FEATURE_PRIMITIVE GetPrimitiveIndex(KODI::JOYSTICK::WHEEL_DIRECTION dir);
static JOYSTICK_FEATURE_PRIMITIVE GetPrimitiveIndex(KODI::JOYSTICK::THROTTLE_DIRECTION dir);
diff --git a/xbmc/peripherals/addons/AddonButtonMapping.cpp b/xbmc/peripherals/addons/AddonButtonMapping.cpp
index 03e47efe7e..6ba9fa2a3a 100644
--- a/xbmc/peripherals/addons/AddonButtonMapping.cpp
+++ b/xbmc/peripherals/addons/AddonButtonMapping.cpp
@@ -104,6 +104,28 @@ void CAddonButtonMapping::OnKeyRelease(const CKey& key)
m_buttonMapping->OnKeyRelease(key);
}
+bool CAddonButtonMapping::OnPosition(int x, int y)
+{
+ if (m_buttonMapping)
+ return m_buttonMapping->OnPosition(x, y);
+
+ return false;
+}
+
+bool CAddonButtonMapping::OnButtonPress(MOUSE::BUTTON_ID button)
+{
+ if (m_buttonMapping)
+ return m_buttonMapping->OnButtonPress(button);
+
+ return false;
+}
+
+void CAddonButtonMapping::OnButtonRelease(MOUSE::BUTTON_ID button)
+{
+ if (m_buttonMapping)
+ m_buttonMapping->OnButtonRelease(button);
+}
+
void CAddonButtonMapping::SaveButtonMap()
{
if (m_buttonMapping)
diff --git a/xbmc/peripherals/addons/AddonButtonMapping.h b/xbmc/peripherals/addons/AddonButtonMapping.h
index e19a174b19..d5c9446e4c 100644
--- a/xbmc/peripherals/addons/AddonButtonMapping.h
+++ b/xbmc/peripherals/addons/AddonButtonMapping.h
@@ -22,6 +22,7 @@
#include "input/joysticks/interfaces/IButtonMapCallback.h"
#include "input/joysticks/interfaces/IDriverHandler.h"
#include "input/keyboard/interfaces/IKeyboardDriverHandler.h"
+#include "input/mouse/interfaces/IMouseDriverHandler.h"
#include <memory>
@@ -42,6 +43,7 @@ namespace PERIPHERALS
class CAddonButtonMapping : public KODI::JOYSTICK::IDriverHandler,
public KODI::KEYBOARD::IKeyboardDriverHandler,
+ public KODI::MOUSE::IMouseDriverHandler,
public KODI::JOYSTICK::IButtonMapCallback
{
public:
@@ -59,6 +61,11 @@ namespace PERIPHERALS
bool OnKeyPress(const CKey& key) override;
void OnKeyRelease(const CKey& key) override;
+ // implementation of IMouseDriverHandler
+ bool OnPosition(int x, int y) override;
+ bool OnButtonPress(KODI::MOUSE::BUTTON_ID button) override;
+ void OnButtonRelease(KODI::MOUSE::BUTTON_ID button) override;
+
// implementation of IButtonMapCallback
void SaveButtonMap() override;
void ResetIgnoredPrimitives() override;
diff --git a/xbmc/peripherals/addons/AddonInputHandling.cpp b/xbmc/peripherals/addons/AddonInputHandling.cpp
index add2ebdaa7..378e6f8f8f 100644
--- a/xbmc/peripherals/addons/AddonInputHandling.cpp
+++ b/xbmc/peripherals/addons/AddonInputHandling.cpp
@@ -25,6 +25,8 @@
#include "input/joysticks/interfaces/IDriverReceiver.h"
#include "input/keyboard/generic/KeyboardInputHandling.h"
#include "input/keyboard/interfaces/IKeyboardInputHandler.h"
+#include "input/mouse/generic/MouseInputHandling.h"
+#include "input/mouse/interfaces/IMouseInputHandler.h"
#include "peripherals/addons/AddonButtonMap.h"
#include "peripherals/devices/PeripheralJoystick.h"
#include "peripherals/Peripherals.h"
@@ -86,6 +88,28 @@ CAddonInputHandling::CAddonInputHandling(CPeripherals& manager, CPeripheral* per
}
}
+CAddonInputHandling::CAddonInputHandling(CPeripherals& manager, CPeripheral* peripheral, MOUSE::IMouseInputHandler* handler)
+{
+ PeripheralAddonPtr addon = manager.GetAddonWithButtonMap(peripheral);
+
+ if (!addon)
+ {
+ CLog::Log(LOGDEBUG, "Failed to locate add-on for \"%s\"", peripheral->DeviceName().c_str());
+ }
+ else
+ {
+ m_buttonMap.reset(new CAddonButtonMap(peripheral, addon, handler->ControllerID()));
+ if (m_buttonMap->Load())
+ {
+ m_mouseHandler.reset(new MOUSE::CMouseInputHandling(handler, m_buttonMap.get()));
+ }
+ else
+ {
+ m_buttonMap.reset();
+ }
+ }
+}
+
CAddonInputHandling::~CAddonInputHandling(void)
{
m_driverHandler.reset();
@@ -138,6 +162,29 @@ void CAddonInputHandling::OnKeyRelease(const CKey& key)
m_keyboardHandler->OnKeyRelease(key);
}
+
+bool CAddonInputHandling::OnPosition(int x, int y)
+{
+ if (m_mouseHandler)
+ return m_mouseHandler->OnPosition(x, y);
+
+ return false;
+}
+
+bool CAddonInputHandling::OnButtonPress(MOUSE::BUTTON_ID button)
+{
+ if (m_mouseHandler)
+ return m_mouseHandler->OnButtonPress(button);
+
+ return false;
+}
+
+void CAddonInputHandling::OnButtonRelease(MOUSE::BUTTON_ID button)
+{
+ if (m_mouseHandler)
+ m_mouseHandler->OnButtonRelease(button);
+}
+
bool CAddonInputHandling::SetRumbleState(const JOYSTICK::FeatureName& feature, float magnitude)
{
if (m_inputReceiver)
diff --git a/xbmc/peripherals/addons/AddonInputHandling.h b/xbmc/peripherals/addons/AddonInputHandling.h
index 3a3a87390c..2ab93fe582 100644
--- a/xbmc/peripherals/addons/AddonInputHandling.h
+++ b/xbmc/peripherals/addons/AddonInputHandling.h
@@ -22,6 +22,7 @@
#include "input/joysticks/interfaces/IDriverHandler.h"
#include "input/joysticks/interfaces/IInputReceiver.h"
#include "input/keyboard/interfaces/IKeyboardDriverHandler.h"
+#include "input/mouse/interfaces/IMouseDriverHandler.h"
#include <memory>
@@ -38,6 +39,11 @@ namespace KEYBOARD
{
class IKeyboardInputHandler;
}
+
+namespace MOUSE
+{
+ class IMouseInputHandler;
+}
}
namespace PERIPHERALS
@@ -47,7 +53,8 @@ namespace PERIPHERALS
class CAddonInputHandling : public KODI::JOYSTICK::IDriverHandler,
public KODI::JOYSTICK::IInputReceiver,
- public KODI::KEYBOARD::IKeyboardDriverHandler
+ public KODI::KEYBOARD::IKeyboardDriverHandler,
+ public KODI::MOUSE::IMouseDriverHandler
{
public:
CAddonInputHandling(CPeripherals& manager,
@@ -59,6 +66,10 @@ namespace PERIPHERALS
CPeripheral* peripheral,
KODI::KEYBOARD::IKeyboardInputHandler* handler);
+ CAddonInputHandling(CPeripherals& manager,
+ CPeripheral* peripheral,
+ KODI::MOUSE::IMouseInputHandler* handler);
+
~CAddonInputHandling(void) override;
// implementation of IDriverHandler
@@ -71,6 +82,11 @@ namespace PERIPHERALS
bool OnKeyPress(const CKey& key) override;
void OnKeyRelease(const CKey& key) override;
+ // implementation of IMouseDriverHandler
+ bool OnPosition(int x, int y) override;
+ bool OnButtonPress(KODI::MOUSE::BUTTON_ID button) override;
+ void OnButtonRelease(KODI::MOUSE::BUTTON_ID button) override;
+
// implementation of IInputReceiver
bool SetRumbleState(const KODI::JOYSTICK::FeatureName& feature, float magnitude) override;
@@ -78,6 +94,7 @@ namespace PERIPHERALS
std::unique_ptr<KODI::JOYSTICK::IDriverHandler> m_driverHandler;
std::unique_ptr<KODI::JOYSTICK::IInputReceiver> m_inputReceiver;
std::unique_ptr<KODI::KEYBOARD::IKeyboardDriverHandler> m_keyboardHandler;
+ std::unique_ptr<KODI::MOUSE::IMouseDriverHandler> m_mouseHandler;
std::unique_ptr<KODI::JOYSTICK::IButtonMap> m_buttonMap;
};
}
diff --git a/xbmc/peripherals/addons/PeripheralAddon.cpp b/xbmc/peripherals/addons/PeripheralAddon.cpp
index df90468cb1..f9be30d623 100644
--- a/xbmc/peripherals/addons/PeripheralAddon.cpp
+++ b/xbmc/peripherals/addons/PeripheralAddon.cpp
@@ -52,6 +52,9 @@ using namespace XFILE;
#define KEYBOARD_BUTTON_MAP_NAME "Keyboard"
#define KEYBOARD_PROVIDER "application"
+#define MOUSE_BUTTON_MAP_NAME "Mouse"
+#define MOUSE_PROVIDER "application"
+
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) do { delete (p); (p) = NULL; } while (0)
#endif
@@ -828,10 +831,11 @@ void CPeripheralAddon::GetJoystickInfo(const CPeripheral* device, kodi::addon::J
joystickInfo.SetMotorCount(joystick->MotorCount());
joystickInfo.SetSupportsPowerOff(joystick->SupportsPowerOff());
}
- else if (device->Type() == PERIPHERAL_KEYBOARD)
+ else if (device->Type() == PERIPHERAL_KEYBOARD ||
+ device->Type() == PERIPHERAL_MOUSE)
{
- joystickInfo.SetName(GetDeviceName(PERIPHERAL_KEYBOARD)); // Override name with non-localized version
- joystickInfo.SetProvider(GetProvider(PERIPHERAL_KEYBOARD));
+ joystickInfo.SetName(GetDeviceName(device->Type())); // Override name with non-localized version
+ joystickInfo.SetProvider(GetProvider(device->Type()));
}
}
@@ -863,6 +867,8 @@ std::string CPeripheralAddon::GetDeviceName(PeripheralType type)
{
case PERIPHERAL_KEYBOARD:
return KEYBOARD_BUTTON_MAP_NAME;
+ case PERIPHERAL_MOUSE:
+ return MOUSE_BUTTON_MAP_NAME;
default:
break;
}
@@ -876,6 +882,8 @@ std::string CPeripheralAddon::GetProvider(PeripheralType type)
{
case PERIPHERAL_KEYBOARD:
return KEYBOARD_PROVIDER;
+ case PERIPHERAL_MOUSE:
+ return MOUSE_PROVIDER;
default:
break;
}
diff --git a/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp b/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp
index 5c0b659322..5e7ceedcee 100644
--- a/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp
+++ b/xbmc/peripherals/addons/PeripheralAddonTranslator.cpp
@@ -116,6 +116,16 @@ CDriverPrimitive CPeripheralAddonTranslator::TranslatePrimitive(const kodi::addo
retVal = CDriverPrimitive(keycode);
break;
}
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_MOUSE_BUTTON:
+ {
+ retVal = CDriverPrimitive(TranslateMouseButton(primitive.MouseIndex()));
+ break;
+ }
+ case JOYSTICK_DRIVER_PRIMITIVE_TYPE_RELPOINTER_DIRECTION:
+ {
+ retVal = CDriverPrimitive(TranslateRelPointerDirection(primitive.RelPointerDirection()));
+ break;
+ }
default:
break;
}
@@ -155,6 +165,16 @@ kodi::addon::DriverPrimitive CPeripheralAddonTranslator::TranslatePrimitive(cons
retVal = kodi::addon::DriverPrimitive(keysym);
break;
}
+ case PRIMITIVE_TYPE::MOUSE_BUTTON:
+ {
+ retVal = kodi::addon::DriverPrimitive::CreateMouseButton(TranslateMouseButton(primitive.MouseButton()));
+ break;
+ }
+ case PRIMITIVE_TYPE::RELATIVE_POINTER:
+ {
+ retVal = kodi::addon::DriverPrimitive(TranslateRelPointerDirection(primitive.PointerDirection()));
+ break;
+ }
default:
break;
}
@@ -195,7 +215,7 @@ HAT_DIRECTION CPeripheralAddonTranslator::TranslateHatDirection(JOYSTICK_DRIVER_
default:
break;
}
- return HAT_DIRECTION::UNKNOWN;
+ return HAT_DIRECTION::NONE;
}
JOYSTICK_DRIVER_HAT_DIRECTION CPeripheralAddonTranslator::TranslateHatDirection(HAT_DIRECTION dir)
@@ -214,7 +234,7 @@ JOYSTICK_DRIVER_HAT_DIRECTION CPeripheralAddonTranslator::TranslateHatDirection(
HAT_STATE CPeripheralAddonTranslator::TranslateHatState(JOYSTICK_STATE_HAT state)
{
- HAT_STATE translatedState = HAT_STATE::UNPRESSED;
+ HAT_STATE translatedState = HAT_STATE::NONE;
if (state & JOYSTICK_STATE_HAT_UP) translatedState |= HAT_STATE::UP;
if (state & JOYSTICK_STATE_HAT_DOWN) translatedState |= HAT_STATE::DOWN;
@@ -248,6 +268,75 @@ JOYSTICK_DRIVER_SEMIAXIS_DIRECTION CPeripheralAddonTranslator::TranslateSemiAxis
return JOYSTICK_DRIVER_SEMIAXIS_UNKNOWN;
}
+MOUSE::BUTTON_ID CPeripheralAddonTranslator::TranslateMouseButton(JOYSTICK_DRIVER_MOUSE_INDEX button)
+{
+ switch (button)
+ {
+ case JOYSTICK_DRIVER_MOUSE_INDEX_LEFT: return MOUSE::BUTTON_ID::LEFT;
+ case JOYSTICK_DRIVER_MOUSE_INDEX_RIGHT: return MOUSE::BUTTON_ID::RIGHT;
+ case JOYSTICK_DRIVER_MOUSE_INDEX_MIDDLE: return MOUSE::BUTTON_ID::MIDDLE;
+ case JOYSTICK_DRIVER_MOUSE_INDEX_BUTTON4: return MOUSE::BUTTON_ID::BUTTON4;
+ case JOYSTICK_DRIVER_MOUSE_INDEX_BUTTON5: return MOUSE::BUTTON_ID::BUTTON5;
+ case JOYSTICK_DRIVER_MOUSE_INDEX_WHEEL_UP: return MOUSE::BUTTON_ID::WHEEL_UP;
+ case JOYSTICK_DRIVER_MOUSE_INDEX_WHEEL_DOWN: return MOUSE::BUTTON_ID::WHEEL_DOWN;
+ case JOYSTICK_DRIVER_MOUSE_INDEX_HORIZ_WHEEL_LEFT: return MOUSE::BUTTON_ID::HORIZ_WHEEL_LEFT;
+ case JOYSTICK_DRIVER_MOUSE_INDEX_HORIZ_WHEEL_RIGHT: return MOUSE::BUTTON_ID::HORIZ_WHEEL_RIGHT;
+ default:
+ break;
+ }
+
+ return MOUSE::BUTTON_ID::UNKNOWN;
+}
+
+JOYSTICK_DRIVER_MOUSE_INDEX CPeripheralAddonTranslator::TranslateMouseButton(MOUSE::BUTTON_ID button)
+{
+ switch (button)
+ {
+ case MOUSE::BUTTON_ID::LEFT: return JOYSTICK_DRIVER_MOUSE_INDEX_LEFT;
+ case MOUSE::BUTTON_ID::RIGHT: return JOYSTICK_DRIVER_MOUSE_INDEX_RIGHT;
+ case MOUSE::BUTTON_ID::MIDDLE: return JOYSTICK_DRIVER_MOUSE_INDEX_MIDDLE;
+ case MOUSE::BUTTON_ID::BUTTON4: return JOYSTICK_DRIVER_MOUSE_INDEX_BUTTON4;
+ case MOUSE::BUTTON_ID::BUTTON5: return JOYSTICK_DRIVER_MOUSE_INDEX_BUTTON5;
+ case MOUSE::BUTTON_ID::WHEEL_UP: return JOYSTICK_DRIVER_MOUSE_INDEX_WHEEL_UP;
+ case MOUSE::BUTTON_ID::WHEEL_DOWN: return JOYSTICK_DRIVER_MOUSE_INDEX_WHEEL_DOWN;
+ case MOUSE::BUTTON_ID::HORIZ_WHEEL_LEFT: return JOYSTICK_DRIVER_MOUSE_INDEX_HORIZ_WHEEL_LEFT;
+ case MOUSE::BUTTON_ID::HORIZ_WHEEL_RIGHT: return JOYSTICK_DRIVER_MOUSE_INDEX_HORIZ_WHEEL_RIGHT;
+ default:
+ break;
+ }
+
+ return JOYSTICK_DRIVER_MOUSE_INDEX_UNKNOWN;
+}
+
+RELATIVE_POINTER_DIRECTION CPeripheralAddonTranslator::TranslateRelPointerDirection(JOYSTICK_DRIVER_RELPOINTER_DIRECTION dir)
+{
+ switch (dir)
+ {
+ case JOYSTICK_DRIVER_RELPOINTER_LEFT: return RELATIVE_POINTER_DIRECTION::LEFT;
+ case JOYSTICK_DRIVER_RELPOINTER_RIGHT: return RELATIVE_POINTER_DIRECTION::RIGHT;
+ case JOYSTICK_DRIVER_RELPOINTER_UP: return RELATIVE_POINTER_DIRECTION::UP;
+ case JOYSTICK_DRIVER_RELPOINTER_DOWN: return RELATIVE_POINTER_DIRECTION::DOWN;
+ default:
+ break;
+ }
+
+ return RELATIVE_POINTER_DIRECTION::NONE;
+}
+
+JOYSTICK_DRIVER_RELPOINTER_DIRECTION CPeripheralAddonTranslator::TranslateRelPointerDirection(RELATIVE_POINTER_DIRECTION dir)
+{
+ switch (dir)
+ {
+ case RELATIVE_POINTER_DIRECTION::UP: return JOYSTICK_DRIVER_RELPOINTER_UP;
+ case RELATIVE_POINTER_DIRECTION::DOWN: return JOYSTICK_DRIVER_RELPOINTER_DOWN;
+ case RELATIVE_POINTER_DIRECTION::RIGHT: return JOYSTICK_DRIVER_RELPOINTER_RIGHT;
+ case RELATIVE_POINTER_DIRECTION::LEFT: return JOYSTICK_DRIVER_RELPOINTER_LEFT;
+ default:
+ break;
+ }
+ return JOYSTICK_DRIVER_RELPOINTER_UNKNOWN;
+}
+
JOYSTICK::FEATURE_TYPE CPeripheralAddonTranslator::TranslateFeatureType(JOYSTICK_FEATURE_TYPE type)
{
switch (type)
diff --git a/xbmc/peripherals/addons/PeripheralAddonTranslator.h b/xbmc/peripherals/addons/PeripheralAddonTranslator.h
index 35c40791e1..683b9e9177 100644
--- a/xbmc/peripherals/addons/PeripheralAddonTranslator.h
+++ b/xbmc/peripherals/addons/PeripheralAddonTranslator.h
@@ -23,6 +23,7 @@
#include "addons/kodi-addon-dev-kit/include/kodi/addon-instance/PeripheralUtils.h"
#include "input/joysticks/DriverPrimitive.h"
#include "input/joysticks/JoystickTypes.h"
+#include "input/mouse/MouseTypes.h"
#include "peripherals/PeripheralTypes.h"
#include <vector>
@@ -51,6 +52,12 @@ namespace PERIPHERALS
static KODI::JOYSTICK::SEMIAXIS_DIRECTION TranslateSemiAxisDirection(JOYSTICK_DRIVER_SEMIAXIS_DIRECTION dir);
static JOYSTICK_DRIVER_SEMIAXIS_DIRECTION TranslateSemiAxisDirection(KODI::JOYSTICK::SEMIAXIS_DIRECTION dir);
+ static KODI::MOUSE::BUTTON_ID TranslateMouseButton(JOYSTICK_DRIVER_MOUSE_INDEX button);
+ static JOYSTICK_DRIVER_MOUSE_INDEX TranslateMouseButton(KODI::MOUSE::BUTTON_ID button);
+
+ static KODI::JOYSTICK::RELATIVE_POINTER_DIRECTION TranslateRelPointerDirection(JOYSTICK_DRIVER_RELPOINTER_DIRECTION dir);
+ static JOYSTICK_DRIVER_RELPOINTER_DIRECTION TranslateRelPointerDirection(KODI::JOYSTICK::RELATIVE_POINTER_DIRECTION dir);
+
static KODI::JOYSTICK::FEATURE_TYPE TranslateFeatureType(JOYSTICK_FEATURE_TYPE type);
static JOYSTICK_FEATURE_TYPE TranslateFeatureType(KODI::JOYSTICK::FEATURE_TYPE type);
diff --git a/xbmc/peripherals/bus/virtual/PeripheralBusApplication.cpp b/xbmc/peripherals/bus/virtual/PeripheralBusApplication.cpp
index 51e1df8835..4603dd90a8 100644
--- a/xbmc/peripherals/bus/virtual/PeripheralBusApplication.cpp
+++ b/xbmc/peripherals/bus/virtual/PeripheralBusApplication.cpp
@@ -56,6 +56,28 @@ bool CPeripheralBusApplication::PerformDeviceScan(PeripheralScanResults& results
results.m_results.push_back(result);
}
+ bool bHasMouse = CServiceBroker::GetSettings().GetBool(CSettings::SETTING_INPUT_ENABLEMOUSE);
+
+ //! @todo Fix game clients to handle mouse disconnecting
+ //! For now mouse is always connected
+ bHasMouse = true;
+
+ if (bHasMouse)
+ {
+ PeripheralScanResult result(Type());
+ result.m_type = PERIPHERAL_MOUSE;
+ result.m_strDeviceName = g_localizeStrings.Get(35171); // "Mouse"
+ result.m_strLocation = PeripheralTypeTranslator::TypeToString(PERIPHERAL_MOUSE);
+ result.m_iVendorId = 0;
+ result.m_iProductId = 0;
+ result.m_mappedType = PERIPHERAL_MOUSE;
+ result.m_mappedBusType = Type();
+ result.m_iSequence = 0;
+
+ if (!results.ContainsResult(result))
+ results.m_results.push_back(result);
+ }
+
return true;
}
diff --git a/xbmc/peripherals/devices/CMakeLists.txt b/xbmc/peripherals/devices/CMakeLists.txt
index bd967340b9..57795f5ffd 100644
--- a/xbmc/peripherals/devices/CMakeLists.txt
+++ b/xbmc/peripherals/devices/CMakeLists.txt
@@ -5,6 +5,7 @@ set(SOURCES Peripheral.cpp
PeripheralImon.cpp
PeripheralJoystick.cpp
PeripheralKeyboard.cpp
+ PeripheralMouse.cpp
PeripheralNIC.cpp
PeripheralNyxboard.cpp
PeripheralTuner.cpp)
@@ -16,6 +17,7 @@ set(HEADERS Peripheral.h
PeripheralImon.h
PeripheralJoystick.h
PeripheralKeyboard.h
+ PeripheralMouse.h
PeripheralNIC.h
PeripheralNyxboard.h
PeripheralTuner.h)
diff --git a/xbmc/peripherals/devices/Peripheral.cpp b/xbmc/peripherals/devices/Peripheral.cpp
index 9e0ca5c9e7..d8d2e5f8d6 100644
--- a/xbmc/peripherals/devices/Peripheral.cpp
+++ b/xbmc/peripherals/devices/Peripheral.cpp
@@ -605,6 +605,27 @@ void CPeripheral::UnregisterKeyboardHandler(KEYBOARD::IKeyboardInputHandler* han
}
}
+void CPeripheral::RegisterMouseHandler(MOUSE::IMouseInputHandler* handler, bool bPromiscuous)
+{
+ auto it = m_mouseHandlers.find(handler);
+ if (it == m_mouseHandlers.end())
+ {
+ std::unique_ptr<CAddonInputHandling> addonInput(new CAddonInputHandling(m_manager, this, handler));
+ RegisterMouseDriverHandler(addonInput.get(), bPromiscuous);
+ m_mouseHandlers[handler] = std::move(addonInput);
+ }
+}
+
+void CPeripheral::UnregisterMouseHandler(MOUSE::IMouseInputHandler* handler)
+{
+ auto it = m_mouseHandlers.find(handler);
+ if (it != m_mouseHandlers.end())
+ {
+ UnregisterMouseDriverHandler(it->second.get());
+ m_mouseHandlers.erase(it);
+ }
+}
+
void CPeripheral::RegisterJoystickButtonMapper(IButtonMapper* mapper)
{
auto it = m_buttonMappers.find(mapper);
@@ -614,6 +635,7 @@ void CPeripheral::RegisterJoystickButtonMapper(IButtonMapper* mapper)
RegisterJoystickDriverHandler(addonMapping.get(), false);
RegisterKeyboardDriverHandler(addonMapping.get(), false);
+ RegisterMouseDriverHandler(addonMapping.get(), false);
m_buttonMappers[mapper] = std::move(addonMapping);
}
@@ -624,6 +646,7 @@ void CPeripheral::UnregisterJoystickButtonMapper(IButtonMapper* mapper)
auto it = m_buttonMappers.find(mapper);
if (it != m_buttonMappers.end())
{
+ UnregisterMouseDriverHandler(it->second.get());
UnregisterKeyboardDriverHandler(it->second.get());
UnregisterJoystickDriverHandler(it->second.get());
diff --git a/xbmc/peripherals/devices/Peripheral.h b/xbmc/peripherals/devices/Peripheral.h
index 9dd5aaf562..a746948477 100644
--- a/xbmc/peripherals/devices/Peripheral.h
+++ b/xbmc/peripherals/devices/Peripheral.h
@@ -26,6 +26,7 @@
#include "input/joysticks/interfaces/IInputProvider.h"
#include "input/keyboard/interfaces/IKeyboardInputProvider.h"
+#include "input/mouse/interfaces/IMouseInputProvider.h"
#include "peripherals/PeripheralTypes.h"
class TiXmlDocument;
@@ -46,6 +47,11 @@ namespace KEYBOARD
{
class IKeyboardDriverHandler;
}
+
+namespace MOUSE
+{
+ class IMouseDriverHandler;
+}
}
namespace PERIPHERALS
@@ -63,7 +69,8 @@ namespace PERIPHERALS
} CecStateChange;
class CPeripheral : public KODI::JOYSTICK::IInputProvider,
- public KODI::KEYBOARD::IKeyboardInputProvider
+ public KODI::KEYBOARD::IKeyboardInputProvider,
+ public KODI::MOUSE::IMouseInputProvider
{
friend class CGUIDialogPeripheralSettings;
@@ -212,6 +219,9 @@ namespace PERIPHERALS
virtual void RegisterKeyboardDriverHandler(KODI::KEYBOARD::IKeyboardDriverHandler* handler, bool bPromiscuous) { }
virtual void UnregisterKeyboardDriverHandler(KODI::KEYBOARD::IKeyboardDriverHandler* handler) { }
+ virtual void RegisterMouseDriverHandler(KODI::MOUSE::IMouseDriverHandler* handler, bool bPromiscuous) { }
+ virtual void UnregisterMouseDriverHandler(KODI::MOUSE::IMouseDriverHandler* handler) { }
+
// implementation of IInputProvider
void RegisterInputHandler(KODI::JOYSTICK::IInputHandler* handler, bool bPromiscuous) override;
void UnregisterInputHandler(KODI::JOYSTICK::IInputHandler* handler) override;
@@ -220,6 +230,10 @@ namespace PERIPHERALS
void RegisterKeyboardHandler(KODI::KEYBOARD::IKeyboardInputHandler* handler, bool bPromiscuous) override;
void UnregisterKeyboardHandler(KODI::KEYBOARD::IKeyboardInputHandler* handler) override;
+ // implementation of IMouseInputProvider
+ void RegisterMouseHandler(KODI::MOUSE::IMouseInputHandler* handler, bool bPromiscuous) override;
+ void UnregisterMouseHandler(KODI::MOUSE::IMouseInputHandler* handler) override;
+
virtual void RegisterJoystickButtonMapper(KODI::JOYSTICK::IButtonMapper* mapper);
virtual void UnregisterJoystickButtonMapper(KODI::JOYSTICK::IButtonMapper* mapper);
@@ -253,6 +267,7 @@ namespace PERIPHERALS
CPeripheralBus* m_bus;
std::map<KODI::JOYSTICK::IInputHandler*, std::unique_ptr<KODI::JOYSTICK::IDriverHandler>> m_inputHandlers;
std::map<KODI::KEYBOARD::IKeyboardInputHandler*, std::unique_ptr<KODI::KEYBOARD::IKeyboardDriverHandler>> m_keyboardHandlers;
+ std::map<KODI::MOUSE::IMouseInputHandler*, std::unique_ptr<KODI::MOUSE::IMouseDriverHandler>> m_mouseHandlers;
std::map<KODI::JOYSTICK::IButtonMapper*, std::unique_ptr<CAddonButtonMapping>> m_buttonMappers;
};
}
diff --git a/xbmc/peripherals/devices/PeripheralJoystick.cpp b/xbmc/peripherals/devices/PeripheralJoystick.cpp
index c8db2a6019..d5cb661089 100644
--- a/xbmc/peripherals/devices/PeripheralJoystick.cpp
+++ b/xbmc/peripherals/devices/PeripheralJoystick.cpp
@@ -241,7 +241,7 @@ bool CPeripheralJoystick::OnHatMotion(unsigned int hatIndex, HAT_STATE state)
DeviceName().c_str(), CJoystickTranslator::HatStateToString(state));
// Avoid sending activated input if the app is in the background
- if (state != HAT_STATE::UNPRESSED && !g_application.IsAppFocused())
+ if (state != HAT_STATE::NONE && !g_application.IsAppFocused())
return false;
CSingleLock lock(m_handlerMutex);
@@ -264,7 +264,7 @@ bool CPeripheralJoystick::OnHatMotion(unsigned int hatIndex, HAT_STATE state)
// If hat is centered, force bHandled to false to notify all handlers.
// This avoids "sticking".
- if (state == HAT_STATE::UNPRESSED)
+ if (state == HAT_STATE::NONE)
bHandled = false;
// Once a hat is handled, we're done
diff --git a/xbmc/peripherals/devices/PeripheralMouse.cpp b/xbmc/peripherals/devices/PeripheralMouse.cpp
new file mode 100644
index 0000000000..884bab22d3
--- /dev/null
+++ b/xbmc/peripherals/devices/PeripheralMouse.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2017-2018 Team Kodi
+ * http://kodi.tv
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "PeripheralMouse.h"
+#include "input/InputManager.h"
+#include "peripherals/Peripherals.h"
+#include "threads/SingleLock.h"
+
+#include <sstream>
+
+using namespace KODI;
+using namespace PERIPHERALS;
+
+CPeripheralMouse::CPeripheralMouse(CPeripherals& manager, const PeripheralScanResult& scanResult, CPeripheralBus* bus) :
+ CPeripheral(manager, scanResult, bus)
+{
+ // Initialize CPeripheral
+ m_features.push_back(FEATURE_MOUSE);
+}
+
+CPeripheralMouse::~CPeripheralMouse(void)
+{
+ m_manager.GetInputManager().UnregisterMouseDriverHandler(this);
+}
+
+bool CPeripheralMouse::InitialiseFeature(const PeripheralFeature feature)
+{
+ bool bSuccess = false;
+
+ if (CPeripheral::InitialiseFeature(feature))
+ {
+ if (feature == FEATURE_MOUSE)
+ {
+ m_manager.GetInputManager().RegisterMouseDriverHandler(this);
+ }
+
+ bSuccess = true;
+ }
+
+ return bSuccess;
+}
+
+void CPeripheralMouse::RegisterMouseDriverHandler(MOUSE::IMouseDriverHandler* handler, bool bPromiscuous)
+{
+ using namespace KEYBOARD;
+
+ CSingleLock lock(m_mutex);
+
+ MouseHandle handle{ handler, bPromiscuous };
+ m_mouseHandlers.insert(m_mouseHandlers.begin(), handle);
+}
+
+void CPeripheralMouse::UnregisterMouseDriverHandler(MOUSE::IMouseDriverHandler* handler)
+{
+ CSingleLock lock(m_mutex);
+
+ auto it = std::find_if(m_mouseHandlers.begin(), m_mouseHandlers.end(),
+ [handler](const MouseHandle &handle)
+ {
+ return handle.handler == handler;
+ });
+
+ if (it != m_mouseHandlers.end())
+ m_mouseHandlers.erase(it);
+}
+
+bool CPeripheralMouse::OnPosition(int x, int y)
+{
+ CSingleLock lock(m_mutex);
+
+ bool bHandled = false;
+
+ // Process promiscuous handlers
+ for (const MouseHandle &handle : m_mouseHandlers)
+ {
+ if (handle.bPromiscuous)
+ handle.handler->OnPosition(x, y);
+ }
+
+ // Process handlers until one is handled
+ for (const MouseHandle &handle : m_mouseHandlers)
+ {
+ if (!handle.bPromiscuous)
+ {
+ bHandled = handle.handler->OnPosition(x, y);
+ if (bHandled)
+ break;
+ }
+ }
+
+ return bHandled;
+}
+
+bool CPeripheralMouse::OnButtonPress(MOUSE::BUTTON_ID button)
+{
+ CSingleLock lock(m_mutex);
+
+ bool bHandled = false;
+
+ // Process promiscuous handlers
+ for (const MouseHandle &handle : m_mouseHandlers)
+ {
+ if (handle.bPromiscuous)
+ handle.handler->OnButtonPress(button);
+ }
+
+ // Process handlers until one is handled
+ for (const MouseHandle &handle : m_mouseHandlers)
+ {
+ if (!handle.bPromiscuous)
+ {
+ bHandled = handle.handler->OnButtonPress(button);
+ if (bHandled)
+ break;
+ }
+ }
+
+ return bHandled;
+}
+
+void CPeripheralMouse::OnButtonRelease(MOUSE::BUTTON_ID button)
+{
+ CSingleLock lock(m_mutex);
+
+ for (const MouseHandle &handle : m_mouseHandlers)
+ handle.handler->OnButtonRelease(button);
+}
diff --git a/xbmc/peripherals/devices/PeripheralMouse.h b/xbmc/peripherals/devices/PeripheralMouse.h
new file mode 100644
index 0000000000..ff152055cc
--- /dev/null
+++ b/xbmc/peripherals/devices/PeripheralMouse.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017-2018 Team Kodi
+ * http://kodi.tv
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this Program; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+#pragma once
+
+#include "Peripheral.h"
+#include "input/mouse/interfaces/IMouseDriverHandler.h"
+#include "threads/CriticalSection.h"
+
+#include <vector>
+
+namespace PERIPHERALS
+{
+ class CPeripheralMouse : public CPeripheral,
+ public KODI::MOUSE::IMouseDriverHandler
+ {
+ public:
+ CPeripheralMouse(CPeripherals& manager, const PeripheralScanResult& scanResult, CPeripheralBus* bus);
+
+ ~CPeripheralMouse(void) override;
+
+ // implementation of CPeripheral
+ bool InitialiseFeature(const PeripheralFeature feature) override;
+ void RegisterMouseDriverHandler(KODI::MOUSE::IMouseDriverHandler* handler, bool bPromiscuous) override;
+ void UnregisterMouseDriverHandler(KODI::MOUSE::IMouseDriverHandler* handler) override;
+
+ // implementation of IMouseDriverHandler
+ bool OnPosition(int x, int y) override;
+ bool OnButtonPress(KODI::MOUSE::BUTTON_ID button) override;
+ void OnButtonRelease(KODI::MOUSE::BUTTON_ID button) override;
+
+ private:
+ struct MouseHandle
+ {
+ KODI::MOUSE::IMouseDriverHandler* handler;
+ bool bPromiscuous;
+ };
+
+ std::vector<MouseHandle> m_mouseHandlers;
+ CCriticalSection m_mutex;
+ };
+}
diff --git a/xbmc/platform/android/activity/AndroidMouse.cpp b/xbmc/platform/android/activity/AndroidMouse.cpp
index 3c771a90db..4973af3e89 100644
--- a/xbmc/platform/android/activity/AndroidMouse.cpp
+++ b/xbmc/platform/android/activity/AndroidMouse.cpp
@@ -23,7 +23,7 @@
#include "XBMCApp.h"
#include "Application.h"
#include "guilib/GUIWindowManager.h"
-#include "input/MouseStat.h"
+#include "input/mouse/MouseStat.h"
#include "ServiceBroker.h"
#include "windowing/android/WinSystemAndroid.h"
diff --git a/xbmc/platform/android/activity/XBMCApp.cpp b/xbmc/platform/android/activity/XBMCApp.cpp
index b6caf1a773..e9408eda50 100644
--- a/xbmc/platform/android/activity/XBMCApp.cpp
+++ b/xbmc/platform/android/activity/XBMCApp.cpp
@@ -82,9 +82,9 @@
#include "guiinfo/GUIInfoLabels.h"
#include "platform/android/activity/IInputDeviceCallbacks.h"
#include "platform/android/activity/IInputDeviceEventHandler.h"
+#include "input/mouse/MouseStat.h"
#include "input/Key.h"
#include "utils/log.h"
-#include "input/MouseStat.h"
#include "network/android/NetworkAndroid.h"
#include "cores/VideoPlayer/VideoRenderers/RenderManager.h"
#include "filesystem/SpecialProtocol.h"
diff --git a/xbmc/platform/darwin/ios/IOSExternalTouchController.mm b/xbmc/platform/darwin/ios/IOSExternalTouchController.mm
index 459b6d26b8..85f2330b28 100644
--- a/xbmc/platform/darwin/ios/IOSExternalTouchController.mm
+++ b/xbmc/platform/darwin/ios/IOSExternalTouchController.mm
@@ -18,9 +18,9 @@
*
*/
-#include "input/MouseStat.h"
#include "filesystem/SpecialProtocol.h"
#include "guilib/LocalizeStrings.h"
+#include "input/mouse/MouseStat.h"
#include "Util.h"
#import "IOSExternalTouchController.h"
diff --git a/xbmc/platform/linux/input/LinuxInputDevices.cpp b/xbmc/platform/linux/input/LinuxInputDevices.cpp
index 7791af3418..9afb5b72e8 100644
--- a/xbmc/platform/linux/input/LinuxInputDevices.cpp
+++ b/xbmc/platform/linux/input/LinuxInputDevices.cpp
@@ -90,11 +90,11 @@ typedef unsigned long kernel_ulong_t;
#include <stdio.h>
#include "guilib/GraphicContext.h"
+#include "input/mouse/MouseStat.h"
+#include "input/touch/generic/GenericTouchActionHandler.h"
#include "input/XBMC_keysym.h"
#include "LinuxInputDevices.h"
-#include "input/MouseStat.h"
#include "utils/log.h"
-#include "input/touch/generic/GenericTouchActionHandler.h"
#include "settings/AdvancedSettings.h"
#ifndef BITS_PER_LONG
diff --git a/xbmc/windowing/WinEventsLinux.cpp b/xbmc/windowing/WinEventsLinux.cpp
index a29d2deac1..a76130308f 100644
--- a/xbmc/windowing/WinEventsLinux.cpp
+++ b/xbmc/windowing/WinEventsLinux.cpp
@@ -23,7 +23,7 @@
#include "XBMC_events.h"
#include "input/XBMC_keysym.h"
#include "Application.h"
-#include "input/MouseStat.h"
+#include "input/mouse/MouseStat.h"
#include "utils/log.h"
#include "powermanagement/PowerManager.h"
#include "peripherals/Peripherals.h"
diff --git a/xbmc/windowing/X11/WinEventsX11.cpp b/xbmc/windowing/X11/WinEventsX11.cpp
index 858b15a24f..4f949153ae 100644
--- a/xbmc/windowing/X11/WinEventsX11.cpp
+++ b/xbmc/windowing/X11/WinEventsX11.cpp
@@ -33,7 +33,7 @@
#include "utils/log.h"
#include "utils/CharsetConverter.h"
#include "guilib/GUIWindowManager.h"
-#include "input/MouseStat.h"
+#include "input/mouse/MouseStat.h"
#include "input/InputManager.h"
#include "ServiceBroker.h"
diff --git a/xbmc/windowing/mir/WinEventsMir.cpp b/xbmc/windowing/mir/WinEventsMir.cpp
index ab8b31ef73..195f7bd2bd 100644
--- a/xbmc/windowing/mir/WinEventsMir.cpp
+++ b/xbmc/windowing/mir/WinEventsMir.cpp
@@ -26,8 +26,8 @@
#include <xkbcommon/xkbcommon-keysyms.h>
#include "Application.h"
+#include "input/mouse/MouseStat.h"
#include "input/Key.h"
-#include "input/MouseStat.h"
namespace
{
diff --git a/xbmc/windowing/osx/WinEventsSDL.cpp b/xbmc/windowing/osx/WinEventsSDL.cpp
index 8c33b017c9..9742f9a5c4 100644
--- a/xbmc/windowing/osx/WinEventsSDL.cpp
+++ b/xbmc/windowing/osx/WinEventsSDL.cpp
@@ -27,9 +27,9 @@
#include "GUIUserMessages.h"
#include "settings/DisplaySettings.h"
#include "guilib/GUIWindowManager.h"
+#include "input/mouse/MouseStat.h"
#include "input/Key.h"
#include "input/InputManager.h"
-#include "input/MouseStat.h"
#include "windowing/WinSystem.h"
#include "platform/darwin/osx/CocoaInterface.h"
#include "ServiceBroker.h"
diff --git a/xbmc/windowing/wayland/InputProcessorPointer.cpp b/xbmc/windowing/wayland/InputProcessorPointer.cpp
index b21758eaaf..f6a9f021af 100644
--- a/xbmc/windowing/wayland/InputProcessorPointer.cpp
+++ b/xbmc/windowing/wayland/InputProcessorPointer.cpp
@@ -24,7 +24,7 @@
#include <linux/input-event-codes.h>
-#include "input/MouseStat.h"
+#include "input/mouse/MouseStat.h"
using namespace KODI::WINDOWING::WAYLAND;
diff --git a/xbmc/windowing/win10/WinEventsWin10.cpp b/xbmc/windowing/win10/WinEventsWin10.cpp
index 0abebb1ed7..1010e9218b 100644
--- a/xbmc/windowing/win10/WinEventsWin10.cpp
+++ b/xbmc/windowing/win10/WinEventsWin10.cpp
@@ -20,11 +20,11 @@
#include "Application.h"
#include "guilib/GUIWindowManager.h"
-#include "input/Action.h"
-#include "input/ActionIDs.h"
-#include "input/MouseStat.h"
+#include "input/mouse/MouseStat.h"
#include "input/touch/generic/GenericTouchActionHandler.h"
#include "input/touch/generic/GenericTouchInputHandler.h"
+#include "input/Action.h"
+#include "input/ActionIDs.h"
#include "messaging/ApplicationMessenger.h"
#include "rendering/dx/DeviceResources.h"
#include "rendering/dx/RenderContext.h"
diff --git a/xbmc/windowing/windows/WinEventsWin32.cpp b/xbmc/windowing/windows/WinEventsWin32.cpp
index 9428f45bff..b1e4c846d7 100644
--- a/xbmc/windowing/windows/WinEventsWin32.cpp
+++ b/xbmc/windowing/windows/WinEventsWin32.cpp
@@ -29,10 +29,10 @@
#include "Application.h"
#include "guilib/GUIControl.h" // for EVENT_RESULT
#include "guilib/GUIWindowManager.h"
-#include "input/MouseStat.h"
-#include "input/InputManager.h"
+#include "input/mouse/MouseStat.h"
#include "input/touch/generic/GenericTouchActionHandler.h"
#include "input/touch/generic/GenericTouchSwipeDetector.h"
+#include "input/InputManager.h"
#include "messaging/ApplicationMessenger.h"
#include "network/Zeroconf.h"
#include "network/ZeroconfBrowser.h"
diff --git a/xbmc/windows/GUIWindowPointer.cpp b/xbmc/windows/GUIWindowPointer.cpp
index 6b4521e328..1488f81583 100644
--- a/xbmc/windows/GUIWindowPointer.cpp
+++ b/xbmc/windows/GUIWindowPointer.cpp
@@ -19,7 +19,7 @@
*/
#include "GUIWindowPointer.h"
-#include "input/MouseStat.h"
+#include "input/mouse/MouseStat.h"
#include "input/InputManager.h"
#include "ServiceBroker.h"
#include "windowing/WinSystem.h"