OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |