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

Side by Side Diff: device/gamepad/xbox_data_fetcher_mac.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/xbox_data_fetcher_mac.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/xbox_data_fetcher_mac.h" 5 #include "device/gamepad/xbox_data_fetcher_mac.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <limits> 9 #include <limits>
10 10
11 #include <CoreFoundation/CoreFoundation.h> 11 #include <CoreFoundation/CoreFoundation.h>
12 #include <IOKit/IOCFPlugIn.h> 12 #include <IOKit/IOCFPlugIn.h>
13 #include <IOKit/IOKitLib.h> 13 #include <IOKit/IOKitLib.h>
14 #include <IOKit/usb/IOUSBLib.h> 14 #include <IOKit/usb/IOUSBLib.h>
15 #include <IOKit/usb/USB.h> 15 #include <IOKit/usb/USB.h>
(...skipping 26 matching lines...) Expand all
42 XBOX_ONE_STATUS_MESSAGE_BUTTONS = 0x20, 42 XBOX_ONE_STATUS_MESSAGE_BUTTONS = 0x20,
43 }; 43 };
44 44
45 enum { 45 enum {
46 CONTROL_MESSAGE_SET_RUMBLE = 0, 46 CONTROL_MESSAGE_SET_RUMBLE = 0,
47 CONTROL_MESSAGE_SET_LED = 1, 47 CONTROL_MESSAGE_SET_LED = 1,
48 }; 48 };
49 49
50 #pragma pack(push, 1) 50 #pragma pack(push, 1)
51 struct Xbox360ButtonData { 51 struct Xbox360ButtonData {
52 bool dpad_up : 1; 52 bool dpad_up : 1;
53 bool dpad_down : 1; 53 bool dpad_down : 1;
54 bool dpad_left : 1; 54 bool dpad_left : 1;
55 bool dpad_right : 1; 55 bool dpad_right : 1;
56 56
57 bool start : 1; 57 bool start : 1;
58 bool back : 1; 58 bool back : 1;
59 bool stick_left_click : 1; 59 bool stick_left_click : 1;
60 bool stick_right_click : 1; 60 bool stick_right_click : 1;
61 61
62 bool bumper_left : 1; 62 bool bumper_left : 1;
63 bool bumper_right : 1; 63 bool bumper_right : 1;
64 bool guide : 1; 64 bool guide : 1;
65 bool dummy1 : 1; // Always 0. 65 bool dummy1 : 1; // Always 0.
66 66
67 bool a : 1; 67 bool a : 1;
68 bool b : 1; 68 bool b : 1;
69 bool x : 1; 69 bool x : 1;
70 bool y : 1; 70 bool y : 1;
71 71
72 uint8_t trigger_left; 72 uint8_t trigger_left;
73 uint8_t trigger_right; 73 uint8_t trigger_right;
74 74
75 int16_t stick_left_x; 75 int16_t stick_left_x;
76 int16_t stick_left_y; 76 int16_t stick_left_y;
77 int16_t stick_right_x; 77 int16_t stick_right_x;
78 int16_t stick_right_y; 78 int16_t stick_right_y;
79 79
80 // Always 0. 80 // Always 0.
81 uint32_t dummy2; 81 uint32_t dummy2;
82 uint16_t dummy3; 82 uint16_t dummy3;
83 }; 83 };
84 84
85 struct XboxOneButtonData { 85 struct XboxOneButtonData {
86 bool sync : 1; 86 bool sync : 1;
87 bool dummy1 : 1; // Always 0. 87 bool dummy1 : 1; // Always 0.
88 bool start : 1; 88 bool start : 1;
89 bool back : 1; 89 bool back : 1;
90 90
91 bool a : 1; 91 bool a : 1;
92 bool b : 1; 92 bool b : 1;
93 bool x : 1; 93 bool x : 1;
94 bool y : 1; 94 bool y : 1;
95 95
96 bool dpad_up : 1; 96 bool dpad_up : 1;
97 bool dpad_down : 1; 97 bool dpad_down : 1;
98 bool dpad_left : 1; 98 bool dpad_left : 1;
99 bool dpad_right : 1; 99 bool dpad_right : 1;
100 100
101 bool bumper_left : 1; 101 bool bumper_left : 1;
102 bool bumper_right : 1; 102 bool bumper_right : 1;
103 bool stick_left_click : 1; 103 bool stick_left_click : 1;
104 bool stick_right_click : 1; 104 bool stick_right_click : 1;
105 105
106 uint16_t trigger_left; 106 uint16_t trigger_left;
107 uint16_t trigger_right; 107 uint16_t trigger_right;
108 108
109 int16_t stick_left_x; 109 int16_t stick_left_x;
110 int16_t stick_left_y; 110 int16_t stick_left_y;
111 int16_t stick_right_x; 111 int16_t stick_right_x;
112 int16_t stick_right_y; 112 int16_t stick_right_y;
113 }; 113 };
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 159
160 float NormalizeTrigger(uint8_t value) { 160 float NormalizeTrigger(uint8_t value) {
161 return value < kXbox360TriggerDeadzone 161 return value < kXbox360TriggerDeadzone
162 ? 0 162 ? 0
163 : static_cast<float>(value - kXbox360TriggerDeadzone) / 163 : static_cast<float>(value - kXbox360TriggerDeadzone) /
164 (std::numeric_limits<uint8_t>::max() - 164 (std::numeric_limits<uint8_t>::max() -
165 kXbox360TriggerDeadzone); 165 kXbox360TriggerDeadzone);
166 } 166 }
167 167
168 float NormalizeXboxOneTrigger(uint16_t value) { 168 float NormalizeXboxOneTrigger(uint16_t value) {
169 return value < kXboxOneTriggerDeadzone ? 0 : 169 return value < kXboxOneTriggerDeadzone
170 static_cast<float>(value - kXboxOneTriggerDeadzone) / 170 ? 0
171 (kXboxOneTriggerMax - kXboxOneTriggerDeadzone); 171 : static_cast<float>(value - kXboxOneTriggerDeadzone) /
172 (kXboxOneTriggerMax - kXboxOneTriggerDeadzone);
172 } 173 }
173 174
174 void NormalizeXbox360ButtonData(const Xbox360ButtonData& data, 175 void NormalizeXbox360ButtonData(const Xbox360ButtonData& data,
175 XboxController::Data* normalized_data) { 176 XboxController::Data* normalized_data) {
176 normalized_data->buttons[0] = data.a; 177 normalized_data->buttons[0] = data.a;
177 normalized_data->buttons[1] = data.b; 178 normalized_data->buttons[1] = data.b;
178 normalized_data->buttons[2] = data.x; 179 normalized_data->buttons[2] = data.x;
179 normalized_data->buttons[3] = data.y; 180 normalized_data->buttons[3] = data.y;
180 normalized_data->buttons[4] = data.bumper_left; 181 normalized_data->buttons[4] = data.bumper_left;
181 normalized_data->buttons[5] = data.bumper_right; 182 normalized_data->buttons[5] = data.bumper_right;
182 normalized_data->buttons[6] = data.back; 183 normalized_data->buttons[6] = data.back;
183 normalized_data->buttons[7] = data.start; 184 normalized_data->buttons[7] = data.start;
184 normalized_data->buttons[8] = data.stick_left_click; 185 normalized_data->buttons[8] = data.stick_left_click;
185 normalized_data->buttons[9] = data.stick_right_click; 186 normalized_data->buttons[9] = data.stick_right_click;
186 normalized_data->buttons[10] = data.dpad_up; 187 normalized_data->buttons[10] = data.dpad_up;
187 normalized_data->buttons[11] = data.dpad_down; 188 normalized_data->buttons[11] = data.dpad_down;
188 normalized_data->buttons[12] = data.dpad_left; 189 normalized_data->buttons[12] = data.dpad_left;
189 normalized_data->buttons[13] = data.dpad_right; 190 normalized_data->buttons[13] = data.dpad_right;
190 normalized_data->buttons[14] = data.guide; 191 normalized_data->buttons[14] = data.guide;
191 normalized_data->triggers[0] = NormalizeTrigger(data.trigger_left); 192 normalized_data->triggers[0] = NormalizeTrigger(data.trigger_left);
192 normalized_data->triggers[1] = NormalizeTrigger(data.trigger_right); 193 normalized_data->triggers[1] = NormalizeTrigger(data.trigger_right);
193 NormalizeAxis(data.stick_left_x, 194 NormalizeAxis(data.stick_left_x, data.stick_left_y, kLeftThumbDeadzone,
194 data.stick_left_y, 195 &normalized_data->axes[0], &normalized_data->axes[1]);
195 kLeftThumbDeadzone, 196 NormalizeAxis(data.stick_right_x, data.stick_right_y, kRightThumbDeadzone,
196 &normalized_data->axes[0], 197 &normalized_data->axes[2], &normalized_data->axes[3]);
197 &normalized_data->axes[1]);
198 NormalizeAxis(data.stick_right_x,
199 data.stick_right_y,
200 kRightThumbDeadzone,
201 &normalized_data->axes[2],
202 &normalized_data->axes[3]);
203 } 198 }
204 199
205 void NormalizeXboxOneButtonData(const XboxOneButtonData& data, 200 void NormalizeXboxOneButtonData(const XboxOneButtonData& data,
206 XboxController::Data* normalized_data) { 201 XboxController::Data* normalized_data) {
207 normalized_data->buttons[0] = data.a; 202 normalized_data->buttons[0] = data.a;
208 normalized_data->buttons[1] = data.b; 203 normalized_data->buttons[1] = data.b;
209 normalized_data->buttons[2] = data.x; 204 normalized_data->buttons[2] = data.x;
210 normalized_data->buttons[3] = data.y; 205 normalized_data->buttons[3] = data.y;
211 normalized_data->buttons[4] = data.bumper_left; 206 normalized_data->buttons[4] = data.bumper_left;
212 normalized_data->buttons[5] = data.bumper_right; 207 normalized_data->buttons[5] = data.bumper_right;
213 normalized_data->buttons[6] = data.back; 208 normalized_data->buttons[6] = data.back;
214 normalized_data->buttons[7] = data.start; 209 normalized_data->buttons[7] = data.start;
215 normalized_data->buttons[8] = data.stick_left_click; 210 normalized_data->buttons[8] = data.stick_left_click;
216 normalized_data->buttons[9] = data.stick_right_click; 211 normalized_data->buttons[9] = data.stick_right_click;
217 normalized_data->buttons[10] = data.dpad_up; 212 normalized_data->buttons[10] = data.dpad_up;
218 normalized_data->buttons[11] = data.dpad_down; 213 normalized_data->buttons[11] = data.dpad_down;
219 normalized_data->buttons[12] = data.dpad_left; 214 normalized_data->buttons[12] = data.dpad_left;
220 normalized_data->buttons[13] = data.dpad_right; 215 normalized_data->buttons[13] = data.dpad_right;
221 normalized_data->buttons[14] = data.sync; 216 normalized_data->buttons[14] = data.sync;
222 normalized_data->triggers[0] = NormalizeXboxOneTrigger(data.trigger_left); 217 normalized_data->triggers[0] = NormalizeXboxOneTrigger(data.trigger_left);
223 normalized_data->triggers[1] = NormalizeXboxOneTrigger(data.trigger_right); 218 normalized_data->triggers[1] = NormalizeXboxOneTrigger(data.trigger_right);
224 NormalizeAxis(data.stick_left_x, 219 NormalizeAxis(data.stick_left_x, data.stick_left_y, kLeftThumbDeadzone,
225 data.stick_left_y, 220 &normalized_data->axes[0], &normalized_data->axes[1]);
226 kLeftThumbDeadzone, 221 NormalizeAxis(data.stick_right_x, data.stick_right_y, kRightThumbDeadzone,
227 &normalized_data->axes[0], 222 &normalized_data->axes[2], &normalized_data->axes[3]);
228 &normalized_data->axes[1]);
229 NormalizeAxis(data.stick_right_x,
230 data.stick_right_y,
231 kRightThumbDeadzone,
232 &normalized_data->axes[2],
233 &normalized_data->axes[3]);
234 } 223 }
235 224
236 } // namespace 225 } // namespace
237 226
238 XboxController::XboxController(Delegate* delegate) 227 XboxController::XboxController(Delegate* delegate)
239 : device_(NULL), 228 : device_(NULL),
240 interface_(NULL), 229 interface_(NULL),
241 device_is_open_(false), 230 device_is_open_(false),
242 interface_is_open_(false), 231 interface_is_open_(false),
243 read_buffer_size_(0), 232 read_buffer_size_(0),
244 led_pattern_(LED_NUM_PATTERNS), 233 led_pattern_(LED_NUM_PATTERNS),
245 location_id_(0), 234 location_id_(0),
246 delegate_(delegate), 235 delegate_(delegate),
247 controller_type_(UNKNOWN_CONTROLLER), 236 controller_type_(UNKNOWN_CONTROLLER),
248 read_endpoint_(0), 237 read_endpoint_(0),
249 control_endpoint_(0) { 238 control_endpoint_(0) {}
250 }
251 239
252 XboxController::~XboxController() { 240 XboxController::~XboxController() {
253 if (source_) 241 if (source_)
254 CFRunLoopSourceInvalidate(source_); 242 CFRunLoopSourceInvalidate(source_);
255 if (interface_ && interface_is_open_) 243 if (interface_ && interface_is_open_)
256 (*interface_)->USBInterfaceClose(interface_); 244 (*interface_)->USBInterfaceClose(interface_);
257 if (device_ && device_is_open_) 245 if (device_ && device_is_open_)
258 (*device_)->USBDeviceClose(device_); 246 (*device_)->USBDeviceClose(device_);
259 } 247 }
260 248
261 bool XboxController::OpenDevice(io_service_t service) { 249 bool XboxController::OpenDevice(io_service_t service) {
262 IOCFPlugInInterface **plugin; 250 IOCFPlugInInterface** plugin;
263 SInt32 score; // Unused, but required for IOCreatePlugInInterfaceForService. 251 SInt32 score; // Unused, but required for IOCreatePlugInInterfaceForService.
264 kern_return_t kr = 252 kern_return_t kr = IOCreatePlugInInterfaceForService(
265 IOCreatePlugInInterfaceForService(service, 253 service, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin,
266 kIOUSBDeviceUserClientTypeID, 254 &score);
267 kIOCFPlugInInterfaceID,
268 &plugin,
269 &score);
270 if (kr != KERN_SUCCESS) 255 if (kr != KERN_SUCCESS)
271 return false; 256 return false;
272 base::mac::ScopedIOPluginInterface<IOCFPlugInInterface> plugin_ref(plugin); 257 base::mac::ScopedIOPluginInterface<IOCFPlugInInterface> plugin_ref(plugin);
273 258
274 HRESULT res = 259 HRESULT res = (*plugin)->QueryInterface(
275 (*plugin)->QueryInterface(plugin, 260 plugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID320),
276 CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID320), 261 (LPVOID*)&device_);
277 (LPVOID *)&device_);
278 if (!SUCCEEDED(res) || !device_) 262 if (!SUCCEEDED(res) || !device_)
279 return false; 263 return false;
280 264
281 UInt16 vendor_id; 265 UInt16 vendor_id;
282 kr = (*device_)->GetDeviceVendor(device_, &vendor_id); 266 kr = (*device_)->GetDeviceVendor(device_, &vendor_id);
283 if (kr != KERN_SUCCESS || vendor_id != kVendorMicrosoft) 267 if (kr != KERN_SUCCESS || vendor_id != kVendorMicrosoft)
284 return false; 268 return false;
285 269
286 UInt16 product_id; 270 UInt16 product_id;
287 kr = (*device_)->GetDeviceProduct(device_, &product_id); 271 kr = (*device_)->GetDeviceProduct(device_, &product_id);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 // There should be exactly one USB interface which matches the requested 335 // There should be exactly one USB interface which matches the requested
352 // settings. 336 // settings.
353 io_service_t usb_interface = IOIteratorNext(iter); 337 io_service_t usb_interface = IOIteratorNext(iter);
354 if (!usb_interface) 338 if (!usb_interface)
355 return false; 339 return false;
356 340
357 // We need to make an InterfaceInterface to communicate with the device 341 // We need to make an InterfaceInterface to communicate with the device
358 // endpoint. This is the same process as earlier: first make a 342 // endpoint. This is the same process as earlier: first make a
359 // PluginInterface from the io_service then make the InterfaceInterface from 343 // PluginInterface from the io_service then make the InterfaceInterface from
360 // that. 344 // that.
361 IOCFPlugInInterface **plugin_interface; 345 IOCFPlugInInterface** plugin_interface;
362 kr = IOCreatePlugInInterfaceForService(usb_interface, 346 kr = IOCreatePlugInInterfaceForService(
363 kIOUSBInterfaceUserClientTypeID, 347 usb_interface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID,
364 kIOCFPlugInInterfaceID, 348 &plugin_interface, &score);
365 &plugin_interface,
366 &score);
367 if (kr != KERN_SUCCESS || !plugin_interface) 349 if (kr != KERN_SUCCESS || !plugin_interface)
368 return false; 350 return false;
369 base::mac::ScopedIOPluginInterface<IOCFPlugInInterface> interface_ref( 351 base::mac::ScopedIOPluginInterface<IOCFPlugInInterface> interface_ref(
370 plugin_interface); 352 plugin_interface);
371 353
372 // Release the USB interface, and any subsequent interfaces returned by the 354 // Release the USB interface, and any subsequent interfaces returned by the
373 // iterator. (There shouldn't be any, but in case a future device does 355 // iterator. (There shouldn't be any, but in case a future device does
374 // contain more interfaces, this will serve to avoid memory leaks.) 356 // contain more interfaces, this will serve to avoid memory leaks.)
375 do { 357 do {
376 IOObjectRelease(usb_interface); 358 IOObjectRelease(usb_interface);
377 } while ((usb_interface = IOIteratorNext(iter))); 359 } while ((usb_interface = IOIteratorNext(iter)));
378 360
379 // Actually create the interface. 361 // Actually create the interface.
380 res = (*plugin_interface)->QueryInterface( 362 res = (*plugin_interface)
381 plugin_interface, 363 ->QueryInterface(plugin_interface,
382 CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID300), 364 CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID300),
383 (LPVOID *)&interface_); 365 (LPVOID*)&interface_);
384 366
385 if (!SUCCEEDED(res) || !interface_) 367 if (!SUCCEEDED(res) || !interface_)
386 return false; 368 return false;
387 369
388 // Actually open the interface. 370 // Actually open the interface.
389 kr = (*interface_)->USBInterfaceOpen(interface_); 371 kr = (*interface_)->USBInterfaceOpen(interface_);
390 if (kr != KERN_SUCCESS) 372 if (kr != KERN_SUCCESS)
391 return false; 373 return false;
392 interface_is_open_ = true; 374 interface_is_open_ = true;
393 375
(...skipping 11 matching lines...) Expand all
405 if (kr != KERN_SUCCESS || num_endpoints < 2) 387 if (kr != KERN_SUCCESS || num_endpoints < 2)
406 return false; 388 return false;
407 389
408 for (int i = 1; i <= 2; i++) { 390 for (int i = 1; i <= 2; i++) {
409 uint8_t direction; 391 uint8_t direction;
410 uint8_t number; 392 uint8_t number;
411 uint8_t transfer_type; 393 uint8_t transfer_type;
412 uint16_t max_packet_size; 394 uint16_t max_packet_size;
413 uint8_t interval; 395 uint8_t interval;
414 396
415 kr = (*interface_)->GetPipeProperties(interface_, 397 kr = (*interface_)
416 i, 398 ->GetPipeProperties(interface_, i, &direction, &number,
417 &direction, 399 &transfer_type, &max_packet_size, &interval);
418 &number,
419 &transfer_type,
420 &max_packet_size,
421 &interval);
422 if (kr != KERN_SUCCESS || transfer_type != kUSBInterrupt) { 400 if (kr != KERN_SUCCESS || transfer_type != kUSBInterrupt) {
423 return false; 401 return false;
424 } 402 }
425 if (i == read_endpoint_) { 403 if (i == read_endpoint_) {
426 if (direction != kUSBIn) 404 if (direction != kUSBIn)
427 return false; 405 return false;
428 read_buffer_.reset(new uint8_t[max_packet_size]); 406 read_buffer_.reset(new uint8_t[max_packet_size]);
429 read_buffer_size_ = max_packet_size; 407 read_buffer_size_ = max_packet_size;
430 QueueRead(); 408 QueueRead();
431 } else if (i == control_endpoint_) { 409 } else if (i == control_endpoint_) {
(...skipping 17 matching lines...) Expand all
449 void XboxController::SetLEDPattern(LEDPattern pattern) { 427 void XboxController::SetLEDPattern(LEDPattern pattern) {
450 led_pattern_ = pattern; 428 led_pattern_ = pattern;
451 const UInt8 length = 3; 429 const UInt8 length = 3;
452 430
453 // This buffer will be released in WriteComplete when WritePipeAsync 431 // This buffer will be released in WriteComplete when WritePipeAsync
454 // finishes. 432 // finishes.
455 UInt8* buffer = new UInt8[length]; 433 UInt8* buffer = new UInt8[length];
456 buffer[0] = static_cast<UInt8>(CONTROL_MESSAGE_SET_LED); 434 buffer[0] = static_cast<UInt8>(CONTROL_MESSAGE_SET_LED);
457 buffer[1] = length; 435 buffer[1] = length;
458 buffer[2] = static_cast<UInt8>(pattern); 436 buffer[2] = static_cast<UInt8>(pattern);
459 kern_return_t kr = (*interface_)->WritePipeAsync(interface_, 437 kern_return_t kr =
460 control_endpoint_, 438 (*interface_)
461 buffer, 439 ->WritePipeAsync(interface_, control_endpoint_, buffer,
462 (UInt32)length, 440 (UInt32)length, WriteComplete, buffer);
463 WriteComplete,
464 buffer);
465 if (kr != KERN_SUCCESS) { 441 if (kr != KERN_SUCCESS) {
466 delete[] buffer; 442 delete[] buffer;
467 IOError(); 443 IOError();
468 return; 444 return;
469 } 445 }
470 } 446 }
471 447
472 int XboxController::GetVendorId() const { 448 int XboxController::GetVendorId() const {
473 return kVendorMicrosoft; 449 return kVendorMicrosoft;
474 } 450 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 delegate_->XboxControllerGotData(this, normalized_data); 555 delegate_->XboxControllerGotData(this, normalized_data);
580 break; 556 break;
581 } 557 }
582 default: 558 default:
583 // Unknown packet: ignore! 559 // Unknown packet: ignore!
584 break; 560 break;
585 } 561 }
586 } 562 }
587 563
588 void XboxController::QueueRead() { 564 void XboxController::QueueRead() {
589 kern_return_t kr = (*interface_)->ReadPipeAsync(interface_, 565 kern_return_t kr =
590 read_endpoint_, 566 (*interface_)
591 read_buffer_.get(), 567 ->ReadPipeAsync(interface_, read_endpoint_, read_buffer_.get(),
592 read_buffer_size_, 568 read_buffer_size_, GotData, this);
593 GotData,
594 this);
595 if (kr != KERN_SUCCESS) 569 if (kr != KERN_SUCCESS)
596 IOError(); 570 IOError();
597 } 571 }
598 572
599 void XboxController::IOError() { 573 void XboxController::IOError() {
600 delegate_->XboxControllerError(this); 574 delegate_->XboxControllerError(this);
601 } 575 }
602 576
603 void XboxController::WriteXboxOneInit() { 577 void XboxController::WriteXboxOneInit() {
604 const UInt8 length = 2; 578 const UInt8 length = 2;
605 579
606 // This buffer will be released in WriteComplete when WritePipeAsync 580 // This buffer will be released in WriteComplete when WritePipeAsync
607 // finishes. 581 // finishes.
608 UInt8* buffer = new UInt8[length]; 582 UInt8* buffer = new UInt8[length];
609 buffer[0] = 0x05; 583 buffer[0] = 0x05;
610 buffer[1] = 0x20; 584 buffer[1] = 0x20;
611 kern_return_t kr = (*interface_)->WritePipeAsync(interface_, 585 kern_return_t kr =
612 control_endpoint_, 586 (*interface_)
613 buffer, 587 ->WritePipeAsync(interface_, control_endpoint_, buffer,
614 (UInt32)length, 588 (UInt32)length, WriteComplete, buffer);
615 WriteComplete,
616 buffer);
617 if (kr != KERN_SUCCESS) { 589 if (kr != KERN_SUCCESS) {
618 delete[] buffer; 590 delete[] buffer;
619 IOError(); 591 IOError();
620 return; 592 return;
621 } 593 }
622 } 594 }
623 595
624 //----------------------------------------------------------------------------- 596 //-----------------------------------------------------------------------------
625 597
626 XboxDataFetcher::XboxDataFetcher(Delegate* delegate) 598 XboxDataFetcher::XboxDataFetcher(Delegate* delegate)
627 : delegate_(delegate), 599 : delegate_(delegate), listening_(false), source_(NULL), port_(NULL) {}
628 listening_(false),
629 source_(NULL),
630 port_(NULL) {
631 }
632 600
633 XboxDataFetcher::~XboxDataFetcher() { 601 XboxDataFetcher::~XboxDataFetcher() {
634 while (!controllers_.empty()) { 602 while (!controllers_.empty()) {
635 RemoveController(*controllers_.begin()); 603 RemoveController(*controllers_.begin());
636 } 604 }
637 UnregisterFromNotifications(); 605 UnregisterFromNotifications();
638 } 606 }
639 607
640 void XboxDataFetcher::DeviceAdded(void* context, io_iterator_t iterator) { 608 void XboxDataFetcher::DeviceAdded(void* context, io_iterator_t iterator) {
641 DCHECK(context); 609 DCHECK(context);
(...skipping 10 matching lines...) Expand all
652 } 620 }
653 } 621 }
654 622
655 void XboxDataFetcher::DeviceRemoved(void* context, io_iterator_t iterator) { 623 void XboxDataFetcher::DeviceRemoved(void* context, io_iterator_t iterator) {
656 DCHECK(context); 624 DCHECK(context);
657 XboxDataFetcher* fetcher = static_cast<XboxDataFetcher*>(context); 625 XboxDataFetcher* fetcher = static_cast<XboxDataFetcher*>(context);
658 io_service_t ref; 626 io_service_t ref;
659 while ((ref = IOIteratorNext(iterator))) { 627 while ((ref = IOIteratorNext(iterator))) {
660 base::mac::ScopedIOObject<io_service_t> scoped_ref(ref); 628 base::mac::ScopedIOObject<io_service_t> scoped_ref(ref);
661 base::ScopedCFTypeRef<CFNumberRef> number( 629 base::ScopedCFTypeRef<CFNumberRef> number(
662 base::mac::CFCastStrict<CFNumberRef>( 630 base::mac::CFCastStrict<CFNumberRef>(IORegistryEntryCreateCFProperty(
663 IORegistryEntryCreateCFProperty(ref, 631 ref, CFSTR(kUSBDevicePropertyLocationID), kCFAllocatorDefault,
664 CFSTR(kUSBDevicePropertyLocationID), 632 kNilOptions)));
665 kCFAllocatorDefault,
666 kNilOptions)));
667 UInt32 location_id = 0; 633 UInt32 location_id = 0;
668 CFNumberGetValue(number, kCFNumberSInt32Type, &location_id); 634 CFNumberGetValue(number, kCFNumberSInt32Type, &location_id);
669 fetcher->RemoveControllerByLocationID(location_id); 635 fetcher->RemoveControllerByLocationID(location_id);
670 } 636 }
671 } 637 }
672 638
673 bool XboxDataFetcher::RegisterForNotifications() { 639 bool XboxDataFetcher::RegisterForNotifications() {
674 if (listening_) 640 if (listening_)
675 return true; 641 return true;
676 port_ = IONotificationPortCreate(kIOMasterPortDefault); 642 port_ = IONotificationPortCreate(kIOMasterPortDefault);
677 if (!port_) 643 if (!port_)
678 return false; 644 return false;
679 source_ = IONotificationPortGetRunLoopSource(port_); 645 source_ = IONotificationPortGetRunLoopSource(port_);
680 if (!source_) 646 if (!source_)
681 return false; 647 return false;
682 CFRunLoopAddSource(CFRunLoopGetCurrent(), source_, kCFRunLoopDefaultMode); 648 CFRunLoopAddSource(CFRunLoopGetCurrent(), source_, kCFRunLoopDefaultMode);
683 649
684 listening_ = true; 650 listening_ = true;
685 651
686 if (!RegisterForDeviceNotifications( 652 if (!RegisterForDeviceNotifications(
687 kVendorMicrosoft, kProductXboxOneController, 653 kVendorMicrosoft, kProductXboxOneController,
688 &xbox_one_device_added_iter_, 654 &xbox_one_device_added_iter_, &xbox_one_device_removed_iter_))
689 &xbox_one_device_removed_iter_))
690 return false; 655 return false;
691 656
692 if (!RegisterForDeviceNotifications( 657 if (!RegisterForDeviceNotifications(
693 kVendorMicrosoft, kProductXbox360Controller, 658 kVendorMicrosoft, kProductXbox360Controller,
694 &xbox_360_device_added_iter_, 659 &xbox_360_device_added_iter_, &xbox_360_device_removed_iter_))
695 &xbox_360_device_removed_iter_))
696 return false; 660 return false;
697 661
698 return true; 662 return true;
699 } 663 }
700 664
701 bool XboxDataFetcher::RegisterForDeviceNotifications( 665 bool XboxDataFetcher::RegisterForDeviceNotifications(
702 int vendor_id, 666 int vendor_id,
703 int product_id, 667 int product_id,
704 base::mac::ScopedIOObject<io_iterator_t>* added_iter, 668 base::mac::ScopedIOObject<io_iterator_t>* added_iter,
705 base::mac::ScopedIOObject<io_iterator_t>* removed_iter) { 669 base::mac::ScopedIOObject<io_iterator_t>* removed_iter) {
706 base::ScopedCFTypeRef<CFNumberRef> vendor_cf(CFNumberCreate( 670 base::ScopedCFTypeRef<CFNumberRef> vendor_cf(
707 kCFAllocatorDefault, kCFNumberSInt32Type, &vendor_id)); 671 CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vendor_id));
708 base::ScopedCFTypeRef<CFNumberRef> product_cf(CFNumberCreate( 672 base::ScopedCFTypeRef<CFNumberRef> product_cf(
709 kCFAllocatorDefault, kCFNumberSInt32Type, &product_id)); 673 CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &product_id));
710 base::ScopedCFTypeRef<CFMutableDictionaryRef> matching_dict( 674 base::ScopedCFTypeRef<CFMutableDictionaryRef> matching_dict(
711 IOServiceMatching(kIOUSBDeviceClassName)); 675 IOServiceMatching(kIOUSBDeviceClassName));
712 if (!matching_dict) 676 if (!matching_dict)
713 return false; 677 return false;
714 CFDictionarySetValue(matching_dict, CFSTR(kUSBVendorID), vendor_cf); 678 CFDictionarySetValue(matching_dict, CFSTR(kUSBVendorID), vendor_cf);
715 CFDictionarySetValue(matching_dict, CFSTR(kUSBProductID), product_cf); 679 CFDictionarySetValue(matching_dict, CFSTR(kUSBProductID), product_cf);
716 680
717 // IOServiceAddMatchingNotification() releases the dictionary when it's done. 681 // IOServiceAddMatchingNotification() releases the dictionary when it's done.
718 // Retain it before each call to IOServiceAddMatchingNotification to keep 682 // Retain it before each call to IOServiceAddMatchingNotification to keep
719 // things balanced. 683 // things balanced.
720 CFRetain(matching_dict); 684 CFRetain(matching_dict);
721 io_iterator_t device_added_iter; 685 io_iterator_t device_added_iter;
722 IOReturn ret; 686 IOReturn ret;
723 ret = IOServiceAddMatchingNotification(port_, 687 ret = IOServiceAddMatchingNotification(port_, kIOFirstMatchNotification,
724 kIOFirstMatchNotification, 688 matching_dict, DeviceAdded, this,
725 matching_dict,
726 DeviceAdded,
727 this,
728 &device_added_iter); 689 &device_added_iter);
729 added_iter->reset(device_added_iter); 690 added_iter->reset(device_added_iter);
730 if (ret != kIOReturnSuccess) { 691 if (ret != kIOReturnSuccess) {
731 LOG(ERROR) << "Error listening for Xbox controller add events: " << ret; 692 LOG(ERROR) << "Error listening for Xbox controller add events: " << ret;
732 return false; 693 return false;
733 } 694 }
734 DeviceAdded(this, added_iter->get()); 695 DeviceAdded(this, added_iter->get());
735 696
736 CFRetain(matching_dict); 697 CFRetain(matching_dict);
737 io_iterator_t device_removed_iter; 698 io_iterator_t device_removed_iter;
738 ret = IOServiceAddMatchingNotification(port_, 699 ret = IOServiceAddMatchingNotification(port_, kIOTerminatedNotification,
739 kIOTerminatedNotification, 700 matching_dict, DeviceRemoved, this,
740 matching_dict,
741 DeviceRemoved,
742 this,
743 &device_removed_iter); 701 &device_removed_iter);
744 removed_iter->reset(device_removed_iter); 702 removed_iter->reset(device_removed_iter);
745 if (ret != kIOReturnSuccess) { 703 if (ret != kIOReturnSuccess) {
746 LOG(ERROR) << "Error listening for Xbox controller remove events: " << ret; 704 LOG(ERROR) << "Error listening for Xbox controller remove events: " << ret;
747 return false; 705 return false;
748 } 706 }
749 DeviceRemoved(this, removed_iter->get()); 707 DeviceRemoved(this, removed_iter->get());
750 return true; 708 return true;
751 } 709 }
752 710
753 void XboxDataFetcher::UnregisterFromNotifications() { 711 void XboxDataFetcher::UnregisterFromNotifications() {
754 if (!listening_) 712 if (!listening_)
755 return; 713 return;
756 listening_ = false; 714 listening_ = false;
757 if (source_) 715 if (source_)
758 CFRunLoopSourceInvalidate(source_); 716 CFRunLoopSourceInvalidate(source_);
759 if (port_) 717 if (port_)
760 IONotificationPortDestroy(port_); 718 IONotificationPortDestroy(port_);
761 port_ = NULL; 719 port_ = NULL;
762 } 720 }
763 721
764 XboxController* XboxDataFetcher::ControllerForLocation(UInt32 location_id) { 722 XboxController* XboxDataFetcher::ControllerForLocation(UInt32 location_id) {
765 for (std::set<XboxController*>::iterator i = controllers_.begin(); 723 for (std::set<XboxController*>::iterator i = controllers_.begin();
766 i != controllers_.end(); 724 i != controllers_.end(); ++i) {
767 ++i) {
768 if ((*i)->location_id() == location_id) 725 if ((*i)->location_id() == location_id)
769 return *i; 726 return *i;
770 } 727 }
771 return NULL; 728 return NULL;
772 } 729 }
773 730
774 void XboxDataFetcher::AddController(XboxController* controller) { 731 void XboxDataFetcher::AddController(XboxController* controller) {
775 DCHECK(!ControllerForLocation(controller->location_id())) 732 DCHECK(!ControllerForLocation(controller->location_id()))
776 << "Controller with location ID " << controller->location_id() 733 << "Controller with location ID " << controller->location_id()
777 << " already exists in the set of controllers."; 734 << " already exists in the set of controllers.";
778 controllers_.insert(controller); 735 controllers_.insert(controller);
779 delegate_->XboxDeviceAdd(controller); 736 delegate_->XboxDeviceAdd(controller);
780 } 737 }
781 738
782 void XboxDataFetcher::RemoveController(XboxController* controller) { 739 void XboxDataFetcher::RemoveController(XboxController* controller) {
783 delegate_->XboxDeviceRemove(controller); 740 delegate_->XboxDeviceRemove(controller);
784 controllers_.erase(controller); 741 controllers_.erase(controller);
785 delete controller; 742 delete controller;
786 } 743 }
787 744
788 void XboxDataFetcher::RemoveControllerByLocationID(uint32_t location_id) { 745 void XboxDataFetcher::RemoveControllerByLocationID(uint32_t location_id) {
789 XboxController* controller = NULL; 746 XboxController* controller = NULL;
790 for (std::set<XboxController*>::iterator i = controllers_.begin(); 747 for (std::set<XboxController*>::iterator i = controllers_.begin();
791 i != controllers_.end(); 748 i != controllers_.end(); ++i) {
792 ++i) {
793 if ((*i)->location_id() == location_id) { 749 if ((*i)->location_id() == location_id) {
794 controller = *i; 750 controller = *i;
795 break; 751 break;
796 } 752 }
797 } 753 }
798 if (controller) 754 if (controller)
799 RemoveController(controller); 755 RemoveController(controller);
800 } 756 }
801 757
802 void XboxDataFetcher::XboxControllerGotData(XboxController* controller, 758 void XboxDataFetcher::XboxControllerGotData(XboxController* controller,
803 const XboxController::Data& data) { 759 const XboxController::Data& data) {
804 delegate_->XboxValueChanged(controller, data); 760 delegate_->XboxValueChanged(controller, data);
805 } 761 }
806 762
807 void XboxDataFetcher::XboxControllerError(XboxController* controller) { 763 void XboxDataFetcher::XboxControllerError(XboxController* controller) {
808 RemoveController(controller); 764 RemoveController(controller);
809 } 765 }
OLDNEW
« no previous file with comments | « device/gamepad/xbox_data_fetcher_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698