Index: content/browser/gamepad/xbox_data_fetcher_mac.mm |
diff --git a/content/browser/gamepad/xbox_data_fetcher_mac.cc b/content/browser/gamepad/xbox_data_fetcher_mac.mm |
similarity index 90% |
rename from content/browser/gamepad/xbox_data_fetcher_mac.cc |
rename to content/browser/gamepad/xbox_data_fetcher_mac.mm |
index 7ef35318d1847cea3fc16d818564430f16229e7f..3163e313c41e6aae57543ff463e9c8548532162d 100644 |
--- a/content/browser/gamepad/xbox_data_fetcher_mac.cc |
+++ b/content/browser/gamepad/xbox_data_fetcher_mac.mm |
@@ -17,6 +17,10 @@ |
#include "base/logging.h" |
#include "base/mac/foundation_util.h" |
+using blink::WebGamepad; |
+ |
+namespace content { |
+ |
namespace { |
const int kVendorMicrosoft = 0x045e; |
const int kProductXbox360Controller = 0x028e; |
@@ -233,6 +237,13 @@ void NormalizeXboxOneButtonData(const XboxOneButtonData& data, |
&normalized_data->axes[3]); |
} |
+void CopyNSStringAsUTF16LittleEndian( |
+ NSString* src, blink::WebUChar* dest, size_t dest_len) { |
+ NSData* as16 = [src dataUsingEncoding:NSUTF16LittleEndianStringEncoding]; |
+ memset(dest, 0, dest_len); |
+ [as16 getBytes:dest length:dest_len - sizeof(blink::WebUChar)]; |
+} |
+ |
} // namespace |
XboxController::XboxController(Delegate* delegate) |
@@ -623,9 +634,8 @@ void XboxController::WriteXboxOneInit() { |
//----------------------------------------------------------------------------- |
-XboxDataFetcher::XboxDataFetcher(Delegate* delegate) |
- : delegate_(delegate), |
- listening_(false), |
+XboxDataFetcher::XboxDataFetcher() |
+ : listening_(false), |
source_(NULL), |
port_(NULL) { |
} |
@@ -637,6 +647,18 @@ XboxDataFetcher::~XboxDataFetcher() { |
UnregisterFromNotifications(); |
} |
+void XboxDataFetcher::GetGamepadData(bool devices_changed_hint) { |
+ // This just loops through all the connected pads and "pings" them to indicate |
+ // that they're still active. |
+ for (const auto& controller : controllers_) { |
+ provider()->GetPadState(GAMEPAD_SOURCE_MAC_XBOX, controller->location_id()); |
+ } |
+} |
+ |
+void XboxDataFetcher::OnAddedToProvider() { |
+ RegisterForNotifications(); |
+} |
+ |
void XboxDataFetcher::DeviceAdded(void* context, io_iterator_t iterator) { |
DCHECK(context); |
XboxDataFetcher* fetcher = static_cast<XboxDataFetcher*>(context); |
@@ -775,12 +797,46 @@ void XboxDataFetcher::AddController(XboxController* controller) { |
DCHECK(!ControllerForLocation(controller->location_id())) |
<< "Controller with location ID " << controller->location_id() |
<< " already exists in the set of controllers."; |
+ |
+ PadState* state = provider()->GetPadState(GAMEPAD_SOURCE_MAC_XBOX, |
+ controller->location_id()); |
+ if (!state) { |
+ delete controller; |
+ return; // No available slot for this device |
+ } |
+ |
controllers_.insert(controller); |
- delegate_->XboxDeviceAdd(controller); |
+ |
+ controller->SetLEDPattern( |
+ (XboxController::LEDPattern)(XboxController::LED_FLASH_TOP_LEFT + |
+ controller->location_id())); |
+ |
+ NSString* ident = [NSString stringWithFormat: |
+ @"%@ (STANDARD GAMEPAD Vendor: %04x Product: %04x)", |
+ controller->GetControllerType() == XboxController::XBOX_360_CONTROLLER |
+ ? @"Xbox 360 Controller" |
+ : @"Xbox One Controller", |
+ controller->GetProductId(), controller->GetVendorId()]; |
+ CopyNSStringAsUTF16LittleEndian( |
+ ident, |
+ state->data.id, |
+ sizeof(state->data.id)); |
+ |
+ CopyNSStringAsUTF16LittleEndian( |
+ @"standard", |
+ state->data.mapping, |
+ sizeof(state->data.mapping)); |
+ |
+ state->data.connected = true; |
+ state->data.axesLength = 4; |
+ state->data.buttonsLength = 17; |
+ state->data.timestamp = 0; |
+ state->mapper = 0; |
+ state->axis_mask = 0; |
+ state->button_mask = 0; |
} |
void XboxDataFetcher::RemoveController(XboxController* controller) { |
- delegate_->XboxDeviceRemove(controller); |
controllers_.erase(controller); |
delete controller; |
} |
@@ -801,9 +857,34 @@ void XboxDataFetcher::RemoveControllerByLocationID(uint32_t location_id) { |
void XboxDataFetcher::XboxControllerGotData(XboxController* controller, |
const XboxController::Data& data) { |
- delegate_->XboxValueChanged(controller, data); |
+ PadState* state = provider()->GetPadState(GAMEPAD_SOURCE_MAC_XBOX, |
+ controller->location_id()); |
+ if (!state) |
+ return; // No available slot for this device |
+ |
+ WebGamepad& pad = state->data; |
+ |
+ for (size_t i = 0; i < 6; i++) { |
+ pad.buttons[i].pressed = data.buttons[i]; |
+ pad.buttons[i].value = data.buttons[i] ? 1.0f : 0.0f; |
+ } |
+ pad.buttons[6].pressed = data.triggers[0] > kDefaultButtonPressedThreshold; |
+ pad.buttons[6].value = data.triggers[0]; |
+ pad.buttons[7].pressed = data.triggers[1] > kDefaultButtonPressedThreshold; |
+ pad.buttons[7].value = data.triggers[1]; |
+ for (size_t i = 8; i < 17; i++) { |
+ pad.buttons[i].pressed = data.buttons[i - 2]; |
+ pad.buttons[i].value = data.buttons[i - 2] ? 1.0f : 0.0f; |
+ } |
+ for (size_t i = 0; i < arraysize(data.axes); i++) { |
+ pad.axes[i] = data.axes[i]; |
+ } |
+ |
+ pad.timestamp = base::TimeTicks::Now().ToInternalValue(); |
} |
void XboxDataFetcher::XboxControllerError(XboxController* controller) { |
RemoveController(controller); |
} |
+ |
+} // namespace content |