OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include <linux/input.h> | |
6 #include <cstdint> | |
7 #include <list> | |
8 #include <set> | |
9 #include <vector> | |
10 | |
11 #include "base/macros.h" | |
12 #include "ui/events/ozone/evdev/event_device_info.h" | |
13 #include "ui/events/ozone/gamepad/generic_gamepad_mapping.h" | |
14 #include "ui/events/ozone/gamepad/webgamepad_constants.h" | |
15 | |
16 namespace ui { | |
17 // This helper class is used to generate generic mapping. | |
18 class GenericMappingHelper { | |
19 public: | |
20 GenericMappingHelper(const EventDeviceInfo& devinfo, | |
spang
2017/06/01 05:08:12
This organization is surprising. Everything happen
jkwang
2017/06/02 22:03:52
Done.
| |
21 std::vector<AbsMapEntry>* abs_map, | |
22 std::vector<KeyMapEntry>* key_map) | |
23 : devinfo_(devinfo), abs_map_(abs_map), key_map_(key_map) { | |
24 for (uint16_t i = 0; i < WG_BUTTON_COUNT; i++) { | |
25 unmapped_wg_btn_.push_back(i); | |
spang
2017/06/01 05:08:13
bitset
with a vector this should call reserve() i
jkwang
2017/06/02 22:03:51
Done.
| |
26 } | |
27 | |
28 for (uint16_t i = 0; i < WG_ABS_COUNT; i++) { | |
29 unmapped_wg_abs_.push_back(i); | |
30 } | |
31 MapAbs(); | |
32 MapBtns(); | |
33 } | |
34 | |
35 private: | |
36 // MapAbs will map all the abs events. | |
37 void MapAbs() { | |
spang
2017/06/01 05:08:13
Although linux uses btn and abs Google style is to
jkwang
2017/06/02 22:03:51
Done.
| |
38 TryMapHat(); | |
39 TryMapTrigger(); | |
40 MapOtherAbs(); | |
41 } | |
42 | |
43 // MapBtns will map all the btn events. | |
44 void MapBtns() { | |
spang
2017/06/01 05:08:12
MapButtons()
jkwang
2017/06/02 22:03:51
Done.
| |
45 // Map Mode. | |
46 StaticMapBtnTo(BTN_MODE, WG_BUTTON_MODE); | |
47 // Special care for adt style select/start. | |
48 StaticMapBtnTo(KEY_BACK, WG_BUTTON_SELECT); | |
49 StaticMapBtnTo(KEY_HOMEPAGE, WG_BUTTON_START); | |
50 | |
51 // In linux kernel, joydev.c map evdev events in the same way. | |
52 for (int i = BTN_JOYSTICK - BTN_MISC; i < KEY_MAX - BTN_MISC + 1; i++) { | |
53 int code = i + BTN_MISC; | |
spang
2017/06/01 05:08:12
Confused by this - what's "i" for here (Why not it
jkwang
2017/06/02 22:03:51
As the comments, it's https://github.com/spotify/l
| |
54 if (unmapped_wg_btn_.empty()) { | |
55 return; | |
56 } | |
57 | |
58 if (devinfo_.HasKeyEvent(code) && !mapped_ev_btn_.count(code)) { | |
spang
2017/06/01 05:08:13
This would read a lot more clearly if you make a f
jkwang
2017/06/02 22:03:52
Done.
| |
59 key_map_->push_back({code, unmapped_wg_btn_.front()}); | |
60 unmapped_wg_btn_.pop_front(); | |
61 } | |
62 } | |
63 | |
64 for (int i = 0; i < BTN_JOYSTICK - BTN_MISC; i++) { | |
65 int code = i + BTN_MISC; | |
66 if (unmapped_wg_btn_.empty()) { | |
67 return; | |
68 } | |
69 | |
70 if (devinfo_.HasKeyEvent(code) && !mapped_ev_btn_.count(code)) { | |
71 key_map_->push_back({code, unmapped_wg_btn_.front()}); | |
72 unmapped_wg_btn_.pop_front(); | |
73 } | |
74 } | |
75 } | |
76 | |
77 void StaticMapBtnTo(uint16_t ev_code, uint16_t wg_code) { | |
78 if (devinfo_.HasKeyEvent(ev_code)) { | |
79 key_map_->push_back({ev_code, wg_code}); | |
80 unmapped_wg_btn_.remove(wg_code); | |
81 mapped_ev_btn_.insert(ev_code); | |
82 } | |
83 } | |
84 | |
85 // We always want to map HAT0X and HAT0Y to DPAD. | |
86 void TryMapHat() { | |
87 if (!devinfo_.HasAbsEvent(ABS_HAT0X) || !devinfo_.HasAbsEvent(ABS_HAT0Y)) { | |
88 return; | |
89 } | |
90 | |
91 unmapped_wg_btn_.remove(WG_BUTTON_DPAD_UP); | |
92 unmapped_wg_btn_.remove(WG_BUTTON_DPAD_DOWN); | |
93 unmapped_wg_btn_.remove(WG_BUTTON_DPAD_LEFT); | |
94 unmapped_wg_btn_.remove(WG_BUTTON_DPAD_RIGHT); | |
95 | |
96 mapped_ev_abs_.insert(ABS_HAT0X); | |
97 mapped_ev_abs_.insert(ABS_HAT0Y); | |
98 | |
99 abs_map_->push_back(TO_BTN(ABS_HAT0X, kHAT_X)); | |
100 abs_map_->push_back(TO_BTN(ABS_HAT0Y, kHAT_Y)); | |
101 } | |
102 | |
103 void TryMapTrigger() { | |
104 // ABS_BRAKE, ABS_GAS style. | |
105 if (devinfo_.HasAbsEvent(ABS_BRAKE) && devinfo_.HasAbsEvent(ABS_GAS)) { | |
106 abs_map_->push_back(TO_BTN(ABS_BRAKE, WG_BUTTON_LT)); | |
107 abs_map_->push_back(TO_BTN(ABS_GAS, WG_BUTTON_RT)); | |
108 | |
109 mapped_ev_abs_.insert(ABS_BRAKE); | |
110 mapped_ev_abs_.insert(ABS_GAS); | |
111 unmapped_wg_btn_.remove(WG_BUTTON_LT); | |
112 unmapped_wg_btn_.remove(WG_BUTTON_RT); | |
113 | |
114 return; | |
115 } | |
116 | |
117 // XInput style: If X,Y,Z,RX,RY,RZ are all there, Z and RZ are triggers. | |
118 if (devinfo_.HasAbsEvent(ABS_X) && devinfo_.HasAbsEvent(ABS_Y) && | |
119 devinfo_.HasAbsEvent(ABS_Z) && devinfo_.HasAbsEvent(ABS_RX) && | |
120 devinfo_.HasAbsEvent(ABS_RY) && devinfo_.HasAbsEvent(ABS_RZ)) { | |
121 abs_map_->push_back(TO_BTN(ABS_Z, WG_BUTTON_LT)); | |
spang
2017/06/01 05:08:13
Can you make more functions to make this read well
jkwang
2017/06/02 22:03:52
Done.
| |
122 abs_map_->push_back(TO_BTN(ABS_RZ, WG_BUTTON_RT)); | |
123 mapped_ev_abs_.insert(ABS_Z); | |
124 mapped_ev_abs_.insert(ABS_RZ); | |
125 unmapped_wg_btn_.remove(WG_BUTTON_LT); | |
126 unmapped_wg_btn_.remove(WG_BUTTON_RT); | |
127 } | |
128 } | |
129 | |
130 // Map other Abs in the Joydev style. | |
131 void MapOtherAbs() { | |
132 for (int code = 0; code < ABS_CNT; ++code) { | |
133 if (unmapped_wg_abs_.empty()) { | |
134 return; | |
135 } | |
136 | |
137 if (devinfo_.HasAbsEvent(code) && !mapped_ev_abs_.count(code)) { | |
138 abs_map_->push_back(TO_ABS(code, unmapped_wg_abs_.front())); | |
139 unmapped_wg_abs_.pop_front(); | |
140 } | |
141 } | |
142 } | |
143 | |
144 const EventDeviceInfo& devinfo_; | |
145 // Webgamepad button and abs remain unmapped. | |
146 std::list<uint16_t> unmapped_wg_btn_; | |
spang
2017/06/01 05:08:13
You can use a std::bitset here. Or std::vector. st
jkwang
2017/06/02 22:03:51
Done.
| |
147 std::list<uint16_t> unmapped_wg_abs_; | |
148 // Evdev btn and abs that are already mapped. | |
149 std::set<uint16_t> mapped_ev_btn_; | |
spang
2017/06/01 05:08:13
Also bitset
jkwang
2017/06/02 22:03:51
Done.
| |
150 std::set<uint16_t> mapped_ev_abs_; | |
151 | |
152 std::vector<AbsMapEntry>* abs_map_; | |
153 std::vector<KeyMapEntry>* key_map_; | |
154 }; | |
155 | |
156 GenericGamepadMapping::GenericGamepadMapping( | |
157 const EventDeviceInfo& device_info) { | |
158 GenericMappingHelper(device_info, &abs_map_, &key_map_); | |
159 } | |
160 | |
161 GenericGamepadMapping::~GenericGamepadMapping() {} | |
162 | |
163 bool GenericGamepadMapping::operator()(uint16_t type, | |
164 uint16_t code, | |
165 GamepadEventType* mapped_type, | |
166 uint16_t* mapped_code) { | |
167 if (type == EV_KEY) { | |
168 for (auto entry : key_map_) { | |
169 if (entry.evdev_code == code) { | |
170 *mapped_type = GamepadEventType::BUTTON; | |
171 *mapped_code = entry.mapped_code; | |
172 return true; | |
173 } | |
174 } | |
175 return false; | |
176 } | |
177 | |
178 if (type == EV_ABS) { | |
179 for (auto entry : abs_map_) { | |
180 if (entry.evdev_code == code) { | |
181 *mapped_type = entry.mapped_type; | |
182 *mapped_code = entry.mapped_code; | |
183 return true; | |
184 } | |
185 } | |
186 return false; | |
187 } | |
188 return false; | |
189 }; | |
190 | |
191 } // namespace ui | |
OLD | NEW |