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 #include "DriverPrimitive.h"
10 
11 #include <utility>
12 
13 using namespace KODI;
14 using namespace JOYSTICK;
15 
16 CDriverPrimitive::CDriverPrimitive(void) = default;
17 
CDriverPrimitive(PRIMITIVE_TYPE type,unsigned int index)18 CDriverPrimitive::CDriverPrimitive(PRIMITIVE_TYPE type, unsigned int index)
19   : m_type(type), m_driverIndex(index)
20 {
21 }
22 
CDriverPrimitive(unsigned int hatIndex,HAT_DIRECTION direction)23 CDriverPrimitive::CDriverPrimitive(unsigned int hatIndex, HAT_DIRECTION direction)
24   : m_type(PRIMITIVE_TYPE::HAT), m_driverIndex(hatIndex), m_hatDirection(direction)
25 {
26 }
27 
CDriverPrimitive(unsigned int axisIndex,int center,SEMIAXIS_DIRECTION direction,unsigned int range)28 CDriverPrimitive::CDriverPrimitive(unsigned int axisIndex,
29                                    int center,
30                                    SEMIAXIS_DIRECTION direction,
31                                    unsigned int range)
32   : m_type(PRIMITIVE_TYPE::SEMIAXIS),
33     m_driverIndex(axisIndex),
34     m_center(center),
35     m_semiAxisDirection(direction),
36     m_range(range)
37 {
38 }
39 
CDriverPrimitive(XBMCKey keycode)40 CDriverPrimitive::CDriverPrimitive(XBMCKey keycode)
41   : m_type(PRIMITIVE_TYPE::KEY), m_keycode(keycode)
42 {
43 }
44 
CDriverPrimitive(MOUSE::BUTTON_ID index)45 CDriverPrimitive::CDriverPrimitive(MOUSE::BUTTON_ID index)
46   : m_type(PRIMITIVE_TYPE::MOUSE_BUTTON), m_driverIndex(static_cast<unsigned int>(index))
47 {
48 }
49 
CDriverPrimitive(RELATIVE_POINTER_DIRECTION direction)50 CDriverPrimitive::CDriverPrimitive(RELATIVE_POINTER_DIRECTION direction)
51   : m_type(PRIMITIVE_TYPE::RELATIVE_POINTER), m_pointerDirection(direction)
52 {
53 }
54 
operator ==(const CDriverPrimitive & rhs) const55 bool CDriverPrimitive::operator==(const CDriverPrimitive& rhs) const
56 {
57   if (m_type == rhs.m_type)
58   {
59     switch (m_type)
60     {
61       case PRIMITIVE_TYPE::BUTTON:
62       case PRIMITIVE_TYPE::MOTOR:
63       case PRIMITIVE_TYPE::MOUSE_BUTTON:
64         return m_driverIndex == rhs.m_driverIndex;
65       case PRIMITIVE_TYPE::HAT:
66         return m_driverIndex == rhs.m_driverIndex && m_hatDirection == rhs.m_hatDirection;
67       case PRIMITIVE_TYPE::SEMIAXIS:
68         return m_driverIndex == rhs.m_driverIndex && m_center == rhs.m_center &&
69                m_semiAxisDirection == rhs.m_semiAxisDirection && m_range == rhs.m_range;
70       case PRIMITIVE_TYPE::KEY:
71         return m_keycode == rhs.m_keycode;
72       case PRIMITIVE_TYPE::RELATIVE_POINTER:
73         return m_pointerDirection == rhs.m_pointerDirection;
74       default:
75         return true;
76     }
77   }
78   return false;
79 }
80 
operator <(const CDriverPrimitive & rhs) const81 bool CDriverPrimitive::operator<(const CDriverPrimitive& rhs) const
82 {
83   if (m_type < rhs.m_type)
84     return true;
85   if (m_type > rhs.m_type)
86     return false;
87 
88   if (m_type == PRIMITIVE_TYPE::BUTTON || m_type == PRIMITIVE_TYPE::HAT ||
89       m_type == PRIMITIVE_TYPE::SEMIAXIS || m_type == PRIMITIVE_TYPE::MOTOR ||
90       m_type == PRIMITIVE_TYPE::MOUSE_BUTTON)
91   {
92     if (m_driverIndex < rhs.m_driverIndex)
93       return true;
94     if (m_driverIndex > rhs.m_driverIndex)
95       return false;
96   }
97 
98   if (m_type == PRIMITIVE_TYPE::HAT)
99   {
100     if (m_hatDirection < rhs.m_hatDirection)
101       return true;
102     if (m_hatDirection > rhs.m_hatDirection)
103       return false;
104   }
105 
106   if (m_type == PRIMITIVE_TYPE::SEMIAXIS)
107   {
108     if (m_center < rhs.m_center)
109       return true;
110     if (m_center > rhs.m_center)
111       return false;
112 
113     if (m_semiAxisDirection < rhs.m_semiAxisDirection)
114       return true;
115     if (m_semiAxisDirection > rhs.m_semiAxisDirection)
116       return false;
117 
118     if (m_range < rhs.m_range)
119       return true;
120     if (m_range > rhs.m_range)
121       return false;
122   }
123 
124   if (m_type == PRIMITIVE_TYPE::KEY)
125   {
126     if (m_keycode < rhs.m_keycode)
127       return true;
128     if (m_keycode > rhs.m_keycode)
129       return false;
130   }
131 
132   if (m_type == PRIMITIVE_TYPE::RELATIVE_POINTER)
133   {
134     if (m_pointerDirection < rhs.m_pointerDirection)
135       return true;
136     if (m_pointerDirection > rhs.m_pointerDirection)
137       return false;
138   }
139 
140   return false;
141 }
142 
IsValid(void) const143 bool CDriverPrimitive::IsValid(void) const
144 {
145   if (m_type == PRIMITIVE_TYPE::BUTTON || m_type == PRIMITIVE_TYPE::MOTOR ||
146       m_type == PRIMITIVE_TYPE::MOUSE_BUTTON)
147     return true;
148 
149   if (m_type == PRIMITIVE_TYPE::HAT)
150   {
151     return m_hatDirection == HAT_DIRECTION::UP || m_hatDirection == HAT_DIRECTION::DOWN ||
152            m_hatDirection == HAT_DIRECTION::RIGHT || m_hatDirection == HAT_DIRECTION::LEFT;
153   }
154 
155   if (m_type == PRIMITIVE_TYPE::SEMIAXIS)
156   {
157     unsigned int maxRange = 1;
158 
159     switch (m_center)
160     {
161       case -1:
162       {
163         if (m_semiAxisDirection != SEMIAXIS_DIRECTION::POSITIVE)
164           return false;
165         maxRange = 2;
166         break;
167       }
168       case 0:
169       {
170         if (m_semiAxisDirection != SEMIAXIS_DIRECTION::POSITIVE &&
171             m_semiAxisDirection != SEMIAXIS_DIRECTION::NEGATIVE)
172           return false;
173         break;
174       }
175       case 1:
176       {
177         if (m_semiAxisDirection != SEMIAXIS_DIRECTION::POSITIVE)
178           return false;
179         maxRange = 2;
180         break;
181       }
182       default:
183         break;
184     }
185 
186     return 1 <= m_range && m_range <= maxRange;
187   }
188 
189   if (m_type == PRIMITIVE_TYPE::KEY)
190     return m_keycode != XBMCK_UNKNOWN;
191 
192   if (m_type == PRIMITIVE_TYPE::RELATIVE_POINTER)
193   {
194     return m_pointerDirection == RELATIVE_POINTER_DIRECTION::UP ||
195            m_pointerDirection == RELATIVE_POINTER_DIRECTION::DOWN ||
196            m_pointerDirection == RELATIVE_POINTER_DIRECTION::RIGHT ||
197            m_pointerDirection == RELATIVE_POINTER_DIRECTION::LEFT;
198   }
199 
200   return false;
201 }
202