| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/gamepad_platform_data_fetcher_mac.h" | 5 #include "device/gamepad/gamepad_platform_data_fetcher_mac.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <string.h> | 8 #include <string.h> |
| 9 | 9 |
| 10 #include "base/mac/foundation_util.h" | 10 #include "base/mac/foundation_util.h" |
| 11 #include "base/mac/scoped_nsobject.h" | 11 #include "base/mac/scoped_nsobject.h" |
| 12 #include "base/macros.h" | 12 #include "base/macros.h" |
| 13 #include "base/strings/string16.h" | 13 #include "base/strings/string16.h" |
| 14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
| 15 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
| 16 #include "base/time/time.h" | 16 #include "base/time/time.h" |
| 17 | 17 |
| 18 #import <Foundation/Foundation.h> | 18 #import <Foundation/Foundation.h> |
| 19 #include <IOKit/hid/IOHIDKeys.h> | 19 #include <IOKit/hid/IOHIDKeys.h> |
| 20 | 20 |
| 21 using blink::WebGamepad; | 21 using blink::WebGamepad; |
| 22 using blink::WebGamepads; | 22 using blink::WebGamepads; |
| 23 | 23 |
| 24 namespace content { | 24 namespace device { |
| 25 | 25 |
| 26 namespace { | 26 namespace { |
| 27 | 27 |
| 28 void CopyNSStringAsUTF16LittleEndian( | 28 void CopyNSStringAsUTF16LittleEndian(NSString* src, |
| 29 NSString* src, blink::WebUChar* dest, size_t dest_len) { | 29 blink::WebUChar* dest, |
| 30 size_t dest_len) { |
| 30 NSData* as16 = [src dataUsingEncoding:NSUTF16LittleEndianStringEncoding]; | 31 NSData* as16 = [src dataUsingEncoding:NSUTF16LittleEndianStringEncoding]; |
| 31 memset(dest, 0, dest_len); | 32 memset(dest, 0, dest_len); |
| 32 [as16 getBytes:dest length:dest_len - sizeof(blink::WebUChar)]; | 33 [as16 getBytes:dest length:dest_len - sizeof(blink::WebUChar)]; |
| 33 } | 34 } |
| 34 | 35 |
| 35 NSDictionary* DeviceMatching(uint32_t usage_page, uint32_t usage) { | 36 NSDictionary* DeviceMatching(uint32_t usage_page, uint32_t usage) { |
| 36 return [NSDictionary dictionaryWithObjectsAndKeys: | 37 return [NSDictionary |
| 37 [NSNumber numberWithUnsignedInt:usage_page], | 38 dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:usage_page], |
| 38 base::mac::CFToNSCast(CFSTR(kIOHIDDeviceUsagePageKey)), | 39 base::mac::CFToNSCast( |
| 39 [NSNumber numberWithUnsignedInt:usage], | 40 CFSTR(kIOHIDDeviceUsagePageKey)), |
| 40 base::mac::CFToNSCast(CFSTR(kIOHIDDeviceUsageKey)), | 41 [NSNumber numberWithUnsignedInt:usage], |
| 41 nil]; | 42 base::mac::CFToNSCast( |
| 43 CFSTR(kIOHIDDeviceUsageKey)), |
| 44 nil]; |
| 42 } | 45 } |
| 43 | 46 |
| 44 float NormalizeAxis(CFIndex value, CFIndex min, CFIndex max) { | 47 float NormalizeAxis(CFIndex value, CFIndex min, CFIndex max) { |
| 45 return (2.f * (value - min) / static_cast<float>(max - min)) - 1.f; | 48 return (2.f * (value - min) / static_cast<float>(max - min)) - 1.f; |
| 46 } | 49 } |
| 47 | 50 |
| 48 float NormalizeUInt8Axis(uint8_t value, uint8_t min, uint8_t max) { | 51 float NormalizeUInt8Axis(uint8_t value, uint8_t min, uint8_t max) { |
| 49 return (2.f * (value - min) / static_cast<float>(max - min)) - 1.f; | 52 return (2.f * (value - min) / static_cast<float>(max - min)) - 1.f; |
| 50 } | 53 } |
| 51 | 54 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 69 } // namespace | 72 } // namespace |
| 70 | 73 |
| 71 GamepadPlatformDataFetcherMac::GamepadPlatformDataFetcherMac() | 74 GamepadPlatformDataFetcherMac::GamepadPlatformDataFetcherMac() |
| 72 : enabled_(true), paused_(false) { | 75 : enabled_(true), paused_(false) { |
| 73 memset(associated_, 0, sizeof(associated_)); | 76 memset(associated_, 0, sizeof(associated_)); |
| 74 | 77 |
| 75 xbox_fetcher_.reset(new XboxDataFetcher(this)); | 78 xbox_fetcher_.reset(new XboxDataFetcher(this)); |
| 76 if (!xbox_fetcher_->RegisterForNotifications()) | 79 if (!xbox_fetcher_->RegisterForNotifications()) |
| 77 xbox_fetcher_.reset(); | 80 xbox_fetcher_.reset(); |
| 78 | 81 |
| 79 hid_manager_ref_.reset(IOHIDManagerCreate(kCFAllocatorDefault, | 82 hid_manager_ref_.reset( |
| 80 kIOHIDOptionsTypeNone)); | 83 IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone)); |
| 81 if (CFGetTypeID(hid_manager_ref_) != IOHIDManagerGetTypeID()) { | 84 if (CFGetTypeID(hid_manager_ref_) != IOHIDManagerGetTypeID()) { |
| 82 enabled_ = false; | 85 enabled_ = false; |
| 83 return; | 86 return; |
| 84 } | 87 } |
| 85 | 88 |
| 86 base::scoped_nsobject<NSArray> criteria([[NSArray alloc] initWithObjects: | 89 base::scoped_nsobject<NSArray> criteria( |
| 87 DeviceMatching(kGenericDesktopUsagePage, kJoystickUsageNumber), | 90 [[NSArray alloc] initWithObjects:DeviceMatching(kGenericDesktopUsagePage, |
| 88 DeviceMatching(kGenericDesktopUsagePage, kGameUsageNumber), | 91 kJoystickUsageNumber), |
| 89 DeviceMatching(kGenericDesktopUsagePage, kMultiAxisUsageNumber), | 92 DeviceMatching(kGenericDesktopUsagePage, |
| 90 nil]); | 93 kGameUsageNumber), |
| 91 IOHIDManagerSetDeviceMatchingMultiple( | 94 DeviceMatching(kGenericDesktopUsagePage, |
| 92 hid_manager_ref_, | 95 kMultiAxisUsageNumber), |
| 93 base::mac::NSToCFCast(criteria)); | 96 nil]); |
| 97 IOHIDManagerSetDeviceMatchingMultiple(hid_manager_ref_, |
| 98 base::mac::NSToCFCast(criteria)); |
| 94 | 99 |
| 95 RegisterForNotifications(); | 100 RegisterForNotifications(); |
| 96 } | 101 } |
| 97 | 102 |
| 98 void GamepadPlatformDataFetcherMac::RegisterForNotifications() { | 103 void GamepadPlatformDataFetcherMac::RegisterForNotifications() { |
| 99 // Register for plug/unplug notifications. | 104 // Register for plug/unplug notifications. |
| 100 IOHIDManagerRegisterDeviceMatchingCallback( | 105 IOHIDManagerRegisterDeviceMatchingCallback(hid_manager_ref_, |
| 101 hid_manager_ref_, | 106 DeviceAddCallback, this); |
| 102 DeviceAddCallback, | 107 IOHIDManagerRegisterDeviceRemovalCallback(hid_manager_ref_, |
| 103 this); | 108 DeviceRemoveCallback, this); |
| 104 IOHIDManagerRegisterDeviceRemovalCallback( | |
| 105 hid_manager_ref_, | |
| 106 DeviceRemoveCallback, | |
| 107 this); | |
| 108 | 109 |
| 109 // Register for value change notifications. | 110 // Register for value change notifications. |
| 110 IOHIDManagerRegisterInputValueCallback( | 111 IOHIDManagerRegisterInputValueCallback(hid_manager_ref_, ValueChangedCallback, |
| 111 hid_manager_ref_, | 112 this); |
| 112 ValueChangedCallback, | |
| 113 this); | |
| 114 | 113 |
| 115 IOHIDManagerScheduleWithRunLoop( | 114 IOHIDManagerScheduleWithRunLoop(hid_manager_ref_, CFRunLoopGetMain(), |
| 116 hid_manager_ref_, | 115 kCFRunLoopDefaultMode); |
| 117 CFRunLoopGetMain(), | |
| 118 kCFRunLoopDefaultMode); | |
| 119 | 116 |
| 120 enabled_ = IOHIDManagerOpen(hid_manager_ref_, | 117 enabled_ = IOHIDManagerOpen(hid_manager_ref_, kIOHIDOptionsTypeNone) == |
| 121 kIOHIDOptionsTypeNone) == kIOReturnSuccess; | 118 kIOReturnSuccess; |
| 122 | 119 |
| 123 if (xbox_fetcher_) | 120 if (xbox_fetcher_) |
| 124 xbox_fetcher_->RegisterForNotifications(); | 121 xbox_fetcher_->RegisterForNotifications(); |
| 125 } | 122 } |
| 126 | 123 |
| 127 void GamepadPlatformDataFetcherMac::UnregisterFromNotifications() { | 124 void GamepadPlatformDataFetcherMac::UnregisterFromNotifications() { |
| 128 IOHIDManagerUnscheduleFromRunLoop( | 125 IOHIDManagerUnscheduleFromRunLoop(hid_manager_ref_, CFRunLoopGetCurrent(), |
| 129 hid_manager_ref_, | 126 kCFRunLoopDefaultMode); |
| 130 CFRunLoopGetCurrent(), | |
| 131 kCFRunLoopDefaultMode); | |
| 132 IOHIDManagerClose(hid_manager_ref_, kIOHIDOptionsTypeNone); | 127 IOHIDManagerClose(hid_manager_ref_, kIOHIDOptionsTypeNone); |
| 133 if (xbox_fetcher_) | 128 if (xbox_fetcher_) |
| 134 xbox_fetcher_->UnregisterFromNotifications(); | 129 xbox_fetcher_->UnregisterFromNotifications(); |
| 135 } | 130 } |
| 136 | 131 |
| 137 void GamepadPlatformDataFetcherMac::PauseHint(bool pause) { | 132 void GamepadPlatformDataFetcherMac::PauseHint(bool pause) { |
| 138 paused_ = pause; | 133 paused_ = pause; |
| 139 } | 134 } |
| 140 | 135 |
| 141 GamepadPlatformDataFetcherMac::~GamepadPlatformDataFetcherMac() { | 136 GamepadPlatformDataFetcherMac::~GamepadPlatformDataFetcherMac() { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 168 InstanceFromContext(context)->ValueChanged(ref); | 163 InstanceFromContext(context)->ValueChanged(ref); |
| 169 } | 164 } |
| 170 | 165 |
| 171 bool GamepadPlatformDataFetcherMac::CheckCollection(IOHIDElementRef element) { | 166 bool GamepadPlatformDataFetcherMac::CheckCollection(IOHIDElementRef element) { |
| 172 // Check that a parent collection of this element matches one of the usage | 167 // Check that a parent collection of this element matches one of the usage |
| 173 // numbers that we are looking for. | 168 // numbers that we are looking for. |
| 174 while ((element = IOHIDElementGetParent(element)) != NULL) { | 169 while ((element = IOHIDElementGetParent(element)) != NULL) { |
| 175 uint32_t usage_page = IOHIDElementGetUsagePage(element); | 170 uint32_t usage_page = IOHIDElementGetUsagePage(element); |
| 176 uint32_t usage = IOHIDElementGetUsage(element); | 171 uint32_t usage = IOHIDElementGetUsage(element); |
| 177 if (usage_page == kGenericDesktopUsagePage) { | 172 if (usage_page == kGenericDesktopUsagePage) { |
| 178 if (usage == kJoystickUsageNumber || | 173 if (usage == kJoystickUsageNumber || usage == kGameUsageNumber || |
| 179 usage == kGameUsageNumber || | |
| 180 usage == kMultiAxisUsageNumber) { | 174 usage == kMultiAxisUsageNumber) { |
| 181 return true; | 175 return true; |
| 182 } | 176 } |
| 183 } | 177 } |
| 184 } | 178 } |
| 185 return false; | 179 return false; |
| 186 } | 180 } |
| 187 | 181 |
| 188 bool GamepadPlatformDataFetcherMac::AddButtonsAndAxes(NSArray* elements, | 182 bool GamepadPlatformDataFetcherMac::AddButtonsAndAxes(NSArray* elements, |
| 189 size_t slot) { | 183 size_t slot) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 206 | 200 |
| 207 uint32_t usage_page = IOHIDElementGetUsagePage(element); | 201 uint32_t usage_page = IOHIDElementGetUsagePage(element); |
| 208 uint32_t usage = IOHIDElementGetUsage(element); | 202 uint32_t usage = IOHIDElementGetUsage(element); |
| 209 if (IOHIDElementGetType(element) == kIOHIDElementTypeInput_Button && | 203 if (IOHIDElementGetType(element) == kIOHIDElementTypeInput_Button && |
| 210 usage_page == kButtonUsagePage) { | 204 usage_page == kButtonUsagePage) { |
| 211 uint32_t button_index = usage - 1; | 205 uint32_t button_index = usage - 1; |
| 212 if (button_index < WebGamepad::buttonsLengthCap) { | 206 if (button_index < WebGamepad::buttonsLengthCap) { |
| 213 associated.hid.button_elements[button_index] = element; | 207 associated.hid.button_elements[button_index] = element; |
| 214 pad.buttonsLength = std::max(pad.buttonsLength, button_index + 1); | 208 pad.buttonsLength = std::max(pad.buttonsLength, button_index + 1); |
| 215 } | 209 } |
| 216 } | 210 } else if (IOHIDElementGetType(element) == kIOHIDElementTypeInput_Misc) { |
| 217 else if (IOHIDElementGetType(element) == kIOHIDElementTypeInput_Misc) { | |
| 218 uint32_t axis_index = usage - kAxisMinimumUsageNumber; | 211 uint32_t axis_index = usage - kAxisMinimumUsageNumber; |
| 219 if (axis_index < WebGamepad::axesLengthCap) { | 212 if (axis_index < WebGamepad::axesLengthCap) { |
| 220 associated.hid.axis_elements[axis_index] = element; | 213 associated.hid.axis_elements[axis_index] = element; |
| 221 pad.axesLength = std::max(pad.axesLength, axis_index + 1); | 214 pad.axesLength = std::max(pad.axesLength, axis_index + 1); |
| 222 } else { | 215 } else { |
| 223 mapped_all_axes = false; | 216 mapped_all_axes = false; |
| 224 } | 217 } |
| 225 } | 218 } |
| 226 } | 219 } |
| 227 | 220 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 if (!pad_state_[slot].data.connected) | 275 if (!pad_state_[slot].data.connected) |
| 283 return slot; | 276 return slot; |
| 284 } | 277 } |
| 285 return WebGamepads::itemsLengthCap; | 278 return WebGamepads::itemsLengthCap; |
| 286 } | 279 } |
| 287 | 280 |
| 288 size_t GamepadPlatformDataFetcherMac::GetSlotForDevice(IOHIDDeviceRef device) { | 281 size_t GamepadPlatformDataFetcherMac::GetSlotForDevice(IOHIDDeviceRef device) { |
| 289 for (size_t slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { | 282 for (size_t slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { |
| 290 // If we already have this device, and it's already connected, don't do | 283 // If we already have this device, and it's already connected, don't do |
| 291 // anything now. | 284 // anything now. |
| 292 if (pad_state_[slot].data.connected && | 285 if (pad_state_[slot].data.connected && !associated_[slot].is_xbox && |
| 293 !associated_[slot].is_xbox && | |
| 294 associated_[slot].hid.device_ref == device) | 286 associated_[slot].hid.device_ref == device) |
| 295 return WebGamepads::itemsLengthCap; | 287 return WebGamepads::itemsLengthCap; |
| 296 } | 288 } |
| 297 return GetEmptySlot(); | 289 return GetEmptySlot(); |
| 298 } | 290 } |
| 299 | 291 |
| 300 size_t GamepadPlatformDataFetcherMac::GetSlotForXboxDevice( | 292 size_t GamepadPlatformDataFetcherMac::GetSlotForXboxDevice( |
| 301 XboxController* device) { | 293 XboxController* device) { |
| 302 for (size_t slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { | 294 for (size_t slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { |
| 303 if (associated_[slot].is_xbox && | 295 if (associated_[slot].is_xbox && |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)))); | 334 IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)))); |
| 343 int vendor_int = [vendor_id intValue]; | 335 int vendor_int = [vendor_id intValue]; |
| 344 int product_int = [product_id intValue]; | 336 int product_int = [product_id intValue]; |
| 345 | 337 |
| 346 char vendor_as_str[5], product_as_str[5]; | 338 char vendor_as_str[5], product_as_str[5]; |
| 347 snprintf(vendor_as_str, sizeof(vendor_as_str), "%04x", vendor_int); | 339 snprintf(vendor_as_str, sizeof(vendor_as_str), "%04x", vendor_int); |
| 348 snprintf(product_as_str, sizeof(product_as_str), "%04x", product_int); | 340 snprintf(product_as_str, sizeof(product_as_str), "%04x", product_int); |
| 349 pad_state_[slot].mapper = | 341 pad_state_[slot].mapper = |
| 350 GetGamepadStandardMappingFunction(vendor_as_str, product_as_str); | 342 GetGamepadStandardMappingFunction(vendor_as_str, product_as_str); |
| 351 | 343 |
| 352 NSString* ident = [NSString stringWithFormat: | 344 NSString* ident = [NSString |
| 353 @"%@ (%sVendor: %04x Product: %04x)", | 345 stringWithFormat:@"%@ (%sVendor: %04x Product: %04x)", product, |
| 354 product, | 346 pad_state_[slot].mapper ? "STANDARD GAMEPAD " : "", |
| 355 pad_state_[slot].mapper ? "STANDARD GAMEPAD " : "", | 347 vendor_int, product_int]; |
| 356 vendor_int, | 348 CopyNSStringAsUTF16LittleEndian(ident, pad_state_[slot].data.id, |
| 357 product_int]; | 349 sizeof(pad_state_[slot].data.id)); |
| 358 CopyNSStringAsUTF16LittleEndian( | |
| 359 ident, | |
| 360 pad_state_[slot].data.id, | |
| 361 sizeof(pad_state_[slot].data.id)); | |
| 362 | 350 |
| 363 if (pad_state_[slot].mapper) { | 351 if (pad_state_[slot].mapper) { |
| 364 CopyNSStringAsUTF16LittleEndian( | 352 CopyNSStringAsUTF16LittleEndian(@"standard", pad_state_[slot].data.mapping, |
| 365 @"standard", | 353 sizeof(pad_state_[slot].data.mapping)); |
| 366 pad_state_[slot].data.mapping, | |
| 367 sizeof(pad_state_[slot].data.mapping)); | |
| 368 } else { | 354 } else { |
| 369 pad_state_[slot].data.mapping[0] = 0; | 355 pad_state_[slot].data.mapping[0] = 0; |
| 370 } | 356 } |
| 371 | 357 |
| 372 base::ScopedCFTypeRef<CFArrayRef> elements( | 358 base::ScopedCFTypeRef<CFArrayRef> elements( |
| 373 IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone)); | 359 IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone)); |
| 374 | 360 |
| 375 if (!AddButtonsAndAxes(CFToNSCast(elements), slot)) | 361 if (!AddButtonsAndAxes(CFToNSCast(elements), slot)) |
| 376 return; | 362 return; |
| 377 | 363 |
| 378 associated_[slot].hid.device_ref = device; | 364 associated_[slot].hid.device_ref = device; |
| 379 pad_state_[slot].data.connected = true; | 365 pad_state_[slot].data.connected = true; |
| 380 pad_state_[slot].axis_mask = 0; | 366 pad_state_[slot].axis_mask = 0; |
| 381 pad_state_[slot].button_mask = 0; | 367 pad_state_[slot].button_mask = 0; |
| 382 } | 368 } |
| 383 | 369 |
| 384 void GamepadPlatformDataFetcherMac::DeviceRemove(IOHIDDeviceRef device) { | 370 void GamepadPlatformDataFetcherMac::DeviceRemove(IOHIDDeviceRef device) { |
| 385 if (!enabled_) | 371 if (!enabled_) |
| 386 return; | 372 return; |
| 387 | 373 |
| 388 // Find the index for this device. | 374 // Find the index for this device. |
| 389 size_t slot; | 375 size_t slot; |
| 390 for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { | 376 for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { |
| 391 if (pad_state_[slot].data.connected && | 377 if (pad_state_[slot].data.connected && !associated_[slot].is_xbox && |
| 392 !associated_[slot].is_xbox && | |
| 393 associated_[slot].hid.device_ref == device) | 378 associated_[slot].hid.device_ref == device) |
| 394 break; | 379 break; |
| 395 } | 380 } |
| 396 DCHECK(slot < WebGamepads::itemsLengthCap); | 381 DCHECK(slot < WebGamepads::itemsLengthCap); |
| 397 // Leave associated device_ref so that it will be reconnected in the same | 382 // Leave associated device_ref so that it will be reconnected in the same |
| 398 // location. Simply mark it as disconnected. | 383 // location. Simply mark it as disconnected. |
| 399 pad_state_[slot].data.connected = false; | 384 pad_state_[slot].data.connected = false; |
| 400 } | 385 } |
| 401 | 386 |
| 402 void GamepadPlatformDataFetcherMac::ValueChanged(IOHIDValueRef value) { | 387 void GamepadPlatformDataFetcherMac::ValueChanged(IOHIDValueRef value) { |
| 403 if (!enabled_ || paused_) | 388 if (!enabled_ || paused_) |
| 404 return; | 389 return; |
| 405 | 390 |
| 406 IOHIDElementRef element = IOHIDValueGetElement(value); | 391 IOHIDElementRef element = IOHIDValueGetElement(value); |
| 407 IOHIDDeviceRef device = IOHIDElementGetDevice(element); | 392 IOHIDDeviceRef device = IOHIDElementGetDevice(element); |
| 408 | 393 |
| 409 // Find device slot. | 394 // Find device slot. |
| 410 size_t slot; | 395 size_t slot; |
| 411 for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { | 396 for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { |
| 412 if (pad_state_[slot].data.connected && | 397 if (pad_state_[slot].data.connected && !associated_[slot].is_xbox && |
| 413 !associated_[slot].is_xbox && | |
| 414 associated_[slot].hid.device_ref == device) | 398 associated_[slot].hid.device_ref == device) |
| 415 break; | 399 break; |
| 416 } | 400 } |
| 417 if (slot == WebGamepads::itemsLengthCap) | 401 if (slot == WebGamepads::itemsLengthCap) |
| 418 return; | 402 return; |
| 419 | 403 |
| 420 WebGamepad& pad = pad_state_[slot].data; | 404 WebGamepad& pad = pad_state_[slot].data; |
| 421 AssociatedData& associated = associated_[slot]; | 405 AssociatedData& associated = associated_[slot]; |
| 422 | 406 |
| 423 uint32_t value_length = IOHIDValueGetLength(value); | 407 uint32_t value_length = IOHIDValueGetLength(value); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 | 457 |
| 474 size_t slot = GetSlotForXboxDevice(device); | 458 size_t slot = GetSlotForXboxDevice(device); |
| 475 | 459 |
| 476 // We can't handle this many connected devices. | 460 // We can't handle this many connected devices. |
| 477 if (slot == WebGamepads::itemsLengthCap) | 461 if (slot == WebGamepads::itemsLengthCap) |
| 478 return; | 462 return; |
| 479 | 463 |
| 480 device->SetLEDPattern( | 464 device->SetLEDPattern( |
| 481 (XboxController::LEDPattern)(XboxController::LED_FLASH_TOP_LEFT + slot)); | 465 (XboxController::LEDPattern)(XboxController::LED_FLASH_TOP_LEFT + slot)); |
| 482 | 466 |
| 483 NSString* ident = | 467 NSString* ident = [NSString |
| 484 [NSString stringWithFormat: | 468 stringWithFormat:@"%@ (STANDARD GAMEPAD Vendor: %04x Product: %04x)", |
| 485 @"%@ (STANDARD GAMEPAD Vendor: %04x Product: %04x)", | 469 device->GetControllerType() == |
| 486 device->GetControllerType() == XboxController::XBOX_360_CONTROLLER | 470 XboxController::XBOX_360_CONTROLLER |
| 487 ? @"Xbox 360 Controller" | 471 ? @"Xbox 360 Controller" |
| 488 : @"Xbox One Controller", | 472 : @"Xbox One Controller", |
| 489 device->GetProductId(), device->GetVendorId()]; | 473 device->GetProductId(), device->GetVendorId()]; |
| 490 CopyNSStringAsUTF16LittleEndian( | 474 CopyNSStringAsUTF16LittleEndian(ident, pad_state_[slot].data.id, |
| 491 ident, | 475 sizeof(pad_state_[slot].data.id)); |
| 492 pad_state_[slot].data.id, | |
| 493 sizeof(pad_state_[slot].data.id)); | |
| 494 | 476 |
| 495 CopyNSStringAsUTF16LittleEndian( | 477 CopyNSStringAsUTF16LittleEndian(@"standard", pad_state_[slot].data.mapping, |
| 496 @"standard", | 478 sizeof(pad_state_[slot].data.mapping)); |
| 497 pad_state_[slot].data.mapping, | |
| 498 sizeof(pad_state_[slot].data.mapping)); | |
| 499 | 479 |
| 500 associated_[slot].is_xbox = true; | 480 associated_[slot].is_xbox = true; |
| 501 associated_[slot].xbox.device = device; | 481 associated_[slot].xbox.device = device; |
| 502 associated_[slot].xbox.location_id = device->location_id(); | 482 associated_[slot].xbox.location_id = device->location_id(); |
| 503 pad_state_[slot].data.connected = true; | 483 pad_state_[slot].data.connected = true; |
| 504 pad_state_[slot].data.axesLength = 4; | 484 pad_state_[slot].data.axesLength = 4; |
| 505 pad_state_[slot].data.buttonsLength = 17; | 485 pad_state_[slot].data.buttonsLength = 17; |
| 506 pad_state_[slot].data.timestamp = 0; | 486 pad_state_[slot].data.timestamp = 0; |
| 507 pad_state_[slot].mapper = 0; | 487 pad_state_[slot].mapper = 0; |
| 508 pad_state_[slot].axis_mask = 0; | 488 pad_state_[slot].axis_mask = 0; |
| 509 pad_state_[slot].button_mask = 0; | 489 pad_state_[slot].button_mask = 0; |
| 510 } | 490 } |
| 511 | 491 |
| 512 void GamepadPlatformDataFetcherMac::XboxDeviceRemove(XboxController* device) { | 492 void GamepadPlatformDataFetcherMac::XboxDeviceRemove(XboxController* device) { |
| 513 if (!enabled_) | 493 if (!enabled_) |
| 514 return; | 494 return; |
| 515 | 495 |
| 516 // Find the index for this device. | 496 // Find the index for this device. |
| 517 size_t slot; | 497 size_t slot; |
| 518 for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { | 498 for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { |
| 519 if (pad_state_[slot].data.connected && | 499 if (pad_state_[slot].data.connected && associated_[slot].is_xbox && |
| 520 associated_[slot].is_xbox && | |
| 521 associated_[slot].xbox.device == device) | 500 associated_[slot].xbox.device == device) |
| 522 break; | 501 break; |
| 523 } | 502 } |
| 524 DCHECK(slot < WebGamepads::itemsLengthCap); | 503 DCHECK(slot < WebGamepads::itemsLengthCap); |
| 525 // Leave associated location id so that the controller will be reconnected in | 504 // Leave associated location id so that the controller will be reconnected in |
| 526 // the same slot if it is plugged in again. Simply mark it as disconnected. | 505 // the same slot if it is plugged in again. Simply mark it as disconnected. |
| 527 pad_state_[slot].data.connected = false; | 506 pad_state_[slot].data.connected = false; |
| 528 } | 507 } |
| 529 | 508 |
| 530 void GamepadPlatformDataFetcherMac::XboxValueChanged( | 509 void GamepadPlatformDataFetcherMac::XboxValueChanged( |
| 531 XboxController* device, const XboxController::Data& data) { | 510 XboxController* device, |
| 511 const XboxController::Data& data) { |
| 532 // Find device slot. | 512 // Find device slot. |
| 533 size_t slot; | 513 size_t slot; |
| 534 for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { | 514 for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { |
| 535 if (pad_state_[slot].data.connected && | 515 if (pad_state_[slot].data.connected && associated_[slot].is_xbox && |
| 536 associated_[slot].is_xbox && | |
| 537 associated_[slot].xbox.device == device) | 516 associated_[slot].xbox.device == device) |
| 538 break; | 517 break; |
| 539 } | 518 } |
| 540 if (slot == WebGamepads::itemsLengthCap) | 519 if (slot == WebGamepads::itemsLengthCap) |
| 541 return; | 520 return; |
| 542 | 521 |
| 543 WebGamepad& pad = pad_state_[slot].data; | 522 WebGamepad& pad = pad_state_[slot].data; |
| 544 | 523 |
| 545 for (size_t i = 0; i < 6; i++) { | 524 for (size_t i = 0; i < 6; i++) { |
| 546 pad.buttons[i].pressed = data.buttons[i]; | 525 pad.buttons[i].pressed = data.buttons[i]; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 565 if (!enabled_ && !xbox_fetcher_) { | 544 if (!enabled_ && !xbox_fetcher_) { |
| 566 pads->length = 0; | 545 pads->length = 0; |
| 567 return; | 546 return; |
| 568 } | 547 } |
| 569 | 548 |
| 570 pads->length = WebGamepads::itemsLengthCap; | 549 pads->length = WebGamepads::itemsLengthCap; |
| 571 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) | 550 for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) |
| 572 MapAndSanitizeGamepadData(&pad_state_[i], &pads->items[i]); | 551 MapAndSanitizeGamepadData(&pad_state_[i], &pads->items[i]); |
| 573 } | 552 } |
| 574 | 553 |
| 575 } // namespace content | 554 } // namespace device |
| OLD | NEW |