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

Side by Side Diff: device/gamepad/raw_input_data_fetcher_win.cc

Issue 2081583002: Migrating majority of gamepad from content/browser/ to device/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Final tweaks Created 4 years, 5 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
« no previous file with comments | « device/gamepad/raw_input_data_fetcher_win.h ('k') | device/gamepad/xbox_data_fetcher_mac.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "device/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"
12 #include "content/common/gamepad_messages.h"
13 11
14 namespace content { 12 namespace device {
15 13
16 using namespace blink; 14 using namespace blink;
17 15
18 namespace { 16 namespace {
19 17
20 float NormalizeAxis(long value, long min, long max) { 18 float NormalizeAxis(long value, long min, long max) {
21 return (2.f * (value - min) / static_cast<float>(max - min)) - 1.f; 19 return (2.f * (value - min) / static_cast<float>(max - min)) - 1.f;
22 } 20 }
23 21
24 unsigned long GetBitmask(unsigned short bits) { 22 unsigned long GetBitmask(unsigned short bits) {
25 return (1 << bits) - 1; 23 return (1 << bits) - 1;
26 } 24 }
27 25
28 // From the HID Usage Tables specification. 26 // From the HID Usage Tables specification.
29 USHORT DeviceUsages[] = { 27 USHORT DeviceUsages[] = {
30 0x04, // Joysticks 28 0x04, // Joysticks
31 0x05, // Gamepads 29 0x05, // Gamepads
32 0x08, // Multi Axis 30 0x08, // Multi Axis
33 }; 31 };
34 32
35 const uint32_t kAxisMinimumUsageNumber = 0x30; 33 const uint32_t kAxisMinimumUsageNumber = 0x30;
36 const uint32_t kGameControlsUsagePage = 0x05; 34 const uint32_t kGameControlsUsagePage = 0x05;
37 const uint32_t kButtonUsagePage = 0x09; 35 const uint32_t kButtonUsagePage = 0x09;
38 36
39 } // namespace 37 } // namespace
40 38
41 RawGamepadInfo::RawGamepadInfo() { 39 RawGamepadInfo::RawGamepadInfo() {}
42 }
43 40
44 RawGamepadInfo::~RawGamepadInfo() { 41 RawGamepadInfo::~RawGamepadInfo() {}
45 }
46 42
47 RawInputDataFetcher::RawInputDataFetcher() 43 RawInputDataFetcher::RawInputDataFetcher()
48 : hid_dll_(base::FilePath(FILE_PATH_LITERAL("hid.dll"))), 44 : hid_dll_(base::FilePath(FILE_PATH_LITERAL("hid.dll"))),
49 rawinput_available_(GetHidDllFunctions()), 45 rawinput_available_(GetHidDllFunctions()),
50 filter_xinput_(true), 46 filter_xinput_(true),
51 events_monitored_(false) { 47 events_monitored_(false) {}
52 }
53 48
54 RawInputDataFetcher::~RawInputDataFetcher() { 49 RawInputDataFetcher::~RawInputDataFetcher() {
55 ClearControllers(); 50 ClearControllers();
56 DCHECK(!window_); 51 DCHECK(!window_);
57 DCHECK(!events_monitored_); 52 DCHECK(!events_monitored_);
58 } 53 }
59 54
60 void RawInputDataFetcher::WillDestroyCurrentMessageLoop() { 55 void RawInputDataFetcher::WillDestroyCurrentMessageLoop() {
61 StopMonitor(); 56 StopMonitor();
62 } 57 }
(...skipping 21 matching lines...) Expand all
84 PLOG(ERROR) << "Failed to create the raw input window"; 79 PLOG(ERROR) << "Failed to create the raw input window";
85 window_.reset(); 80 window_.reset();
86 return; 81 return;
87 } 82 }
88 } 83 }
89 84
90 // Register to receive raw HID input. 85 // Register to receive raw HID input.
91 std::unique_ptr<RAWINPUTDEVICE[]> devices( 86 std::unique_ptr<RAWINPUTDEVICE[]> devices(
92 GetRawInputDevices(RIDEV_INPUTSINK)); 87 GetRawInputDevices(RIDEV_INPUTSINK));
93 if (!RegisterRawInputDevices(devices.get(), arraysize(DeviceUsages), 88 if (!RegisterRawInputDevices(devices.get(), arraysize(DeviceUsages),
94 sizeof(RAWINPUTDEVICE))) { 89 sizeof(RAWINPUTDEVICE))) {
95 PLOG(ERROR) << "RegisterRawInputDevices() failed for RIDEV_INPUTSINK"; 90 PLOG(ERROR) << "RegisterRawInputDevices() failed for RIDEV_INPUTSINK";
96 window_.reset(); 91 window_.reset();
97 return; 92 return;
98 } 93 }
99 94
100 // Start observing message loop destruction if we start monitoring the first 95 // Start observing message loop destruction if we start monitoring the first
101 // event. 96 // event.
102 if (!events_monitored_) 97 if (!events_monitored_)
103 base::MessageLoop::current()->AddDestructionObserver(this); 98 base::MessageLoop::current()->AddDestructionObserver(this);
104 99
105 events_monitored_ = true; 100 events_monitored_ = true;
106 } 101 }
107 102
108 void RawInputDataFetcher::StopMonitor() { 103 void RawInputDataFetcher::StopMonitor() {
109 if (!rawinput_available_ || !events_monitored_) 104 if (!rawinput_available_ || !events_monitored_)
110 return; 105 return;
111 106
112 // Stop receiving raw input. 107 // Stop receiving raw input.
113 DCHECK(window_); 108 DCHECK(window_);
114 std::unique_ptr<RAWINPUTDEVICE[]> devices(GetRawInputDevices(RIDEV_REMOVE)); 109 std::unique_ptr<RAWINPUTDEVICE[]> devices(GetRawInputDevices(RIDEV_REMOVE));
115 110
116 if (!RegisterRawInputDevices(devices.get(), arraysize(DeviceUsages), 111 if (!RegisterRawInputDevices(devices.get(), arraysize(DeviceUsages),
117 sizeof(RAWINPUTDEVICE))) { 112 sizeof(RAWINPUTDEVICE))) {
118 PLOG(INFO) << "RegisterRawInputDevices() failed for RIDEV_REMOVE"; 113 PLOG(INFO) << "RegisterRawInputDevices() failed for RIDEV_REMOVE";
119 } 114 }
120 115
121 events_monitored_ = false; 116 events_monitored_ = false;
122 window_.reset(); 117 window_.reset();
123 118
124 // Stop observing message loop destruction if no event is being monitored. 119 // Stop observing message loop destruction if no event is being monitored.
125 base::MessageLoop::current()->RemoveDestructionObserver(this); 120 base::MessageLoop::current()->RemoveDestructionObserver(this);
126 } 121 }
127 122
(...skipping 14 matching lines...) Expand all
142 UINT result = GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)); 137 UINT result = GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST));
143 if (result == static_cast<UINT>(-1)) { 138 if (result == static_cast<UINT>(-1)) {
144 PLOG(ERROR) << "GetRawInputDeviceList() failed"; 139 PLOG(ERROR) << "GetRawInputDeviceList() failed";
145 return valid_controllers; 140 return valid_controllers;
146 } 141 }
147 DCHECK_EQ(0u, result); 142 DCHECK_EQ(0u, result);
148 143
149 std::unique_ptr<RAWINPUTDEVICELIST[]> device_list( 144 std::unique_ptr<RAWINPUTDEVICELIST[]> device_list(
150 new RAWINPUTDEVICELIST[count]); 145 new RAWINPUTDEVICELIST[count]);
151 result = GetRawInputDeviceList(device_list.get(), &count, 146 result = GetRawInputDeviceList(device_list.get(), &count,
152 sizeof(RAWINPUTDEVICELIST)); 147 sizeof(RAWINPUTDEVICELIST));
153 if (result == static_cast<UINT>(-1)) { 148 if (result == static_cast<UINT>(-1)) {
154 PLOG(ERROR) << "GetRawInputDeviceList() failed"; 149 PLOG(ERROR) << "GetRawInputDeviceList() failed";
155 return valid_controllers; 150 return valid_controllers;
156 } 151 }
157 DCHECK_EQ(count, result); 152 DCHECK_EQ(count, result);
158 153
159 for (UINT i = 0; i < count; ++i) { 154 for (UINT i = 0; i < count; ++i) {
160 if (device_list[i].dwType == RIM_TYPEHID) { 155 if (device_list[i].dwType == RIM_TYPEHID) {
161 HANDLE device_handle = device_list[i].hDevice; 156 HANDLE device_handle = device_list[i].hDevice;
162 RawGamepadInfo* gamepad_info = ParseGamepadInfo(device_handle); 157 RawGamepadInfo* gamepad_info = ParseGamepadInfo(device_handle);
(...skipping 15 matching lines...) Expand all
178 } 173 }
179 174
180 RawGamepadInfo* RawInputDataFetcher::ParseGamepadInfo(HANDLE hDevice) { 175 RawGamepadInfo* RawInputDataFetcher::ParseGamepadInfo(HANDLE hDevice) {
181 UINT size = 0; 176 UINT size = 0;
182 177
183 // Do we already have this device in the map? 178 // Do we already have this device in the map?
184 if (GetGamepadInfo(hDevice)) 179 if (GetGamepadInfo(hDevice))
185 return NULL; 180 return NULL;
186 181
187 // Query basic device info. 182 // Query basic device info.
188 UINT result = GetRawInputDeviceInfo(hDevice, RIDI_DEVICEINFO, 183 UINT result = GetRawInputDeviceInfo(hDevice, RIDI_DEVICEINFO, NULL, &size);
189 NULL, &size);
190 if (result == static_cast<UINT>(-1)) { 184 if (result == static_cast<UINT>(-1)) {
191 PLOG(ERROR) << "GetRawInputDeviceInfo() failed"; 185 PLOG(ERROR) << "GetRawInputDeviceInfo() failed";
192 return NULL; 186 return NULL;
193 } 187 }
194 DCHECK_EQ(0u, result); 188 DCHECK_EQ(0u, result);
195 189
196 std::unique_ptr<uint8_t[]> di_buffer(new uint8_t[size]); 190 std::unique_ptr<uint8_t[]> di_buffer(new uint8_t[size]);
197 RID_DEVICE_INFO* device_info = 191 RID_DEVICE_INFO* device_info =
198 reinterpret_cast<RID_DEVICE_INFO*>(di_buffer.get()); 192 reinterpret_cast<RID_DEVICE_INFO*>(di_buffer.get());
199 result = GetRawInputDeviceInfo(hDevice, RIDI_DEVICEINFO, 193 result =
200 di_buffer.get(), &size); 194 GetRawInputDeviceInfo(hDevice, RIDI_DEVICEINFO, di_buffer.get(), &size);
201 if (result == static_cast<UINT>(-1)) { 195 if (result == static_cast<UINT>(-1)) {
202 PLOG(ERROR) << "GetRawInputDeviceInfo() failed"; 196 PLOG(ERROR) << "GetRawInputDeviceInfo() failed";
203 return NULL; 197 return NULL;
204 } 198 }
205 DCHECK_EQ(size, result); 199 DCHECK_EQ(size, result);
206 200
207 // Make sure this device is of a type that we want to observe. 201 // Make sure this device is of a type that we want to observe.
208 bool valid_type = false; 202 bool valid_type = false;
209 for (USHORT device_usage : DeviceUsages) { 203 for (USHORT device_usage : DeviceUsages) {
210 if (device_info->hid.usUsage == device_usage) { 204 if (device_info->hid.usUsage == device_usage) {
211 valid_type = true; 205 valid_type = true;
212 break; 206 break;
213 } 207 }
214 } 208 }
215 209
216 if (!valid_type) 210 if (!valid_type)
217 return NULL; 211 return NULL;
218 212
219 std::unique_ptr<RawGamepadInfo> gamepad_info(new RawGamepadInfo); 213 std::unique_ptr<RawGamepadInfo> gamepad_info(new RawGamepadInfo);
220 gamepad_info->handle = hDevice; 214 gamepad_info->handle = hDevice;
221 gamepad_info->report_id = 0; 215 gamepad_info->report_id = 0;
222 gamepad_info->vendor_id = device_info->hid.dwVendorId; 216 gamepad_info->vendor_id = device_info->hid.dwVendorId;
223 gamepad_info->product_id = device_info->hid.dwProductId; 217 gamepad_info->product_id = device_info->hid.dwProductId;
224 gamepad_info->buttons_length = 0; 218 gamepad_info->buttons_length = 0;
225 ZeroMemory(gamepad_info->buttons, sizeof(gamepad_info->buttons)); 219 ZeroMemory(gamepad_info->buttons, sizeof(gamepad_info->buttons));
226 gamepad_info->axes_length = 0; 220 gamepad_info->axes_length = 0;
227 ZeroMemory(gamepad_info->axes, sizeof(gamepad_info->axes)); 221 ZeroMemory(gamepad_info->axes, sizeof(gamepad_info->axes));
228 222
229 // Query device identifier 223 // Query device identifier
230 result = GetRawInputDeviceInfo(hDevice, RIDI_DEVICENAME, 224 result = GetRawInputDeviceInfo(hDevice, RIDI_DEVICENAME, NULL, &size);
231 NULL, &size);
232 if (result == static_cast<UINT>(-1)) { 225 if (result == static_cast<UINT>(-1)) {
233 PLOG(ERROR) << "GetRawInputDeviceInfo() failed"; 226 PLOG(ERROR) << "GetRawInputDeviceInfo() failed";
234 return NULL; 227 return NULL;
235 } 228 }
236 DCHECK_EQ(0u, result); 229 DCHECK_EQ(0u, result);
237 230
238 std::unique_ptr<wchar_t[]> name_buffer(new wchar_t[size]); 231 std::unique_ptr<wchar_t[]> name_buffer(new wchar_t[size]);
239 result = GetRawInputDeviceInfo(hDevice, RIDI_DEVICENAME, 232 result =
240 name_buffer.get(), &size); 233 GetRawInputDeviceInfo(hDevice, RIDI_DEVICENAME, name_buffer.get(), &size);
241 if (result == static_cast<UINT>(-1)) { 234 if (result == static_cast<UINT>(-1)) {
242 PLOG(ERROR) << "GetRawInputDeviceInfo() failed"; 235 PLOG(ERROR) << "GetRawInputDeviceInfo() failed";
243 return NULL; 236 return NULL;
244 } 237 }
245 DCHECK_EQ(size, result); 238 DCHECK_EQ(size, result);
246 239
247 // The presence of "IG_" in the device name indicates that this is an XInput 240 // The presence of "IG_" in the device name indicates that this is an XInput
248 // Gamepad. Skip enumerating these devices and let the XInput path handle it. 241 // Gamepad. Skip enumerating these devices and let the XInput path handle it.
249 // http://msdn.microsoft.com/en-us/library/windows/desktop/ee417014.aspx 242 // http://msdn.microsoft.com/en-us/library/windows/desktop/ee417014.aspx
250 if (filter_xinput_ && wcsstr( name_buffer.get(), L"IG_" ) ) 243 if (filter_xinput_ && wcsstr(name_buffer.get(), L"IG_"))
251 return NULL; 244 return NULL;
252 245
253 // Get a friendly device name 246 // Get a friendly device name
254 BOOLEAN got_product_string = FALSE; 247 BOOLEAN got_product_string = FALSE;
255 HANDLE hid_handle = CreateFile(name_buffer.get(), GENERIC_READ|GENERIC_WRITE, 248 HANDLE hid_handle = CreateFile(
256 FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL); 249 name_buffer.get(), GENERIC_READ | GENERIC_WRITE,
250 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
257 if (hid_handle) { 251 if (hid_handle) {
258 got_product_string = hidd_get_product_string_(hid_handle, gamepad_info->id, 252 got_product_string = hidd_get_product_string_(hid_handle, gamepad_info->id,
259 sizeof(gamepad_info->id)); 253 sizeof(gamepad_info->id));
260 CloseHandle(hid_handle); 254 CloseHandle(hid_handle);
261 } 255 }
262 256
263 if (!got_product_string) 257 if (!got_product_string)
264 swprintf(gamepad_info->id, WebGamepad::idLengthCap, L"Unknown Gamepad"); 258 swprintf(gamepad_info->id, WebGamepad::idLengthCap, L"Unknown Gamepad");
265 259
266 // Query device capabilities. 260 // Query device capabilities.
267 result = GetRawInputDeviceInfo(hDevice, RIDI_PREPARSEDDATA, 261 result = GetRawInputDeviceInfo(hDevice, RIDI_PREPARSEDDATA, NULL, &size);
268 NULL, &size);
269 if (result == static_cast<UINT>(-1)) { 262 if (result == static_cast<UINT>(-1)) {
270 PLOG(ERROR) << "GetRawInputDeviceInfo() failed"; 263 PLOG(ERROR) << "GetRawInputDeviceInfo() failed";
271 return NULL; 264 return NULL;
272 } 265 }
273 DCHECK_EQ(0u, result); 266 DCHECK_EQ(0u, result);
274 267
275 gamepad_info->ppd_buffer.reset(new uint8_t[size]); 268 gamepad_info->ppd_buffer.reset(new uint8_t[size]);
276 gamepad_info->preparsed_data = 269 gamepad_info->preparsed_data =
277 reinterpret_cast<PHIDP_PREPARSED_DATA>(gamepad_info->ppd_buffer.get()); 270 reinterpret_cast<PHIDP_PREPARSED_DATA>(gamepad_info->ppd_buffer.get());
278 result = GetRawInputDeviceInfo(hDevice, RIDI_PREPARSEDDATA, 271 result = GetRawInputDeviceInfo(hDevice, RIDI_PREPARSEDDATA,
279 gamepad_info->ppd_buffer.get(), &size); 272 gamepad_info->ppd_buffer.get(), &size);
280 if (result == static_cast<UINT>(-1)) { 273 if (result == static_cast<UINT>(-1)) {
281 PLOG(ERROR) << "GetRawInputDeviceInfo() failed"; 274 PLOG(ERROR) << "GetRawInputDeviceInfo() failed";
282 return NULL; 275 return NULL;
283 } 276 }
284 DCHECK_EQ(size, result); 277 DCHECK_EQ(size, result);
285 278
286 HIDP_CAPS caps; 279 HIDP_CAPS caps;
287 NTSTATUS status = hidp_get_caps_(gamepad_info->preparsed_data, &caps); 280 NTSTATUS status = hidp_get_caps_(gamepad_info->preparsed_data, &caps);
288 DCHECK_EQ(HIDP_STATUS_SUCCESS, status); 281 DCHECK_EQ(HIDP_STATUS_SUCCESS, status);
289 282
290 // Query button information. 283 // Query button information.
291 USHORT count = caps.NumberInputButtonCaps; 284 USHORT count = caps.NumberInputButtonCaps;
292 if (count > 0) { 285 if (count > 0) {
293 std::unique_ptr<HIDP_BUTTON_CAPS[]> button_caps( 286 std::unique_ptr<HIDP_BUTTON_CAPS[]> button_caps(
294 new HIDP_BUTTON_CAPS[count]); 287 new HIDP_BUTTON_CAPS[count]);
295 status = hidp_get_button_caps_( 288 status = hidp_get_button_caps_(HidP_Input, button_caps.get(), &count,
296 HidP_Input, button_caps.get(), &count, gamepad_info->preparsed_data); 289 gamepad_info->preparsed_data);
297 DCHECK_EQ(HIDP_STATUS_SUCCESS, status); 290 DCHECK_EQ(HIDP_STATUS_SUCCESS, status);
298 291
299 for (uint32_t i = 0; i < count; ++i) { 292 for (uint32_t i = 0; i < count; ++i) {
300 if (button_caps[i].Range.UsageMin <= WebGamepad::buttonsLengthCap && 293 if (button_caps[i].Range.UsageMin <= WebGamepad::buttonsLengthCap &&
301 button_caps[i].UsagePage == kButtonUsagePage) { 294 button_caps[i].UsagePage == kButtonUsagePage) {
302 uint32_t max_index = 295 uint32_t max_index =
303 std::min(WebGamepad::buttonsLengthCap, 296 std::min(WebGamepad::buttonsLengthCap,
304 static_cast<size_t>(button_caps[i].Range.UsageMax)); 297 static_cast<size_t>(button_caps[i].Range.UsageMax));
305 gamepad_info->buttons_length = std::max( 298 gamepad_info->buttons_length =
306 gamepad_info->buttons_length, max_index); 299 std::max(gamepad_info->buttons_length, max_index);
307 } 300 }
308 } 301 }
309 } 302 }
310 303
311 // Query axis information. 304 // Query axis information.
312 count = caps.NumberInputValueCaps; 305 count = caps.NumberInputValueCaps;
313 std::unique_ptr<HIDP_VALUE_CAPS[]> axes_caps(new HIDP_VALUE_CAPS[count]); 306 std::unique_ptr<HIDP_VALUE_CAPS[]> axes_caps(new HIDP_VALUE_CAPS[count]);
314 status = hidp_get_value_caps_(HidP_Input, axes_caps.get(), &count, 307 status = hidp_get_value_caps_(HidP_Input, axes_caps.get(), &count,
315 gamepad_info->preparsed_data); 308 gamepad_info->preparsed_data);
316 309
317 bool mapped_all_axes = true; 310 bool mapped_all_axes = true;
318 311
319 for (UINT i = 0; i < count; i++) { 312 for (UINT i = 0; i < count; i++) {
320 uint32_t axis_index = axes_caps[i].Range.UsageMin - kAxisMinimumUsageNumber; 313 uint32_t axis_index = axes_caps[i].Range.UsageMin - kAxisMinimumUsageNumber;
321 if (axis_index < WebGamepad::axesLengthCap) { 314 if (axis_index < WebGamepad::axesLengthCap) {
322 gamepad_info->axes[axis_index].caps = axes_caps[i]; 315 gamepad_info->axes[axis_index].caps = axes_caps[i];
323 gamepad_info->axes[axis_index].value = 0; 316 gamepad_info->axes[axis_index].value = 0;
324 gamepad_info->axes[axis_index].active = true; 317 gamepad_info->axes[axis_index].active = true;
325 gamepad_info->axes[axis_index].bitmask = GetBitmask(axes_caps[i].BitSize); 318 gamepad_info->axes[axis_index].bitmask = GetBitmask(axes_caps[i].BitSize);
326 gamepad_info->axes_length = 319 gamepad_info->axes_length =
327 std::max(gamepad_info->axes_length, axis_index + 1); 320 std::max(gamepad_info->axes_length, axis_index + 1);
328 } else { 321 } else {
329 mapped_all_axes = false; 322 mapped_all_axes = false;
330 } 323 }
331 } 324 }
332 325
333 if (!mapped_all_axes) { 326 if (!mapped_all_axes) {
334 // For axes who's usage puts them outside the standard axesLengthCap range. 327 // For axes who's usage puts them outside the standard axesLengthCap range.
335 uint32_t next_index = 0; 328 uint32_t next_index = 0;
336 for (UINT i = 0; i < count; i++) { 329 for (UINT i = 0; i < count; i++) {
337 uint32_t usage = axes_caps[i].Range.UsageMin - kAxisMinimumUsageNumber; 330 uint32_t usage = axes_caps[i].Range.UsageMin - kAxisMinimumUsageNumber;
338 if (usage >= WebGamepad::axesLengthCap && 331 if (usage >= WebGamepad::axesLengthCap &&
339 axes_caps[i].UsagePage <= kGameControlsUsagePage) { 332 axes_caps[i].UsagePage <= kGameControlsUsagePage) {
340
341 for (; next_index < WebGamepad::axesLengthCap; ++next_index) { 333 for (; next_index < WebGamepad::axesLengthCap; ++next_index) {
342 if (!gamepad_info->axes[next_index].active) 334 if (!gamepad_info->axes[next_index].active)
343 break; 335 break;
344 } 336 }
345 if (next_index < WebGamepad::axesLengthCap) { 337 if (next_index < WebGamepad::axesLengthCap) {
346 gamepad_info->axes[next_index].caps = axes_caps[i]; 338 gamepad_info->axes[next_index].caps = axes_caps[i];
347 gamepad_info->axes[next_index].value = 0; 339 gamepad_info->axes[next_index].value = 0;
348 gamepad_info->axes[next_index].active = true; 340 gamepad_info->axes[next_index].active = true;
349 gamepad_info->axes[next_index].bitmask = GetBitmask( 341 gamepad_info->axes[next_index].bitmask =
350 axes_caps[i].BitSize); 342 GetBitmask(axes_caps[i].BitSize);
351 gamepad_info->axes_length = 343 gamepad_info->axes_length =
352 std::max(gamepad_info->axes_length, next_index + 1); 344 std::max(gamepad_info->axes_length, next_index + 1);
353 } 345 }
354 } 346 }
355 347
356 if (next_index >= WebGamepad::axesLengthCap) 348 if (next_index >= WebGamepad::axesLengthCap)
357 break; 349 break;
358 } 350 }
359 } 351 }
360 352
361 return gamepad_info.release(); 353 return gamepad_info.release();
362 } 354 }
363 355
364 void RawInputDataFetcher::UpdateGamepad( 356 void RawInputDataFetcher::UpdateGamepad(RAWINPUT* input,
365 RAWINPUT* input, 357 RawGamepadInfo* gamepad_info) {
366 RawGamepadInfo* gamepad_info) {
367 NTSTATUS status; 358 NTSTATUS status;
368 359
369 gamepad_info->report_id++; 360 gamepad_info->report_id++;
370 361
371 // Query button state. 362 // Query button state.
372 if (gamepad_info->buttons_length) { 363 if (gamepad_info->buttons_length) {
373 // Clear the button state 364 // Clear the button state
374 ZeroMemory(gamepad_info->buttons, sizeof(gamepad_info->buttons)); 365 ZeroMemory(gamepad_info->buttons, sizeof(gamepad_info->buttons));
375 ULONG buttons_length = 0; 366 ULONG buttons_length = 0;
376 367
377 hidp_get_usages_ex_(HidP_Input, 368 hidp_get_usages_ex_(HidP_Input, 0, NULL, &buttons_length,
378 0,
379 NULL,
380 &buttons_length,
381 gamepad_info->preparsed_data, 369 gamepad_info->preparsed_data,
382 reinterpret_cast<PCHAR>(input->data.hid.bRawData), 370 reinterpret_cast<PCHAR>(input->data.hid.bRawData),
383 input->data.hid.dwSizeHid); 371 input->data.hid.dwSizeHid);
384 372
385 std::unique_ptr<USAGE_AND_PAGE[]> usages( 373 std::unique_ptr<USAGE_AND_PAGE[]> usages(
386 new USAGE_AND_PAGE[buttons_length]); 374 new USAGE_AND_PAGE[buttons_length]);
387 status = 375 status =
388 hidp_get_usages_ex_(HidP_Input, 376 hidp_get_usages_ex_(HidP_Input, 0, usages.get(), &buttons_length,
389 0,
390 usages.get(),
391 &buttons_length,
392 gamepad_info->preparsed_data, 377 gamepad_info->preparsed_data,
393 reinterpret_cast<PCHAR>(input->data.hid.bRawData), 378 reinterpret_cast<PCHAR>(input->data.hid.bRawData),
394 input->data.hid.dwSizeHid); 379 input->data.hid.dwSizeHid);
395 380
396 if (status == HIDP_STATUS_SUCCESS) { 381 if (status == HIDP_STATUS_SUCCESS) {
397 // Set each reported button to true. 382 // Set each reported button to true.
398 for (uint32_t j = 0; j < buttons_length; j++) { 383 for (uint32_t j = 0; j < buttons_length; j++) {
399 int32_t button_index = usages[j].Usage - 1; 384 int32_t button_index = usages[j].Usage - 1;
400 if (usages[j].UsagePage == kButtonUsagePage && 385 if (usages[j].UsagePage == kButtonUsagePage && button_index >= 0 &&
401 button_index >= 0 &&
402 button_index < 386 button_index <
403 static_cast<int>(blink::WebGamepad::buttonsLengthCap)) { 387 static_cast<int>(blink::WebGamepad::buttonsLengthCap)) {
404 gamepad_info->buttons[button_index] = true; 388 gamepad_info->buttons[button_index] = true;
405 } 389 }
406 } 390 }
407 } 391 }
408 } 392 }
409 393
410 // Query axis state. 394 // Query axis state.
411 ULONG axis_value = 0; 395 ULONG axis_value = 0;
412 LONG scaled_axis_value = 0; 396 LONG scaled_axis_value = 0;
413 for (uint32_t i = 0; i < gamepad_info->axes_length; i++) { 397 for (uint32_t i = 0; i < gamepad_info->axes_length; i++) {
414 RawGamepadAxis* axis = &gamepad_info->axes[i]; 398 RawGamepadAxis* axis = &gamepad_info->axes[i];
415 399
416 // If the min is < 0 we have to query the scaled value, otherwise we need 400 // If the min is < 0 we have to query the scaled value, otherwise we need
417 // the normal unscaled value. 401 // the normal unscaled value.
418 if (axis->caps.LogicalMin < 0) { 402 if (axis->caps.LogicalMin < 0) {
419 status = hidp_get_scaled_usage_value_(HidP_Input, axis->caps.UsagePage, 0, 403 status = hidp_get_scaled_usage_value_(
420 axis->caps.Range.UsageMin, &scaled_axis_value, 404 HidP_Input, axis->caps.UsagePage, 0, axis->caps.Range.UsageMin,
421 gamepad_info->preparsed_data, 405 &scaled_axis_value, gamepad_info->preparsed_data,
422 reinterpret_cast<PCHAR>(input->data.hid.bRawData), 406 reinterpret_cast<PCHAR>(input->data.hid.bRawData),
423 input->data.hid.dwSizeHid); 407 input->data.hid.dwSizeHid);
424 if (status == HIDP_STATUS_SUCCESS) { 408 if (status == HIDP_STATUS_SUCCESS) {
425 axis->value = NormalizeAxis(scaled_axis_value, 409 axis->value = NormalizeAxis(scaled_axis_value, axis->caps.PhysicalMin,
426 axis->caps.PhysicalMin, axis->caps.PhysicalMax); 410 axis->caps.PhysicalMax);
427 } 411 }
428 } else { 412 } else {
429 status = hidp_get_usage_value_(HidP_Input, axis->caps.UsagePage, 0, 413 status = hidp_get_usage_value_(
430 axis->caps.Range.UsageMin, &axis_value, 414 HidP_Input, axis->caps.UsagePage, 0, axis->caps.Range.UsageMin,
431 gamepad_info->preparsed_data, 415 &axis_value, gamepad_info->preparsed_data,
432 reinterpret_cast<PCHAR>(input->data.hid.bRawData), 416 reinterpret_cast<PCHAR>(input->data.hid.bRawData),
433 input->data.hid.dwSizeHid); 417 input->data.hid.dwSizeHid);
434 if (status == HIDP_STATUS_SUCCESS) { 418 if (status == HIDP_STATUS_SUCCESS) {
435 axis->value = NormalizeAxis(axis_value & axis->bitmask, 419 axis->value = NormalizeAxis(axis_value & axis->bitmask,
436 axis->caps.LogicalMin & axis->bitmask, 420 axis->caps.LogicalMin & axis->bitmask,
437 axis->caps.LogicalMax & axis->bitmask); 421 axis->caps.LogicalMax & axis->bitmask);
438 } 422 }
439 } 423 }
440 } 424 }
441 } 425 }
442 426
443 LRESULT RawInputDataFetcher::OnInput(HRAWINPUT input_handle) { 427 LRESULT RawInputDataFetcher::OnInput(HRAWINPUT input_handle) {
444 // Get the size of the input record. 428 // Get the size of the input record.
445 UINT size = 0; 429 UINT size = 0;
446 UINT result = GetRawInputData( 430 UINT result = GetRawInputData(input_handle, RID_INPUT, NULL, &size,
447 input_handle, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); 431 sizeof(RAWINPUTHEADER));
448 if (result == static_cast<UINT>(-1)) { 432 if (result == static_cast<UINT>(-1)) {
449 PLOG(ERROR) << "GetRawInputData() failed"; 433 PLOG(ERROR) << "GetRawInputData() failed";
450 return 0; 434 return 0;
451 } 435 }
452 DCHECK_EQ(0u, result); 436 DCHECK_EQ(0u, result);
453 437
454 // Retrieve the input record. 438 // Retrieve the input record.
455 std::unique_ptr<uint8_t[]> buffer(new uint8_t[size]); 439 std::unique_ptr<uint8_t[]> buffer(new uint8_t[size]);
456 RAWINPUT* input = reinterpret_cast<RAWINPUT*>(buffer.get()); 440 RAWINPUT* input = reinterpret_cast<RAWINPUT*>(buffer.get());
457 result = GetRawInputData( 441 result = GetRawInputData(input_handle, RID_INPUT, buffer.get(), &size,
458 input_handle, RID_INPUT, buffer.get(), &size, sizeof(RAWINPUTHEADER)); 442 sizeof(RAWINPUTHEADER));
459 if (result == static_cast<UINT>(-1)) { 443 if (result == static_cast<UINT>(-1)) {
460 PLOG(ERROR) << "GetRawInputData() failed"; 444 PLOG(ERROR) << "GetRawInputData() failed";
461 return 0; 445 return 0;
462 } 446 }
463 DCHECK_EQ(size, result); 447 DCHECK_EQ(size, result);
464 448
465 // Notify the observer about events generated locally. 449 // Notify the observer about events generated locally.
466 if (input->header.dwType == RIM_TYPEHID && input->header.hDevice != NULL) { 450 if (input->header.dwType == RIM_TYPEHID && input->header.hDevice != NULL) {
467 RawGamepadInfo* gamepad = GetGamepadInfo(input->header.hDevice); 451 RawGamepadInfo* gamepad = GetGamepadInfo(input->header.hDevice);
468 if (gamepad) 452 if (gamepad)
(...skipping 19 matching lines...) Expand all
488 472
489 bool RawInputDataFetcher::GetHidDllFunctions() { 473 bool RawInputDataFetcher::GetHidDllFunctions() {
490 hidp_get_caps_ = NULL; 474 hidp_get_caps_ = NULL;
491 hidp_get_button_caps_ = NULL; 475 hidp_get_button_caps_ = NULL;
492 hidp_get_value_caps_ = NULL; 476 hidp_get_value_caps_ = NULL;
493 hidp_get_usages_ex_ = NULL; 477 hidp_get_usages_ex_ = NULL;
494 hidp_get_usage_value_ = NULL; 478 hidp_get_usage_value_ = NULL;
495 hidp_get_scaled_usage_value_ = NULL; 479 hidp_get_scaled_usage_value_ = NULL;
496 hidd_get_product_string_ = NULL; 480 hidd_get_product_string_ = NULL;
497 481
498 if (!hid_dll_.is_valid()) return false; 482 if (!hid_dll_.is_valid())
483 return false;
499 484
500 hidp_get_caps_ = reinterpret_cast<HidPGetCapsFunc>( 485 hidp_get_caps_ = reinterpret_cast<HidPGetCapsFunc>(
501 hid_dll_.GetFunctionPointer("HidP_GetCaps")); 486 hid_dll_.GetFunctionPointer("HidP_GetCaps"));
502 if (!hidp_get_caps_) 487 if (!hidp_get_caps_)
503 return false; 488 return false;
504 hidp_get_button_caps_ = reinterpret_cast<HidPGetButtonCapsFunc>( 489 hidp_get_button_caps_ = reinterpret_cast<HidPGetButtonCapsFunc>(
505 hid_dll_.GetFunctionPointer("HidP_GetButtonCaps")); 490 hid_dll_.GetFunctionPointer("HidP_GetButtonCaps"));
506 if (!hidp_get_button_caps_) 491 if (!hidp_get_button_caps_)
507 return false; 492 return false;
508 hidp_get_value_caps_ = reinterpret_cast<HidPGetValueCapsFunc>( 493 hidp_get_value_caps_ = reinterpret_cast<HidPGetValueCapsFunc>(
(...skipping 13 matching lines...) Expand all
522 if (!hidp_get_scaled_usage_value_) 507 if (!hidp_get_scaled_usage_value_)
523 return false; 508 return false;
524 hidd_get_product_string_ = reinterpret_cast<HidDGetStringFunc>( 509 hidd_get_product_string_ = reinterpret_cast<HidDGetStringFunc>(
525 hid_dll_.GetFunctionPointer("HidD_GetProductString")); 510 hid_dll_.GetFunctionPointer("HidD_GetProductString"));
526 if (!hidd_get_product_string_) 511 if (!hidd_get_product_string_)
527 return false; 512 return false;
528 513
529 return true; 514 return true;
530 } 515 }
531 516
532 } // namespace content 517 } // namespace device
OLDNEW
« no previous file with comments | « device/gamepad/raw_input_data_fetcher_win.h ('k') | device/gamepad/xbox_data_fetcher_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698