Chromium Code Reviews| 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 |