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 "device/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> |
16 | 16 |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 #include "base/mac/foundation_util.h" | 18 #include "base/mac/foundation_util.h" |
19 | 19 |
| 20 using blink::WebGamepad; |
| 21 |
| 22 namespace device { |
| 23 |
20 namespace { | 24 namespace { |
| 25 |
21 const int kVendorMicrosoft = 0x045e; | 26 const int kVendorMicrosoft = 0x045e; |
22 const int kProductXbox360Controller = 0x028e; | 27 const int kProductXbox360Controller = 0x028e; |
23 const int kProductXboxOneController = 0x02d1; | 28 const int kProductXboxOneController = 0x02d1; |
24 | 29 |
25 const int kXbox360ReadEndpoint = 1; | 30 const int kXbox360ReadEndpoint = 1; |
26 const int kXbox360ControlEndpoint = 2; | 31 const int kXbox360ControlEndpoint = 2; |
27 | 32 |
28 const int kXboxOneReadEndpoint = 2; | 33 const int kXboxOneReadEndpoint = 2; |
29 const int kXboxOneControlEndpoint = 1; | 34 const int kXboxOneControlEndpoint = 1; |
30 | 35 |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 normalized_data->buttons[13] = data.dpad_right; | 220 normalized_data->buttons[13] = data.dpad_right; |
216 normalized_data->buttons[14] = data.sync; | 221 normalized_data->buttons[14] = data.sync; |
217 normalized_data->triggers[0] = NormalizeXboxOneTrigger(data.trigger_left); | 222 normalized_data->triggers[0] = NormalizeXboxOneTrigger(data.trigger_left); |
218 normalized_data->triggers[1] = NormalizeXboxOneTrigger(data.trigger_right); | 223 normalized_data->triggers[1] = NormalizeXboxOneTrigger(data.trigger_right); |
219 NormalizeAxis(data.stick_left_x, data.stick_left_y, kLeftThumbDeadzone, | 224 NormalizeAxis(data.stick_left_x, data.stick_left_y, kLeftThumbDeadzone, |
220 &normalized_data->axes[0], &normalized_data->axes[1]); | 225 &normalized_data->axes[0], &normalized_data->axes[1]); |
221 NormalizeAxis(data.stick_right_x, data.stick_right_y, kRightThumbDeadzone, | 226 NormalizeAxis(data.stick_right_x, data.stick_right_y, kRightThumbDeadzone, |
222 &normalized_data->axes[2], &normalized_data->axes[3]); | 227 &normalized_data->axes[2], &normalized_data->axes[3]); |
223 } | 228 } |
224 | 229 |
| 230 void CopyNSStringAsUTF16LittleEndian(NSString* src, |
| 231 blink::WebUChar* dest, |
| 232 size_t dest_len) { |
| 233 NSData* as16 = [src dataUsingEncoding:NSUTF16LittleEndianStringEncoding]; |
| 234 memset(dest, 0, dest_len); |
| 235 [as16 getBytes:dest length:dest_len - sizeof(blink::WebUChar)]; |
| 236 } |
| 237 |
225 } // namespace | 238 } // namespace |
226 | 239 |
227 XboxController::XboxController(Delegate* delegate) | 240 XboxController::XboxController(Delegate* delegate) |
228 : device_(NULL), | 241 : device_(NULL), |
229 interface_(NULL), | 242 interface_(NULL), |
230 device_is_open_(false), | 243 device_is_open_(false), |
231 interface_is_open_(false), | 244 interface_is_open_(false), |
232 read_buffer_size_(0), | 245 read_buffer_size_(0), |
233 led_pattern_(LED_NUM_PATTERNS), | 246 led_pattern_(LED_NUM_PATTERNS), |
234 location_id_(0), | 247 location_id_(0), |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 (UInt32)length, WriteComplete, buffer); | 601 (UInt32)length, WriteComplete, buffer); |
589 if (kr != KERN_SUCCESS) { | 602 if (kr != KERN_SUCCESS) { |
590 delete[] buffer; | 603 delete[] buffer; |
591 IOError(); | 604 IOError(); |
592 return; | 605 return; |
593 } | 606 } |
594 } | 607 } |
595 | 608 |
596 //----------------------------------------------------------------------------- | 609 //----------------------------------------------------------------------------- |
597 | 610 |
598 XboxDataFetcher::XboxDataFetcher(Delegate* delegate) | 611 XboxDataFetcher::XboxDataFetcher() |
599 : delegate_(delegate), listening_(false), source_(NULL), port_(NULL) {} | 612 : listening_(false), source_(NULL), port_(NULL) {} |
600 | 613 |
601 XboxDataFetcher::~XboxDataFetcher() { | 614 XboxDataFetcher::~XboxDataFetcher() { |
602 while (!controllers_.empty()) { | 615 while (!controllers_.empty()) { |
603 RemoveController(*controllers_.begin()); | 616 RemoveController(*controllers_.begin()); |
604 } | 617 } |
605 UnregisterFromNotifications(); | 618 UnregisterFromNotifications(); |
606 } | 619 } |
607 | 620 |
| 621 GamepadSource XboxDataFetcher::source() { |
| 622 return Factory::static_source(); |
| 623 } |
| 624 |
| 625 void XboxDataFetcher::GetGamepadData(bool devices_changed_hint) { |
| 626 // This just loops through all the connected pads and "pings" them to indicate |
| 627 // that they're still active. |
| 628 for (const auto& controller : controllers_) { |
| 629 GetPadState(controller->location_id()); |
| 630 } |
| 631 } |
| 632 |
| 633 void XboxDataFetcher::OnAddedToProvider() { |
| 634 RegisterForNotifications(); |
| 635 } |
| 636 |
608 void XboxDataFetcher::DeviceAdded(void* context, io_iterator_t iterator) { | 637 void XboxDataFetcher::DeviceAdded(void* context, io_iterator_t iterator) { |
609 DCHECK(context); | 638 DCHECK(context); |
610 XboxDataFetcher* fetcher = static_cast<XboxDataFetcher*>(context); | 639 XboxDataFetcher* fetcher = static_cast<XboxDataFetcher*>(context); |
611 io_service_t ref; | 640 io_service_t ref; |
612 while ((ref = IOIteratorNext(iterator))) { | 641 while ((ref = IOIteratorNext(iterator))) { |
613 base::mac::ScopedIOObject<io_service_t> scoped_ref(ref); | 642 base::mac::ScopedIOObject<io_service_t> scoped_ref(ref); |
614 XboxController* controller = new XboxController(fetcher); | 643 XboxController* controller = new XboxController(fetcher); |
615 if (controller->OpenDevice(ref)) { | 644 if (controller->OpenDevice(ref)) { |
616 fetcher->AddController(controller); | 645 fetcher->AddController(controller); |
617 } else { | 646 } else { |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 if ((*i)->location_id() == location_id) | 754 if ((*i)->location_id() == location_id) |
726 return *i; | 755 return *i; |
727 } | 756 } |
728 return NULL; | 757 return NULL; |
729 } | 758 } |
730 | 759 |
731 void XboxDataFetcher::AddController(XboxController* controller) { | 760 void XboxDataFetcher::AddController(XboxController* controller) { |
732 DCHECK(!ControllerForLocation(controller->location_id())) | 761 DCHECK(!ControllerForLocation(controller->location_id())) |
733 << "Controller with location ID " << controller->location_id() | 762 << "Controller with location ID " << controller->location_id() |
734 << " already exists in the set of controllers."; | 763 << " already exists in the set of controllers."; |
| 764 PadState* state = GetPadState(controller->location_id()); |
| 765 if (!state) { |
| 766 delete controller; |
| 767 return; // No available slot for this device |
| 768 } |
| 769 |
735 controllers_.insert(controller); | 770 controllers_.insert(controller); |
736 delegate_->XboxDeviceAdd(controller); | 771 |
| 772 controller->SetLEDPattern((XboxController::LEDPattern)( |
| 773 XboxController::LED_FLASH_TOP_LEFT + controller->location_id())); |
| 774 |
| 775 NSString* ident = [NSString |
| 776 stringWithFormat:@"%@ (STANDARD GAMEPAD Vendor: %04x Product: %04x)", |
| 777 controller->GetControllerType() == |
| 778 XboxController::XBOX_360_CONTROLLER |
| 779 ? @"Xbox 360 Controller" |
| 780 : @"Xbox One Controller", |
| 781 controller->GetProductId(), controller->GetVendorId()]; |
| 782 CopyNSStringAsUTF16LittleEndian(ident, state->data.id, |
| 783 sizeof(state->data.id)); |
| 784 |
| 785 CopyNSStringAsUTF16LittleEndian(@"standard", state->data.mapping, |
| 786 sizeof(state->data.mapping)); |
| 787 |
| 788 state->data.connected = true; |
| 789 state->data.axesLength = 4; |
| 790 state->data.buttonsLength = 17; |
| 791 state->data.timestamp = 0; |
| 792 state->mapper = 0; |
| 793 state->axis_mask = 0; |
| 794 state->button_mask = 0; |
737 } | 795 } |
738 | 796 |
739 void XboxDataFetcher::RemoveController(XboxController* controller) { | 797 void XboxDataFetcher::RemoveController(XboxController* controller) { |
740 delegate_->XboxDeviceRemove(controller); | |
741 controllers_.erase(controller); | 798 controllers_.erase(controller); |
742 delete controller; | 799 delete controller; |
743 } | 800 } |
744 | 801 |
745 void XboxDataFetcher::RemoveControllerByLocationID(uint32_t location_id) { | 802 void XboxDataFetcher::RemoveControllerByLocationID(uint32_t location_id) { |
746 XboxController* controller = NULL; | 803 XboxController* controller = NULL; |
747 for (std::set<XboxController*>::iterator i = controllers_.begin(); | 804 for (std::set<XboxController*>::iterator i = controllers_.begin(); |
748 i != controllers_.end(); ++i) { | 805 i != controllers_.end(); ++i) { |
749 if ((*i)->location_id() == location_id) { | 806 if ((*i)->location_id() == location_id) { |
750 controller = *i; | 807 controller = *i; |
751 break; | 808 break; |
752 } | 809 } |
753 } | 810 } |
754 if (controller) | 811 if (controller) |
755 RemoveController(controller); | 812 RemoveController(controller); |
756 } | 813 } |
757 | 814 |
758 void XboxDataFetcher::XboxControllerGotData(XboxController* controller, | 815 void XboxDataFetcher::XboxControllerGotData(XboxController* controller, |
759 const XboxController::Data& data) { | 816 const XboxController::Data& data) { |
760 delegate_->XboxValueChanged(controller, data); | 817 PadState* state = GetPadState(controller->location_id()); |
| 818 if (!state) |
| 819 return; // No available slot for this device |
| 820 |
| 821 WebGamepad& pad = state->data; |
| 822 |
| 823 for (size_t i = 0; i < 6; i++) { |
| 824 pad.buttons[i].pressed = data.buttons[i]; |
| 825 pad.buttons[i].value = data.buttons[i] ? 1.0f : 0.0f; |
| 826 } |
| 827 pad.buttons[6].pressed = data.triggers[0] > kDefaultButtonPressedThreshold; |
| 828 pad.buttons[6].value = data.triggers[0]; |
| 829 pad.buttons[7].pressed = data.triggers[1] > kDefaultButtonPressedThreshold; |
| 830 pad.buttons[7].value = data.triggers[1]; |
| 831 for (size_t i = 8; i < 17; i++) { |
| 832 pad.buttons[i].pressed = data.buttons[i - 2]; |
| 833 pad.buttons[i].value = data.buttons[i - 2] ? 1.0f : 0.0f; |
| 834 } |
| 835 for (size_t i = 0; i < arraysize(data.axes); i++) { |
| 836 pad.axes[i] = data.axes[i]; |
| 837 } |
| 838 |
| 839 pad.timestamp = base::TimeTicks::Now().ToInternalValue(); |
761 } | 840 } |
762 | 841 |
763 void XboxDataFetcher::XboxControllerError(XboxController* controller) { | 842 void XboxDataFetcher::XboxControllerError(XboxController* controller) { |
764 RemoveController(controller); | 843 RemoveController(controller); |
765 } | 844 } |
| 845 |
| 846 } // namespace device |
OLD | NEW |