1 /*
2  *  Copyright (C) 2016-2020 Garrett Brown
3  *  Copyright (C) 2016-2020 Team Kodi
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSE.md for more information.
7  */
8 
9 #pragma once
10 
11 /*
12  * Derived from udev_joypad.c in the RetroArch project.
13  */
14 
15 /*  RetroArch - A frontend for libretro.
16  *  Copyright (C) 2010-2015 - Hans-Kristian Arntzen
17  *  Copyright (C) 2011-2016 - Daniel De Matteis
18  *
19  *  RetroArch is free software: you can redistribute it and/or modify it under the terms
20  *  of the GNU General Public License as published by the Free Software Found-
21  *  ation, either version 3 of the License, or (at your option) any later version.
22  *
23  *  RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
24  *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
25  *  PURPOSE.  See the GNU General Public License for more details.
26  *
27  *  You should have received a copy of the GNU General Public License along with RetroArch.
28  *  If not, see <http://www.gnu.org/licenses/>.
29  */
30 
31 #include "api/Joystick.h"
32 
33 #include <array>
34 #include <linux/input.h>
35 #include <map>
36 #include <mutex>
37 #include <sys/types.h>
38 
39 struct udev_device;
40 
41 namespace JOYSTICK
42 {
43   class CJoystickUdev : public CJoystick
44   {
45   public:
46     enum
47     {
48       MOTOR_STRONG = 0,
49       MOTOR_WEAK   = 1,
50       MOTOR_COUNT  = 2,
51     };
52 
53     CJoystickUdev(udev_device* dev, const char* path);
~CJoystickUdev(void)54     virtual ~CJoystickUdev(void) { Deinitialize(); }
55 
56     // implementation of CJoystick
57     virtual bool Equals(const CJoystick* rhs) const override;
58     virtual bool Initialize(void) override;
59     virtual void Deinitialize(void) override;
60     virtual void ProcessEvents(void) override;
61 
62   protected:
63     // implementation of CJoystick
64     virtual bool ScanEvents(void) override;
65     bool SetMotor(unsigned int motorIndex, float magnitude);
66 
67   private:
68     void UpdateMotorState(const std::array<uint16_t, MOTOR_COUNT>& motors);
69     void Play(bool bPlayStop);
70 
71     struct Axis
72     {
73       unsigned int  axisIndex;
74       input_absinfo axisInfo;
75     };
76 
77     bool OpenJoystick();
78     bool GetProperties();
79 
80     // Udev properties
81     udev_device* m_dev;
82     std::string  m_path;
83     dev_t        m_deviceNumber;
84     int          m_fd;
85     bool         m_bInitialized;
86     int          m_effect;
87 
88     // Joystick properties
89     std::map<unsigned int, unsigned int> m_button_bind; // Maps keycodes -> button
90     std::map<unsigned int, Axis>         m_axes_bind;   // Maps keycodes -> axis and axis info
91     std::array<uint16_t, MOTOR_COUNT>    m_motors;
92     std::array<uint16_t, MOTOR_COUNT>    m_previousMotors;
93     std::recursive_mutex m_mutex;
94   };
95 }
96