xbmc
ButtonMapping.h
1 /*
2  * Copyright (C) 2014-2018 Team Kodi
3  * This file is part of Kodi - https://kodi.tv
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  * See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "input/joysticks/DriverPrimitive.h"
12 #include "input/joysticks/interfaces/IButtonMapCallback.h"
13 #include "input/joysticks/interfaces/IDriverHandler.h"
14 #include "input/keyboard/interfaces/IKeyboardDriverHandler.h"
15 #include "input/mouse/MouseTypes.h"
16 #include "input/mouse/interfaces/IMouseDriverHandler.h"
17 
18 #include <chrono>
19 #include <map>
20 #include <memory>
21 #include <stdint.h>
22 
23 class IKeymap;
24 
25 namespace KODI
26 {
27 namespace JOYSTICK
28 {
29 class CButtonMapping;
30 class IButtonMap;
31 class IButtonMapper;
32 
43 {
44 protected:
45  CPrimitiveDetector(CButtonMapping* buttonMapping);
46 
52  bool MapPrimitive(const CDriverPrimitive& primitive);
53 
54 private:
55  CButtonMapping* const m_buttonMapping;
56 };
57 
62 {
63 public:
64  CButtonDetector(CButtonMapping* buttonMapping, unsigned int buttonIndex);
65 
74  bool OnMotion(bool bPressed);
75 
76 private:
77  // Construction parameters
78  const unsigned int m_buttonIndex;
79 };
80 
85 {
86 public:
87  CHatDetector(CButtonMapping* buttonMapping, unsigned int hatIndex);
88 
96  bool OnMotion(HAT_STATE state);
97 
98 private:
99  // Construction parameters
100  const unsigned int m_hatIndex;
101 };
102 
104 {
105  bool bKnown = false;
106  int center = 0;
107  unsigned int range = 1;
108  bool bLateDiscovery = false;
109 };
110 
115 {
116 public:
117  CAxisDetector(CButtonMapping* buttonMapping,
118  unsigned int axisIndex,
119  const AxisConfiguration& config);
120 
128  bool OnMotion(float position);
129 
136  void ProcessMotion();
137 
143  bool IsMapping() const { return m_state == AXIS_STATE::MAPPED; }
144 
152  void SetEmitted(const CDriverPrimitive& activePrimitive);
153 
154 private:
155  enum class AXIS_STATE
156  {
160  INACTIVE,
161 
165  ACTIVATED,
166 
170  MAPPED,
171  };
172 
173  enum class AXIS_TYPE
174  {
178  UNKNOWN,
179 
192  NORMAL,
193 
203  OFFSET,
204  };
205 
206  void DetectType(float position);
207 
208  // Construction parameters
209  const unsigned int m_axisIndex;
210  AxisConfiguration m_config; // mutable
211 
212  // State variables
213  AXIS_STATE m_state = AXIS_STATE::INACTIVE;
214  CDriverPrimitive m_activatedPrimitive;
215  AXIS_TYPE m_type = AXIS_TYPE::UNKNOWN;
216  bool m_initialPositionKnown = false; // set to true on first motion
217  float m_initialPosition = 0.0f; // set to position of first motion
218  bool m_initialPositionChanged =
219  false; // set to true when position differs from the initial position
220  std::chrono::time_point<std::chrono::steady_clock>
221  m_activationTimeMs; // only used to delay anomalous trigger mapping to detect full range
222 };
223 
228 {
229 public:
230  CKeyDetector(CButtonMapping* buttonMapping, XBMCKey keycode);
231 
240  bool OnMotion(bool bPressed);
241 
242 private:
243  // Construction parameters
244  const XBMCKey m_keycode;
245 };
246 
251 {
252 public:
253  CMouseButtonDetector(CButtonMapping* buttonMapping, MOUSE::BUTTON_ID buttonIndex);
254 
263  bool OnMotion(bool bPressed);
264 
265 private:
266  // Construction parameters
267  const MOUSE::BUTTON_ID m_buttonIndex;
268 };
269 
274 {
275 public:
276  CPointerDetector(CButtonMapping* buttonMapping);
277 
287  bool OnMotion(int x, int y);
288 
289 private:
290  // Utility function
291  static INPUT::INTERCARDINAL_DIRECTION GetPointerDirection(int x, int y);
292 
293  static const unsigned int MIN_FRAME_COUNT = 10;
294 
295  // State variables
296  bool m_bStarted = false;
297  int m_startX = 0;
298  int m_startY = 0;
299  unsigned int m_frameCount = 0;
300 };
301 
316  public IButtonMapCallback
317 {
318 public:
325  CButtonMapping(IButtonMapper* buttonMapper, IButtonMap* buttonMap, IKeymap* keymap);
326 
327  ~CButtonMapping() override = default;
328 
329  // implementation of IDriverHandler
330  bool OnButtonMotion(unsigned int buttonIndex, bool bPressed) override;
331  bool OnHatMotion(unsigned int hatIndex, HAT_STATE state) override;
332  bool OnAxisMotion(unsigned int axisIndex,
333  float position,
334  int center,
335  unsigned int range) override;
336  void OnInputFrame() override;
337 
338  // implementation of IKeyboardDriverHandler
339  bool OnKeyPress(const CKey& key) override;
340  void OnKeyRelease(const CKey& key) override {}
341 
342  // implementation of IMouseDriverHandler
343  bool OnPosition(int x, int y) override;
344  bool OnButtonPress(MOUSE::BUTTON_ID button) override;
345  void OnButtonRelease(MOUSE::BUTTON_ID button) override;
346 
347  // implementation of IButtonMapCallback
348  void SaveButtonMap() override;
349  void ResetIgnoredPrimitives() override;
350  void RevertButtonMap() override;
351 
363  bool MapPrimitive(const CDriverPrimitive& primitive);
364 
365 private:
366  bool IsMapping() const;
367 
368  void OnLateDiscovery(unsigned int axisIndex);
369 
370  CButtonDetector& GetButton(unsigned int buttonIndex);
371  CHatDetector& GetHat(unsigned int hatIndex);
372  CAxisDetector& GetAxis(unsigned int axisIndex,
373  float position,
374  const AxisConfiguration& initialConfig = AxisConfiguration());
375  CKeyDetector& GetKey(XBMCKey keycode);
376  CMouseButtonDetector& GetMouseButton(MOUSE::BUTTON_ID buttonIndex);
377  CPointerDetector& GetPointer();
378 
379  // Construction parameters
380  IButtonMapper* const m_buttonMapper;
381  IButtonMap* const m_buttonMap;
382  IKeymap* const m_keymap;
383 
384  std::map<unsigned int, CButtonDetector> m_buttons;
385  std::map<unsigned int, CHatDetector> m_hats;
386  std::map<unsigned int, CAxisDetector> m_axes;
387  std::map<XBMCKey, CKeyDetector> m_keys;
388  std::map<MOUSE::BUTTON_ID, CMouseButtonDetector> m_mouseButtons;
389  std::unique_ptr<CPointerDetector> m_pointer;
390  std::chrono::time_point<std::chrono::steady_clock> m_lastAction;
391  uint64_t m_frameCount = 0;
392 };
393 } // namespace JOYSTICK
394 } // namespace KODI
Definition: ButtonMapping.h:103
Interface for classes that can map buttons to Kodi actions.
Definition: IButtonMapper.h:19
Detects when a button should be mapped.
Definition: ButtonMapping.h:61
Definition: deflate.c:123
void OnKeyRelease(const CKey &key) override
A key has been released.
Definition: ButtonMapping.h:340
bool MapPrimitive(const CDriverPrimitive &primitive)
Dispatch a mapping event.
Definition: ButtonMapping.cpp:45
Interface defining methods to handle joystick events for raw driver elements (buttons, hats, axes)
Definition: IDriverHandler.h:21
Interface for mapping buttons to Kodi actions.
Definition: IKeymap.h:22
Detects and dispatches mapping events.
Definition: ButtonMapping.h:42
Button map interface to translate between the driver&#39;s raw button/hat/axis elements and physical joys...
Definition: IButtonMap.h:28
Detects when a D-pad direction should be mapped.
Definition: ButtonMapping.h:84
Detects when a keyboard key should be mapped.
Definition: ButtonMapping.h:227
Detects when a mouse button should be mapped.
Definition: ButtonMapping.h:250
bool IsMapping() const
Check if the axis was mapped and is still in motion.
Definition: ButtonMapping.h:143
Definition: AudioDecoder.h:18
Generic implementation of a class that provides button mapping by translating driver events to button...
Definition: ButtonMapping.h:313
Interface for handling mouse driver events.
Definition: IMouseDriverHandler.h:21
Basic driver element associated with input events.
Definition: DriverPrimitive.h:69
Detects when a mouse button should be mapped.
Definition: ButtonMapping.h:273
Detects when an axis should be mapped.
Definition: ButtonMapping.h:114
Button mapper interface to assign the driver&#39;s raw button/hat/axis elements to physical joystick feat...
Definition: IButtonMapper.h:33
Interface for handling keyboard events.
Definition: IKeyboardDriverHandler.h:21
Interface for handling button maps.
Definition: IButtonMapCallback.h:18
Definition: Key.h:135