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

Side by Side Diff: content/browser/gamepad/raw_input_data_fetcher_win.cc

Issue 1627643002: Revert of Refactoring gamepad polling to support dynamically added sources (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/gamepad/raw_input_data_fetcher_win.h" 5 #include "content/browser/gamepad/raw_input_data_fetcher_win.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/trace_event/trace_event.h" 10 #include "base/trace_event/trace_event.h"
11 #include "content/common/gamepad_hardware_buffer.h"
11 #include "content/common/gamepad_messages.h" 12 #include "content/common/gamepad_messages.h"
12 13
13 namespace content { 14 namespace content {
14 15
15 using namespace blink; 16 using namespace blink;
16 17
17 namespace { 18 namespace {
18 19
19 float NormalizeAxis(long value, long min, long max) { 20 float NormalizeAxis(long value, long min, long max) {
20 return (2.f * (value - min) / static_cast<float>(max - min)) - 1.f; 21 return (2.f * (value - min) / static_cast<float>(max - min)) - 1.f;
(...skipping 15 matching lines...) Expand all
36 37
37 } // namespace 38 } // namespace
38 39
39 RawGamepadInfo::RawGamepadInfo() { 40 RawGamepadInfo::RawGamepadInfo() {
40 } 41 }
41 42
42 RawGamepadInfo::~RawGamepadInfo() { 43 RawGamepadInfo::~RawGamepadInfo() {
43 } 44 }
44 45
45 RawInputDataFetcher::RawInputDataFetcher() 46 RawInputDataFetcher::RawInputDataFetcher()
46 : rawinput_available_(false), 47 : hid_dll_(base::FilePath(FILE_PATH_LITERAL("hid.dll"))),
48 rawinput_available_(GetHidDllFunctions()),
47 filter_xinput_(true), 49 filter_xinput_(true),
48 events_monitored_(false), 50 events_monitored_(false) {
49 last_source_id_(0),
50 last_enumeration_id_(0) {
51 } 51 }
52 52
53 RawInputDataFetcher::~RawInputDataFetcher() { 53 RawInputDataFetcher::~RawInputDataFetcher() {
54 ClearControllers(); 54 ClearControllers();
55 DCHECK(!window_); 55 DCHECK(!window_);
56 DCHECK(!events_monitored_); 56 DCHECK(!events_monitored_);
57 } 57 }
58 58
59 void RawInputDataFetcher::WillDestroyCurrentMessageLoop() { 59 void RawInputDataFetcher::WillDestroyCurrentMessageLoop() {
60 StopMonitor(); 60 StopMonitor();
61 } 61 }
62 62
63 void RawInputDataFetcher::OnAddedToProvider() {
64 hid_dll_.Reset(base::LoadNativeLibrary(
65 base::FilePath(FILE_PATH_LITERAL("hid.dll")), nullptr));
66 rawinput_available_ = GetHidDllFunctions();
67 }
68
69 RAWINPUTDEVICE* RawInputDataFetcher::GetRawInputDevices(DWORD flags) { 63 RAWINPUTDEVICE* RawInputDataFetcher::GetRawInputDevices(DWORD flags) {
70 size_t usage_count = arraysize(DeviceUsages); 64 size_t usage_count = arraysize(DeviceUsages);
71 scoped_ptr<RAWINPUTDEVICE[]> devices(new RAWINPUTDEVICE[usage_count]); 65 scoped_ptr<RAWINPUTDEVICE[]> devices(new RAWINPUTDEVICE[usage_count]);
72 for (size_t i = 0; i < usage_count; ++i) { 66 for (size_t i = 0; i < usage_count; ++i) {
73 devices[i].dwFlags = flags; 67 devices[i].dwFlags = flags;
74 devices[i].usUsagePage = 1; 68 devices[i].usUsagePage = 1;
75 devices[i].usUsage = DeviceUsages[i]; 69 devices[i].usUsage = DeviceUsages[i];
76 devices[i].hwndTarget = (flags & RIDEV_REMOVE) ? 0 : window_->hwnd(); 70 devices[i].hwndTarget = (flags & RIDEV_REMOVE) ? 0 : window_->hwnd();
77 } 71 }
78 return devices.release(); 72 return devices.release();
79 } 73 }
80 74
81 void RawInputDataFetcher::PauseHint(bool pause) {
82 if (pause)
83 StopMonitor();
84 else
85 StartMonitor();
86 }
87
88 void RawInputDataFetcher::StartMonitor() { 75 void RawInputDataFetcher::StartMonitor() {
89 if (!rawinput_available_ || events_monitored_) 76 if (!rawinput_available_ || events_monitored_)
90 return; 77 return;
91 78
92 if (!window_) { 79 if (!window_) {
93 window_.reset(new base::win::MessageWindow()); 80 window_.reset(new base::win::MessageWindow());
94 if (!window_->Create(base::Bind(&RawInputDataFetcher::HandleMessage, 81 if (!window_->Create(base::Bind(&RawInputDataFetcher::HandleMessage,
95 base::Unretained(this)))) { 82 base::Unretained(this)))) {
96 PLOG(ERROR) << "Failed to create the raw input window"; 83 PLOG(ERROR) << "Failed to create the raw input window";
97 window_.reset(); 84 window_.reset();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 } 124 }
138 125
139 void RawInputDataFetcher::ClearControllers() { 126 void RawInputDataFetcher::ClearControllers() {
140 while (!controllers_.empty()) { 127 while (!controllers_.empty()) {
141 RawGamepadInfo* gamepad_info = controllers_.begin()->second; 128 RawGamepadInfo* gamepad_info = controllers_.begin()->second;
142 controllers_.erase(gamepad_info->handle); 129 controllers_.erase(gamepad_info->handle);
143 delete gamepad_info; 130 delete gamepad_info;
144 } 131 }
145 } 132 }
146 133
147 void RawInputDataFetcher::GetGamepadData(bool devices_changed_hint) { 134 std::vector<RawGamepadInfo*> RawInputDataFetcher::EnumerateDevices() {
148 if (!rawinput_available_) 135 std::vector<RawGamepadInfo*> valid_controllers;
149 return;
150 136
151 if (devices_changed_hint) 137 ClearControllers();
152 EnumerateDevices();
153
154 for (const auto& controller : controllers_) {
155 RawGamepadInfo* gamepad = controller.second;
156 PadState* state = provider()->GetPadState(GAMEPAD_SOURCE_WIN_RAW,
157 gamepad->source_id);
158 if (!state)
159 continue;
160
161 WebGamepad& pad = state->data;
162
163 pad.timestamp = gamepad->report_id;
164 pad.buttonsLength = gamepad->buttons_length;
165 pad.axesLength = gamepad->axes_length;
166
167 for (unsigned int i = 0; i < pad.buttonsLength; i++) {
168 pad.buttons[i].pressed = gamepad->buttons[i];
169 pad.buttons[i].value = gamepad->buttons[i] ? 1.0 : 0.0;
170 }
171
172 for (unsigned int i = 0; i < pad.axesLength; i++)
173 pad.axes[i] = gamepad->axes[i].value;
174 }
175 }
176
177 void RawInputDataFetcher::EnumerateDevices() {
178 last_enumeration_id_++;
179 138
180 UINT count = 0; 139 UINT count = 0;
181 UINT result = GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)); 140 UINT result = GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST));
182 if (result == static_cast<UINT>(-1)) { 141 if (result == static_cast<UINT>(-1)) {
183 PLOG(ERROR) << "GetRawInputDeviceList() failed"; 142 PLOG(ERROR) << "GetRawInputDeviceList() failed";
184 return; 143 return valid_controllers;
185 } 144 }
186 DCHECK_EQ(0u, result); 145 DCHECK_EQ(0u, result);
187 146
188 scoped_ptr<RAWINPUTDEVICELIST[]> device_list(new RAWINPUTDEVICELIST[count]); 147 scoped_ptr<RAWINPUTDEVICELIST[]> device_list(new RAWINPUTDEVICELIST[count]);
189 result = GetRawInputDeviceList(device_list.get(), &count, 148 result = GetRawInputDeviceList(device_list.get(), &count,
190 sizeof(RAWINPUTDEVICELIST)); 149 sizeof(RAWINPUTDEVICELIST));
191 if (result == static_cast<UINT>(-1)) { 150 if (result == static_cast<UINT>(-1)) {
192 PLOG(ERROR) << "GetRawInputDeviceList() failed"; 151 PLOG(ERROR) << "GetRawInputDeviceList() failed";
193 return; 152 return valid_controllers;
194 } 153 }
195 DCHECK_EQ(count, result); 154 DCHECK_EQ(count, result);
196 155
197 for (UINT i = 0; i < count; ++i) { 156 for (UINT i = 0; i < count; ++i) {
198 if (device_list[i].dwType == RIM_TYPEHID) { 157 if (device_list[i].dwType == RIM_TYPEHID) {
199 HANDLE device_handle = device_list[i].hDevice; 158 HANDLE device_handle = device_list[i].hDevice;
200 ControllerMap::iterator controller = controllers_.find(device_handle); 159 RawGamepadInfo* gamepad_info = ParseGamepadInfo(device_handle);
201 160 if (gamepad_info) {
202 RawGamepadInfo* gamepad; 161 controllers_[device_handle] = gamepad_info;
203 if (controller != controllers_.end()) { 162 valid_controllers.push_back(gamepad_info);
204 gamepad = controller->second;
205 } else {
206 gamepad = ParseGamepadInfo(device_handle);
207 if (!gamepad)
208 continue;
209
210 PadState* state = provider()->GetPadState(GAMEPAD_SOURCE_WIN_RAW,
211 gamepad->source_id);
212 if (!state)
213 continue; // No slot available for this gamepad.
214
215 controllers_[device_handle] = gamepad;
216
217 WebGamepad& pad = state->data;
218 pad.connected = true;
219
220 std::string vendor = base::StringPrintf("%04x", gamepad->vendor_id);
221 std::string product = base::StringPrintf("%04x", gamepad->product_id);
222 state->mapper = GetGamepadStandardMappingFunction(vendor, product);
223 state->axis_mask = 0;
224 state->button_mask = 0;
225
226 swprintf(pad.id, WebGamepad::idLengthCap,
227 L"%ls (%lsVendor: %04x Product: %04x)",
228 gamepad->id, state->mapper ? L"STANDARD GAMEPAD " : L"",
229 gamepad->vendor_id, gamepad->product_id);
230
231 if (state->mapper)
232 swprintf(pad.mapping, WebGamepad::mappingLengthCap, L"standard");
233 else
234 pad.mapping[0] = 0;
235 } 163 }
236
237 gamepad->enumeration_id = last_enumeration_id_;
238 } 164 }
239 } 165 }
166 return valid_controllers;
167 }
240 168
241 // Clear out old controllers that weren't part of this enumeration pass. 169 RawGamepadInfo* RawInputDataFetcher::GetGamepadInfo(HANDLE handle) {
242 for (const auto& controller : controllers_) { 170 std::map<HANDLE, RawGamepadInfo*>::iterator it = controllers_.find(handle);
243 RawGamepadInfo* gamepad = controller.second; 171 if (it != controllers_.end())
244 if (gamepad->enumeration_id != last_enumeration_id_) { 172 return it->second;
245 controllers_.erase(gamepad->handle);
246 delete gamepad;
247 }
248 }
249 173
250 return; 174 return NULL;
251 } 175 }
252 176
253 RawGamepadInfo* RawInputDataFetcher::ParseGamepadInfo(HANDLE hDevice) { 177 RawGamepadInfo* RawInputDataFetcher::ParseGamepadInfo(HANDLE hDevice) {
254 UINT size = 0; 178 UINT size = 0;
255 179
180 // Do we already have this device in the map?
181 if (GetGamepadInfo(hDevice))
182 return NULL;
183
256 // Query basic device info. 184 // Query basic device info.
257 UINT result = GetRawInputDeviceInfo(hDevice, RIDI_DEVICEINFO, 185 UINT result = GetRawInputDeviceInfo(hDevice, RIDI_DEVICEINFO,
258 NULL, &size); 186 NULL, &size);
259 if (result == static_cast<UINT>(-1)) { 187 if (result == static_cast<UINT>(-1)) {
260 PLOG(ERROR) << "GetRawInputDeviceInfo() failed"; 188 PLOG(ERROR) << "GetRawInputDeviceInfo() failed";
261 return NULL; 189 return NULL;
262 } 190 }
263 DCHECK_EQ(0u, result); 191 DCHECK_EQ(0u, result);
264 192
265 scoped_ptr<uint8_t[]> di_buffer(new uint8_t[size]); 193 scoped_ptr<uint8_t[]> di_buffer(new uint8_t[size]);
(...skipping 13 matching lines...) Expand all
279 if (device_info->hid.usUsage == device_usage) { 207 if (device_info->hid.usUsage == device_usage) {
280 valid_type = true; 208 valid_type = true;
281 break; 209 break;
282 } 210 }
283 } 211 }
284 212
285 if (!valid_type) 213 if (!valid_type)
286 return NULL; 214 return NULL;
287 215
288 scoped_ptr<RawGamepadInfo> gamepad_info(new RawGamepadInfo); 216 scoped_ptr<RawGamepadInfo> gamepad_info(new RawGamepadInfo);
289 gamepad_info->source_id = ++last_source_id_;
290 gamepad_info->enumeration_id = last_enumeration_id_;
291 gamepad_info->handle = hDevice; 217 gamepad_info->handle = hDevice;
292 gamepad_info->report_id = 0; 218 gamepad_info->report_id = 0;
293 gamepad_info->vendor_id = device_info->hid.dwVendorId; 219 gamepad_info->vendor_id = device_info->hid.dwVendorId;
294 gamepad_info->product_id = device_info->hid.dwProductId; 220 gamepad_info->product_id = device_info->hid.dwProductId;
295 gamepad_info->buttons_length = 0; 221 gamepad_info->buttons_length = 0;
296 ZeroMemory(gamepad_info->buttons, sizeof(gamepad_info->buttons)); 222 ZeroMemory(gamepad_info->buttons, sizeof(gamepad_info->buttons));
297 gamepad_info->axes_length = 0; 223 gamepad_info->axes_length = 0;
298 ZeroMemory(gamepad_info->axes, sizeof(gamepad_info->axes)); 224 ZeroMemory(gamepad_info->axes, sizeof(gamepad_info->axes));
299 225
300 // Query device identifier 226 // Query device identifier
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 gamepad_info->axes_length = 346 gamepad_info->axes_length =
421 std::max(gamepad_info->axes_length, next_index + 1); 347 std::max(gamepad_info->axes_length, next_index + 1);
422 } 348 }
423 } 349 }
424 350
425 if (next_index >= WebGamepad::axesLengthCap) 351 if (next_index >= WebGamepad::axesLengthCap)
426 break; 352 break;
427 } 353 }
428 } 354 }
429 355
430 // Sometimes devices show up with no buttons or axes. Don't return these.
431 if (gamepad_info->buttons_length == 0 && gamepad_info->axes_length == 0)
432 return nullptr;
433
434 return gamepad_info.release(); 356 return gamepad_info.release();
435 } 357 }
436 358
437 void RawInputDataFetcher::UpdateGamepad( 359 void RawInputDataFetcher::UpdateGamepad(
438 RAWINPUT* input, 360 RAWINPUT* input,
439 RawGamepadInfo* gamepad_info) { 361 RawGamepadInfo* gamepad_info) {
440 NTSTATUS status; 362 NTSTATUS status;
441 363
442 gamepad_info->report_id++; 364 gamepad_info->report_id++;
443 365
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 result = GetRawInputData( 450 result = GetRawInputData(
529 input_handle, RID_INPUT, buffer.get(), &size, sizeof(RAWINPUTHEADER)); 451 input_handle, RID_INPUT, buffer.get(), &size, sizeof(RAWINPUTHEADER));
530 if (result == static_cast<UINT>(-1)) { 452 if (result == static_cast<UINT>(-1)) {
531 PLOG(ERROR) << "GetRawInputData() failed"; 453 PLOG(ERROR) << "GetRawInputData() failed";
532 return 0; 454 return 0;
533 } 455 }
534 DCHECK_EQ(size, result); 456 DCHECK_EQ(size, result);
535 457
536 // Notify the observer about events generated locally. 458 // Notify the observer about events generated locally.
537 if (input->header.dwType == RIM_TYPEHID && input->header.hDevice != NULL) { 459 if (input->header.dwType == RIM_TYPEHID && input->header.hDevice != NULL) {
538 ControllerMap::iterator it = controllers_.find(input->header.hDevice); 460 RawGamepadInfo* gamepad = GetGamepadInfo(input->header.hDevice);
539 if (it != controllers_.end()) 461 if (gamepad)
540 UpdateGamepad(input, it->second); 462 UpdateGamepad(input, gamepad);
541 } 463 }
542 464
543 return DefRawInputProc(&input, 1, sizeof(RAWINPUTHEADER)); 465 return DefRawInputProc(&input, 1, sizeof(RAWINPUTHEADER));
544 } 466 }
545 467
546 bool RawInputDataFetcher::HandleMessage(UINT message, 468 bool RawInputDataFetcher::HandleMessage(UINT message,
547 WPARAM wparam, 469 WPARAM wparam,
548 LPARAM lparam, 470 LPARAM lparam,
549 LRESULT* result) { 471 LRESULT* result) {
550 switch (message) { 472 switch (message) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 return false; 516 return false;
595 hidd_get_product_string_ = reinterpret_cast<HidDGetStringFunc>( 517 hidd_get_product_string_ = reinterpret_cast<HidDGetStringFunc>(
596 hid_dll_.GetFunctionPointer("HidD_GetProductString")); 518 hid_dll_.GetFunctionPointer("HidD_GetProductString"));
597 if (!hidd_get_product_string_) 519 if (!hidd_get_product_string_)
598 return false; 520 return false;
599 521
600 return true; 522 return true;
601 } 523 }
602 524
603 } // namespace content 525 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/gamepad/raw_input_data_fetcher_win.h ('k') | content/browser/gamepad/xbox_data_fetcher_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698