Chromium Code Reviews| 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 "content/browser/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 content { | |
| 23 | |
| 20 namespace { | 24 namespace { |
| 21 const int kVendorMicrosoft = 0x045e; | 25 const int kVendorMicrosoft = 0x045e; |
| 22 const int kProductXbox360Controller = 0x028e; | 26 const int kProductXbox360Controller = 0x028e; |
| 23 const int kProductXboxOneController = 0x02d1; | 27 const int kProductXboxOneController = 0x02d1; |
| 24 | 28 |
| 25 const int kXbox360ReadEndpoint = 1; | 29 const int kXbox360ReadEndpoint = 1; |
| 26 const int kXbox360ControlEndpoint = 2; | 30 const int kXbox360ControlEndpoint = 2; |
| 27 | 31 |
| 28 const int kXboxOneReadEndpoint = 2; | 32 const int kXboxOneReadEndpoint = 2; |
| 29 const int kXboxOneControlEndpoint = 1; | 33 const int kXboxOneControlEndpoint = 1; |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 226 kLeftThumbDeadzone, | 230 kLeftThumbDeadzone, |
| 227 &normalized_data->axes[0], | 231 &normalized_data->axes[0], |
| 228 &normalized_data->axes[1]); | 232 &normalized_data->axes[1]); |
| 229 NormalizeAxis(data.stick_right_x, | 233 NormalizeAxis(data.stick_right_x, |
| 230 data.stick_right_y, | 234 data.stick_right_y, |
| 231 kRightThumbDeadzone, | 235 kRightThumbDeadzone, |
| 232 &normalized_data->axes[2], | 236 &normalized_data->axes[2], |
| 233 &normalized_data->axes[3]); | 237 &normalized_data->axes[3]); |
| 234 } | 238 } |
| 235 | 239 |
| 240 void CopyNSStringAsUTF16LittleEndian( | |
| 241 NSString* src, blink::WebUChar* dest, size_t dest_len) { | |
| 242 NSData* as16 = [src dataUsingEncoding:NSUTF16LittleEndianStringEncoding]; | |
| 243 memset(dest, 0, dest_len); | |
| 244 [as16 getBytes:dest length:dest_len - sizeof(blink::WebUChar)]; | |
| 245 } | |
| 246 | |
| 236 } // namespace | 247 } // namespace |
| 237 | 248 |
| 238 XboxController::XboxController(Delegate* delegate) | 249 XboxController::XboxController(Delegate* delegate) |
| 239 : device_(NULL), | 250 : device_(NULL), |
| 240 interface_(NULL), | 251 interface_(NULL), |
| 241 device_is_open_(false), | 252 device_is_open_(false), |
| 242 interface_is_open_(false), | 253 interface_is_open_(false), |
| 243 read_buffer_size_(0), | 254 read_buffer_size_(0), |
| 244 led_pattern_(LED_NUM_PATTERNS), | 255 led_pattern_(LED_NUM_PATTERNS), |
| 245 location_id_(0), | 256 location_id_(0), |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 616 buffer); | 627 buffer); |
| 617 if (kr != KERN_SUCCESS) { | 628 if (kr != KERN_SUCCESS) { |
| 618 delete[] buffer; | 629 delete[] buffer; |
| 619 IOError(); | 630 IOError(); |
| 620 return; | 631 return; |
| 621 } | 632 } |
| 622 } | 633 } |
| 623 | 634 |
| 624 //----------------------------------------------------------------------------- | 635 //----------------------------------------------------------------------------- |
| 625 | 636 |
| 626 XboxDataFetcher::XboxDataFetcher(Delegate* delegate) | 637 XboxDataFetcher::XboxDataFetcher() |
| 627 : delegate_(delegate), | 638 : listening_(false), |
| 628 listening_(false), | |
| 629 source_(NULL), | 639 source_(NULL), |
| 630 port_(NULL) { | 640 port_(NULL) { |
| 631 } | 641 } |
| 632 | 642 |
| 633 XboxDataFetcher::~XboxDataFetcher() { | 643 XboxDataFetcher::~XboxDataFetcher() { |
| 634 while (!controllers_.empty()) { | 644 while (!controllers_.empty()) { |
| 635 RemoveController(*controllers_.begin()); | 645 RemoveController(*controllers_.begin()); |
| 636 } | 646 } |
| 637 UnregisterFromNotifications(); | 647 UnregisterFromNotifications(); |
| 638 } | 648 } |
| 639 | 649 |
| 650 void XboxDataFetcher::GetGamepadData(bool devices_changed_hint) { | |
| 651 // This just loops through all the connected pads and "pings" them to indicate | |
| 652 // that they're still active. | |
| 653 for (const auto& controller : controllers_) { | |
| 654 provider()->GetPadState(GAMEPAD_SOURCE_MAC_XBOX, controller->location_id()); | |
| 655 } | |
| 656 } | |
| 657 | |
| 658 void XboxDataFetcher::OnAddedToProvider() { | |
| 659 RegisterForNotifications(); | |
| 660 } | |
| 661 | |
| 640 void XboxDataFetcher::DeviceAdded(void* context, io_iterator_t iterator) { | 662 void XboxDataFetcher::DeviceAdded(void* context, io_iterator_t iterator) { |
| 641 DCHECK(context); | 663 DCHECK(context); |
| 642 XboxDataFetcher* fetcher = static_cast<XboxDataFetcher*>(context); | 664 XboxDataFetcher* fetcher = static_cast<XboxDataFetcher*>(context); |
| 643 io_service_t ref; | 665 io_service_t ref; |
| 644 while ((ref = IOIteratorNext(iterator))) { | 666 while ((ref = IOIteratorNext(iterator))) { |
| 645 base::mac::ScopedIOObject<io_service_t> scoped_ref(ref); | 667 base::mac::ScopedIOObject<io_service_t> scoped_ref(ref); |
| 646 XboxController* controller = new XboxController(fetcher); | 668 XboxController* controller = new XboxController(fetcher); |
| 647 if (controller->OpenDevice(ref)) { | 669 if (controller->OpenDevice(ref)) { |
| 648 fetcher->AddController(controller); | 670 fetcher->AddController(controller); |
| 649 } else { | 671 } else { |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 768 if ((*i)->location_id() == location_id) | 790 if ((*i)->location_id() == location_id) |
| 769 return *i; | 791 return *i; |
| 770 } | 792 } |
| 771 return NULL; | 793 return NULL; |
| 772 } | 794 } |
| 773 | 795 |
| 774 void XboxDataFetcher::AddController(XboxController* controller) { | 796 void XboxDataFetcher::AddController(XboxController* controller) { |
| 775 DCHECK(!ControllerForLocation(controller->location_id())) | 797 DCHECK(!ControllerForLocation(controller->location_id())) |
| 776 << "Controller with location ID " << controller->location_id() | 798 << "Controller with location ID " << controller->location_id() |
| 777 << " already exists in the set of controllers."; | 799 << " already exists in the set of controllers."; |
| 800 //delegate_->XboxDeviceAdd(controller); | |
|
scottmg
2016/01/18 22:54:52
Delete.
| |
| 801 | |
| 802 PadState* state = provider()->GetPadState(GAMEPAD_SOURCE_MAC_XBOX, | |
| 803 controller->location_id()); | |
| 804 if (!state) { | |
| 805 delete controller; | |
| 806 return; // No available slot for this device | |
| 807 } | |
| 808 | |
| 778 controllers_.insert(controller); | 809 controllers_.insert(controller); |
| 779 delegate_->XboxDeviceAdd(controller); | 810 |
| 811 controller->SetLEDPattern( | |
| 812 (XboxController::LEDPattern)(XboxController::LED_FLASH_TOP_LEFT + | |
| 813 controller->location_id())); | |
| 814 | |
| 815 NSString* ident = [NSString stringWithFormat: | |
| 816 @"%@ (STANDARD GAMEPAD Vendor: %04x Product: %04x)", | |
| 817 controller->GetControllerType() == XboxController::XBOX_360_CONTROLLER | |
| 818 ? @"Xbox 360 Controller" | |
| 819 : @"Xbox One Controller", | |
| 820 controller->GetProductId(), controller->GetVendorId()]; | |
| 821 CopyNSStringAsUTF16LittleEndian( | |
| 822 ident, | |
| 823 state->data.id, | |
| 824 sizeof(state->data.id)); | |
| 825 | |
| 826 CopyNSStringAsUTF16LittleEndian( | |
| 827 @"standard", | |
| 828 state->data.mapping, | |
| 829 sizeof(state->data.mapping)); | |
| 830 | |
| 831 state->data.connected = true; | |
| 832 state->data.axesLength = 4; | |
| 833 state->data.buttonsLength = 17; | |
| 834 state->data.timestamp = 0; | |
| 835 state->mapper = 0; | |
| 836 state->axis_mask = 0; | |
| 837 state->button_mask = 0; | |
| 780 } | 838 } |
| 781 | 839 |
| 782 void XboxDataFetcher::RemoveController(XboxController* controller) { | 840 void XboxDataFetcher::RemoveController(XboxController* controller) { |
| 783 delegate_->XboxDeviceRemove(controller); | 841 //delegate_->XboxDeviceRemove(controller); |
|
scottmg
2016/01/18 22:54:52
Delete.
| |
| 784 controllers_.erase(controller); | 842 controllers_.erase(controller); |
| 785 delete controller; | 843 delete controller; |
| 786 } | 844 } |
| 787 | 845 |
| 788 void XboxDataFetcher::RemoveControllerByLocationID(uint32_t location_id) { | 846 void XboxDataFetcher::RemoveControllerByLocationID(uint32_t location_id) { |
| 789 XboxController* controller = NULL; | 847 XboxController* controller = NULL; |
| 790 for (std::set<XboxController*>::iterator i = controllers_.begin(); | 848 for (std::set<XboxController*>::iterator i = controllers_.begin(); |
| 791 i != controllers_.end(); | 849 i != controllers_.end(); |
| 792 ++i) { | 850 ++i) { |
| 793 if ((*i)->location_id() == location_id) { | 851 if ((*i)->location_id() == location_id) { |
| 794 controller = *i; | 852 controller = *i; |
| 795 break; | 853 break; |
| 796 } | 854 } |
| 797 } | 855 } |
| 798 if (controller) | 856 if (controller) |
| 799 RemoveController(controller); | 857 RemoveController(controller); |
| 800 } | 858 } |
| 801 | 859 |
| 802 void XboxDataFetcher::XboxControllerGotData(XboxController* controller, | 860 void XboxDataFetcher::XboxControllerGotData(XboxController* controller, |
| 803 const XboxController::Data& data) { | 861 const XboxController::Data& data) { |
| 804 delegate_->XboxValueChanged(controller, data); | 862 //delegate_->XboxValueChanged(controller, data); |
|
scottmg
2016/01/18 22:54:52
Delete.
| |
| 863 | |
| 864 PadState* state = provider()->GetPadState(GAMEPAD_SOURCE_MAC_XBOX, | |
| 865 controller->location_id()); | |
| 866 if (!state) | |
| 867 return; // No available slot for this device | |
| 868 | |
| 869 WebGamepad& pad = state->data; | |
| 870 | |
| 871 for (size_t i = 0; i < 6; i++) { | |
| 872 pad.buttons[i].pressed = data.buttons[i]; | |
| 873 pad.buttons[i].value = data.buttons[i] ? 1.0f : 0.0f; | |
| 874 } | |
| 875 pad.buttons[6].pressed = data.triggers[0] > kDefaultButtonPressedThreshold; | |
| 876 pad.buttons[6].value = data.triggers[0]; | |
| 877 pad.buttons[7].pressed = data.triggers[1] > kDefaultButtonPressedThreshold; | |
| 878 pad.buttons[7].value = data.triggers[1]; | |
| 879 for (size_t i = 8; i < 17; i++) { | |
| 880 pad.buttons[i].pressed = data.buttons[i - 2]; | |
| 881 pad.buttons[i].value = data.buttons[i - 2] ? 1.0f : 0.0f; | |
| 882 } | |
| 883 for (size_t i = 0; i < arraysize(data.axes); i++) { | |
| 884 pad.axes[i] = data.axes[i]; | |
| 885 } | |
| 886 | |
| 887 pad.timestamp = base::TimeTicks::Now().ToInternalValue(); | |
| 805 } | 888 } |
| 806 | 889 |
| 807 void XboxDataFetcher::XboxControllerError(XboxController* controller) { | 890 void XboxDataFetcher::XboxControllerError(XboxController* controller) { |
| 808 RemoveController(controller); | 891 RemoveController(controller); |
| 809 } | 892 } |
| 893 | |
| 894 } // namespace content | |
| OLD | NEW |