Index: device/gamepad/xbox_data_fetcher_mac.mm |
diff --git a/device/gamepad/xbox_data_fetcher_mac.cc b/device/gamepad/xbox_data_fetcher_mac.mm |
similarity index 89% |
rename from device/gamepad/xbox_data_fetcher_mac.cc |
rename to device/gamepad/xbox_data_fetcher_mac.mm |
index 4c526a7c4c58335e3b7c0fb53f1090527bda13ce..7b15fc72b228714bd9f00569ad0eba30fb3a2b0c 100644 |
--- a/device/gamepad/xbox_data_fetcher_mac.cc |
+++ b/device/gamepad/xbox_data_fetcher_mac.mm |
@@ -17,7 +17,12 @@ |
#include "base/logging.h" |
#include "base/mac/foundation_util.h" |
+using blink::WebGamepad; |
+ |
+namespace device { |
+ |
namespace { |
+ |
const int kVendorMicrosoft = 0x045e; |
const int kProductXbox360Controller = 0x028e; |
const int kProductXboxOneController = 0x02d1; |
@@ -222,6 +227,14 @@ void NormalizeXboxOneButtonData(const XboxOneButtonData& data, |
&normalized_data->axes[2], &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) |
@@ -595,8 +608,8 @@ void XboxController::WriteXboxOneInit() { |
//----------------------------------------------------------------------------- |
-XboxDataFetcher::XboxDataFetcher(Delegate* delegate) |
- : delegate_(delegate), listening_(false), source_(NULL), port_(NULL) {} |
+XboxDataFetcher::XboxDataFetcher() |
+ : listening_(false), source_(NULL), port_(NULL) {} |
XboxDataFetcher::~XboxDataFetcher() { |
while (!controllers_.empty()) { |
@@ -605,6 +618,22 @@ XboxDataFetcher::~XboxDataFetcher() { |
UnregisterFromNotifications(); |
} |
+GamepadSource XboxDataFetcher::source() { |
+ return Factory::static_source(); |
+} |
+ |
+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_) { |
+ GetPadState(controller->location_id()); |
+ } |
+} |
+ |
+void XboxDataFetcher::OnAddedToProvider() { |
+ RegisterForNotifications(); |
+} |
+ |
void XboxDataFetcher::DeviceAdded(void* context, io_iterator_t iterator) { |
DCHECK(context); |
XboxDataFetcher* fetcher = static_cast<XboxDataFetcher*>(context); |
@@ -732,12 +761,40 @@ 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 = GetPadState(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; |
} |
@@ -757,9 +814,33 @@ void XboxDataFetcher::RemoveControllerByLocationID(uint32_t location_id) { |
void XboxDataFetcher::XboxControllerGotData(XboxController* controller, |
const XboxController::Data& data) { |
- delegate_->XboxValueChanged(controller, data); |
+ PadState* state = GetPadState(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 device |