Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: ui/events/ozone/gamepad/generic_gamepad_mapping.cc

Issue 2899893003: Add generic mapping for gamepad (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698