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;
214  CDriverPrimitive m_activatedPrimitive;
215  AXIS_TYPE m_type;
216  bool m_initialPositionKnown; // set to true on first motion
217  float m_initialPosition; // set to position of first motion
218  bool m_initialPositionChanged; // set to true when position differs from the initial position
219  std::chrono::time_point<std::chrono::steady_clock>
220  m_activationTimeMs; // only used to delay anomalous trigger mapping to detect full range
221 };
222 
227 {
228 public:
229  CKeyDetector(CButtonMapping* buttonMapping, XBMCKey keycode);
230 
239  bool OnMotion(bool bPressed);
240 
241 private:
242  // Construction parameters
243  const XBMCKey m_keycode;
244 };
245 
250 {
251 public:
252  CMouseButtonDetector(CButtonMapping* buttonMapping, MOUSE::BUTTON_ID buttonIndex);
253 
262  bool OnMotion(bool bPressed);
263 
264 private:
265  // Construction parameters
266  const MOUSE::BUTTON_ID m_buttonIndex;
267 };
268 
273 {
274 public:
275  CPointerDetector(CButtonMapping* buttonMapping);
276 
286  bool OnMotion(int x, int y);
287 
288 private:
289  // Utility function
290  static INPUT::INTERCARDINAL_DIRECTION GetPointerDirection(int x, int y);
291 
292  static const unsigned int MIN_FRAME_COUNT = 10;
293 
294  // State variables
295  bool m_bStarted = false;
296  int m_startX = 0;
297  int m_startY = 0;
298  unsigned int m_frameCount = 0;
299 };
300 
315  public IButtonMapCallback
316 {
317 public:
324  CButtonMapping(IButtonMapper* buttonMapper, IButtonMap* buttonMap, IKeymap* keymap);
325 
326  ~CButtonMapping() override = default;
327 
328  // implementation of IDriverHandler
329  bool OnButtonMotion(unsigned int buttonIndex, bool bPressed) override;
330  bool OnHatMotion(unsigned int hatIndex, HAT_STATE state) override;
331  bool OnAxisMotion(unsigned int axisIndex,
332  float position,
333  int center,
334  unsigned int range) override;
335  void OnInputFrame() override;
336 
337  // implementation of IKeyboardDriverHandler
338  bool OnKeyPress(const CKey& key) override;
339  void OnKeyRelease(const CKey& key) override {}
340 
341  // implementation of IMouseDriverHandler
342  bool OnPosition(int x, int y) override;
343  bool OnButtonPress(MOUSE::BUTTON_ID button) override;
344  void OnButtonRelease(MOUSE::BUTTON_ID button) override;
345 
346  // implementation of IButtonMapCallback
347  void SaveButtonMap() override;
348  void ResetIgnoredPrimitives() override;
349  void RevertButtonMap() override;
350 
362  bool MapPrimitive(const CDriverPrimitive& primitive);
363 
364 private:
365  bool IsMapping() const;
366 
367  void OnLateDiscovery(unsigned int axisIndex);
368 
369  CButtonDetector& GetButton(unsigned int buttonIndex);
370  CHatDetector& GetHat(unsigned int hatIndex);
371  CAxisDetector& GetAxis(unsigned int axisIndex,
372  float position,
373  const AxisConfiguration& initialConfig = AxisConfiguration());
374  CKeyDetector& GetKey(XBMCKey keycode);
375  CMouseButtonDetector& GetMouseButton(MOUSE::BUTTON_ID buttonIndex);
376  CPointerDetector& GetPointer();
377 
378  // Construction parameters
379  IButtonMapper* const m_buttonMapper;
380  IButtonMap* const m_buttonMap;
381  IKeymap* const m_keymap;
382 
383  std::map<unsigned int, CButtonDetector> m_buttons;
384  std::map<unsigned int, CHatDetector> m_hats;
385  std::map<unsigned int, CAxisDetector> m_axes;
386  std::map<XBMCKey, CKeyDetector> m_keys;
387  std::map<MOUSE::BUTTON_ID, CMouseButtonDetector> m_mouseButtons;
388  std::unique_ptr<CPointerDetector> m_pointer;
389  std::chrono::time_point<std::chrono::steady_clock> m_lastAction;
390  uint64_t m_frameCount;
391 };
392 } // namespace JOYSTICK
393 } // namespace KODI
Definition: ButtonMapping.h:103
Interface for classes that can map buttons to Kodi actions.
Definition: IButtonMapper.h:16
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:339
bool MapPrimitive(const CDriverPrimitive &primitive)
Dispatch a mapping event.
Definition: ButtonMapping.cpp:44
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:226
Detects when a mouse button should be mapped.
Definition: ButtonMapping.h:249
bool IsMapping() const
Check if the axis was mapped and is still in motion.
Definition: ButtonMapping.h:143
Controller configuration window.
Definition: AudioDecoder.h:18
Generic implementation of a class that provides button mapping by translating driver events to button...
Definition: ButtonMapping.h:312
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:272
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